Initial Commit ...
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Expert Advisor
|
||||
// ----------------------------------------
|
||||
// Name: XEA
|
||||
// Description: this is an expert controller
|
||||
// advisors which provides a mechanism for use them ...
|
||||
//
|
||||
//
|
||||
// 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 XEA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
input group "Commons";
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Including Providers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Logger Library ...
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Common Library ...
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Alert Library ...
|
||||
#include "..\Libraries\x-saherelm.alert.lib.mq5";
|
||||
|
||||
//
|
||||
// Draw Library ...
|
||||
#include "..\Libraries\x-saherelm.draw.lib.mq5";
|
||||
|
||||
// //
|
||||
// // XTM Signal Provider ...
|
||||
// #include "..\Libraries\x-saherelm.xtm.provider.lib.mq5";
|
||||
|
||||
// //
|
||||
// // XTD Signal Provider ...
|
||||
// #include "..\Libraries\x-saherelm.xtd.provider.lib.mq5";
|
||||
|
||||
// //
|
||||
// // XCHMA Signal Provider ...
|
||||
// #include "..\Libraries\x-saherelm.xchma.provider.lib.mq5";
|
||||
|
||||
// //
|
||||
// // XOBD Signal Provider ...
|
||||
// #include "..\Libraries\x-saherelm.xobd.provider.lib.mq5";
|
||||
|
||||
//
|
||||
// XCHLH Signal Provider ...
|
||||
#include "..\Libraries\x-saherelm.xchlh.provider.lib.mq5";
|
||||
|
||||
//
|
||||
// END Including Providers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
logTag = "XEA";
|
||||
drawPrefix = logTag;
|
||||
alertPrefix = logTag;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
// //
|
||||
// // Initialize XTM Provider ...
|
||||
// if (!XTMInitSignalProviderLibrary())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Initialize XTD Provider ...
|
||||
// if (!XTDInitSignalProviderLibrary())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Initialize XCHMA Provider ...
|
||||
// if (!XCHMAInitSignalProviderLibrary())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Initialize XOBD Provider ...
|
||||
// if (!XOBDInitSignalProviderLibrary())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
//
|
||||
// Initialize XCHLH Provider ...
|
||||
if (!XCHLHInitSignalProviderLibrary())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply default Chart Style for EA ...
|
||||
ApplyChartStyle();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
// //
|
||||
// // De Initialize XTM Provider ...
|
||||
// XTMDeinitSignalProviderLibrary(reason);
|
||||
|
||||
// //
|
||||
// // De Initialize XTD Provider ...
|
||||
// XTDDeinitSignalProviderLibrary(reason);
|
||||
|
||||
// //
|
||||
// // De Initialize XCHMA Provider ...
|
||||
// XCHMADeinitSignalProviderLibrary(reason);
|
||||
|
||||
// //
|
||||
// // De Initialize XOBD Provider ...
|
||||
// XOBDDeinitSignalProviderLibrary(reason);
|
||||
|
||||
//
|
||||
// De Initialize XCHLH Provider ...
|
||||
XCHLHDeinitSignalProviderLibrary(reason);
|
||||
|
||||
//
|
||||
// De Init XDraw Library ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!IsNewCandle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// //
|
||||
// // Handle Processing on XTM Signal Provider ...
|
||||
// XTMSignalProviderHandleTick();
|
||||
|
||||
// //
|
||||
// // Handle Processing on XTD Signal Provider ...
|
||||
// XTDSignalProviderHandleTick();
|
||||
|
||||
// //
|
||||
// // Handle Processing on XCHMA Signal Provider ...
|
||||
// XCHMASignalProviderHandleTick();
|
||||
|
||||
// //
|
||||
// // Handle Processing on XOBD Signal Provider ...
|
||||
// XOBDSignalProviderHandleTick();
|
||||
|
||||
//
|
||||
// Handle Processing on XCHLH Signal Provider ...
|
||||
XCHLHSignalProviderHandleTick();
|
||||
}
|
||||
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
|
||||
// //
|
||||
// // Validate XTM Provider Inputs ...
|
||||
// result = XTMValidateInputs();
|
||||
// if (!result) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Validate XTD Provider Inputs ...
|
||||
// result = XTDValidateInputs();
|
||||
// if (!result) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Validate XCHMA Provider Inputs ...
|
||||
// result = XCHMAValidateInputs();
|
||||
// if (!result) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // Validate XOBD Provider Inputs ...
|
||||
// result = XOBDValidateInputs();
|
||||
// if (!result) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
//
|
||||
// Validate XCHLH Provider Inputs ...
|
||||
result = XCHLHValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "Validation of (" + "XEA" + ") Inputs " + (result ? "Succeeded" : "Failed") + " ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,185 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Expert Advisor
|
||||
// ----------------------------------------
|
||||
// Name: XEA
|
||||
// Description: this is an expert controller
|
||||
// advisors which provides a mechanism for use them ...
|
||||
//
|
||||
//
|
||||
// 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 XEA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
input group "Commons";
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Including Providers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Logger Library ...
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Common Library ...
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Alert Library ...
|
||||
#include "..\Libraries\x-saherelm.alert.lib.mq5";
|
||||
|
||||
//
|
||||
// Draw Library ...
|
||||
#include "..\Libraries\x-saherelm.draw.lib.mq5";
|
||||
|
||||
//
|
||||
// XTEST Signal Provider ...
|
||||
#include "..\Libraries\x-saherelm.xtest.provider.lib.mq5";
|
||||
|
||||
//
|
||||
// END Including Providers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
logTag = "XEA";
|
||||
drawPrefix = logTag;
|
||||
alertPrefix = logTag;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize XTEST Provider ...
|
||||
if (!XTESTInitSignalProviderLibrary())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply default Chart Style for EA ...
|
||||
ApplyChartStyle();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
//
|
||||
// De Initialize XTEST Provider ...
|
||||
XTESTDeinitSignalProviderLibrary(reason);
|
||||
|
||||
//
|
||||
// De Init XDraw Library ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!IsNewCandle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Processing on XTEST Signal Provider ...
|
||||
XTESTSignalProviderHandleTick();
|
||||
}
|
||||
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
|
||||
//
|
||||
// Validate XTEST Provider Inputs ...
|
||||
result = XTESTValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "Validation of (" + "XEA" + ") Inputs " + (result ? "Succeeded" : "Failed") + " ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,197 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 = true; // Terminal Alerts
|
||||
input bool mailAlerts = true; // Mail Alerts
|
||||
input bool pushAlerts = true; // 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)
|
||||
{
|
||||
//
|
||||
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);
|
||||
}
|
||||
}
|
||||
void SendAlert(
|
||||
XSignal &signal, // the Signal Object which requred to Alert
|
||||
bool asExecuted = true // determines Alert Signal as Executed Signal or not
|
||||
)
|
||||
{
|
||||
//
|
||||
// Prepare Message ...
|
||||
string message = asExecuted ? ExecutedSignalToString(signal) : SignalToString(signal);
|
||||
|
||||
//
|
||||
// Do Alerting ...
|
||||
SendAlert(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.
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 ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,161 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Logger Library
|
||||
// ---------------------------------------
|
||||
// Name: XLogger
|
||||
// Description: provides Logging 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 "Logging";
|
||||
input bool enableLogging = true; // Enable Logging
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Including Models ...
|
||||
#include "x-saherelm.models.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
string logTag = "X-Logger"; // LogTag
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Logging a Message ...
|
||||
void LogMessage(string message)
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, " > ", message);
|
||||
}
|
||||
void LogMessage(string tag, string message)
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(tag, " > ", message);
|
||||
}
|
||||
|
||||
//
|
||||
// Logging an Array ...
|
||||
void LogArray(int &array[])
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, ">");
|
||||
ArrayPrint(array);
|
||||
}
|
||||
void LogArray(double &array[])
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, ">");
|
||||
ArrayPrint(array);
|
||||
}
|
||||
void LogArray(string &array[])
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, ">");
|
||||
ArrayPrint(array);
|
||||
}
|
||||
|
||||
//
|
||||
// Convert a Signal to String Message ...
|
||||
string SignalToString(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Convert an Executed Signal to String Message ...
|
||||
string ExecutedSignalToString(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal Executed provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Logging Signal ...
|
||||
void LogSignal(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string message = SignalToString(signal);
|
||||
|
||||
//
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
// Log Signal Execution ...
|
||||
void LogExecutedSignal(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string message = ExecutedSignalToString(signal);
|
||||
|
||||
//
|
||||
LogMessage(message);
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,189 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Model Definitions ...
|
||||
//
|
||||
//
|
||||
// OHCL Candel Model ...
|
||||
enum ENUM_X_PRICE
|
||||
{
|
||||
X_PRICE_HIGH,
|
||||
X_PRICE_OPEN,
|
||||
X_PRICE_CLOSE,
|
||||
X_PRICE_LOW
|
||||
};
|
||||
|
||||
//
|
||||
// Describe an Specific Candle ...
|
||||
struct XOHCL
|
||||
{
|
||||
double high;
|
||||
double open;
|
||||
double close;
|
||||
double low;
|
||||
};
|
||||
|
||||
//
|
||||
// Swing Types Enum ...
|
||||
enum ENUM_X_SWING_TYPE
|
||||
{
|
||||
X_NO_SWING = 0,
|
||||
X_SWING_HIGH = 1,
|
||||
X_SWING_LOW = -1,
|
||||
};
|
||||
|
||||
//
|
||||
// XTrader Execution Signal Result ...
|
||||
enum ENUM_EXECUTION_SIGNAL_RESULT
|
||||
{
|
||||
X_INVALID_SIGNAL_ERROR,
|
||||
X_XTRADER_NOT_ENOUGH_BALANCE_ERROR,
|
||||
X_XTRADER_NOT_ENOUGH_MARIGIN_ERROR,
|
||||
X_XTRADER_MAX_ALLOWED_TRADE_KIND_REACHED_ERROR,
|
||||
X_XTRADER_MAX_ALLOWED_SUPPORT_KIND_REACHED_ERROR,
|
||||
X_UNKNOWN_ERROR,
|
||||
X_SUCCEED_EXECUTION
|
||||
};
|
||||
|
||||
//
|
||||
// Signal Types ...
|
||||
enum ENUM_X_SIGNAL_TYPE
|
||||
{
|
||||
X_SIGNAL_LONG,
|
||||
X_SIGNAL_SHORT,
|
||||
X_SIGNAL_UNKNOWN,
|
||||
};
|
||||
|
||||
//
|
||||
// Represent a Signal issued for Trade or Support a Trade ...
|
||||
enum ENUM_X_SIGNAL_KIND
|
||||
{
|
||||
X_KIND_TRADE,
|
||||
X_KIND_SUPPORT
|
||||
};
|
||||
|
||||
//
|
||||
// Signal Structure ...
|
||||
struct XSignal
|
||||
{
|
||||
//
|
||||
// Identifier ...
|
||||
ulong id;
|
||||
|
||||
//
|
||||
// Which Symbol used for Signal ...
|
||||
string symbol;
|
||||
|
||||
//
|
||||
// Which Type of operations ...
|
||||
ENUM_X_SIGNAL_TYPE type;
|
||||
|
||||
//
|
||||
// Signal Kind ...
|
||||
ENUM_X_SIGNAL_KIND kind;
|
||||
|
||||
//
|
||||
// Parent Ticket ...
|
||||
ulong parent;
|
||||
|
||||
//
|
||||
// Magic Number ...
|
||||
ulong magicNumber;
|
||||
|
||||
//
|
||||
// Ticket ...
|
||||
ulong ticket;
|
||||
|
||||
//
|
||||
// Entry/Open Price ...
|
||||
double entry;
|
||||
|
||||
//
|
||||
// TP ...
|
||||
double tp;
|
||||
|
||||
//
|
||||
double virtualTP;
|
||||
|
||||
//
|
||||
// SL ...
|
||||
double sl;
|
||||
|
||||
//
|
||||
double virtualSL;
|
||||
|
||||
//
|
||||
// Make Risk Free Trade on this Value if provided ...
|
||||
double riskFree;
|
||||
|
||||
//
|
||||
// a Multiplier for determines how much trade volume exit on risk free time ...
|
||||
double riskFreeRate;
|
||||
|
||||
//
|
||||
// Trade Profit ...
|
||||
double profit;
|
||||
|
||||
//
|
||||
// Time of Operation ...
|
||||
datetime time;
|
||||
|
||||
//
|
||||
// Volume ...
|
||||
double volume;
|
||||
|
||||
//
|
||||
// Comment ...
|
||||
string comment;
|
||||
};
|
||||
|
||||
//
|
||||
// TP/SL Struct ...
|
||||
struct XTPSL
|
||||
{
|
||||
ENUM_X_SIGNAL_TYPE type;
|
||||
double tp;
|
||||
double sl;
|
||||
double entry;
|
||||
double r2r;
|
||||
};
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,258 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 NN Class Library
|
||||
// ----------------------------------------
|
||||
// Name: XNNClass
|
||||
// Description: provides all classes for implementing
|
||||
// Neural Network ...
|
||||
//
|
||||
//
|
||||
// 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 Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
class XCNNBase
|
||||
{
|
||||
//
|
||||
// Public Definitions ...
|
||||
public:
|
||||
//
|
||||
// Constructor ...
|
||||
void XCNNBase(
|
||||
int nodes = 10, // Number of Input Nodes
|
||||
double starterWeight = 0.5, // start weight for each input
|
||||
double coEfficient = 0.1, // COEfficient Multiplier
|
||||
double upperRange = 1, // Upper Normal Range Value
|
||||
double lowerRange = -1, // Lower Normal Range Value
|
||||
double learningRates = 0.1 // Back Propagation Learning Rate
|
||||
) {
|
||||
//
|
||||
mNodes = nodes;
|
||||
mUpperRange = upperRange;
|
||||
mLowerRange = lowerRange;
|
||||
mCoEfficient = coEfficient;
|
||||
mLearningRates = learningRates;
|
||||
mStarterWeight = starterWeight;
|
||||
|
||||
//
|
||||
ReConstructWeights();
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XCNNBase() {}
|
||||
|
||||
//
|
||||
// Protected Definitions ...
|
||||
void NormalizeInputs(double &inputs[], double &result[])
|
||||
{
|
||||
//
|
||||
ArrayFree(result);
|
||||
ArrayResize(result, 1);
|
||||
|
||||
//
|
||||
// Validate inputs ...
|
||||
if (ArraySize(inputs) != mNodes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Result ...
|
||||
ArrayResize(result, mNodes);
|
||||
|
||||
//
|
||||
// Calculating min and max range value ...
|
||||
double minRangeValue = inputs[ArrayMinimum(inputs)];
|
||||
double maxRangeValue = inputs[ArrayMaximum(inputs)];
|
||||
|
||||
//
|
||||
// Loop through Inputs nd Normalize them ...
|
||||
for (int i = 0; i < mNodes; i++)
|
||||
{
|
||||
//
|
||||
double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange;
|
||||
result[i] = normalValue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Hyperbolic Tangent Activation Function ...
|
||||
double TanHActivationFunction(double weightedInputs)
|
||||
{
|
||||
//
|
||||
double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs));
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Weighted Inputs ...
|
||||
double CalculateWeightedInputs(
|
||||
double &inputs[],
|
||||
bool applyCOEfficient = true)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (ArraySize(inputs) != mNodes)
|
||||
{
|
||||
//
|
||||
result = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < mNodes; i++)
|
||||
{
|
||||
result += inputs[i] * mWeights[i];
|
||||
}
|
||||
|
||||
//
|
||||
// Multiply if required ...
|
||||
if (applyCOEfficient)
|
||||
{
|
||||
result *= mCoEfficient;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Hidden Layers ...
|
||||
virtual double CalculateHiddenLayer(double &inputs[])
|
||||
{
|
||||
//
|
||||
// this is Default Activation Function which used ...
|
||||
// you can override this by writing your own ...
|
||||
double totalWeightedInputs = CalculateWeightedInputs(inputs);
|
||||
double result = TanHActivationFunction(totalWeightedInputs);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Output Layers ...
|
||||
double CalculateOutputLayer(double &inputs[])
|
||||
{
|
||||
//
|
||||
double result = -1;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (ArraySize(inputs) != mNodes) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double normalizedInputs[];
|
||||
NormalizeInputs(inputs, normalizedInputs);
|
||||
if (ArraySize(normalizedInputs) != mNodes) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs);
|
||||
|
||||
//
|
||||
result = 1 * hiddenLayerResult;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Basck Propaggation Learning ...
|
||||
void BackPropagation(
|
||||
double &inputs[],
|
||||
double &outputs,
|
||||
double targetOutput
|
||||
) {
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (ArraySize(inputs) != mNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double normalizedInputs[];
|
||||
NormalizeInputs(inputs, normalizedInputs);
|
||||
if (ArraySize(normalizedInputs) != mNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double error = targetOutput - outputs;
|
||||
double derivative = 1 - MathPow(outputs, 2);
|
||||
|
||||
//
|
||||
for (int i = 0; i < mNodes; i++) {
|
||||
//
|
||||
double gradient = error * derivative * inputs[i];
|
||||
mWeights[i] = mLearningRates * gradient;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
//
|
||||
// Private Definitions ...
|
||||
private:
|
||||
//
|
||||
// Number of Input Nodes ...
|
||||
int mNodes;
|
||||
|
||||
//
|
||||
// Specify Upper range of Normal Values ...
|
||||
double mUpperRange;
|
||||
|
||||
//
|
||||
// Specify Lower range of Normal Values ...
|
||||
double mLowerRange;
|
||||
|
||||
//
|
||||
// Starter Weight for each input node ...
|
||||
double mStarterWeight;
|
||||
|
||||
//
|
||||
// double Input Node Weights ...
|
||||
double mWeights[];
|
||||
|
||||
//
|
||||
// CoEfficient is a multiplyer for weighted inputs ...
|
||||
double mCoEfficient;
|
||||
|
||||
//
|
||||
// Back Propagation Learning Rates ...
|
||||
double mLearningRates;
|
||||
|
||||
//
|
||||
// ReConstruct Weights ...
|
||||
void ReConstructWeights() {
|
||||
//
|
||||
ArrayFree(mWeights);
|
||||
ArrayResize(mWeights, mNodes);
|
||||
|
||||
//
|
||||
for (int i = 0; i< mNodes; i++) {
|
||||
mWeights[i] = mStarterWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
BIN
Binary file not shown.
+126
@@ -0,0 +1,126 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 _INDICATOR_ Indicator Helper for Signal Providers
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Includes ...
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5"
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5"
|
||||
//
|
||||
// TODO: Include Main Provider Inputs ...
|
||||
// #include "x-saherelm.xmap.provider.inputs.lib.mq5"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "_INDICATOR_ Indicator/Oscillator";
|
||||
// TODO: Implement Named Indicator/Oscillator Specific Inputs here ...
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Definitions ...
|
||||
int _iNDICATOR_Handler = INVALID_HANDLE;
|
||||
//
|
||||
// TODO: Define Specific Buffers here ...
|
||||
// double _iNDICATOR_Buffer[];
|
||||
//
|
||||
// END Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Handler Functions ...
|
||||
//
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool _INDICATOR_InitHandlers()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// _INDICATOR_ Handler ...
|
||||
// TODO: Set As Buffer Series ...
|
||||
// ArraySetAsSeries(_iNDICATOR_Buffer, true);
|
||||
_iNDICATOR_Handler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
// TODO: Set Indicator Name ...
|
||||
""
|
||||
//
|
||||
// Inputs ...
|
||||
// TODO: Attach Inputs here ...
|
||||
//
|
||||
);
|
||||
if (_iNDICATOR_Handler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
// TODO: Edit Error Message ...
|
||||
LogMessage("failed to Initialize _INDICATOR_ Indicator: " + (string)GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void _INDICATOR_ReleaseHandlers()
|
||||
{
|
||||
IndicatorRelease(_iNDICATOR_Handler);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void _INDICATOR_ReadBuffers()
|
||||
{
|
||||
//
|
||||
// TODO: Fix Copy Buffer ...
|
||||
// CopyBuffer(
|
||||
// _iNDICATOR_Handler,
|
||||
// 0,
|
||||
// 0,
|
||||
// //
|
||||
// // TODO: Use Global Number Of Items Per Tick ...
|
||||
// 0
|
||||
// //
|
||||
// // TODO Define Which buffer to save results ...
|
||||
// // _iNDICATOR_Buffer
|
||||
// //
|
||||
// );
|
||||
}
|
||||
//
|
||||
// END Handler Funcions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START _INDICATOR_ Custom Functions ...
|
||||
//
|
||||
// TODO: Attach all Aditional Helper Functions for Specific Indicator/Oscillator here ...
|
||||
//
|
||||
// END _INDICATOR_ Custom Functions ...
|
||||
//
|
||||
@@ -0,0 +1,758 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 _XPROVIDER_ Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: _XPROVIDER_SignalProvider
|
||||
// Description: _XPROVIDER_ based 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
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "_XPROVIDER_ Provider";
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Common";
|
||||
input bool enable_XPROVIDER_Provider = true; // Enable Provider
|
||||
input bool _xPROVIDER_EnableAlerts = true; // Enable Events Alert
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Indicator";
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Trader";
|
||||
input int _xPROVIDER_MagicNumber = 16940562; // Trader MagicNumber
|
||||
input int _xPROVIDER_Slippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Trade Management";
|
||||
input bool _xPROVIDER_AllowLongTrades = true; // Allow Long Trades
|
||||
input bool _xPROVIDER_AllowShortTrades = true; // Allow Short Trades
|
||||
input bool _xPROVIDER_UseGridTrades = true; // Enable Grid Trades
|
||||
input double _xPROVIDER_GridVolumeMultiplier = 2; // Grid Volume Multiplier
|
||||
input double _xPROVIDER_GridDistancePips = 10; // Grid Position Distance in Pips
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Risk Management";
|
||||
input bool _xPROVIDER_UseDynamicVolume = true; // Enable Dynamic Volume
|
||||
input double _xPROVIDER_StaticVolume = 0.01; // Static Volume
|
||||
input double _xPROVIDER_BalanceIncreased = 500; // Balance Increase
|
||||
input double _xPROVIDER_VolumeIncreased = 0.01; // Volume Increase
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
XCTrade *_xPROVIDER_Trader;
|
||||
XCAccountInfo _xPROVIDER_AccountInfo;
|
||||
|
||||
//
|
||||
double _xPROVIDER_GridLongPrice = 0;
|
||||
double _xPROVIDER_GridLongVolume = 0;
|
||||
|
||||
//
|
||||
double _xPROVIDER_GridShortPrice = 0;
|
||||
double _xPROVIDER_GridShortVolume = 0;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool OnInInit_XPROVIDER_SignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Error Message ...
|
||||
string message = "";
|
||||
|
||||
//
|
||||
// Check Risk Management ...
|
||||
if (_xPROVIDER_UseDynamicVolume)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_BalanceIncreased <= 0 || _xPROVIDER_VolumeIncreased <= 0)
|
||||
{
|
||||
//
|
||||
message = "invalid volume increased factors ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
if (_xPROVIDER_StaticVolume > maxAvailableVolume || _xPROVIDER_StaticVolume < minAvailableVolume)
|
||||
{
|
||||
//
|
||||
message = "invalid static volume ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
_xPROVIDER_Trader = new XCTrade(
|
||||
_Symbol,
|
||||
_xPROVIDER_Slippage,
|
||||
_xPROVIDER_MagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
message = "Initializion of (" + "_XPROVIDER_ Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void OnDeinit_XPROVIDER_SignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "De Initializion of (" + "_XPROVIDER_ Provider" + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void Handle_XPROVIDER_SignalProviderTick()
|
||||
{
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
_XPROVIDER_HandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
_XPROVIDER_HandleCloseTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Primary Signals ...
|
||||
bool _XPROVIDER_HasPrimaryLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Primary Signals ...
|
||||
bool _XPROVIDER_HasPrimaryShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Grid Signals ...
|
||||
bool _XPROVIDER_HasGridLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Grid Signals ...
|
||||
bool _XPROVIDER_HasGridShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Long Trades ...
|
||||
bool _XPROVIDER_CanCloseLongTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Short Trades ...
|
||||
bool _XPROVIDER_CanCloseShortTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Primary Trades...
|
||||
bool _XPROVIDER_HandlePrimaryLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
if (_XPROVIDER_HasPrimaryLongSignal() && _xPROVIDER_Trader.CountLongs() == 0)
|
||||
{
|
||||
//
|
||||
double entry = GetAsk();
|
||||
double volume = _XPROVIDER_CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary _XPROVIDER_ Long";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowLongTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Primary Trades...
|
||||
bool _XPROVIDER_HandlePrimaryShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
if (_XPROVIDER_HasPrimaryShortSignal() && _xPROVIDER_Trader.CountShorts() == 0)
|
||||
{
|
||||
//
|
||||
double entry = GetBid();
|
||||
double volume = _XPROVIDER_CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary _XPROVIDER_ Short";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowShortTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Grid Trades...
|
||||
bool _XPROVIDER_HandleGridLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
bool canDoGridTrade = ask <= _xPROVIDER_GridLongPrice;
|
||||
if (_XPROVIDER_HasGridLongSignal() && _xPROVIDER_Trader.CountLongs() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = ask;
|
||||
double volume = _xPROVIDER_GridLongVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid _XPROVIDER_ Long";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowLongTrades && _xPROVIDER_UseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Grid Trades...
|
||||
bool _XPROVIDER_HandleGridShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double bid = GetBid();
|
||||
bool canDoGridTrade = bid >= _xPROVIDER_GridShortPrice;
|
||||
if (_XPROVIDER_HasGridShortSignal() && _xPROVIDER_Trader.CountShorts() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = bid;
|
||||
double volume = _xPROVIDER_GridShortVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid _XPROVIDER_ Short";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowShortTrades && _xPROVIDER_UseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void _XPROVIDER_HandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
XSignal primaryLongSignal = {};
|
||||
bool isPrimaryLongSignalExecuted = _XPROVIDER_HandlePrimaryLong(primaryLongSignal);
|
||||
if (isPrimaryLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
_XPROVIDER_CalculateGridLongConditions(primaryLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
XSignal primaryShortSignal = {};
|
||||
bool isPrimaryShortSignalExecuted = _XPROVIDER_HandlePrimaryShort(primaryShortSignal);
|
||||
if (isPrimaryShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
_XPROVIDER_CalculateGridShortConditions(primaryShortSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Check Grid Trades ...
|
||||
if (_xPROVIDER_UseGridTrades)
|
||||
{
|
||||
//
|
||||
// Grid Long Trade ...
|
||||
XSignal gridLongSignal = {};
|
||||
bool isGridLongSignalExecuted = _XPROVIDER_HandleGridLong(gridLongSignal);
|
||||
if (isGridLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
_XPROVIDER_CalculateGridLongConditions(gridLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Grid Short Trade ...
|
||||
XSignal gridShortSignal = {};
|
||||
bool isGridShortSignalExecuted = _XPROVIDER_HandleGridShort(gridShortSignal);
|
||||
if (isGridShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
_XPROVIDER_CalculateGridShortConditions(gridShortSignal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void _XPROVIDER_HandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (_xPROVIDER_Trader.CountLongs() > 0 && _XPROVIDER_CanCloseLongTrades())
|
||||
{
|
||||
//
|
||||
_xPROVIDER_Trader.CloseLongPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Long Conditions ...
|
||||
_xPROVIDER_GridLongPrice = 0;
|
||||
_xPROVIDER_GridLongVolume = 0;
|
||||
|
||||
//
|
||||
string message = "_XPROVIDER_ Closing Long Trades ...";
|
||||
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (_xPROVIDER_Trader.CountShorts() > 0 && _XPROVIDER_CanCloseShortTrades())
|
||||
{
|
||||
//
|
||||
_xPROVIDER_Trader.CloseShortPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Short Conditions ...
|
||||
_xPROVIDER_GridShortPrice = 0;
|
||||
_xPROVIDER_GridShortVolume = 0;
|
||||
|
||||
//
|
||||
string message = "_XPROVIDER_ Closing Short Trades ...";
|
||||
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double _XPROVIDER_CalculateVolume()
|
||||
{
|
||||
//
|
||||
double result = _xPROVIDER_StaticVolume;
|
||||
if (!_xPROVIDER_UseDynamicVolume)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double accountBalance = _xPROVIDER_AccountInfo.GetBalance();
|
||||
double balanceIncreased = _xPROVIDER_BalanceIncreased;
|
||||
double volumeIncreased = _xPROVIDER_VolumeIncreased;
|
||||
|
||||
//
|
||||
result = (volumeIncreased * accountBalance) / balanceIncreased;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeDouble(result, 2);
|
||||
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
// Validate Result ...
|
||||
if (result > maxAvailableVolume)
|
||||
{
|
||||
result = maxAvailableVolume;
|
||||
}
|
||||
else if (result < minAvailableVolume)
|
||||
{
|
||||
result = minAvailableVolume;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Long Trades Price and Volume ...
|
||||
void _XPROVIDER_CalculateGridLongConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!_xPROVIDER_UseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridLongPrice and GridLongVolume ...
|
||||
_xPROVIDER_GridLongVolume = NormalizeDouble(signal.volume * _xPROVIDER_GridVolumeMultiplier, 2);
|
||||
_xPROVIDER_GridLongPrice = NormalizeDouble(signal.entry - (_xPROVIDER_GridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Short Trades Price and Volume ...
|
||||
void _XPROVIDER_CalculateGridShortConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!_xPROVIDER_UseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridShortPrice and GridShortVolume ...
|
||||
_xPROVIDER_GridShortVolume = NormalizeDouble(signal.volume * _xPROVIDER_GridVolumeMultiplier, 2);
|
||||
_xPROVIDER_GridShortPrice = NormalizeDouble(signal.entry + (_xPROVIDER_GridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Determine based on current account state
|
||||
bool _XPROVIDER_CanDoTrade()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,925 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XCHLH Oscillator Helper for Signal Providers
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Includes ...
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5"
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// START Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// XCHLH Hot States ...
|
||||
enum ENUM_X_XCHLH_HOT_STATES
|
||||
{
|
||||
X_XCHLH_HOT_HH = 1,
|
||||
X_XCHLH_NEUTURAL = 0,
|
||||
X_XCHLH_HOT_LL = -1,
|
||||
};
|
||||
|
||||
//
|
||||
// XCHLH Signal Calculation Types ...
|
||||
enum ENUM_X_XCHLH_SIGNAL_TYPES
|
||||
{
|
||||
X_XCHLH_AVG_SIGNAL,
|
||||
X_XCHLH_DELTA_SIGNAL,
|
||||
};
|
||||
|
||||
//
|
||||
// XCHLH Buffer Lines ...
|
||||
enum ENUM_X_XCHLH_BUFFER_LINES
|
||||
{
|
||||
X_XCHLH_LC_HH_LINE = 0,
|
||||
X_XCHLH_LC_LL_LINE = 1,
|
||||
X_XCHLH_MC_HH_LINE = 2,
|
||||
X_XCHLH_MC_LL_LINE = 3,
|
||||
X_XCHLH_SC_HH_LINE = 4,
|
||||
X_XCHLH_SC_LL_LINE = 5,
|
||||
X_XCHLH_SIGNAL_T_LINE = 6,
|
||||
X_XCHLH_SIGNAL_B_LINE = 7,
|
||||
X_XCHLH_HOT_STATE_LINE = 8,
|
||||
};
|
||||
|
||||
//
|
||||
// END Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
input group "XCHLH Oscillator";
|
||||
|
||||
//
|
||||
// Signal Calculations ...
|
||||
input group "XCHLH Signal Calculations";
|
||||
input ENUM_X_XCHLH_SIGNAL_TYPES xCHLHSignalType = X_XCHLH_AVG_SIGNAL; // Signal Method
|
||||
|
||||
//
|
||||
// Common ...
|
||||
input group "XCHLH Hot Areas";
|
||||
input bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol
|
||||
input uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code
|
||||
input color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color
|
||||
input uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code
|
||||
input color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color
|
||||
|
||||
//
|
||||
// LC Inputs ...
|
||||
input group "XCHLH Long Cycle";
|
||||
input group "XCHLH LC Market";
|
||||
input int xCHLHLcLength = 288; // Length
|
||||
input double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips
|
||||
input ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method
|
||||
input ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method
|
||||
input group "XCHLH LC Style";
|
||||
input int xCHLHLcDrawWidth = 1; // Draw Width
|
||||
input ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type
|
||||
input ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style
|
||||
input color xCHLHLcHHColor = clrAqua; // Highest High Color
|
||||
input color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color
|
||||
input group "XCHLH LC Drawings";
|
||||
input bool xCHLHLcDrawHH = true; // Draw Highest High
|
||||
input bool xCHLHLcDrawLL = true; // Draw Lowest Low
|
||||
|
||||
//
|
||||
// MC Inputs ...
|
||||
input group "XCHLH Medium Cycle";
|
||||
input group "XCHLH MC Market";
|
||||
input int xCHLHMcLength = 72; // Length
|
||||
input double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips
|
||||
input ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method
|
||||
input ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method
|
||||
input group "XCHLH MC Style";
|
||||
input int xCHLHMcDrawWidth = 1; // Draw Width
|
||||
input ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type
|
||||
input ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style
|
||||
input color xCHLHMcHHColor = clrLime; // Highest High Color
|
||||
input color xCHLHMcLLColor = clrRed; // Lowest Low Color
|
||||
input group "XCHLH MC Drawings";
|
||||
input bool xCHLHMcDrawHH = false; // Draw Highest High
|
||||
input bool xCHLHMcDrawLL = false; // Draw Lowest Low
|
||||
|
||||
//
|
||||
// SC Inputs ...
|
||||
input group "XCHLH Short Cycle";
|
||||
input group "XCHLH SC Market";
|
||||
input int xCHLHScLength = 7; // Length
|
||||
input double xCHLHScThresholdInPips = 0.3; // Threshold In Pips
|
||||
input ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method
|
||||
input ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method
|
||||
input group "XCHLH SC Style";
|
||||
input int xCHLHScDrawWidth = 1; // Draw Width
|
||||
input ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type
|
||||
input ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style
|
||||
input color xCHLHScHHColor = clrLightBlue; // Highest High Color
|
||||
input color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color
|
||||
input group "XCHLH SC Drawings";
|
||||
input bool xCHLHScDrawHH = false; // Draw Highest High
|
||||
input bool xCHLHScDrawLL = false; // Draw Lowest Low
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Definitions ...
|
||||
//
|
||||
|
||||
int xCHLHHandler = INVALID_HANDLE;
|
||||
double xCHLHLcHHBuffer[];
|
||||
double xCHLHLcLLBuffer[];
|
||||
double xCHLHMcHHBuffer[];
|
||||
double xCHLHMcLLBuffer[];
|
||||
double xCHLHScHHBuffer[];
|
||||
double xCHLHScLLBuffer[];
|
||||
double xCHLHSignalTBuffer[];
|
||||
double xCHLHSignalBBuffer[];
|
||||
|
||||
//
|
||||
// END Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Handler Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Init Oscillators ...
|
||||
bool XCHLHInitHandlers()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XCHLH Handler ...
|
||||
ArraySetAsSeries(xCHLHLcHHBuffer, true);
|
||||
ArraySetAsSeries(xCHLHLcLLBuffer, true);
|
||||
ArraySetAsSeries(xCHLHMcHHBuffer, true);
|
||||
ArraySetAsSeries(xCHLHMcLLBuffer, true);
|
||||
ArraySetAsSeries(xCHLHScHHBuffer, true);
|
||||
ArraySetAsSeries(xCHLHScLLBuffer, true);
|
||||
ArraySetAsSeries(xCHLHSignalTBuffer, true);
|
||||
ArraySetAsSeries(xCHLHSignalBBuffer, true);
|
||||
xCHLHHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xchlh.oscillator",
|
||||
//
|
||||
// Inputs ...
|
||||
//
|
||||
// Signal Calculations ...
|
||||
"",
|
||||
xCHLHSignalType,
|
||||
//
|
||||
// Commons ...
|
||||
"",
|
||||
xCHLHDrawHotAreas,
|
||||
xCHLHHotHHArrowCode,
|
||||
xCHLHHotHHArrowColor,
|
||||
xCHLHHotLLArrowCode,
|
||||
xCHLHHotLLArrowColor,
|
||||
//
|
||||
// LC ...
|
||||
"",
|
||||
"",
|
||||
xCHLHLcLength,
|
||||
xCHLHLcThresholdInPips,
|
||||
xCHLHLcHHMode,
|
||||
xCHLHLcLLMode,
|
||||
"",
|
||||
xCHLHLcDrawWidth,
|
||||
xCHLHLcDrawType,
|
||||
xCHLHLcDrawStyle,
|
||||
xCHLHLcHHColor,
|
||||
xCHLHLcLLColor,
|
||||
"",
|
||||
xCHLHLcDrawHH,
|
||||
xCHLHLcDrawLL,
|
||||
//
|
||||
// MC ...
|
||||
"",
|
||||
"",
|
||||
xCHLHMcLength,
|
||||
xCHLHMcThresholdInPips,
|
||||
xCHLHMcHHMode,
|
||||
xCHLHMcLLMode,
|
||||
"",
|
||||
xCHLHMcDrawWidth,
|
||||
xCHLHMcDrawType,
|
||||
xCHLHMcDrawStyle,
|
||||
xCHLHMcHHColor,
|
||||
xCHLHMcLLColor,
|
||||
"",
|
||||
xCHLHMcDrawHH,
|
||||
xCHLHMcDrawLL,
|
||||
//
|
||||
// SC ...
|
||||
"",
|
||||
"",
|
||||
xCHLHScLength,
|
||||
xCHLHScThresholdInPips,
|
||||
xCHLHScHHMode,
|
||||
xCHLHScLLMode,
|
||||
"",
|
||||
xCHLHScDrawWidth,
|
||||
xCHLHScDrawType,
|
||||
xCHLHScDrawStyle,
|
||||
xCHLHScHHColor,
|
||||
xCHLHScLLColor,
|
||||
"",
|
||||
xCHLHScDrawHH,
|
||||
xCHLHScDrawLL);
|
||||
if (xCHLHHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("failed to Initialize XCHLH Indicator: " + (string)GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Oscillators ...
|
||||
void XCHLHReleaseHandlers()
|
||||
{
|
||||
IndicatorRelease(xCHLHHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XCHLHReadBuffers(
|
||||
int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
// XCHLH LC HH Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_LC_HH_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHLcHHBuffer);
|
||||
|
||||
//
|
||||
// XCHLH LC LL Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_LC_LL_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHLcLLBuffer);
|
||||
|
||||
//
|
||||
// XCHLH MC HH Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_MC_HH_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHMcHHBuffer);
|
||||
|
||||
//
|
||||
// XCHLH MC LL Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_MC_LL_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHMcLLBuffer);
|
||||
|
||||
//
|
||||
// XCHLH SC HH Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_SC_HH_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHScHHBuffer);
|
||||
|
||||
//
|
||||
// XCHLH SC LL Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_SC_LL_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHScLLBuffer);
|
||||
|
||||
//
|
||||
// XCHLH Signal T Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_SIGNAL_T_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHSignalTBuffer);
|
||||
|
||||
//
|
||||
// XCHLH Signal B Buffer ...
|
||||
CopyBuffer(
|
||||
xCHLHHandler,
|
||||
X_XCHLH_SIGNAL_B_LINE,
|
||||
0,
|
||||
xCHLHItemsPerTick,
|
||||
xCHLHSignalBBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// END Handler Funcions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Signal Related Conditions ...
|
||||
//
|
||||
|
||||
//
|
||||
// XCHLH Long Conditions ...
|
||||
bool XCHLHHasLongConditions(
|
||||
int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isSignalBCrossedOverLCLL = XCHLHIsSignalBCrossedOverLCLL(1);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isSignalBCrossedOverLCLL
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XCHLH Close Long Conditions ...
|
||||
bool XCHLHHasLongCloseConditions(
|
||||
int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
) {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isSignalBCrossedOverSignalT = XCHLHIsSignalBCrossedOverSignalT(1);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isSignalBCrossedOverSignalT
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XCHLH Short Conditions ...
|
||||
bool XCHLHHasShortConditions(
|
||||
int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isSignalBCrossedUnderSignalT = XCHLHIsSignalBCrossedUnderSignalT(1);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isSignalBCrossedUnderSignalT
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XCHLH Close Short Conditions ...
|
||||
bool XCHLHHasShortCloseConditions(
|
||||
int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isSignalBCrossedUnderLCLL = XCHLHIsSignalBCrossedUnderLCLL(1);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isSignalBCrossedUnderLCLL
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Signal Related Conditions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START XCHLH Custom Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Check Signal B Crossed Over LC LL ...
|
||||
bool XCHLHIsSignalBCrossedOverLCLL(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossOver(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHLcLLBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal B Over LC LL ...
|
||||
bool XCHLHIsSignalBOverLCLL(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsOver(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHLcLLBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal B Crossed Under LC LL ...
|
||||
bool XCHLHIsSignalBCrossedUnderLCLL(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossUnder(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHLcLLBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal B Under LC LL ...
|
||||
bool XCHLHIsSignalBUnderLCLL(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsUnder(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHLcLLBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal B Crossed Over Signal T ...
|
||||
bool XCHLHIsSignalBCrossedOverSignalT(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossOver(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHSignalTBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal B Over Signal T ...
|
||||
bool XCHLHIsSignalBOverSignalT(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsOver(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHSignalTBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal B Crossed Under Signal T ...
|
||||
bool XCHLHIsSignalBCrossedUnderSignalT(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossUnder(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHSignalTBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal B Under Signal T ...
|
||||
bool XCHLHIsSignalBUnderSignalT(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 2))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsUnder(
|
||||
xCHLHSignalBBuffer,
|
||||
xCHLHSignalTBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check LC and MC has Same HH ...
|
||||
bool XCHLHIsLCMCHasSameHH(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double lcValue = xCHLHLcHHBuffer[bar_index];
|
||||
double mcValue = xCHLHMcHHBuffer[bar_index];
|
||||
|
||||
//
|
||||
result = lcValue == mcValue;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check LC and MC has Same LL ...
|
||||
bool XCHLHIsLCMCHasSameLL(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double lcValue = xCHLHLcLLBuffer[bar_index];
|
||||
double mcValue = xCHLHMcLLBuffer[bar_index];
|
||||
|
||||
//
|
||||
result = lcValue == mcValue;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check LC and SC has Same HH ...
|
||||
bool XCHLHIsLCSCHasSameHH(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double lcValue = xCHLHLcHHBuffer[bar_index];
|
||||
double scValue = xCHLHScHHBuffer[bar_index];
|
||||
|
||||
//
|
||||
result = lcValue == scValue;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check LC and SC has Same LL ...
|
||||
bool XCHLHIsLCSCHasSameLL(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double lcValue = xCHLHLcLLBuffer[bar_index];
|
||||
double scValue = xCHLHScLLBuffer[bar_index];
|
||||
|
||||
//
|
||||
result = lcValue == scValue;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check MC and SC has Same HH ...
|
||||
bool XCHLHIsMCSCHasSameHH(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double mcValue = xCHLHMcHHBuffer[bar_index];
|
||||
double scValue = xCHLHScHHBuffer[bar_index];
|
||||
|
||||
//
|
||||
result = mcValue == scValue;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check MC and SC has Same LL ...
|
||||
bool XCHLHIsMCSCHasSameLL(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double mcValue = xCHLHMcLLBuffer[bar_index];
|
||||
double scValue = xCHLHScLLBuffer[bar_index];
|
||||
|
||||
//
|
||||
result = mcValue == scValue;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Is Same Highest Highs ...
|
||||
bool XCHLHIsSameHHs(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double lcValue = xCHLHLcHHBuffer[bar_index];
|
||||
double mcValue = xCHLHMcHHBuffer[bar_index];
|
||||
double scValue = xCHLHScHHBuffer[bar_index];
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
lcValue == mcValue &&
|
||||
mcValue == scValue
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Is Same Lowest Lows ...
|
||||
bool XCHLHIsSameLLs(
|
||||
int bar_index // Specified Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XCHLHIsValidBufferSizes(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double lcValue = xCHLHLcLLBuffer[bar_index];
|
||||
double mcValue = xCHLHMcLLBuffer[bar_index];
|
||||
double scValue = xCHLHScLLBuffer[bar_index];
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
lcValue == mcValue &&
|
||||
mcValue == scValue
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check and Validate Buffer Sizes ...
|
||||
bool XCHLHIsValidBufferSizes(
|
||||
int size // Specified Min Size
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
ArraySize(xCHLHLcHHBuffer) > size &&
|
||||
ArraySize(xCHLHLcLLBuffer) > size &&
|
||||
//
|
||||
ArraySize(xCHLHMcHHBuffer) > size &&
|
||||
ArraySize(xCHLHMcLLBuffer) > size &&
|
||||
//
|
||||
ArraySize(xCHLHScHHBuffer) > size &&
|
||||
ArraySize(xCHLHScLLBuffer) > size;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END XCHLH Custom Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,166 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XCHLH Signal Provider Indicators Library
|
||||
// ----------------------------------------------------------------
|
||||
//
|
||||
// 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 Provider Inputs ...
|
||||
#include "x-saherelm.xchlh.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// Imports all Indicators Helper here ...
|
||||
input group "XCHLH Provider Indicators";
|
||||
#include "x-saherelm.xchlh.oscillator.helper.lib.mq5";
|
||||
|
||||
//
|
||||
int xCHLHMaxLengthOfInputs = 0;
|
||||
int xCHLHCalculatedBars = 0;
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XCHLHInitIndicators()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check and Calculate Max Length in Inputs ...
|
||||
xCHLHMaxLengthOfInputs = MathMax(
|
||||
xCHLHLcLength,
|
||||
xCHLHMcLength);
|
||||
xCHLHMaxLengthOfInputs = MathMax(
|
||||
xCHLHScLength,
|
||||
xCHLHMaxLengthOfInputs);
|
||||
xCHLHMaxLengthOfInputs = MathMax(
|
||||
xCHLHNumberOfItemsPerTick,
|
||||
xCHLHMaxLengthOfInputs);
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XCHLH Init ...
|
||||
result = XCHLHInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XCHLHReleaseIndicators()
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XCHLHReleaseHandlers();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XCHLHHandleReadingBuffers()
|
||||
{
|
||||
//
|
||||
// Reading Calculated Bars for a Simple Handler ...
|
||||
xCHLHCalculatedBars = BarsCalculated(xCHLHHandler);
|
||||
|
||||
//
|
||||
// Read Indicators Buffers ...
|
||||
XCHLHReadBuffers(xCHLHNumberOfItemsPerTick);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// START Combination Functions ...
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Can Open Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XCHLHCanOpenLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XCHLHHasLongConditions(xCHLHNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XCHLHCanCloseLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// result = XCHLHHasLongCloseConditions(xCHLHNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Open Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XCHLHCanOpenShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XCHLHHasShortConditions(xCHLHNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XCHLHCanCloseShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// result = XCHLHHasShortCloseConditions(xCHLHNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// END Combination Functions ...
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,64 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XCHLH Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
input group "XCHLH Provider";
|
||||
|
||||
//
|
||||
input group "XCHLH Common";
|
||||
input bool xCHLHEnableProvider = true; // Enable Provider
|
||||
input bool xCHLHEnableAlerts = false; // Enable Events Alert
|
||||
input int xCHLHNumberOfItemsPerTick = 110; // Number Of items Readed In Each Tick
|
||||
|
||||
//
|
||||
input group "XCHLH Trader";
|
||||
input int xCHLHMagicNumber = 16940562; // Trader MagicNumber
|
||||
input int xCHLHSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XCHLH Trade Management";
|
||||
input bool xCHLHAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xCHLHAllowShortTrades = true; // Allow Short Trades
|
||||
|
||||
//
|
||||
input group "XCHLH Risk Management";
|
||||
input int xCHLHMaxAllowedTrades = 5; // Max Allowed Trades at Same Time
|
||||
input int xCHLHMaxInProfitTradeAge = 0; // Max In Profit Trades Age
|
||||
input int xCHLHMaxInDrawDownTradeAge = 576; // Max In DrawDown Trades Age
|
||||
input double xCHLHStaticVolume = 0.02; // Static Volume
|
||||
input double xCHLHVolumeMultiplier = 2; // Volume Multiplier
|
||||
input double xCHLHMinRewardPerTradeInPips = 2; // Min Reward Per Trade In Pips
|
||||
input double xCHLHFreeMarginFactorForOpenTrades = 0.5; // Minimum Free Marging for Open Trades
|
||||
input double xCHLHBalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades
|
||||
// input bool xCHLHEnableSupportTrades = true; // Enable Support Trade
|
||||
input int xCHLHMaxAllowedSupportTrades = 5; // Max Allowed Support Trade
|
||||
|
||||
//
|
||||
// Validate Inputs before Initialization ...
|
||||
bool XCHLHValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
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,165 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XCHMA Signal Provider Indicators Library
|
||||
// ----------------------------------------------------------------
|
||||
//
|
||||
// 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 Provider Inputs ...
|
||||
#include "x-saherelm.xchma.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// Imports all Indicators Helper here ...
|
||||
input group "XCHMA Provider Indicators";
|
||||
#include "x-saherelm.xchma.oscillator.helper.lib.mq5";
|
||||
|
||||
//
|
||||
int xCHMAMaxLengthOfInputs = 0;
|
||||
int xCHMACalculatedBars = 0;
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XCHMAInitIndicators()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check and Calculate Max Length in Inputs ...
|
||||
xCHMAMaxLengthOfInputs = MathMax(
|
||||
xCHMAScFastLength,
|
||||
xCHMAScSlowLength);
|
||||
xCHMAMaxLengthOfInputs = MathMax(
|
||||
xCHMAMcFastLength,
|
||||
xCHMAMaxLengthOfInputs);
|
||||
xCHMAMaxLengthOfInputs = MathMax(
|
||||
xCHMAMcSlowLength,
|
||||
xCHMAMaxLengthOfInputs);
|
||||
xCHMAMaxLengthOfInputs = MathMax(
|
||||
xCHMALcFastLength,
|
||||
xCHMAMaxLengthOfInputs);
|
||||
xCHMAMaxLengthOfInputs = MathMax(
|
||||
xCHMALcSlowLength,
|
||||
xCHMAMaxLengthOfInputs);
|
||||
xCHMAMaxLengthOfInputs = MathMax(
|
||||
xCHMANumberOfItemsPerTick,
|
||||
xCHMAMaxLengthOfInputs);
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XCHMA Init ...
|
||||
result = XCHMAInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XCHMAReleaseIndicators()
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XCHMAReleaseHandlers();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XCHMAHandleReadingBuffers()
|
||||
{
|
||||
//
|
||||
// Reading Calculated Bars for a Simple Handler ...
|
||||
xCHMACalculatedBars = BarsCalculated(xCHMAHandler);
|
||||
|
||||
//
|
||||
// Read Indicators Buffers ...
|
||||
XCHMAReadBuffers(xCHMANumberOfItemsPerTick);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// START Combination Functions ...
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Can Open Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XCHMACanOpenLongTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XCHMAHasLongConditions(xCHMANumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XCHMACanCloseLongTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Open Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XCHMACanOpenShortTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XCHMAHasShortConditions(xCHMANumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XCHMACanCloseShortTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// END Combination Functions ...
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,63 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XCHMA Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
input group "XCHMA Provider";
|
||||
|
||||
//
|
||||
input group "XCHMA Common";
|
||||
input bool xCHMAEnableProvider = true; // Enable Provider
|
||||
input bool xCHMAEnableAlerts = false; // Enable Events Alert
|
||||
input int xCHMANumberOfItemsPerTick = 110; // Number Of items Readed In Each Tick
|
||||
|
||||
//
|
||||
input group "XCHMA Trader";
|
||||
input int xCHMAMagicNumber = 16940562; // Trader MagicNumber
|
||||
input int xCHMASlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XCHMA Trade Management";
|
||||
input bool xCHMAAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xCHMAAllowShortTrades = true; // Allow Short Trades
|
||||
|
||||
//
|
||||
input group "XCHMA Risk Management";
|
||||
input int xCHMAMaxAllowedTrades = 5; // Max Allowed Trades at Same Time
|
||||
input int xCHMAMaxInProfitTradeAge = 0; // Max In Profit Trades Age
|
||||
input int xCHMAMaxInDrawDownTradeAge = 576; // Max In DrawDown Trades Age
|
||||
input double xCHMAStaticVolume = 0.02; // Static Volume
|
||||
input double xCHMAVolumeMultiplier = 2; // Volume Multiplier
|
||||
input double xCHMAMinRewardPerTradeInPips = 2; // Min Reward Per Trade In Pips
|
||||
input double xCHMAFreeMarginFactorForOpenTrades = 0.5; // Minimum Free Marging for Open Trades
|
||||
input double xCHMABalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades
|
||||
input bool xCHMAEnableSupportTrades = false; // Enable Support Trade
|
||||
|
||||
//
|
||||
// Validate Inputs before Initialization ...
|
||||
bool XCHMAValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,861 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XCHMA Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XCHMASignalProvider
|
||||
// Description: XCHMA based 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
|
||||
|
||||
#define XCHMAProviderName "XCHMA"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
#include "x-saherelm.xchma.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
XCTrade *xCHMATrader;
|
||||
XCAccountInfo xCHMAAccountInfo;
|
||||
|
||||
//
|
||||
#include "x-saherelm.xchma.provider.indicators.lib.mq5"
|
||||
|
||||
//
|
||||
double xCHMADeposit = 0;
|
||||
double xCHMABalance = 0;
|
||||
double xCHMAFreeMargin = 0;
|
||||
double xCHMAFreeMarginForOpenTrades = 0;
|
||||
double xCHMABalanceForOpenTrades = 0;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool XCHMAInitSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
result = XCHMAValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
result = XCHMAInitIndicators();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Account Deposit ...
|
||||
xCHMADeposit = xCHMAAccountInfo.GetInitialBalance();
|
||||
|
||||
//
|
||||
// Calculate Min Balance for Trades ...
|
||||
if (xCHMABalanceFactorForOpenTrades > 0)
|
||||
{
|
||||
xCHMABalanceForOpenTrades = xCHMABalanceFactorForOpenTrades * xCHMADeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Claculate Min Free Marging for Trades ...
|
||||
if (xCHMAFreeMarginFactorForOpenTrades > 0)
|
||||
{
|
||||
xCHMAFreeMarginForOpenTrades = xCHMAFreeMarginFactorForOpenTrades * xCHMADeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
xCHMATrader = new XCTrade(
|
||||
_Symbol,
|
||||
xCHMASlippage,
|
||||
xCHMAMagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XCHMAIssueInitializationSucceedAlert();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void XCHMADeinitSignalProviderLibrary(
|
||||
const int reason)
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XCHMAReleaseIndicators();
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XCHMAIssueDeinitializationSucceedAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void XCHMASignalProviderHandleTick()
|
||||
{
|
||||
//
|
||||
// Update account Balance ...
|
||||
xCHMABalance = xCHMAAccountInfo.GetBalance();
|
||||
xCHMAFreeMargin = xCHMAAccountInfo.GetFreeMargin();
|
||||
|
||||
//
|
||||
// Check Provider is Enable or Not ...
|
||||
if (!xCHMAEnableProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Indicator Buffers ...
|
||||
XCHMAHandleReadingBuffers();
|
||||
if (xCHMACalculatedBars < xCHMAMaxLengthOfInputs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
XCHMAHandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
XCHMAHandleCloseTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void XCHMAHandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Check Can Trade ...
|
||||
bool canTrade = xCHMAAllowLongTrades || xCHMAAllowShortTrades;
|
||||
if (!canTrade)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// First Check Signal Exists or NOt ...
|
||||
bool xCHMAHasLongSignal = XCHMACanOpenLongTrade();
|
||||
bool xCHMAHasShortSignal = XCHMACanOpenShortTrade();
|
||||
if (!xCHMAHasLongSignal && !xCHMAHasShortSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Max Open Trades ...
|
||||
if (xCHMAMaxAllowedTrades > 0)
|
||||
{
|
||||
//
|
||||
int count = xCHMATrader.Count();
|
||||
bool canOpenTrade = count < xCHMAMaxAllowedTrades;
|
||||
if (!canOpenTrade)
|
||||
{
|
||||
//
|
||||
XCHMAIssueMaxAllowedTradesReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Free Margin ...
|
||||
if (xCHMAFreeMargin <= xCHMAFreeMarginForOpenTrades)
|
||||
{
|
||||
//
|
||||
XCHMAIssueMaxAllowedFreeMarginReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Account Balance ...
|
||||
if (xCHMABalance <= xCHMABalanceForOpenTrades)
|
||||
{
|
||||
//
|
||||
XCHMAIssueMinAllowedBalanceReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
if (
|
||||
xCHMAHasLongSignal &&
|
||||
xCHMAAllowLongTrades)
|
||||
{
|
||||
//
|
||||
bool isLongSignalExecuted = XCHMAOpenLongPosition();
|
||||
if (isLongSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
if (
|
||||
xCHMAHasShortSignal &&
|
||||
xCHMAAllowShortTrades)
|
||||
{
|
||||
//
|
||||
bool isShortSignalExecuted = XCHMAOpenShortPosition();
|
||||
if (isShortSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void XCHMAHandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (xCHMATrader.CountLongs() > 0 && XCHMACanCloseLongTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xCHMATrader.CloseLongPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XCHMAIssueForceCloseTradesAlert(X_SIGNAL_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (xCHMATrader.CountShorts() > 0 && XCHMACanCloseShortTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xCHMATrader.CloseShortPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XCHMAIssueForceCloseTradesAlert(X_SIGNAL_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In Profit Teades ...
|
||||
if (xCHMAMaxInProfitTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xCHMATrader.GetLongTimeTrades(
|
||||
xCHMAMaxInProfitTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isClosed = xCHMATrader.Close(trade.ticket);
|
||||
if (isClosed)
|
||||
{
|
||||
Add(
|
||||
trade,
|
||||
closed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XCHMAIssueLongInProfitTradeClosed();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In DrawDown Trades ...
|
||||
if (xCHMAMaxInDrawDownTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xCHMATrader.GetLongTimeTrades(
|
||||
xCHMAMaxInDrawDownTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Grid Trades ...
|
||||
XCHMAOpenSuppurtTrade(trade);
|
||||
|
||||
// //
|
||||
// bool isClosed = xCHMATrader.Close(trade.ticket);
|
||||
// if (isClosed)
|
||||
// {
|
||||
// //
|
||||
// Add(
|
||||
// trade,
|
||||
// closed);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XCHMAIssueLongInDrawdownTradeClosed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Position ...
|
||||
bool XCHMAOpenLongPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XCHMAGeneratePositionSignal(X_SIGNAL_LONG);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xCHMAMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xCHMATrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XCHMAIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Position ...
|
||||
bool XCHMAOpenShortPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XCHMAGeneratePositionSignal(X_SIGNAL_SHORT);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xCHMAMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xCHMATrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XCHMAIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Support Signal ...
|
||||
bool XCHMAOpenSuppurtTrade(
|
||||
XSignal &signal // Parent Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!xCHMAEnableSupportTrades) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Signal ...
|
||||
if (!IsValid(signal, xCHMAMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Market Conditions ...
|
||||
bool hasLongSignal = XCHMACanOpenLongTrade();
|
||||
bool hasShortSignal = XCHMACanOpenShortTrade();
|
||||
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN;
|
||||
|
||||
//
|
||||
// Detect Support Signal Direction ...
|
||||
XSignal support = {};
|
||||
switch (signal.type)
|
||||
{
|
||||
//
|
||||
case X_SIGNAL_LONG:
|
||||
//
|
||||
// First Check Long Support ...
|
||||
// Then Look for Short Support ...
|
||||
if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
case X_SIGNAL_SHORT:
|
||||
// First Check Short Support ...
|
||||
// Then Look for Long Support ...
|
||||
if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (type == X_SIGNAL_UNKNOWN)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
// Find Common Used ...
|
||||
double entry = GetEntry(type);
|
||||
double volumeMultiplier = 2;
|
||||
if (xCHMAVolumeMultiplier > 2)
|
||||
{
|
||||
volumeMultiplier = xCHMAVolumeMultiplier;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal is Support ot nor ...
|
||||
int titlePosition = StringFind(
|
||||
signal.comment,
|
||||
"Support");
|
||||
bool isSupport = titlePosition >= 0;
|
||||
double priceDistance = MathAbs(signal.entry - entry);
|
||||
|
||||
//
|
||||
if (isSupport || priceDistance < PipsToPrice(5)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
double volume = NormalizeVolume(isSupport ? signal.volume : signal.volume * volumeMultiplier);
|
||||
string comment = "Support_" + GetSignalType(type) + "_For_" + (string)signal.ticket + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XCHMACalculateTPSL(type);
|
||||
if (!IsValid(tpSL))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate reward of signal ...
|
||||
double reward = MathAbs(signal.entry - signal.tp) / 2;
|
||||
double tp = tpSL.sl; // isLong ? entry + reward : entry - reward;
|
||||
double sl = tpSL.sl;
|
||||
|
||||
//
|
||||
// Filling Support Signal ...
|
||||
support.tp = tp;
|
||||
support.sl = sl;
|
||||
support.type = type;
|
||||
support.time = time;
|
||||
support.entry = entry;
|
||||
support.volume = volume;
|
||||
support.symbol = _Symbol;
|
||||
support.comment = comment;
|
||||
support.magicNumber = xCHMAMagicNumber;
|
||||
|
||||
//
|
||||
// Validate Generated Support ...
|
||||
if (!IsValid(support, xCHMAMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = xCHMATrader.ExecuteSignal(support);
|
||||
if (result)
|
||||
{
|
||||
XCHMAIssueSignalExecutionAlert(support);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate Specific type of Signals for Trading ...
|
||||
XSignal XCHMAGeneratePositionSignal(
|
||||
ENUM_X_SIGNAL_TYPE type // direction of position
|
||||
)
|
||||
{
|
||||
//
|
||||
XSignal result = {};
|
||||
|
||||
//
|
||||
if (type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double entry = GetEntry(type);
|
||||
|
||||
//
|
||||
double volume = XCHMACalculateVolume();
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
|
||||
//
|
||||
string typeString = GetSignalType(type);
|
||||
string comment = XCHMAProviderName + "_" + typeString + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XCHMACalculateTPSL(type);
|
||||
if (IsValid(tpSL))
|
||||
{
|
||||
//
|
||||
// Apply TP ...
|
||||
if (tpSL.tp > 0)
|
||||
{
|
||||
result.tp = tpSL.tp;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply SL ...
|
||||
if (tpSL.sl > 0)
|
||||
{
|
||||
result.sl = tpSL.sl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.time = time;
|
||||
result.entry = entry;
|
||||
result.volume = volume;
|
||||
result.symbol = _Symbol;
|
||||
result.comment = comment;
|
||||
result.magicNumber = xCHMAMagicNumber;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Private Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double XCHMACalculateVolume()
|
||||
{
|
||||
//
|
||||
// Assign default Value ...
|
||||
double result = xCHMAStaticVolume;
|
||||
|
||||
//
|
||||
// we can count open trades and in draw down trades
|
||||
// then do check volume based on it for gridding ...
|
||||
int openTrades = xCHMATrader.Count();
|
||||
if (openTrades == 0)
|
||||
{
|
||||
openTrades = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Normalized Multiplier ...
|
||||
double multiplier = xCHMAVolumeMultiplier <= 0 ? 1 : xCHMAVolumeMultiplier;
|
||||
|
||||
//
|
||||
result = multiplier * openTrades * xCHMAStaticVolume;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeVolume(result);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Signal TP and SL ...
|
||||
XTPSL XCHMACalculateTPSL(
|
||||
ENUM_X_SIGNAL_TYPE type // Position Type
|
||||
)
|
||||
{
|
||||
//
|
||||
XTPSL result = {};
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double spread = GetSpread();
|
||||
double entry = isLong ? ask : bid;
|
||||
|
||||
//
|
||||
// TODO: Find Risk ..
|
||||
double risk = 0;
|
||||
|
||||
//
|
||||
// Calculate Reward ...
|
||||
double reward = PipsToPrice(xCHMAMinRewardPerTradeInPips) + spread;
|
||||
|
||||
//
|
||||
// Calculate TP and SL ...
|
||||
double tp = isLong ? entry + reward : entry - reward;
|
||||
double sl = 0;
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.tp = tp;
|
||||
result.sl = sl;
|
||||
result.entry = entry;
|
||||
//
|
||||
// TODO: Calculate R2R ...
|
||||
result.r2r = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
void XCHMAIssueInitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "Initializion of (" + XCHMAProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueDeinitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "De Initializion of (" + XCHMAProviderName + " Provider" + ") Succeeded ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type) {
|
||||
//
|
||||
string typeStr = GetSignalType(type);
|
||||
if (StringLen(typeStr) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string message = "Force Close " + typeStr + " Trades ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueMaxAllowedTradesReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached Max Allowed Same Time Trades ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueMaxAllowedFreeMarginReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached FreeMarigin For Open Trades ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueMinAllowedBalanceReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "doesn't have Minimum Balance For Open Trades ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueSignalExecutionAlert(
|
||||
XSignal &signal // Executed Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
XCHMAIssueAlert(signal);
|
||||
}
|
||||
|
||||
void XCHMAIssueLongInProfitTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueLongInDrawdownTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XCHMAIssueAlert(message);
|
||||
}
|
||||
|
||||
void XCHMAIssueAlert(string message)
|
||||
{
|
||||
//
|
||||
if (xCHMAEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
void XCHMAIssueAlert(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (xCHMAEnableAlerts)
|
||||
{
|
||||
SendAlert(signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Private Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,279 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XOBD Oscillator Helper for Signal Providers
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Includes ...
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5"
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// START Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// XOBD Oscillator Buffer Lines ...
|
||||
enum ENUM_X_XOBD_BUFFER_LINES
|
||||
{
|
||||
X_XOBD_SWING_HIGH_LINE = 0,
|
||||
X_XOBD_SWING_LOW_LINE = 1,
|
||||
X_XOBD_SIGNAL_LINE = 2,
|
||||
};
|
||||
|
||||
//
|
||||
// END Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
input group "XOBD Oscillator";
|
||||
input int xOBDLength = 72; // Market Length
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Definitions ...
|
||||
//
|
||||
|
||||
int xOBDHandler = INVALID_HANDLE;
|
||||
double xOBDSwingHighBuffer[];
|
||||
double xOBDSwingLowBuffer[];
|
||||
double xOBDSignalBuffer[];
|
||||
|
||||
//
|
||||
// END Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Handler Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Init Oscillators ...
|
||||
bool XOBDInitHandlers()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XOBD Handler ...
|
||||
ArraySetAsSeries(xOBDSwingHighBuffer, true);
|
||||
ArraySetAsSeries(xOBDSwingLowBuffer, true);
|
||||
ArraySetAsSeries(xOBDSignalBuffer, true);
|
||||
xOBDHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xobd.oscillator",
|
||||
//
|
||||
// Inputs ...
|
||||
xOBDLength
|
||||
//
|
||||
);
|
||||
if (xOBDHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("failed to Initialize XOBD Oscillator: " + (string)GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Oscillators ...
|
||||
void XOBDReleaseHandlers()
|
||||
{
|
||||
IndicatorRelease(xOBDHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XOBDReadBuffers(
|
||||
int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
// XOBD Swing High ...
|
||||
CopyBuffer(
|
||||
xOBDHandler,
|
||||
X_XOBD_SWING_HIGH_LINE,
|
||||
0,
|
||||
xOBDItemsPerTick,
|
||||
xOBDSwingHighBuffer);
|
||||
|
||||
//
|
||||
// XOBD Swing Low ...
|
||||
CopyBuffer(
|
||||
xOBDHandler,
|
||||
X_XOBD_SWING_LOW_LINE,
|
||||
0,
|
||||
xOBDItemsPerTick,
|
||||
xOBDSwingLowBuffer);
|
||||
|
||||
//
|
||||
// XOBD Signal ...
|
||||
CopyBuffer(
|
||||
xOBDHandler,
|
||||
X_XOBD_SIGNAL_LINE,
|
||||
0,
|
||||
xOBDItemsPerTick,
|
||||
xOBDSignalBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// END Handler Funcions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Signal Related Conditions ...
|
||||
//
|
||||
|
||||
//
|
||||
// XOBD Long Conditions ...
|
||||
bool XOBDHasLongConditions(
|
||||
int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isVale = XOBDIsVale();
|
||||
bool isInPeak = IsInPeak(
|
||||
xOBDItemsPerTick,
|
||||
xOBDSignalBuffer);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isVale
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isInPeak
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XOBD Short Conditions ...
|
||||
bool XOBDHasShortConditions(
|
||||
int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Signal Related Conditions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START XOBD Custom Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Check SC is Peak ...
|
||||
bool XOBDIsPeak()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isIncreasing = IsIncreasing(
|
||||
10,
|
||||
3,
|
||||
xOBDSignalBuffer);
|
||||
|
||||
//
|
||||
bool isDecreasing = IsDecreasing(
|
||||
3,
|
||||
1,
|
||||
xOBDSignalBuffer);
|
||||
|
||||
//
|
||||
// Generating Result ...
|
||||
result =
|
||||
//
|
||||
isIncreasing
|
||||
//
|
||||
&&
|
||||
//
|
||||
isDecreasing
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check SC is Vale ...
|
||||
bool XOBDIsVale()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isIncreasing = IsIncreasing(
|
||||
5,
|
||||
1,
|
||||
xOBDSignalBuffer);
|
||||
|
||||
//
|
||||
bool isDecreasing = IsDecreasing(
|
||||
20,
|
||||
5,
|
||||
xOBDSignalBuffer);
|
||||
|
||||
//
|
||||
// Generating Result ...
|
||||
result =
|
||||
//
|
||||
isIncreasing
|
||||
//
|
||||
&&
|
||||
//
|
||||
isDecreasing
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END XOBD Custom Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,154 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XOBD Signal Provider Indicators Library
|
||||
// ----------------------------------------------------------------
|
||||
//
|
||||
// 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 Provider Inputs ...
|
||||
#include "x-saherelm.xobd.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// Imports all Indicators Helper here ...
|
||||
input group "XOBD Provider Indicators";
|
||||
#include "x-saherelm.xobd.oscillator.helper.lib.mq5";
|
||||
|
||||
//
|
||||
int xOBDMaxLengthOfInputs = 0;
|
||||
int xOBDCalculatedBars = 0;
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XOBDInitIndicators()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check and Calculate Max Length in Inputs ...
|
||||
xOBDMaxLengthOfInputs = MathMax(
|
||||
xOBDNumberOfItemsPerTick,
|
||||
xOBDLength);
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XOBD Init ...
|
||||
result = XOBDInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XOBDReleaseIndicators()
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XOBDReleaseHandlers();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XOBDHandleReadingBuffers()
|
||||
{
|
||||
//
|
||||
// Reading Calculated Bars for a Simple Handler ...
|
||||
xOBDCalculatedBars = BarsCalculated(xOBDHandler);
|
||||
|
||||
//
|
||||
// Read Indicators Buffers ...
|
||||
XOBDReadBuffers(xOBDNumberOfItemsPerTick);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// START Combination Functions ...
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Can Open Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XOBDCanOpenLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XOBDHasLongConditions(xOBDNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XOBDCanCloseLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Open Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XOBDCanOpenShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XOBDHasShortConditions(xOBDNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XOBDCanCloseShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// END Combination Functions ...
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,63 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XOBD Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
input group "XOBD Provider";
|
||||
|
||||
//
|
||||
input group "XOBD Common";
|
||||
input bool xOBDEnableProvider = true; // Enable Provider
|
||||
input bool xOBDEnableAlerts = false; // Enable Events Alert
|
||||
input int xOBDNumberOfItemsPerTick = 110; // Number Of items Readed In Each Tick
|
||||
|
||||
//
|
||||
input group "XOBD Trader";
|
||||
input int xOBDMagicNumber = 16940563; // Trader MagicNumber
|
||||
input int xOBDSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XOBD Trade Management";
|
||||
input bool xOBDAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xOBDAllowShortTrades = true; // Allow Short Trades
|
||||
|
||||
//
|
||||
input group "XOBD Risk Management";
|
||||
input int xOBDMaxAllowedTrades = 5; // Max Allowed Trades at Same Time
|
||||
input int xOBDMaxInProfitTradeAge = 0; // Max In Profit Trades Age
|
||||
input int xOBDMaxInDrawDownTradeAge = 576; // Max In DrawDown Trades Age
|
||||
input double xOBDStaticVolume = 0.02; // Static Volume
|
||||
input double xOBDVolumeMultiplier = 2; // Volume Multiplier
|
||||
input double xOBDMinRewardPerTradeInPips = 2; // Min Reward Per Trade In Pips
|
||||
input double xOBDFreeMarginFactorForOpenTrades = 0.5; // Minimum Free Marging for Open Trades
|
||||
input double xOBDBalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades
|
||||
input bool xOBDEnableSupportTrades = false; // Enable Support Trade
|
||||
|
||||
//
|
||||
// Validate Inputs before Initialization ...
|
||||
bool XOBDValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,861 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XOBD Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XOBDSignalProvider
|
||||
// Description: XOBD based 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
|
||||
|
||||
#define XOBDProviderName "XOBD"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
#include "x-saherelm.xobd.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
XCTrade *xOBDTrader;
|
||||
XCAccountInfo xOBDAccountInfo;
|
||||
|
||||
//
|
||||
#include "x-saherelm.xobd.provider.indicators.lib.mq5"
|
||||
|
||||
//
|
||||
double xOBDDeposit = 0;
|
||||
double xOBDBalance = 0;
|
||||
double xOBDFreeMargin = 0;
|
||||
double xOBDFreeMarginForOpenTrades = 0;
|
||||
double xOBDBalanceForOpenTrades = 0;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool XOBDInitSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
result = XOBDValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
result = XOBDInitIndicators();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Account Deposit ...
|
||||
xOBDDeposit = xOBDAccountInfo.GetInitialBalance();
|
||||
|
||||
//
|
||||
// Calculate Min Balance for Trades ...
|
||||
if (xOBDBalanceFactorForOpenTrades > 0)
|
||||
{
|
||||
xOBDBalanceForOpenTrades = xOBDBalanceFactorForOpenTrades * xOBDDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Claculate Min Free Marging for Trades ...
|
||||
if (xOBDFreeMarginFactorForOpenTrades > 0)
|
||||
{
|
||||
xOBDFreeMarginForOpenTrades = xOBDFreeMarginFactorForOpenTrades * xOBDDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
xOBDTrader = new XCTrade(
|
||||
_Symbol,
|
||||
xOBDSlippage,
|
||||
xOBDMagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XOBDIssueInitializationSucceedAlert();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void XOBDDeinitSignalProviderLibrary(
|
||||
const int reason)
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XOBDReleaseIndicators();
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XOBDIssueDeinitializationSucceedAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void XOBDSignalProviderHandleTick()
|
||||
{
|
||||
//
|
||||
// Update account Balance ...
|
||||
xOBDBalance = xOBDAccountInfo.GetBalance();
|
||||
xOBDFreeMargin = xOBDAccountInfo.GetFreeMargin();
|
||||
|
||||
//
|
||||
// Check Provider is Enable or Not ...
|
||||
if (!xOBDEnableProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Indicator Buffers ...
|
||||
XOBDHandleReadingBuffers();
|
||||
if (xOBDCalculatedBars < xOBDMaxLengthOfInputs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
XOBDHandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
XOBDHandleCloseTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void XOBDHandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Check Can Trade ...
|
||||
bool canTrade = xOBDAllowLongTrades || xOBDAllowShortTrades;
|
||||
if (!canTrade)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// First Check Signal Exists or NOt ...
|
||||
bool xOBDHasLongSignal = XOBDCanOpenLongTrade();
|
||||
bool xOBDHasShortSignal = XOBDCanOpenShortTrade();
|
||||
if (!xOBDHasLongSignal && !xOBDHasShortSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Max Open Trades ...
|
||||
if (xOBDMaxAllowedTrades > 0)
|
||||
{
|
||||
//
|
||||
int count = xOBDTrader.Count();
|
||||
bool canOpenTrade = count < xOBDMaxAllowedTrades;
|
||||
if (!canOpenTrade)
|
||||
{
|
||||
//
|
||||
XOBDIssueMaxAllowedTradesReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Free Margin ...
|
||||
if (xOBDFreeMargin <= xOBDFreeMarginForOpenTrades)
|
||||
{
|
||||
//
|
||||
XOBDIssueMaxAllowedFreeMarginReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Account Balance ...
|
||||
if (xOBDBalance <= xOBDBalanceForOpenTrades)
|
||||
{
|
||||
//
|
||||
XOBDIssueMinAllowedBalanceReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
if (
|
||||
xOBDHasLongSignal &&
|
||||
xOBDAllowLongTrades)
|
||||
{
|
||||
//
|
||||
bool isLongSignalExecuted = XOBDOpenLongPosition();
|
||||
if (isLongSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
if (
|
||||
xOBDHasShortSignal &&
|
||||
xOBDAllowShortTrades)
|
||||
{
|
||||
//
|
||||
bool isShortSignalExecuted = XOBDOpenShortPosition();
|
||||
if (isShortSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void XOBDHandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (xOBDTrader.CountLongs() > 0 && XOBDCanCloseLongTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xOBDTrader.CloseLongPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XOBDIssueForceCloseTradesAlert(X_SIGNAL_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (xOBDTrader.CountShorts() > 0 && XOBDCanCloseShortTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xOBDTrader.CloseShortPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XOBDIssueForceCloseTradesAlert(X_SIGNAL_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In Profit Teades ...
|
||||
if (xOBDMaxInProfitTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xOBDTrader.GetLongTimeTrades(
|
||||
xOBDMaxInProfitTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isClosed = xOBDTrader.Close(trade.ticket);
|
||||
if (isClosed)
|
||||
{
|
||||
Add(
|
||||
trade,
|
||||
closed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XOBDIssueLongInProfitTradeClosed();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In DrawDown Trades ...
|
||||
if (xOBDMaxInDrawDownTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xOBDTrader.GetLongTimeTrades(
|
||||
xOBDMaxInDrawDownTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Grid Trades ...
|
||||
XOBDOpenSuppurtTrade(trade);
|
||||
|
||||
// //
|
||||
// bool isClosed = xOBDTrader.Close(trade.ticket);
|
||||
// if (isClosed)
|
||||
// {
|
||||
// //
|
||||
// Add(
|
||||
// trade,
|
||||
// closed);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XOBDIssueLongInDrawdownTradeClosed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Position ...
|
||||
bool XOBDOpenLongPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XOBDGeneratePositionSignal(X_SIGNAL_LONG);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xOBDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xOBDTrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XOBDIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Position ...
|
||||
bool XOBDOpenShortPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XOBDGeneratePositionSignal(X_SIGNAL_SHORT);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xOBDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xOBDTrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XOBDIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Support Signal ...
|
||||
bool XOBDOpenSuppurtTrade(
|
||||
XSignal &signal // Parent Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!xOBDEnableSupportTrades) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Signal ...
|
||||
if (!IsValid(signal, xOBDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Market Conditions ...
|
||||
bool hasLongSignal = XOBDCanOpenLongTrade();
|
||||
bool hasShortSignal = XOBDCanOpenShortTrade();
|
||||
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN;
|
||||
|
||||
//
|
||||
// Detect Support Signal Direction ...
|
||||
XSignal support = {};
|
||||
switch (signal.type)
|
||||
{
|
||||
//
|
||||
case X_SIGNAL_LONG:
|
||||
//
|
||||
// First Check Long Support ...
|
||||
// Then Look for Short Support ...
|
||||
if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
case X_SIGNAL_SHORT:
|
||||
// First Check Short Support ...
|
||||
// Then Look for Long Support ...
|
||||
if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (type == X_SIGNAL_UNKNOWN)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
// Find Common Used ...
|
||||
double entry = GetEntry(type);
|
||||
double volumeMultiplier = 2;
|
||||
if (xOBDVolumeMultiplier > 2)
|
||||
{
|
||||
volumeMultiplier = xOBDVolumeMultiplier;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal is Support ot nor ...
|
||||
int titlePosition = StringFind(
|
||||
signal.comment,
|
||||
"Support");
|
||||
bool isSupport = titlePosition >= 0;
|
||||
double priceDistance = MathAbs(signal.entry - entry);
|
||||
|
||||
//
|
||||
if (isSupport || priceDistance < PipsToPrice(5)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
double volume = NormalizeVolume(isSupport ? signal.volume : signal.volume * volumeMultiplier);
|
||||
string comment = "Support_" + GetSignalType(type) + "_For_" + (string)signal.ticket + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XOBDCalculateTPSL(type);
|
||||
if (!IsValid(tpSL))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate reward of signal ...
|
||||
double reward = MathAbs(signal.entry - signal.tp) / 2;
|
||||
double tp = tpSL.sl; // isLong ? entry + reward : entry - reward;
|
||||
double sl = tpSL.sl;
|
||||
|
||||
//
|
||||
// Filling Support Signal ...
|
||||
support.tp = tp;
|
||||
support.sl = sl;
|
||||
support.type = type;
|
||||
support.time = time;
|
||||
support.entry = entry;
|
||||
support.volume = volume;
|
||||
support.symbol = _Symbol;
|
||||
support.comment = comment;
|
||||
support.magicNumber = xOBDMagicNumber;
|
||||
|
||||
//
|
||||
// Validate Generated Support ...
|
||||
if (!IsValid(support, xOBDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = xOBDTrader.ExecuteSignal(support);
|
||||
if (result)
|
||||
{
|
||||
XOBDIssueSignalExecutionAlert(support);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate Specific type of Signals for Trading ...
|
||||
XSignal XOBDGeneratePositionSignal(
|
||||
ENUM_X_SIGNAL_TYPE type // direction of position
|
||||
)
|
||||
{
|
||||
//
|
||||
XSignal result = {};
|
||||
|
||||
//
|
||||
if (type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double entry = GetEntry(type);
|
||||
|
||||
//
|
||||
double volume = XOBDCalculateVolume();
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
|
||||
//
|
||||
string typeString = GetSignalType(type);
|
||||
string comment = XOBDProviderName + "_" + typeString + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XOBDCalculateTPSL(type);
|
||||
if (IsValid(tpSL))
|
||||
{
|
||||
//
|
||||
// Apply TP ...
|
||||
if (tpSL.tp > 0)
|
||||
{
|
||||
result.tp = tpSL.tp;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply SL ...
|
||||
if (tpSL.sl > 0)
|
||||
{
|
||||
result.sl = tpSL.sl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.time = time;
|
||||
result.entry = entry;
|
||||
result.volume = volume;
|
||||
result.symbol = _Symbol;
|
||||
result.comment = comment;
|
||||
result.magicNumber = xOBDMagicNumber;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Private Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double XOBDCalculateVolume()
|
||||
{
|
||||
//
|
||||
// Assign default Value ...
|
||||
double result = xOBDStaticVolume;
|
||||
|
||||
//
|
||||
// we can count open trades and in draw down trades
|
||||
// then do check volume based on it for gridding ...
|
||||
int openTrades = xOBDTrader.Count();
|
||||
if (openTrades == 0)
|
||||
{
|
||||
openTrades = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Normalized Multiplier ...
|
||||
double multiplier = xOBDVolumeMultiplier <= 0 ? 1 : xOBDVolumeMultiplier;
|
||||
|
||||
//
|
||||
result = multiplier * openTrades * xOBDStaticVolume;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeVolume(result);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Signal TP and SL ...
|
||||
XTPSL XOBDCalculateTPSL(
|
||||
ENUM_X_SIGNAL_TYPE type // Position Type
|
||||
)
|
||||
{
|
||||
//
|
||||
XTPSL result = {};
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double spread = GetSpread();
|
||||
double entry = isLong ? ask : bid;
|
||||
|
||||
//
|
||||
// TODO: Find Risk ..
|
||||
double risk = 0;
|
||||
|
||||
//
|
||||
// Calculate Reward ...
|
||||
double reward = PipsToPrice(xOBDMinRewardPerTradeInPips) + spread;
|
||||
|
||||
//
|
||||
// Calculate TP and SL ...
|
||||
double tp = isLong ? entry + reward : entry - reward;
|
||||
double sl = 0;
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.tp = tp;
|
||||
result.sl = sl;
|
||||
result.entry = entry;
|
||||
//
|
||||
// TODO: Calculate R2R ...
|
||||
result.r2r = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
void XOBDIssueInitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "Initializion of (" + XOBDProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueDeinitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "De Initializion of (" + XOBDProviderName + " Provider" + ") Succeeded ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type) {
|
||||
//
|
||||
string typeStr = GetSignalType(type);
|
||||
if (StringLen(typeStr) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string message = "Force Close " + typeStr + " Trades ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueMaxAllowedTradesReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached Max Allowed Same Time Trades ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueMaxAllowedFreeMarginReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached FreeMarigin For Open Trades ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueMinAllowedBalanceReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "doesn't have Minimum Balance For Open Trades ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueSignalExecutionAlert(
|
||||
XSignal &signal // Executed Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
XOBDIssueAlert(signal);
|
||||
}
|
||||
|
||||
void XOBDIssueLongInProfitTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueLongInDrawdownTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XOBDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XOBDIssueAlert(string message)
|
||||
{
|
||||
//
|
||||
if (xOBDEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
void XOBDIssueAlert(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (xOBDEnableAlerts)
|
||||
{
|
||||
SendAlert(signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Private Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,917 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTD Oscillator Helper for Signal Providers
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Includes ...
|
||||
#include "..\Libraries\x-saherelm.log.lib.mq5"
|
||||
#include "..\Libraries\x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// START Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// XTD Oscillator States ...
|
||||
enum ENUM_X_XTD_STATES
|
||||
{
|
||||
X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2,
|
||||
X_XTD_BULLISH_OVER_BEARISH = 1,
|
||||
X_XTD_NEUTURAL = 0,
|
||||
X_XTD_BULLISH_UNDER_BEARISH = -1,
|
||||
X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2
|
||||
};
|
||||
|
||||
//
|
||||
// XTD Oscillator Buffer Lines ...
|
||||
enum ENUM_X_XTD_BUFFER_LINES
|
||||
{
|
||||
X_XTD_BULLISH_POWER_LINE = 0,
|
||||
X_XTD_BEARISH_POWER_LINE = 1,
|
||||
X_XTD_SIGNAL_LINE = 2,
|
||||
};
|
||||
|
||||
//
|
||||
// END Enum Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
input group "XTD Oscillator";
|
||||
input int xTDLength = 14; // Market Length
|
||||
input bool xTDDrawCrosses = false; // Draw Cross Arrows
|
||||
input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code
|
||||
input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color
|
||||
input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code
|
||||
input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Definitions ...
|
||||
//
|
||||
|
||||
int xTDHandler = INVALID_HANDLE;
|
||||
double xTDBullishBuffer[];
|
||||
double xTDBearishBuffer[];
|
||||
double xTDSignalBuffer[];
|
||||
//
|
||||
// END Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Handler Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Init Oscillators ...
|
||||
bool XTDInitHandlers()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XTD Handler ...
|
||||
ArraySetAsSeries(xTDBullishBuffer, true);
|
||||
ArraySetAsSeries(xTDBearishBuffer, true);
|
||||
ArraySetAsSeries(xTDSignalBuffer, true);
|
||||
xTDHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xtd.oscillator",
|
||||
//
|
||||
// Inputs ...
|
||||
xTDLength,
|
||||
xTDDrawCrosses,
|
||||
xTDBullishArrowCode,
|
||||
xTDBullishArrowColor,
|
||||
xTDBearishArrowCode,
|
||||
xTDBearishArrowColor);
|
||||
if (xTDHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("failed to Initialize XTD Oscillator: " + (string)GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Oscillators ...
|
||||
void XTDReleaseHandlers()
|
||||
{
|
||||
IndicatorRelease(xTDHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XTDReadBuffers(
|
||||
int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
// XTD Bullish Buffer ...
|
||||
CopyBuffer(
|
||||
xTDHandler,
|
||||
X_XTD_BULLISH_POWER_LINE,
|
||||
0,
|
||||
xTDItemsPerTick,
|
||||
xTDBullishBuffer);
|
||||
|
||||
//
|
||||
// XTD Bullish Buffer ...
|
||||
CopyBuffer(
|
||||
xTDHandler,
|
||||
X_XTD_BEARISH_POWER_LINE,
|
||||
0,
|
||||
xTDItemsPerTick,
|
||||
xTDBearishBuffer);
|
||||
|
||||
//
|
||||
// XTD Signal Buffer ...
|
||||
CopyBuffer(
|
||||
xTDHandler,
|
||||
X_XTD_SIGNAL_LINE,
|
||||
0,
|
||||
xTDItemsPerTick,
|
||||
xTDSignalBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// END Handler Funcions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Signal Related Conditions ...
|
||||
//
|
||||
|
||||
//
|
||||
// XTD Long Conditions ...
|
||||
bool XTDHasLongConditions(
|
||||
int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isVale = XTDIsSignalVale();
|
||||
|
||||
//
|
||||
bool isInPeak = IsInPeak(
|
||||
15,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
bool isSharpChanged = IsSharpChanged(
|
||||
15,
|
||||
1,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
double entry = GetEntry(X_SIGNAL_LONG);
|
||||
double maxPrice = GetHighestHigh(
|
||||
7,
|
||||
0);
|
||||
double minPrice = GetLowestLow(
|
||||
7,
|
||||
0);
|
||||
double priceDelta = maxPrice - minPrice;
|
||||
double priceStep = priceDelta / 7;
|
||||
|
||||
//
|
||||
bool isPricePassed =
|
||||
entry < maxPrice &&
|
||||
maxPrice - entry < (priceDelta / 4) * 3;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isVale
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isInPeak
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isSharpChanged
|
||||
//
|
||||
&&
|
||||
//
|
||||
isPricePassed
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XTD Short Conditions ...
|
||||
bool XTDHasShortConditions(
|
||||
int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isPeak = XTDIsSignalPeak();
|
||||
|
||||
//
|
||||
bool isInVale = IsInVale(
|
||||
15,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
bool isSharpChanged = IsSharpChanged(
|
||||
15,
|
||||
1,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
double entry = GetEntry(X_SIGNAL_SHORT);
|
||||
double maxPrice = GetHighestHigh(
|
||||
7,
|
||||
0);
|
||||
double minPrice = GetLowestLow(
|
||||
7,
|
||||
0);
|
||||
double priceDelta = maxPrice - minPrice;
|
||||
double priceStep = priceDelta / 7;
|
||||
|
||||
//
|
||||
bool isPricePassed =
|
||||
entry > minPrice &&
|
||||
minPrice + entry > (priceDelta / 4);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isPeak
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isInVale
|
||||
//
|
||||
&&
|
||||
//
|
||||
!isSharpChanged
|
||||
//
|
||||
&&
|
||||
//
|
||||
isPricePassed
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Signal Related Conditions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START XTD Custom Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Check Signal Vale ...
|
||||
bool XTDIsSignalVale()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Must Decreasing ...
|
||||
bool isIncreasing = IsIncreasing(
|
||||
3,
|
||||
1,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
// Must Increasing ...
|
||||
bool isDecreasing = IsDecreasing(
|
||||
15,
|
||||
3,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
// Generating Result ...
|
||||
result =
|
||||
//
|
||||
isIncreasing
|
||||
//
|
||||
&&
|
||||
//
|
||||
isDecreasing
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal Peak ...
|
||||
bool XTDIsSignalPeak()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Must Decreasing ...
|
||||
bool isIncreasing = IsIncreasing(
|
||||
15,
|
||||
3,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
// Must Increasing ...
|
||||
bool isDecreasing = IsDecreasing(
|
||||
3,
|
||||
1,
|
||||
xTDSignalBuffer);
|
||||
|
||||
//
|
||||
// Generating Result ...
|
||||
result =
|
||||
//
|
||||
isIncreasing
|
||||
//
|
||||
&&
|
||||
//
|
||||
isDecreasing
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal Peak ...
|
||||
|
||||
//
|
||||
// Check Bullish Crossed Over Bearish ...
|
||||
bool XTDIsBullCrossedOverBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossOver(
|
||||
xTDBullishBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bullish Over Bearish ...
|
||||
bool XTDIsBullOverBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsOver(
|
||||
xTDBullishBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bullish Crossed Under Bearish ...
|
||||
bool XTDIsBullCrossedUnderBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossUnder(
|
||||
xTDBullishBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Bullish Under Bearish ...
|
||||
bool XTDIsBullUnderBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsUnder(
|
||||
xTDBullishBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal Crossed Over Bearish ...
|
||||
bool XTDIsSignalCrossedOverBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossOver(
|
||||
xTDSignalBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal Over Bearish ...
|
||||
bool XTDIsSignalOverBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsOver(
|
||||
xTDSignalBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal Crossed Under Bearish ...
|
||||
bool XTDIsSignalCrossedUnderBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsCrossUnder(
|
||||
xTDSignalBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal Under Bearish ...
|
||||
bool XTDIsSignalUnderBear(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
!XTDIsValidBuffersSize(bar_index + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = IsUnder(
|
||||
xTDSignalBuffer,
|
||||
xTDBearishBuffer,
|
||||
1);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check all Buffers has valid Size ...
|
||||
bool XTDIsValidBuffersSize(
|
||||
int size // the size of buffers which min size for requirements
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
size <= 0 ||
|
||||
ArraySize(xTDBullishBuffer) < size ||
|
||||
ArraySize(xTDBullishBuffer) < size ||
|
||||
ArraySize(xTDSignalBuffer) < size)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Signal Crossed Over Bear ...
|
||||
int XTDCountSignalCrossedOverBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsSignalCrossedOverBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Signal Crossed Under Bear ...
|
||||
int XTDCountSignalCrossedUnderBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Bull Crossed Over Bear ...
|
||||
int XTDCountBullCrossedOverBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsBullCrossedOverBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Bull Crossed Under Bear ...
|
||||
int XTDCountBullCrossedUnderBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsBullCrossedUnderBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Last Signal Crossed Over Bear ...
|
||||
int XTDFindLastSignalCrossedOverBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsSignalCrossedOverBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
//
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Last Signal Crossed Onder Bear ...
|
||||
int XTDFindLastSignalCrossedUnderBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
//
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Last Bull Crossed Over Bear ...
|
||||
int XTDFindLastBullCrossedOverBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsBullCrossedOverBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
//
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Find Last Bull Crossed Under Bear ...
|
||||
int XTDFindLastBullCrossedUnderBearIndex(
|
||||
int bar_index // Specified Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
int count = ArraySize(xTDSignalBuffer) - 1;
|
||||
if (
|
||||
bar_index <= 0 ||
|
||||
count <= bar_index + 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop Through ...
|
||||
for (int i = bar_index + 1; i < count && result == -1; i++)
|
||||
{
|
||||
//
|
||||
// Check Cross On i Point ...
|
||||
bool isCrossedOnI = XTDIsBullCrossedUnderBear(i);
|
||||
if (isCrossedOnI)
|
||||
{
|
||||
//
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END XTD Custom Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,158 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTD Signal Provider Indicators Library
|
||||
// ----------------------------------------------------------------
|
||||
//
|
||||
// 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 Provider Inputs ...
|
||||
#include "x-saherelm.xtd.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// Imports all Indicators Helper here ...
|
||||
input group "XTD Provider Indicators";
|
||||
#include "x-saherelm.xtd.oscillator.helper.lib.mq5";
|
||||
|
||||
//
|
||||
int xTDMaxLengthOfInputs = 0;
|
||||
int xTDCalculatedBars = 0;
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XTDInitIndicators()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check and Calculate Max Length in Inputs ...
|
||||
xTDMaxLengthOfInputs = MathMax(
|
||||
xTDLength,
|
||||
xTDMaxLengthOfInputs);
|
||||
xTDMaxLengthOfInputs = MathMax(
|
||||
xTDNumberOfItemsPerTick,
|
||||
xTDMaxLengthOfInputs);
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XTD Init ...
|
||||
result = XTDInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XTDReleaseIndicators()
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTDReleaseHandlers();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XTDHandleReadingBuffers()
|
||||
{
|
||||
//
|
||||
// Reading Calculated Bars for a Simple Handler ...
|
||||
xTDCalculatedBars = BarsCalculated(xTDHandler);
|
||||
|
||||
//
|
||||
// Read Indicators Buffers ...
|
||||
XTDReadBuffers(xTDNumberOfItemsPerTick);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// START Combination Functions ...
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Can Open Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XTDCanOpenLongTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XTDHasLongConditions(xTDNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
// if (result) {
|
||||
// LogMessage("Salam");
|
||||
// }
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XTDCanCloseLongTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Open Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XTDCanOpenShortTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XTDHasShortConditions(xTDNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XTDCanCloseShortTrade() {
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// END Combination Functions ...
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,63 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTD Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
input group "XTD Provider";
|
||||
|
||||
//
|
||||
input group "XTD Common";
|
||||
input bool xTDEnableProvider = true; // Enable Provider
|
||||
input bool xTDEnableAlerts = false; // Enable Events Alert
|
||||
input int xTDNumberOfItemsPerTick = 110; // Number Of items Readed In Each Tick
|
||||
|
||||
//
|
||||
input group "XTD Trader";
|
||||
input int xTDMagicNumber = 16940561; // Trader MagicNumber
|
||||
input int xTDSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XTD Trade Management";
|
||||
input bool xTDAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xTDAllowShortTrades = true; // Allow Short Trades
|
||||
|
||||
//
|
||||
input group "XTD Risk Management";
|
||||
input int xTDMaxAllowedTrades = 5; // Max Allowed Trades at Same Time
|
||||
input int xTDMaxInProfitTradeAge = 0; // Max In Profit Trades Age
|
||||
input int xTDMaxInDrawDownTradeAge = 576; // Max In DrawDown Trades Age
|
||||
input double xTDStaticVolume = 0.02; // Static Volume
|
||||
input double xTDVolumeMultiplier = 2; // Volume Multiplier
|
||||
input double xTDMinRewardPerTradeInPips = 2; // Min Reward Per Trade In Pips
|
||||
input double xTDFreeMarginFactorForOpenTrades = 0.5; // Minimum Free Marging for Open Trades
|
||||
input double xTDBalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades
|
||||
input bool xTDEnableSupportTrades = false; // Enable Support Trade
|
||||
|
||||
//
|
||||
// Validate Inputs before Initialization ...
|
||||
bool XTDValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,861 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTD Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XTDSignalProvider
|
||||
// Description: XTD based 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
|
||||
|
||||
#define XTDProviderName "XTD"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
#include "x-saherelm.xtd.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
XCTrade *xTDTrader;
|
||||
XCAccountInfo xTDAccountInfo;
|
||||
|
||||
//
|
||||
#include "x-saherelm.xtd.provider.indicators.lib.mq5"
|
||||
|
||||
//
|
||||
double xTDDeposit = 0;
|
||||
double xTDBalance = 0;
|
||||
double xTDFreeMargin = 0;
|
||||
double xTDFreeMarginForOpenTrades = 0;
|
||||
double xTDBalanceForOpenTrades = 0;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool XTDInitSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
result = XTDValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
result = XTDInitIndicators();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Account Deposit ...
|
||||
xTDDeposit = xTDAccountInfo.GetInitialBalance();
|
||||
|
||||
//
|
||||
// Calculate Min Balance for Trades ...
|
||||
if (xTDBalanceFactorForOpenTrades > 0)
|
||||
{
|
||||
xTDBalanceForOpenTrades = xTDBalanceFactorForOpenTrades * xTDDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Claculate Min Free Marging for Trades ...
|
||||
if (xTDFreeMarginFactorForOpenTrades > 0)
|
||||
{
|
||||
xTDFreeMarginForOpenTrades = xTDFreeMarginFactorForOpenTrades * xTDDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
xTDTrader = new XCTrade(
|
||||
_Symbol,
|
||||
xTDSlippage,
|
||||
xTDMagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTDIssueInitializationSucceedAlert();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void XTDDeinitSignalProviderLibrary(
|
||||
const int reason)
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTDReleaseIndicators();
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTDIssueDeinitializationSucceedAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void XTDSignalProviderHandleTick()
|
||||
{
|
||||
//
|
||||
// Update account Balance ...
|
||||
xTDBalance = xTDAccountInfo.GetBalance();
|
||||
xTDFreeMargin = xTDAccountInfo.GetFreeMargin();
|
||||
|
||||
//
|
||||
// Check Provider is Enable or Not ...
|
||||
if (!xTDEnableProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Indicator Buffers ...
|
||||
XTDHandleReadingBuffers();
|
||||
if (xTDCalculatedBars < xTDMaxLengthOfInputs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
XTDHandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
XTDHandleCloseTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void XTDHandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Check Can Trade ...
|
||||
bool canTrade = xTDAllowLongTrades || xTDAllowShortTrades;
|
||||
if (!canTrade)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// First Check Signal Exists or NOt ...
|
||||
bool xTDHasLongSignal = XTDCanOpenLongTrade();
|
||||
bool xTDHasShortSignal = XTDCanOpenShortTrade();
|
||||
if (!xTDHasLongSignal && !xTDHasShortSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Max Open Trades ...
|
||||
if (xTDMaxAllowedTrades > 0)
|
||||
{
|
||||
//
|
||||
int count = xTDTrader.Count();
|
||||
bool canOpenTrade = count < xTDMaxAllowedTrades;
|
||||
if (!canOpenTrade)
|
||||
{
|
||||
//
|
||||
XTDIssueMaxAllowedTradesReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Free Margin ...
|
||||
if (xTDFreeMargin <= xTDFreeMarginForOpenTrades)
|
||||
{
|
||||
//
|
||||
XTDIssueMaxAllowedFreeMarginReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Account Balance ...
|
||||
if (xTDBalance <= xTDBalanceForOpenTrades)
|
||||
{
|
||||
//
|
||||
XTDIssueMinAllowedBalanceReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
if (
|
||||
xTDHasLongSignal &&
|
||||
xTDAllowLongTrades)
|
||||
{
|
||||
//
|
||||
bool isLongSignalExecuted = XTDOpenLongPosition();
|
||||
if (isLongSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
if (
|
||||
xTDHasShortSignal &&
|
||||
xTDAllowShortTrades)
|
||||
{
|
||||
//
|
||||
bool isShortSignalExecuted = XTDOpenShortPosition();
|
||||
if (isShortSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void XTDHandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (xTDTrader.CountLongs() > 0 && XTDCanCloseLongTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xTDTrader.CloseLongPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XTDIssueForceCloseTradesAlert(X_SIGNAL_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (xTDTrader.CountShorts() > 0 && XTDCanCloseShortTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xTDTrader.CloseShortPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XTDIssueForceCloseTradesAlert(X_SIGNAL_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In Profit Teades ...
|
||||
if (xTDMaxInProfitTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xTDTrader.GetLongTimeTrades(
|
||||
xTDMaxInProfitTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isClosed = xTDTrader.Close(trade.ticket);
|
||||
if (isClosed)
|
||||
{
|
||||
Add(
|
||||
trade,
|
||||
closed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XTDIssueLongInProfitTradeClosed();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In DrawDown Trades ...
|
||||
if (xTDMaxInDrawDownTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xTDTrader.GetLongTimeTrades(
|
||||
xTDMaxInDrawDownTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Grid Trades ...
|
||||
XTDOpenSuppurtTrade(trade);
|
||||
|
||||
// //
|
||||
// bool isClosed = xTDTrader.Close(trade.ticket);
|
||||
// if (isClosed)
|
||||
// {
|
||||
// //
|
||||
// Add(
|
||||
// trade,
|
||||
// closed);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XTDIssueLongInDrawdownTradeClosed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Position ...
|
||||
bool XTDOpenLongPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XTDGeneratePositionSignal(X_SIGNAL_LONG);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xTDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xTDTrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XTDIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Position ...
|
||||
bool XTDOpenShortPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XTDGeneratePositionSignal(X_SIGNAL_SHORT);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xTDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xTDTrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XTDIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Support Signal ...
|
||||
bool XTDOpenSuppurtTrade(
|
||||
XSignal &signal // Parent Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!xTDEnableSupportTrades) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Signal ...
|
||||
if (!IsValid(signal, xTDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Market Conditions ...
|
||||
bool hasLongSignal = XTDCanOpenLongTrade();
|
||||
bool hasShortSignal = XTDCanOpenShortTrade();
|
||||
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN;
|
||||
|
||||
//
|
||||
// Detect Support Signal Direction ...
|
||||
XSignal support = {};
|
||||
switch (signal.type)
|
||||
{
|
||||
//
|
||||
case X_SIGNAL_LONG:
|
||||
//
|
||||
// First Check Long Support ...
|
||||
// Then Look for Short Support ...
|
||||
if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
case X_SIGNAL_SHORT:
|
||||
// First Check Short Support ...
|
||||
// Then Look for Long Support ...
|
||||
if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (type == X_SIGNAL_UNKNOWN)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
// Find Common Used ...
|
||||
double entry = GetEntry(type);
|
||||
double volumeMultiplier = 2;
|
||||
if (xTDVolumeMultiplier > 2)
|
||||
{
|
||||
volumeMultiplier = xTDVolumeMultiplier;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal is Support ot nor ...
|
||||
int titlePosition = StringFind(
|
||||
signal.comment,
|
||||
"Support");
|
||||
bool isSupport = titlePosition >= 0;
|
||||
double priceDistance = MathAbs(signal.entry - entry);
|
||||
|
||||
//
|
||||
if (isSupport || priceDistance < PipsToPrice(5)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
double volume = NormalizeVolume(isSupport ? signal.volume : signal.volume * volumeMultiplier);
|
||||
string comment = "Support_" + GetSignalType(type) + "_For_" + (string)signal.ticket + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XTDCalculateTPSL(type);
|
||||
if (!IsValid(tpSL))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate reward of signal ...
|
||||
double reward = MathAbs(signal.entry - signal.tp) / 2;
|
||||
double tp = tpSL.sl; // isLong ? entry + reward : entry - reward;
|
||||
double sl = tpSL.sl;
|
||||
|
||||
//
|
||||
// Filling Support Signal ...
|
||||
support.tp = tp;
|
||||
support.sl = sl;
|
||||
support.type = type;
|
||||
support.time = time;
|
||||
support.entry = entry;
|
||||
support.volume = volume;
|
||||
support.symbol = _Symbol;
|
||||
support.comment = comment;
|
||||
support.magicNumber = xTDMagicNumber;
|
||||
|
||||
//
|
||||
// Validate Generated Support ...
|
||||
if (!IsValid(support, xTDMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = xTDTrader.ExecuteSignal(support);
|
||||
if (result)
|
||||
{
|
||||
XTDIssueSignalExecutionAlert(support);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate Specific type of Signals for Trading ...
|
||||
XSignal XTDGeneratePositionSignal(
|
||||
ENUM_X_SIGNAL_TYPE type // direction of position
|
||||
)
|
||||
{
|
||||
//
|
||||
XSignal result = {};
|
||||
|
||||
//
|
||||
if (type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double entry = GetEntry(type);
|
||||
|
||||
//
|
||||
double volume = XTDCalculateVolume();
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
|
||||
//
|
||||
string typeString = GetSignalType(type);
|
||||
string comment = XTDProviderName + "_" + typeString + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XTDCalculateTPSL(type);
|
||||
if (IsValid(tpSL))
|
||||
{
|
||||
//
|
||||
// Apply TP ...
|
||||
if (tpSL.tp > 0)
|
||||
{
|
||||
result.tp = tpSL.tp;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply SL ...
|
||||
if (tpSL.sl > 0)
|
||||
{
|
||||
result.sl = tpSL.sl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.time = time;
|
||||
result.entry = entry;
|
||||
result.volume = volume;
|
||||
result.symbol = _Symbol;
|
||||
result.comment = comment;
|
||||
result.magicNumber = xTDMagicNumber;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Private Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double XTDCalculateVolume()
|
||||
{
|
||||
//
|
||||
// Assign default Value ...
|
||||
double result = xTDStaticVolume;
|
||||
|
||||
//
|
||||
// we can count open trades and in draw down trades
|
||||
// then do check volume based on it for gridding ...
|
||||
int openTrades = xTDTrader.Count();
|
||||
if (openTrades == 0)
|
||||
{
|
||||
openTrades = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Normalized Multiplier ...
|
||||
double multiplier = xTDVolumeMultiplier <= 0 ? 1 : xTDVolumeMultiplier;
|
||||
|
||||
//
|
||||
result = multiplier * openTrades * xTDStaticVolume;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeVolume(result);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Signal TP and SL ...
|
||||
XTPSL XTDCalculateTPSL(
|
||||
ENUM_X_SIGNAL_TYPE type // Position Type
|
||||
)
|
||||
{
|
||||
//
|
||||
XTPSL result = {};
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double spread = GetSpread();
|
||||
double entry = isLong ? ask : bid;
|
||||
|
||||
//
|
||||
// TODO: Find Risk ..
|
||||
double risk = 0;
|
||||
|
||||
//
|
||||
// Calculate Reward ...
|
||||
double reward = PipsToPrice(xTDMinRewardPerTradeInPips) + spread;
|
||||
|
||||
//
|
||||
// Calculate TP and SL ...
|
||||
double tp = isLong ? entry + reward : entry - reward;
|
||||
double sl = 0;
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.tp = tp;
|
||||
result.sl = sl;
|
||||
result.entry = entry;
|
||||
//
|
||||
// TODO: Calculate R2R ...
|
||||
result.r2r = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
void XTDIssueInitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "Initializion of (" + XTDProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueDeinitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "De Initializion of (" + XTDProviderName + " Provider" + ") Succeeded ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type) {
|
||||
//
|
||||
string typeStr = GetSignalType(type);
|
||||
if (StringLen(typeStr) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string message = "Force Close " + typeStr + " Trades ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueMaxAllowedTradesReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached Max Allowed Same Time Trades ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueMaxAllowedFreeMarginReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached FreeMarigin For Open Trades ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueMinAllowedBalanceReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "doesn't have Minimum Balance For Open Trades ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueSignalExecutionAlert(
|
||||
XSignal &signal // Executed Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
XTDIssueAlert(signal);
|
||||
}
|
||||
|
||||
void XTDIssueLongInProfitTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueLongInDrawdownTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTDIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTDIssueAlert(string message)
|
||||
{
|
||||
//
|
||||
if (xTDEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
void XTDIssueAlert(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (xTDEnableAlerts)
|
||||
{
|
||||
SendAlert(signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Private Functions ...
|
||||
//
|
||||
@@ -0,0 +1,166 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTEST Signal Provider Indicators Library
|
||||
// ----------------------------------------------------------------
|
||||
//
|
||||
// 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 Provider Inputs ...
|
||||
#include "x-saherelm.xtest.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// Imports all Indicators Helper here ...
|
||||
input group "XTEST Provider Indicators";
|
||||
//
|
||||
#include "x-saherelm.xtm.indicator.helper.lib.mq5";
|
||||
|
||||
//
|
||||
int xTESTMaxLengthOfInputs = 0;
|
||||
int xTESTCalculatedBars = 0;
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XTESTInitIndicators()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check and Calculate Max Length in Inputs ...
|
||||
xTESTMaxLengthOfInputs = MathMax(
|
||||
xTMMaPeriod,
|
||||
xTESTMaxLengthOfInputs);
|
||||
xTESTMaxLengthOfInputs = MathMax(
|
||||
xTESTNumberOfItemsPerTick,
|
||||
xTESTMaxLengthOfInputs);
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XTM Init ...
|
||||
result = XTMInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XTESTReleaseIndicators()
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTMReleaseHandlers();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XTESTHandleReadingBuffers()
|
||||
{
|
||||
//
|
||||
// Reading Calculated Bars for a Simple Handler ...
|
||||
xTESTCalculatedBars = BarsCalculated(xTMHandler);
|
||||
|
||||
//
|
||||
// Read Indicators Buffers ...
|
||||
XTMReadBuffers(xTESTNumberOfItemsPerTick);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// START Combination Functions ...
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Can Open Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XTESTCanOpenLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XTMHasLongConditions(xTESTNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XTESTCanCloseLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Check Market Conditions for Close Long Trades ...
|
||||
// result = XTESTHasLongCloseConditions(xTESTNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Open Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XTESTCanOpenShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XTMHasShortConditions(xTESTNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XTESTCanCloseShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Check Market Conditions for Close Short Trades ...
|
||||
// result = XTESTHasShortCloseConditions(xTESTNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// END Combination Functions ...
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,65 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTEST Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
input group "XTEST Provider";
|
||||
|
||||
//
|
||||
input group "XTEST Common";
|
||||
input bool xTESTEnableProvider = true; // Enable Provider
|
||||
input bool xTESTEnableAlerts = false; // Enable Events Alert
|
||||
input int xTESTNumberOfItemsPerTick = 110; // Number Of items Readed In Each Tick
|
||||
|
||||
//
|
||||
input group "XTEST Trader";
|
||||
input int xTESTMagicNumber = 16940562; // Trader MagicNumber
|
||||
input int xTESTSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XTEST Trade Management";
|
||||
input bool xTESTUseVirtualTPSL = true; // Use Virtual TP SL
|
||||
input bool xTESTAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xTESTAllowShortTrades = true; // Allow Short Trades
|
||||
|
||||
//
|
||||
input group "XTEST Risk Management";
|
||||
input int xTESTMaxAllowedTrades = 5; // Max Allowed Trades at Same Time
|
||||
input int xTESTMaxInProfitTradeAge = 0; // Max In Profit Trades Age
|
||||
input int xTESTMaxInDrawDownTradeAge = 576; // Max In DrawDown Trades Age
|
||||
input double xTESTStaticVolume = 0.02; // Static Volume
|
||||
input double xTESTVolumeMultiplier = 2; // Volume Multiplier
|
||||
input double xTESTMinRewardPerTradeInPips = 2; // Min Reward Per Trade In Pips
|
||||
input double xTESTFreeMarginFactorForOpenTrades = 0.5; // Minimum Free Marging for Open Trades
|
||||
input double xTESTBalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades
|
||||
input int xTESTMaxAllowedSupportTrades = 5; // Max Allowed Support Trade
|
||||
input int xTESTSupportTradesPriceDistanceInPips = 5; // Distance Price to Open Support Trade
|
||||
|
||||
//
|
||||
// Validate Inputs before Initialization ...
|
||||
bool XTESTValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,670 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTEST Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XTESTSignalProvider
|
||||
// Description: XTEST based 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
|
||||
|
||||
#define XTESTProviderName "XTEST"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
#include "x-saherelm.xtest.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
XCTrade *xTESTTrader;
|
||||
XCAccountInfo xTESTAccountInfo;
|
||||
|
||||
//
|
||||
#include "x-saherelm.xtest.provider.indicators.lib.mq5"
|
||||
|
||||
//
|
||||
double xTESTDeposit = 0;
|
||||
double xTESTBalance = 0;
|
||||
double xTESTFreeMargin = 0;
|
||||
double xTESTMinRewardPerTrade = 0;
|
||||
double xTESTFreeMarginForOpenTrades = 0;
|
||||
double xTESTBalanceForOpenTrades = 0;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool XTESTInitSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
result = XTESTValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
result = XTESTInitIndicators();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Account Deposit ...
|
||||
xTESTDeposit = xTESTAccountInfo.GetInitialBalance();
|
||||
|
||||
//
|
||||
// Calculate xTESTMinRewardPerTrade ...
|
||||
if (xTESTMinRewardPerTradeInPips > 0)
|
||||
{
|
||||
xTESTMinRewardPerTrade = PipsToPrice(xTESTMinRewardPerTradeInPips);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Min Balance for Trades ...
|
||||
if (xTESTBalanceFactorForOpenTrades > 0)
|
||||
{
|
||||
xTESTBalanceForOpenTrades = xTESTBalanceFactorForOpenTrades * xTESTDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Claculate Min Free Marging for Trades ...
|
||||
if (xTESTFreeMarginFactorForOpenTrades > 0)
|
||||
{
|
||||
xTESTFreeMarginForOpenTrades = xTESTFreeMarginFactorForOpenTrades * xTESTDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
xTESTTrader = new XCTrade(
|
||||
XTESTProviderName,
|
||||
_Symbol,
|
||||
xTESTSlippage,
|
||||
xTESTMagicNumber,
|
||||
xTESTMaxAllowedTrades,
|
||||
xTESTMaxAllowedSupportTrades,
|
||||
xTESTMinRewardPerTradeInPips,
|
||||
xTESTSupportTradesPriceDistanceInPips,
|
||||
xTESTFreeMarginForOpenTrades,
|
||||
xTESTBalanceForOpenTrades);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTESTIssueInitializationSucceedAlert();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void XTESTDeinitSignalProviderLibrary(
|
||||
const int reason)
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTESTReleaseIndicators();
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTESTIssueDeinitializationSucceedAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void XTESTSignalProviderHandleTick()
|
||||
{
|
||||
//
|
||||
// Update account Balance ...
|
||||
xTESTBalance = xTESTAccountInfo.GetBalance();
|
||||
xTESTFreeMargin = xTESTAccountInfo.GetFreeMargin();
|
||||
|
||||
//
|
||||
// Check Provider is Enable or Not ...
|
||||
if (!xTESTEnableProvider)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Indicator Buffers ...
|
||||
XTESTHandleReadingBuffers();
|
||||
if (xTESTCalculatedBars < xTESTMaxLengthOfInputs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
XTESTHandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
XTESTHandleCloseTrades();
|
||||
|
||||
//
|
||||
// Handle Support Trades ...
|
||||
XTESTHandleSupportTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void XTESTHandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Check Can Trade ...
|
||||
bool canTrade = xTESTAllowLongTrades || xTESTAllowShortTrades;
|
||||
if (!canTrade)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signals Exists ...
|
||||
bool hasLongSignal = XTESTCanOpenLongTrade();
|
||||
bool hasShortSignal = XTESTCanOpenShortTrade();
|
||||
if (!hasLongSignal && !hasShortSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Trades ...
|
||||
if (
|
||||
//
|
||||
hasLongSignal &&
|
||||
xTESTAllowLongTrades)
|
||||
{
|
||||
//
|
||||
bool isOpened = XTESTOpenLongPosition();
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Trades ...
|
||||
if (
|
||||
//
|
||||
hasShortSignal &&
|
||||
xTESTAllowShortTrades)
|
||||
{
|
||||
//
|
||||
bool isOpened = XTESTOpenShortPosition();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void XTESTHandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// All Close Mechanism Handles Here ...
|
||||
// - Force Close;
|
||||
// - Partial Close;
|
||||
// - Risk Free Close;
|
||||
// - Virtual TP/SL Close;
|
||||
|
||||
//
|
||||
// Force Close Long Trades ...
|
||||
bool canCloseLongTrades = XTESTCanCloseLongTrade();
|
||||
if (xTESTAllowLongTrades && canCloseLongTrades)
|
||||
{
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
XSignal closed[];
|
||||
xTESTTrader.ClosePositionsByType(
|
||||
type,
|
||||
closed);
|
||||
|
||||
//
|
||||
bool isClosed = ArraySize(closed) > 0;
|
||||
if (isClosed)
|
||||
{
|
||||
XTESTIssueForceCloseTradesAlert(type);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Force Close Short Trades ...
|
||||
bool canCloseShortTrades = XTESTCanCloseShortTrade();
|
||||
if (xTESTAllowShortTrades && canCloseShortTrades)
|
||||
{
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT;
|
||||
|
||||
//
|
||||
XSignal closed[];
|
||||
xTESTTrader.ClosePositionsByType(
|
||||
type,
|
||||
closed);
|
||||
|
||||
//
|
||||
bool isClosed = ArraySize(closed) > 0;
|
||||
if (isClosed)
|
||||
{
|
||||
XTESTIssueForceCloseTradesAlert(type);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close Risk Free Trades ...
|
||||
XSignal riskFrees[];
|
||||
xTESTTrader.RiskFreeSignals(riskFrees);
|
||||
bool isRiskFree = ArraySize(riskFrees) > 0;
|
||||
if (isRiskFree)
|
||||
{
|
||||
XTESTIssueRiskFreeTradesAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// Close Virtual TP / SL Trades ...
|
||||
if (xTESTUseVirtualTPSL)
|
||||
{
|
||||
//
|
||||
XSignal takeProfits[];
|
||||
XSignal stopLosses[];
|
||||
|
||||
//
|
||||
xTESTTrader.HandleVirtualTPSL(
|
||||
takeProfits,
|
||||
stopLosses);
|
||||
|
||||
//
|
||||
// Take Profits ...
|
||||
int takeProfitsCount = ArraySize(takeProfits);
|
||||
if (takeProfitsCount > 0)
|
||||
{
|
||||
//
|
||||
// Do What we Want in Profits Trades ...
|
||||
}
|
||||
|
||||
//
|
||||
// Stop Losses ...
|
||||
int stopLossesCount = ArraySize(stopLosses);
|
||||
if (stopLossesCount > 0)
|
||||
{
|
||||
//
|
||||
// Do What we Want in Stop Losses Trades ...
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close Max DrawDown Trades ...
|
||||
|
||||
//
|
||||
// Close Long Time Trades ...
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Support Trades ...
|
||||
void XTESTHandleSupportTrades()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Position ...
|
||||
bool XTESTOpenLongPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double tp = PipsToPrice(xTESTMinRewardPerTradeInPips * 3);
|
||||
double riskFree = PipsToPrice(xTESTMinRewardPerTradeInPips);
|
||||
double riskFreeRate = 0.75;
|
||||
double volume = XTESTCalculateVolume();
|
||||
|
||||
//
|
||||
XSignal signal = {};
|
||||
signal = xTESTTrader.GenerateTradeSignal(
|
||||
X_SIGNAL_LONG,
|
||||
tp,
|
||||
0,
|
||||
volume,
|
||||
riskFree,
|
||||
riskFreeRate,
|
||||
true);
|
||||
bool isValidSignal = IsValid(
|
||||
signal,
|
||||
xTESTMagicNumber);
|
||||
if (!isValidSignal)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int error = -1;
|
||||
result = xTESTTrader.ExecuteSignal(signal, error);
|
||||
if (result)
|
||||
{
|
||||
XTESTIssueSignalExecutionAlert(signal);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Position ...
|
||||
bool XTESTOpenShortPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double tp = PipsToPrice(xTESTMinRewardPerTradeInPips * 3);
|
||||
double riskFree = PipsToPrice(xTESTMinRewardPerTradeInPips);
|
||||
double riskFreeRate = 0.75;
|
||||
double volume = XTESTCalculateVolume();
|
||||
|
||||
//
|
||||
XSignal signal = {};
|
||||
signal = xTESTTrader.GenerateTradeSignal(
|
||||
X_SIGNAL_LONG,
|
||||
tp,
|
||||
0,
|
||||
volume,
|
||||
riskFree,
|
||||
riskFreeRate,
|
||||
true);
|
||||
bool isValidSignal = IsValid(
|
||||
signal,
|
||||
xTESTMagicNumber);
|
||||
if (!isValidSignal)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int error = -1;
|
||||
result = xTESTTrader.ExecuteSignal(signal, error);
|
||||
if (result)
|
||||
{
|
||||
XTESTIssueSignalExecutionAlert(signal);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Support Signal ...
|
||||
bool XTESTOpenSupportTrade(
|
||||
XSignal &signal // Parent Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Private Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double XTESTCalculateVolume()
|
||||
{
|
||||
//
|
||||
// Assign default Value ...
|
||||
double result = xTESTStaticVolume;
|
||||
|
||||
//
|
||||
// we can count open trades and in draw down trades
|
||||
// then do check volume based on it for gridding ...
|
||||
int openTrades = xTESTTrader.Count();
|
||||
if (openTrades == 0)
|
||||
{
|
||||
openTrades = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Normalized Multiplier ...
|
||||
double multiplier = xTESTVolumeMultiplier <= 0 ? 1 : xTESTVolumeMultiplier;
|
||||
|
||||
//
|
||||
result = multiplier * openTrades * xTESTStaticVolume;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeVolume(result);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Signal TP and SL ...
|
||||
XTPSL XTESTCalculateTPSL(
|
||||
ENUM_X_SIGNAL_TYPE type // Position Type
|
||||
)
|
||||
{
|
||||
//
|
||||
XTPSL result = {};
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double spread = GetSpread();
|
||||
double entry = isLong ? ask : bid;
|
||||
|
||||
//
|
||||
// TODO: Find Risk ..
|
||||
double risk = 0;
|
||||
|
||||
//
|
||||
// Calculate Reward ...
|
||||
double reward = PipsToPrice(xTESTMinRewardPerTradeInPips) + spread;
|
||||
|
||||
//
|
||||
// Calculate TP and SL ...
|
||||
double tp = isLong ? entry + reward : entry - reward;
|
||||
double sl = 0;
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.tp = tp;
|
||||
result.sl = sl;
|
||||
result.entry = entry;
|
||||
//
|
||||
// TODO: Calculate R2R ...
|
||||
result.r2r = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
void XTESTIssueInitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "Initializion of (" + XTESTProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueDeinitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "De Initializion of (" + XTESTProviderName + " Provider" + ") Succeeded ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type)
|
||||
{
|
||||
//
|
||||
string typeStr = GetSignalType(type);
|
||||
if (StringLen(typeStr) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string message = "Force Close " + typeStr + " Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueMaxAllowedTradesReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached Max Allowed Same Time Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueMaxAllowedFreeMarginReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached FreeMarigin For Open Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueMinAllowedBalanceReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "doesn't have Minimum Balance For Open Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueSignalExecutionAlert(
|
||||
XSignal &signal // Executed Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
XTESTIssueAlert(signal);
|
||||
}
|
||||
|
||||
void XTESTIssueSignalExecutionError(int error)
|
||||
{
|
||||
//
|
||||
string message = GetSignalExecutionError(error);
|
||||
if (StringLen(message) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueRiskFreeTradesAlert()
|
||||
{
|
||||
//
|
||||
string message = "Make Some Trades Risk Free ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueLongInProfitTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueLongInDrawdownTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueAlert(string message)
|
||||
{
|
||||
//
|
||||
if (xTESTEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
void XTESTIssueAlert(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (xTESTEnableAlerts)
|
||||
{
|
||||
SendAlert(signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Private Functions ...
|
||||
//
|
||||
@@ -0,0 +1,157 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTM Signal Provider Indicators Library
|
||||
// ----------------------------------------------------------------
|
||||
//
|
||||
// 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 Provider Inputs ...
|
||||
#include "x-saherelm.xtm.provider.inputs.lib.mq5";
|
||||
|
||||
//
|
||||
// Imports all Indicators Helper here ...
|
||||
input group "XTM Provider Indicators";
|
||||
#include "x-saherelm.xtm.indicator.helper.lib.mq5";
|
||||
|
||||
//
|
||||
int xTMMaxLengthOfInputs = 0;
|
||||
int xTMCalculatedBars = 0;
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
bool XTMInitIndicators()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check and Calculate Max Length in Inputs ...
|
||||
xTMMaxLengthOfInputs = MathMax(
|
||||
xTMMaPeriod,
|
||||
xTMMaxLengthOfInputs);
|
||||
xTMMaxLengthOfInputs = MathMax(
|
||||
xTMNumberOfItemsPerTick,
|
||||
xTMMaxLengthOfInputs);
|
||||
|
||||
//
|
||||
// Initialize Indicator/Oscillator Handlers ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// XTM Init ...
|
||||
result = XTMInitHandlers();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Release Indicators ...
|
||||
void XTMReleaseIndicators()
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTMReleaseHandlers();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Reading Buffers ...
|
||||
void XTMHandleReadingBuffers()
|
||||
{
|
||||
//
|
||||
// Reading Calculated Bars for a Simple Handler ...
|
||||
xTMCalculatedBars = BarsCalculated(xTMHandler);
|
||||
|
||||
//
|
||||
// Read Indicators Buffers ...
|
||||
XTMReadBuffers(xTMNumberOfItemsPerTick);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// START Combination Functions ...
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// Can Open Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XTMCanOpenLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XTMHasLongConditions(xTMNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Long Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Long Signals ...
|
||||
bool XTMCanCloseLongTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Open Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XTMCanOpenShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = XTMHasShortConditions(xTMNumberOfItemsPerTick);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Can Close Short Trade ...
|
||||
// this is a Function will Check all market Conditions and get all
|
||||
// Strategy requirement Verifications for Short Signals ...
|
||||
bool XTMCanCloseShortTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// END Combination Functions ...
|
||||
//
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,63 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTM Signal Provider Library Inputs
|
||||
// -----------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
input group "XTM Provider";
|
||||
|
||||
//
|
||||
input group "XTM Common";
|
||||
input bool xTMEnableProvider = true; // Enable Provider
|
||||
input bool xTMEnableAlerts = false; // Enable Events Alert
|
||||
input int xTMNumberOfItemsPerTick = 72; // Number Of items Readed In Each Tick
|
||||
|
||||
//
|
||||
input group "XTM Trader";
|
||||
input int xTMMagicNumber = 16940560; // Trader MagicNumber
|
||||
input int xTMSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XTM Trade Management";
|
||||
input bool xTMAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xTMAllowShortTrades = true; // Allow Short Trades
|
||||
|
||||
//
|
||||
input group "XTM Risk Management";
|
||||
input int xTMMaxAllowedTrades = 5; // Max Allowed Trades at Same Time
|
||||
input int xTMMaxInProfitTradeAge = 0; // Max In Profit Trades Age
|
||||
input int xTMMaxInDrawDownTradeAge = 576; // Max In DrawDown Trades Age
|
||||
input double xTMStaticVolume = 0.02; // Static Volume
|
||||
input double xTMVolumeMultiplier = 2; // Volume Multiplier
|
||||
input double xTMMinRewardPerTradeInPips = 1; // Min Reward Per Trade In Pips
|
||||
input double xTMFreeMarginFactorForOpenTrades = 0.5; // Minimum Free Marging for Open Trades
|
||||
input double xTMBalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades
|
||||
input bool xTMEnableSupportTrades = false; // Enable Support Trade
|
||||
|
||||
//
|
||||
// Validate Inputs before Initialization ...
|
||||
bool XTMValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,859 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTM Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XTMSignalProvider
|
||||
// Description: XTM based 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
|
||||
|
||||
#define XTMProviderName "XTM"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
#include "x-saherelm.xtm.provider.inputs.lib.mq5";
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
XCTrade *xTMTrader;
|
||||
XCAccountInfo xTMAccountInfo;
|
||||
|
||||
//
|
||||
#include "x-saherelm.xtm.provider.indicators.lib.mq5"
|
||||
|
||||
//
|
||||
double xTMDeposit = 0;
|
||||
double xTMBalance = 0;
|
||||
double xTMFreeMargin = 0;
|
||||
double xTMFreeMarginForOpenTrades = 0;
|
||||
double xTMBalanceForOpenTrades = 0;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool XTMInitSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
result = XTMValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
result = XTMInitIndicators();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Account Deposit ...
|
||||
xTMDeposit = xTMAccountInfo.GetInitialBalance();
|
||||
|
||||
//
|
||||
// Calculate Min Balance for Trades ...
|
||||
if (xTMBalanceFactorForOpenTrades > 0)
|
||||
{
|
||||
xTMBalanceForOpenTrades = xTMBalanceFactorForOpenTrades * xTMDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Claculate Min Free Marging for Trades ...
|
||||
if (xTMFreeMarginFactorForOpenTrades > 0)
|
||||
{
|
||||
xTMFreeMarginForOpenTrades = xTMFreeMarginFactorForOpenTrades * xTMDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
xTMTrader = new XCTrade(
|
||||
_Symbol,
|
||||
xTMSlippage,
|
||||
xTMMagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTMIssueInitializationSucceedAlert();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void XTMDeinitSignalProviderLibrary(
|
||||
const int reason)
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTMReleaseIndicators();
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTMIssueDeinitializationSucceedAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void XTMSignalProviderHandleTick()
|
||||
{
|
||||
//
|
||||
// Update account Balance ...
|
||||
xTMBalance = xTMAccountInfo.GetBalance();
|
||||
xTMFreeMargin = xTMAccountInfo.GetFreeMargin();
|
||||
|
||||
//
|
||||
// Check Provider is Enable or Not ...
|
||||
if (!xTMEnableProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Indicator Buffers ...
|
||||
XTMHandleReadingBuffers();
|
||||
if (xTMCalculatedBars < xTMMaxLengthOfInputs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
XTMHandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
XTMHandleCloseTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void XTMHandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Check Can Trade ...
|
||||
bool canTrade = xTMAllowLongTrades || xTMAllowShortTrades;
|
||||
if (!canTrade)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// First Check Signal Exists or NOt ...
|
||||
bool xTMHasLongSignal = XTMCanOpenLongTrade();
|
||||
bool xTMHasShortSignal = XTMCanOpenShortTrade();
|
||||
if (!xTMHasLongSignal && !xTMHasShortSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Max Open Trades ...
|
||||
if (xTMMaxAllowedTrades > 0)
|
||||
{
|
||||
//
|
||||
int count = xTMTrader.Count();
|
||||
bool canOpenTrade = count < xTMMaxAllowedTrades;
|
||||
if (!canOpenTrade)
|
||||
{
|
||||
//
|
||||
XTMIssueMaxAllowedTradesReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Free Margin ...
|
||||
if (xTMFreeMargin <= xTMFreeMarginForOpenTrades)
|
||||
{
|
||||
//
|
||||
XTMIssueMaxAllowedFreeMarginReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Account Balance ...
|
||||
if (xTMBalance <= xTMBalanceForOpenTrades)
|
||||
{
|
||||
//
|
||||
XTMIssueMinAllowedBalanceReachedAlert();
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
if (
|
||||
xTMHasLongSignal &&
|
||||
xTMAllowLongTrades)
|
||||
{
|
||||
//
|
||||
bool isLongSignalExecuted = XTMOpenLongPosition();
|
||||
if (isLongSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
if (
|
||||
xTMHasShortSignal &&
|
||||
xTMAllowShortTrades)
|
||||
{
|
||||
//
|
||||
bool isShortSignalExecuted = XTMOpenShortPosition();
|
||||
if (isShortSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void XTMHandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (xTMTrader.CountLongs() > 0 && XTMCanCloseLongTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xTMTrader.CloseLongPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XTMIssueForceCloseTradesAlert(X_SIGNAL_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (xTMTrader.CountShorts() > 0 && XTMCanCloseShortTrade())
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
xTMTrader.CloseShortPositions(closed);
|
||||
bool hasClosed = ArraySize(closed) > 0;
|
||||
if (hasClosed)
|
||||
{
|
||||
XTMIssueForceCloseTradesAlert(X_SIGNAL_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In Profit Teades ...
|
||||
if (xTMMaxInProfitTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xTMTrader.GetLongTimeTrades(
|
||||
xTMMaxInProfitTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isClosed = xTMTrader.Close(trade.ticket);
|
||||
if (isClosed)
|
||||
{
|
||||
Add(
|
||||
trade,
|
||||
closed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XTMIssueLongInProfitTradeClosed();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close In DrawDown Trades ...
|
||||
if (xTMMaxInDrawDownTradeAge > 0)
|
||||
{
|
||||
//
|
||||
XSignal closed[];
|
||||
XSignal longTimeTrades[];
|
||||
xTMTrader.GetLongTimeTrades(
|
||||
xTMMaxInDrawDownTradeAge,
|
||||
_Period,
|
||||
longTimeTrades);
|
||||
int count = ArraySize(longTimeTrades);
|
||||
if (count > 0)
|
||||
{
|
||||
//
|
||||
// Loop ...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
//
|
||||
XSignal trade = longTimeTrades[i];
|
||||
if (trade.profit > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Grid Trades ...
|
||||
XTMOpenSuppurtTrade(trade);
|
||||
|
||||
// //
|
||||
// bool isClosed = xTMTrader.Close(trade.ticket);
|
||||
// if (isClosed)
|
||||
// {
|
||||
// //
|
||||
// Add(
|
||||
// trade,
|
||||
// closed);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (ArraySize(closed) > 0)
|
||||
{
|
||||
XTMIssueLongInDrawdownTradeClosed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Position ...
|
||||
bool XTMOpenLongPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XTMGeneratePositionSignal(X_SIGNAL_LONG);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xTMMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xTMTrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XTMIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Position ...
|
||||
bool XTMOpenShortPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Generate Position Signal and Validate it ...
|
||||
XSignal position = XTMGeneratePositionSignal(X_SIGNAL_SHORT);
|
||||
if (!IsValid(
|
||||
position,
|
||||
xTMMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to Open Position ...
|
||||
result = xTMTrader.ExecuteSignal(position);
|
||||
if (result)
|
||||
{
|
||||
XTMIssueSignalExecutionAlert(position);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Support Signal ...
|
||||
bool XTMOpenSuppurtTrade(
|
||||
XSignal &signal // Parent Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!xTMEnableSupportTrades) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Signal ...
|
||||
if (!IsValid(signal, xTMMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Market Conditions ...
|
||||
bool hasLongSignal = XTMCanOpenLongTrade();
|
||||
bool hasShortSignal = XTMCanOpenShortTrade();
|
||||
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN;
|
||||
|
||||
//
|
||||
// Detect Support Signal Direction ...
|
||||
XSignal support = {};
|
||||
switch (signal.type)
|
||||
{
|
||||
//
|
||||
case X_SIGNAL_LONG:
|
||||
//
|
||||
// First Check Long Support ...
|
||||
// Then Look for Short Support ...
|
||||
if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
case X_SIGNAL_SHORT:
|
||||
// First Check Short Support ...
|
||||
// Then Look for Long Support ...
|
||||
if (hasShortSignal)
|
||||
{
|
||||
type = X_SIGNAL_SHORT;
|
||||
}
|
||||
else if (hasLongSignal)
|
||||
{
|
||||
type = X_SIGNAL_LONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = signal.type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (type == X_SIGNAL_UNKNOWN)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
// Find Common Used ...
|
||||
double entry = GetEntry(type);
|
||||
double volumeMultiplier = 2;
|
||||
if (xTMVolumeMultiplier > 2)
|
||||
{
|
||||
volumeMultiplier = xTMVolumeMultiplier;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signal is Support ot nor ...
|
||||
int titlePosition = StringFind(
|
||||
signal.comment,
|
||||
"Support");
|
||||
bool isSupport = titlePosition >= 0;
|
||||
double priceDistance = MathAbs(signal.entry - entry);
|
||||
|
||||
//
|
||||
if (isSupport || priceDistance < PipsToPrice(5)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
double volume = NormalizeVolume(isSupport ? signal.volume : signal.volume * volumeMultiplier);
|
||||
string comment = "Support_" + GetSignalType(type) + "_For_" + (string)signal.ticket + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XTMCalculateTPSL(type);
|
||||
if (!IsValid(tpSL))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate reward of signal ...
|
||||
double reward = MathAbs(signal.entry - signal.tp) / 2;
|
||||
double tp = tpSL.sl; // isLong ? entry + reward : entry - reward;
|
||||
double sl = tpSL.sl;
|
||||
|
||||
//
|
||||
// Filling Support Signal ...
|
||||
support.tp = tp;
|
||||
support.sl = sl;
|
||||
support.type = type;
|
||||
support.time = time;
|
||||
support.entry = entry;
|
||||
support.volume = volume;
|
||||
support.symbol = _Symbol;
|
||||
support.comment = comment;
|
||||
support.magicNumber = xTMMagicNumber;
|
||||
|
||||
//
|
||||
// Validate Generated Support ...
|
||||
if (!IsValid(support, xTMMagicNumber))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = xTMTrader.ExecuteSignal(support);
|
||||
if (result)
|
||||
{
|
||||
XTMIssueSignalExecutionAlert(support);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate Specific type of Signals for Trading ...
|
||||
XSignal XTMGeneratePositionSignal(
|
||||
ENUM_X_SIGNAL_TYPE type // direction of position
|
||||
)
|
||||
{
|
||||
//
|
||||
XSignal result = {};
|
||||
|
||||
//
|
||||
if (type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double entry = GetEntry(type);
|
||||
|
||||
//
|
||||
double volume = XTMCalculateVolume();
|
||||
|
||||
//
|
||||
datetime time = iTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0);
|
||||
|
||||
//
|
||||
string typeString = GetSignalType(type);
|
||||
string comment = XTMProviderName + "_" + typeString + "_" + (string)volume + "_" + (string)time;
|
||||
|
||||
//
|
||||
XTPSL tpSL = XTMCalculateTPSL(type);
|
||||
if (IsValid(tpSL))
|
||||
{
|
||||
//
|
||||
// Apply TP ...
|
||||
if (tpSL.tp > 0)
|
||||
{
|
||||
result.tp = tpSL.tp;
|
||||
}
|
||||
|
||||
//
|
||||
// Apply SL ...
|
||||
if (tpSL.sl > 0)
|
||||
{
|
||||
result.sl = tpSL.sl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.time = time;
|
||||
result.entry = entry;
|
||||
result.volume = volume;
|
||||
result.symbol = _Symbol;
|
||||
result.comment = comment;
|
||||
result.magicNumber = xTMMagicNumber;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Private Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double XTMCalculateVolume()
|
||||
{
|
||||
//
|
||||
// Assign default Value ...
|
||||
double result = xTMStaticVolume;
|
||||
|
||||
//
|
||||
// we can count open trades and in draw down trades
|
||||
// then do check volume based on it for gridding ...
|
||||
int openTrades = xTMTrader.Count();
|
||||
if (openTrades == 0)
|
||||
{
|
||||
openTrades = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Normalized Multiplier ...
|
||||
double multiplier = xTMVolumeMultiplier <= 0 ? 1 : xTMVolumeMultiplier;
|
||||
|
||||
//
|
||||
result = multiplier * openTrades * xTMStaticVolume;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeVolume(result);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Signal TP and SL ...
|
||||
XTPSL XTMCalculateTPSL(
|
||||
ENUM_X_SIGNAL_TYPE type // Position Type
|
||||
)
|
||||
{
|
||||
//
|
||||
XTPSL result = {};
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
type != X_SIGNAL_LONG &&
|
||||
type != X_SIGNAL_SHORT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
double bid = GetBid();
|
||||
double spread = GetSpread();
|
||||
double entry = isLong ? ask : bid;
|
||||
|
||||
//
|
||||
// TODO: Find Risk ..
|
||||
double risk = 0;
|
||||
|
||||
//
|
||||
// Calculate Reward ...
|
||||
double reward = PipsToPrice(xTMMinRewardPerTradeInPips) + spread;
|
||||
|
||||
//
|
||||
// Calculate TP and SL ...
|
||||
double tp = isLong ? entry + reward : entry - reward;
|
||||
double sl = 0;
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.tp = tp;
|
||||
result.sl = sl;
|
||||
result.entry = entry;
|
||||
//
|
||||
// TODO: Calculate R2R ...
|
||||
result.r2r = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
void XTMIssueInitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "Initializion of (" + XTMProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueDeinitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "De Initializion of (" + XTMProviderName + " Provider" + ") Succeeded ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type) {
|
||||
//
|
||||
string typeStr = GetSignalType(type);
|
||||
if (StringLen(typeStr) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string message = "Force Close " + typeStr + " Trades ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueMaxAllowedTradesReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached Max Allowed Same Time Trades ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueMaxAllowedFreeMarginReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached FreeMarigin For Open Trades ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueMinAllowedBalanceReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "doesn't have Minimum Balance For Open Trades ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueSignalExecutionAlert(
|
||||
XSignal &signal // Executed Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
XTMIssueAlert(signal);
|
||||
}
|
||||
|
||||
void XTMIssueLongInProfitTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueLongInDrawdownTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTMIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTMIssueAlert(string message)
|
||||
{
|
||||
//
|
||||
if (xTMEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
void XTMIssueAlert(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (xTMEnableAlerts)
|
||||
{
|
||||
SendAlert(signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Private Functions ...
|
||||
//
|
||||
@@ -0,0 +1,30 @@
|
||||
2021.02.26 00:05:00 XEA > | XTM |
|
||||
2021.02.26 00:05:00
|
||||
2021.02.26 00:05:00 | XTD |
|
||||
2021.02.26 00:05:00 isXTDSignalOverBear: true
|
||||
2021.02.26 00:05:00
|
||||
2021.02.26 00:05:00 | XRSI |
|
||||
2021.02.26 00:05:00
|
||||
2021.02.26 00:05:00 | XOBD |
|
||||
2021.02.26 00:05:00 isXOBDSignalUnderSwingHigh: true
|
||||
2021.02.26 00:05:00
|
||||
2021.02.26 00:05:00 | XCHLH |
|
||||
2021.02.26 00:05:00 isXCHLHSignalBUnderSignalT: true
|
||||
2021.02.26 00:05:00 isXCHLHSignalBUnderLCLL: true
|
||||
2021.02.26 00:05:00
|
||||
2021.02.26 00:05:00 | XCHMA |
|
||||
2021.02.26 00:05:00 isXCHMASCFastOverSlow: true
|
||||
2021.02.26 00:05:00 isXCHMAMCFastUnderSlow: true
|
||||
2021.02.26 00:05:00 isXCHMALCFastOverSlow: true
|
||||
2021.02.26 00:05:00
|
||||
2021.02.26 00:05:00
|
||||
2021.02.26 00:05:00 instant buy 1.39 EURUSD at 1.21803 tp: 1.21890 (1.21796 / 1.21803 / 1.21796)
|
||||
2021.02.26 00:05:00 deal #282 buy 1.39 EURUSD at 1.21803 done (based on order #282)
|
||||
2021.02.26 00:05:00 deal performed [#282 buy 1.39 EURUSD at 1.21803]
|
||||
2021.02.26 00:05:00 order performed buy 1.39 at 1.21803 [#282 buy 1.39 EURUSD at 1.21803]
|
||||
2021.02.26 00:05:00 CTrade::OrderSend: instant buy 1.39 EURUSD at 1.21803 tp: 1.21890 [done at 1.21803]
|
||||
2021.02.26 00:05:00 XEA > T(282)_TY(Long)_K(Trade)_PR(0)_E(1.21803)_RF(1.21833)_RR(0.5)_V(1.3900000000000001)
|
||||
2021.03.08 13:05:00 position stop out triggered at 8.71% [#282 buy 1.39 EURUSD 1.21803 tp: 1.21890]
|
||||
2021.03.08 13:05:00 deal #283 sell 1.39 EURUSD at 1.18626 done (based on order #283)
|
||||
2021.03.08 13:05:00 deal performed [#283 sell 1.39 EURUSD at 1.18626]
|
||||
2021.03.08 13:05:00 order performed sell 1.39 at 1.18626 [#283 sell 1.39 EURUSD at 1.18626]
|
||||
@@ -0,0 +1,178 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Learn 3.mq5 |
|
||||
//| Copyright 2016, Hudson Analytics |
|
||||
//| NurudeenAmedu |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2016, Hudson Analytics"
|
||||
#property link "NurudeenAmedu"
|
||||
#property version "1.00"
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 2
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
|
||||
double ExtBuffer1[];
|
||||
double ExtBuffer2[];
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0, ExtBuffer1);
|
||||
SetIndexBuffer(1, ExtBuffer2);
|
||||
//---
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total, // 1001
|
||||
const int prev_calculated, // 1000
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//---
|
||||
int x, y, limit;
|
||||
int min_rates_total = 100;
|
||||
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(ExtBuffer1, true);
|
||||
ArraySetAsSeries(ExtBuffer2, true);
|
||||
|
||||
//---- calculations of the necessary amount of data to be copied
|
||||
//---- and the 'limit' starting index for the bars recalculation loop
|
||||
if (prev_calculated > rates_total || prev_calculated <= 0) // checking for the first start of the indicator calculation
|
||||
{
|
||||
limit = rates_total - min_rates_total - 1; // calculated number of all bars
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = rates_total - prev_calculated; // starting index for calculation of new bars
|
||||
}
|
||||
|
||||
for (int i = limit; i >= 0; i--)
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
|
||||
if (close[i] > close[i + 1])
|
||||
x++;
|
||||
if (close[i] < close[i + 1])
|
||||
y++;
|
||||
|
||||
if (close[i] > close[i + 2])
|
||||
x++;
|
||||
if (close[i] < close[i + 2])
|
||||
y++;
|
||||
|
||||
if (close[i] > close[i + 3])
|
||||
x++;
|
||||
if (close[i] < close[i + 3])
|
||||
y++;
|
||||
|
||||
if (close[i] > close[i + 4])
|
||||
x++;
|
||||
if (close[i] < close[i + 4])
|
||||
y++;
|
||||
|
||||
if (close[i] > close[i + 5])
|
||||
x++;
|
||||
if (close[i] < close[i + 5])
|
||||
y++;
|
||||
|
||||
if (close[i] > close[i + 6])
|
||||
x++;
|
||||
if (close[i] < close[i + 6])
|
||||
y++;
|
||||
|
||||
//////////////////////////
|
||||
if (close[i + 1] > close[i + 2])
|
||||
x++;
|
||||
if (close[i + 1] < close[i + 2])
|
||||
y++;
|
||||
|
||||
if (close[i + 1] > close[i + 3])
|
||||
x++;
|
||||
if (close[i + 1] < close[i + 3])
|
||||
y++;
|
||||
|
||||
if (close[i + 1] > close[i + 4])
|
||||
x++;
|
||||
if (close[i + 1] < close[i + 4])
|
||||
y++;
|
||||
|
||||
if (close[i + 1] > close[i + 5])
|
||||
x++;
|
||||
if (close[i + 1] < close[i + 5])
|
||||
y++;
|
||||
|
||||
if (close[i + 1] > close[i + 6])
|
||||
x++;
|
||||
if (close[i + 1] < close[i + 6])
|
||||
y++;
|
||||
|
||||
//////////////////////////////
|
||||
if (close[i + 2] > close[i + 3])
|
||||
x++;
|
||||
if (close[i + 2] < close[i + 3])
|
||||
y++;
|
||||
|
||||
if (close[i + 2] > close[i + 4])
|
||||
x++;
|
||||
if (close[i + 2] < close[i + 4])
|
||||
y++;
|
||||
|
||||
if (close[i + 2] > close[i + 5])
|
||||
x++;
|
||||
if (close[i + 2] < close[i + 5])
|
||||
y++;
|
||||
|
||||
if (close[i + 2] > close[i + 6])
|
||||
x++;
|
||||
if (close[i + 2] < close[i + 6])
|
||||
y++;
|
||||
|
||||
////////////////////////////
|
||||
if (close[i + 3] > close[i + 4])
|
||||
x++;
|
||||
if (close[i + 3] < close[i + 4])
|
||||
y++;
|
||||
|
||||
if (close[i + 3] > close[i + 5])
|
||||
x++;
|
||||
if (close[i + 3] < close[i + 5])
|
||||
y++;
|
||||
|
||||
if (close[i + 3] > close[i + 6])
|
||||
x++;
|
||||
if (close[i + 3] < close[i + 6])
|
||||
y++;
|
||||
|
||||
////////////////////////////
|
||||
if (close[i + 4] > close[i + 5])
|
||||
x++;
|
||||
if (close[i + 4] < close[i + 5])
|
||||
y++;
|
||||
|
||||
if (close[i + 4] > close[i + 6])
|
||||
x++;
|
||||
if (close[i + 4] < close[i + 6])
|
||||
y++;
|
||||
|
||||
ExtBuffer1[i] = MathAbs(x);
|
||||
ExtBuffer2[i] = MathAbs(y);
|
||||
}
|
||||
//--- return value of prev_calculated for next call
|
||||
return (rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,367 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 MA Candle Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XMACCandle
|
||||
// Description: Moving Average Indicator which
|
||||
// colorified Candle based on price state ...
|
||||
//
|
||||
//
|
||||
// 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 XMAC Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XMACC"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int maPeriod = 14; // Period
|
||||
input int maShift = 0; // Shift
|
||||
input ENUM_MA_METHOD maMethod = MODE_SMA; // Method
|
||||
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// maBuffer ...
|
||||
#define openBufferIndex 0
|
||||
#define highBufferIndex 1
|
||||
#define lowBufferIndex 2
|
||||
#define closeBufferIndex 3
|
||||
#define colorsIndex 4
|
||||
#define maBufferIndex 5
|
||||
|
||||
double openBuffer[];
|
||||
double highBuffer[];
|
||||
double lowBuffer[];
|
||||
double closeBuffer[];
|
||||
double colors[];
|
||||
|
||||
#property indicator_label1 "Open; High; Low; Close;"
|
||||
#property indicator_type1 DRAW_COLOR_CANDLES
|
||||
#property indicator_color1 clrLime, clrGray, clrRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
double maBuffer[];
|
||||
int maHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handler ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
maPeriod,
|
||||
maShift,
|
||||
maMethod,
|
||||
maAppliedTo);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Handler ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, maPeriod);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
int maCalculatedBars = BarsCalculated(maHandler);
|
||||
if (maCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Limit ...
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Prepare Copy Buffers ...
|
||||
bool isBuffersPrepared = PrepareBuffers(limit);
|
||||
if (!isBuffersPrepared) {
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateColorBuffer(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (maPeriod >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// Open Buffer ...
|
||||
ArraySetAsSeries(openBuffer, true);
|
||||
SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(openBufferIndex, PLOT_DRAW_BEGIN, maPeriod);
|
||||
|
||||
//
|
||||
// High Buffer ...
|
||||
ArraySetAsSeries(highBuffer, true);
|
||||
SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(highBufferIndex, PLOT_DRAW_BEGIN, maPeriod);
|
||||
|
||||
//
|
||||
// Low Buffer ...
|
||||
ArraySetAsSeries(lowBuffer, true);
|
||||
SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(lowBufferIndex, PLOT_DRAW_BEGIN, maPeriod);
|
||||
|
||||
//
|
||||
// Close Buffer ...
|
||||
ArraySetAsSeries(closeBuffer, true);
|
||||
SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(closeBufferIndex, PLOT_DRAW_BEGIN, maPeriod);
|
||||
|
||||
//
|
||||
// Colors ...
|
||||
ArraySetAsSeries(colors, true);
|
||||
SetIndexBuffer(colorsIndex, colors, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", maPeriod, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
bool PrepareBuffers(int count) {
|
||||
//
|
||||
// Copy MaBuffer ...
|
||||
int maCopied = CopyBuffer(maHandler, 0, 0, count, maBuffer);
|
||||
if (maCopied <= maPeriod) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy OHLC Buffers ...
|
||||
CopyOpen(_Symbol, _Period, 0, count, openBuffer);
|
||||
CopyHigh(_Symbol, _Period, 0, count, highBuffer);
|
||||
CopyLow(_Symbol, _Period, 0, count, lowBuffer);
|
||||
CopyClose(_Symbol, _Period, 0, count, closeBuffer);
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Setting Ma Color ...
|
||||
void CalculateColorBuffer(int bar_index)
|
||||
{
|
||||
//
|
||||
double low = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double high = iHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double clrValue =
|
||||
maBuffer[bar_index] < low ? 0 : maBuffer[bar_index] > high ? 2
|
||||
: 1;
|
||||
//
|
||||
colors[bar_index] = clrValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,319 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 MA Colorify Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XMAC
|
||||
// Description: Moving Average Indicator which
|
||||
// colorified based on price state ...
|
||||
//
|
||||
//
|
||||
// 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 XMAC Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XMAC"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int maPeriod = 14; // Period
|
||||
input int maShift = 0; // Shift
|
||||
input ENUM_MA_METHOD maMethod = MODE_SMA; // Method
|
||||
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
// #property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// maBuffer ...
|
||||
#define maBufferIndex 0
|
||||
#define maColorIndex 1
|
||||
|
||||
double maBuffer[];
|
||||
double maColor[];
|
||||
|
||||
#property indicator_label1 "XMAC"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrLime, clrGray, clrRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int maHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handler ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
maPeriod,
|
||||
maShift,
|
||||
maMethod,
|
||||
maAppliedTo);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Handler ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, maPeriod);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
int maCalculatedBars = BarsCalculated(maHandler);
|
||||
if (maCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
int copiedMas = CopyBuffer(maHandler, 0, 0, limit + 1, maBuffer);
|
||||
if (copiedMas <= 0)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
SetMaColor(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (maPeriod >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string maBufferLabel = "MA " + "(" + (string)maPeriod + ")";
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel);
|
||||
|
||||
//
|
||||
// Ma Color ...
|
||||
ArraySetAsSeries(maColor, true);
|
||||
SetIndexBuffer(maColorIndex, maColor, INDICATOR_COLOR_INDEX);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", maPeriod, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Setting Ma Color ...
|
||||
void SetMaColor(int bar_index)
|
||||
{
|
||||
//
|
||||
double low = iLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double high = iHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double clrValue =
|
||||
maBuffer[bar_index] < low ? 0 : maBuffer[bar_index] > high ? 2
|
||||
: 1;
|
||||
//
|
||||
maColor[bar_index] = clrValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,276 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 MA Candle Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XMA
|
||||
// Description: Moving Average 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 XMA Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XMA"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int maPeriod = 14; // Period
|
||||
input int maShift = 0; // Shift
|
||||
input ENUM_MA_METHOD maMethod = MODE_SMA; // Method
|
||||
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
// #property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// maBuffer ...
|
||||
#define maBufferIndex 0
|
||||
|
||||
double maBuffer[];
|
||||
|
||||
#property indicator_label1 "XMA"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int maHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handler ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
maPeriod,
|
||||
maShift,
|
||||
maMethod,
|
||||
maAppliedTo);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Handler ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, maPeriod);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
if (BarsCalculated(maHandler) < rates_total)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
if (CopyBuffer(maHandler, 0, 0, limit, maBuffer) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (maPeriod >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string maBufferLabel = "MA " + "(" + (string) maPeriod + ")";
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,260 @@
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Strong Body Candel Detector Indicator
|
||||
// -------------------------------------------------------------
|
||||
// Name: XSBCD
|
||||
// Description: detect Strong Body Candles ...
|
||||
//
|
||||
//
|
||||
// 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 XSBCD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XSBCD"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Common and Models Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 0
|
||||
#property indicator_plots 0
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START 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();
|
||||
|
||||
//
|
||||
LogMessage("Initialized ...");
|
||||
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
//
|
||||
LogMessage("De Init Indicator");
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, 1);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
XOHCL c = GetCandle(bar_index + 1);
|
||||
bool isStrong = HasStrongBody(c);
|
||||
|
||||
//
|
||||
if (!isStrong)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Draw a Vertical Line on it ...
|
||||
datetime time = iTime(_Symbol, _Period, bar_index + 1);
|
||||
string name = "StrongBodyCandle" + (string)time;
|
||||
color clr = clrYellow;
|
||||
|
||||
//
|
||||
DrawVerticalLine(
|
||||
0,
|
||||
name,
|
||||
0,
|
||||
time,
|
||||
clr);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,327 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Trend Power Oscillator
|
||||
// --------------------------------------------------
|
||||
// Name: XTPW
|
||||
// Description: trend power detecting in both sides ...
|
||||
//
|
||||
//
|
||||
// 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 XTPW Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XTPW"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Market Length
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Common and Models Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#property indicator_minimum 0
|
||||
#property indicator_maximum 100
|
||||
|
||||
//
|
||||
#define bullishBufferIndex 0
|
||||
#define bearishBufferIndex 1
|
||||
|
||||
double bullishBuffer[];
|
||||
double bearishBuffer[];
|
||||
|
||||
#property indicator_label1 "XBullPower"
|
||||
#property indicator_type1 DRAW_HISTOGRAM
|
||||
#property indicator_color1 clrLime
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XBearPower"
|
||||
#property indicator_type2 DRAW_HISTOGRAM
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 5)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string bullishBufferLabel = "BullPow " + "(" + (string)length + ")";
|
||||
string bearishBufferLabel = "BearPow " + "(" + (string)length + ")";
|
||||
|
||||
//
|
||||
// Bullish Buffer ...
|
||||
ArraySetAsSeries(bullishBuffer, true);
|
||||
SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel);
|
||||
|
||||
//
|
||||
// Bearish Buffer ...
|
||||
ArraySetAsSeries(bearishBuffer, true);
|
||||
SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
double bullPower = 0;
|
||||
double bearPower = 0;
|
||||
|
||||
//
|
||||
double upperRange = 100;
|
||||
double lowerRange = 0;
|
||||
|
||||
//
|
||||
for (int i = bar_index + 1; i < bar_index + length + 1; i++) {
|
||||
//
|
||||
XOHCL c = GetCandle(i);
|
||||
|
||||
//
|
||||
double cRange =
|
||||
MathAbs(c.open - c.close);
|
||||
|
||||
//
|
||||
bool isBullish = c.open < c.close;
|
||||
bool isBearish = c.open > c.close;
|
||||
|
||||
//
|
||||
if (isBullish) {
|
||||
bullPower += cRange;
|
||||
} else {
|
||||
bearPower += cRange;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bullishBuffer[bar_index] = bullPower;
|
||||
bearishBuffer[bar_index] = bearPower;
|
||||
|
||||
// //
|
||||
// double maxBullRange = bullishBuffer[ArrayMaximum(bullishBuffer)];
|
||||
// double minBullRange = bullishBuffer[ArrayMinimum(bullishBuffer)];
|
||||
|
||||
// //
|
||||
// double maxBearRange = bearishBuffer[ArrayMaximum(bearishBuffer)];
|
||||
// double minBearRange = bearishBuffer[ArrayMinimum(bearishBuffer)];
|
||||
|
||||
// //
|
||||
// // Bullish Buffer ...
|
||||
// double normalBullPower = (((bullPower - minBullRange) * (upperRange - lowerRange)) / (maxBullRange - minBullRange)) + lowerRange;
|
||||
// bullishBuffer[bar_index] = normalBullPower;
|
||||
|
||||
// //
|
||||
// // Bearish Buffer ...
|
||||
// double normalBearPower = (((bearPower - minBearRange) * (upperRange - lowerRange)) / (maxBearRange - minBearRange)) + lowerRange;
|
||||
// bearishBuffer[bar_index] = normalBearPower;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,354 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XATR Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XATR
|
||||
// Description: Moving Average Indicator
|
||||
// Market Analysor ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XATR Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XATR"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Length
|
||||
input double multiplier = 1.6; // Multiplier
|
||||
input ENUM_APPLIED_PRICE longAppliedTo = PRICE_CLOSE; // Long ATR Source
|
||||
input ENUM_APPLIED_PRICE shortAppliedTo = PRICE_OPEN; // Short ATR Source
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
// LONG Buffer ...
|
||||
#define longSLBufferIndex 0
|
||||
|
||||
//
|
||||
double longSLBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XATR Long SL"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// SHORT Buffer ...
|
||||
#define shortSLBufferIndex 1
|
||||
|
||||
//
|
||||
double shortSLBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "XATR Short SL"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
// ATR Buffer ...
|
||||
#define atrBufferIndex 2
|
||||
|
||||
//
|
||||
double atrBuffer[];
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int atrHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// ATR Handler ...
|
||||
atrHandler = iATR(
|
||||
_Symbol,
|
||||
_Period,
|
||||
length);
|
||||
if (atrHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing ATR Indicator ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
int atrCalculatedBars = BarsCalculated(atrHandler);
|
||||
if (atrCalculatedBars < rates_total)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
int atrCopiedItems = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer);
|
||||
if (atrCopiedItems <= 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 = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// LONG SL Buffers ...
|
||||
string longSLBufferLabel = ShortName + " L SL " + "(" + (string)length + ")";
|
||||
ArraySetAsSeries(longSLBuffer, true);
|
||||
SetIndexBuffer(longSLBufferIndex, longSLBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(longSLBufferIndex, PLOT_DRAW_BEGIN, length);
|
||||
PlotIndexSetString(longSLBufferIndex, PLOT_LABEL, longSLBufferLabel);
|
||||
|
||||
//
|
||||
// SHORT SL Buffers ...
|
||||
string shortSLBufferLabel = ShortName + " S SL " + "(" + (string)length + ")";
|
||||
ArraySetAsSeries(shortSLBuffer, true);
|
||||
SetIndexBuffer(shortSLBufferIndex, shortSLBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(shortSLBufferIndex, PLOT_DRAW_BEGIN, length);
|
||||
PlotIndexSetString(shortSLBufferIndex, PLOT_LABEL, shortSLBufferLabel);
|
||||
|
||||
//
|
||||
// ATR Buffer ...
|
||||
ArraySetAsSeries(atrBuffer, true);
|
||||
SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index // Selected Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
// ATR ...
|
||||
double atrValue = atrBuffer[bar_index];
|
||||
|
||||
//
|
||||
// LOMNG Buffer ...
|
||||
double longPrice = GetAppliedPrice(
|
||||
bar_index,
|
||||
longAppliedTo);
|
||||
double longSLValue = longPrice - (atrValue * multiplier);
|
||||
|
||||
//
|
||||
longSLBuffer[bar_index] = longSLValue;
|
||||
|
||||
//
|
||||
// SHORT Buffer ...
|
||||
double shortPrice = GetAppliedPrice(
|
||||
bar_index,
|
||||
shortAppliedTo);
|
||||
double shortSLValue = shortPrice + (atrValue * multiplier);
|
||||
|
||||
//
|
||||
shortSLBuffer[bar_index] = shortSLValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,476 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Cycle Channel Oscillator
|
||||
// ---------------------------------------------------------
|
||||
// Name: XCCH
|
||||
// Description: Cycle Channel Oscillator ...
|
||||
//
|
||||
//
|
||||
// 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 XCCH Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XCCH"
|
||||
|
||||
//
|
||||
// Including Models Library ...
|
||||
#include "..\Libraries\x-saherelm.models.lib.mq5"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
input int fastLength = 10; // Fast Length
|
||||
input double fastMultiplier = 1.0; // Fast Multiplier
|
||||
|
||||
//
|
||||
input int slowLength = 30; // Slow Length
|
||||
input double slowMultiplier = 3.0; // Slow Multiplier
|
||||
|
||||
//
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Source
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#define fastBufferIndex 0
|
||||
#define slowBufferIndex 1
|
||||
#define fastRMABufferIndex 2
|
||||
#define slowRMABufferIndex 3
|
||||
#define fastATRBufferIndex 4
|
||||
#define slowATRBufferIndex 5
|
||||
|
||||
//
|
||||
double fastBuffer[];
|
||||
double slowBuffer[];
|
||||
double fastRMABuffer[];
|
||||
double slowRMABuffer[];
|
||||
double fastATRBuffer[];
|
||||
double slowATRBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XCCH Fast"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XCCH Slow"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
int fastRMAHandler = INVALID_HANDLE;
|
||||
int slowRMAHandler = INVALID_HANDLE;
|
||||
int fastATRHandler = INVALID_HANDLE;
|
||||
int slowATRHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Resetting Last Error ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Initialized Requirements ...
|
||||
//
|
||||
// Fast ATR Handler ...
|
||||
fastATRHandler = iATR(
|
||||
_Symbol,
|
||||
_Period,
|
||||
fastLength / 2);
|
||||
if (fastATRHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("ATR Indicator initialization failed: " + (string)GetLastError());
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Slow ATR Handler ...
|
||||
slowATRHandler = iATR(
|
||||
_Symbol,
|
||||
_Period,
|
||||
slowLength / 2);
|
||||
if (slowATRHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("ATR Indicator initialization failed: " + (string)GetLastError());
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Fast RMA ...
|
||||
fastRMAHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xrma.indicator",
|
||||
//
|
||||
// Inputs ...
|
||||
fastLength / 2,
|
||||
appliedTo);
|
||||
if (fastRMAHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("XRMA Indicator initialization failed: " + (string)GetLastError());
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Slow RMA ...
|
||||
slowRMAHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xrma.indicator",
|
||||
//
|
||||
// Inputs ...
|
||||
slowLength / 2,
|
||||
appliedTo);
|
||||
if (fastRMAHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("XRMA Indicator initialization failed: " + (string)GetLastError());
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
//
|
||||
// ReDraw Chart ...
|
||||
ChartRedraw();
|
||||
|
||||
//
|
||||
Comment("");
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(fastLength, slowLength);
|
||||
maxLength = MathMax(maxLength, 14);
|
||||
|
||||
//
|
||||
// Get Retrieved Values from indicators ...
|
||||
int fastRMACalculatedBars = BarsCalculated(fastRMAHandler);
|
||||
int slowRMACalculatedBars = BarsCalculated(slowRMAHandler);
|
||||
int fastATRCalculatedBars = BarsCalculated(fastATRHandler);
|
||||
int slowATRCalculatedBars = BarsCalculated(slowATRHandler);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
if (
|
||||
fastRMACalculatedBars < maxLength ||
|
||||
slowRMACalculatedBars < maxLength ||
|
||||
fastATRCalculatedBars < maxLength ||
|
||||
slowATRCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Copy Buffers from indicators ...
|
||||
int fastRMACopiedItems = CopyBuffer(fastRMAHandler, 0, 0, limit + 1, fastRMABuffer);
|
||||
int slowRMACopiedItems = CopyBuffer(slowRMAHandler, 0, 0, limit + 1, slowRMABuffer);
|
||||
int fastATRCopiedItems = CopyBuffer(fastATRHandler, 0, 0, limit + 1, fastATRBuffer);
|
||||
int slowATRCopiedItems = CopyBuffer(slowATRHandler, 0, 0, limit + 1, slowATRBuffer);
|
||||
|
||||
//
|
||||
// Check Copied Items Number ...
|
||||
if (
|
||||
fastRMACopiedItems <= 0 ||
|
||||
slowRMACopiedItems <= 0 ||
|
||||
fastATRCopiedItems <= 0 ||
|
||||
slowATRCopiedItems <= 0)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (fastLength >= 4 && slowLength > fastLength)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string fastBufferLabel = ShortName + " Fast (" + (string)fastLength + ")";
|
||||
string slowBufferLabel = ShortName + " Slow (" + (string)slowLength + ")";
|
||||
|
||||
//
|
||||
// Fast Buffer ...
|
||||
ArraySetAsSeries(fastBuffer, true);
|
||||
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, fastLength);
|
||||
PlotIndexSetString(fastBufferIndex, PLOT_LABEL, fastBufferLabel);
|
||||
|
||||
//
|
||||
// Slow Buffer ...
|
||||
ArraySetAsSeries(slowBuffer, true);
|
||||
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, slowLength);
|
||||
PlotIndexSetString(slowBufferIndex, PLOT_LABEL, slowBufferLabel);
|
||||
|
||||
//
|
||||
// Fast RMA Buffer ...
|
||||
ArraySetAsSeries(fastRMABuffer, true);
|
||||
SetIndexBuffer(fastRMABufferIndex, fastRMABuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Slow RMA Buffer ...
|
||||
ArraySetAsSeries(slowRMABuffer, true);
|
||||
SetIndexBuffer(slowRMABufferIndex, slowRMABuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Fast ATR Buffer ...
|
||||
ArraySetAsSeries(fastATRBuffer, true);
|
||||
SetIndexBuffer(fastATRBufferIndex, fastATRBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Slow ATR Buffer ...
|
||||
ArraySetAsSeries(slowATRBuffer, true);
|
||||
SetIndexBuffer(slowATRBufferIndex, slowATRBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// Retrieve RMA Values ...
|
||||
double fastRMA = fastRMABuffer[bar_index];
|
||||
double slowRMA = slowRMABuffer[bar_index];
|
||||
|
||||
//
|
||||
// Calculate Offsetes ...
|
||||
double fastOffset = fastMultiplier * fastATRBuffer[bar_index];
|
||||
double slowOffset = slowMultiplier * slowATRBuffer[bar_index];
|
||||
|
||||
//
|
||||
int hFastLength = fastLength / 2;
|
||||
int hSlowLength = slowLength / 2;
|
||||
int qFastLength = hFastLength / 2;
|
||||
int qSlowLength = hSlowLength / 2;
|
||||
|
||||
//
|
||||
double price = GetAppliedPrice(bar_index, appliedTo);
|
||||
|
||||
//
|
||||
// Calculate Fast Top and Bottom ...
|
||||
double fastTOP = (ArraySize(fastRMABuffer) == qFastLength + 1 ? fastRMABuffer[qFastLength] : price) + fastOffset;
|
||||
double fastBOTTOM = (ArraySize(fastRMABuffer) == qFastLength + 1 ? fastRMABuffer[qFastLength] : price) - fastOffset;
|
||||
|
||||
//
|
||||
// Calculate Slow Top and Bottom ...
|
||||
double slowTOP = (ArraySize(slowRMABuffer) == qSlowLength + 1 ? slowRMABuffer[qSlowLength] : price) + slowOffset;
|
||||
double slowBOTTOM = (ArraySize(slowRMABuffer) == qSlowLength + 1 ? slowRMABuffer[qSlowLength] : price) - slowOffset;
|
||||
|
||||
//
|
||||
// Fast Average ...
|
||||
double fastAverage = (fastTOP + fastBOTTOM) / 2;
|
||||
|
||||
//
|
||||
// Calculate Buffer Values ...
|
||||
|
||||
//
|
||||
// Fast ...
|
||||
double fastValue = (price - slowBOTTOM) / (slowTOP - slowBOTTOM);
|
||||
fastBuffer[bar_index] = fastValue;
|
||||
|
||||
//
|
||||
// Slow ...
|
||||
double slowValue = (fastAverage - slowBOTTOM) / (slowTOP - slowBOTTOM);
|
||||
slowBuffer[bar_index] = slowValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,443 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Cycle Trend Detector Indicator
|
||||
// ---------------------------------------------------------
|
||||
// Name: XCTD
|
||||
// Description: trend detecting based on cycles ...
|
||||
//
|
||||
//
|
||||
// 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 XCTD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XCTD"
|
||||
|
||||
//
|
||||
// Including Models Library ...
|
||||
#include "..\Libraries\x-saherelm.models.lib.mq5"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
input int fastLength = 9; // Fast Length
|
||||
input int slowLength = 18; // Slow Length
|
||||
|
||||
//
|
||||
input ENUM_MA_METHOD method = MODE_EMA; // Calculation Method
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 4
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#define fastBufferIndex 0
|
||||
#define slowBufferIndex 1
|
||||
#define stateBufferIndex 2
|
||||
#define maBufferIndex 3
|
||||
|
||||
//
|
||||
double fastBuffer[];
|
||||
double slowBuffer[];
|
||||
double stateBuffer[];
|
||||
double maBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XCTD Fast"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XCTD Slow"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
ENUM_TIMEFRAMES cyclePeriod;
|
||||
int maHandler = INVALID_HANDLE;
|
||||
int fastHandler = INVALID_HANDLE;
|
||||
int slowHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Resetting Last Error ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Initialized Requirements ...
|
||||
cyclePeriod = GetFarestTimeFrame();
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
14,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_CLOSE);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Ma Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// fatst Handler ...
|
||||
fastHandler = iMA(
|
||||
_Symbol,
|
||||
cyclePeriod,
|
||||
fastLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (fastHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Fast Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// slow Handler ...
|
||||
slowHandler = iMA(
|
||||
_Symbol,
|
||||
cyclePeriod,
|
||||
slowLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (slowHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Slow Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
Comment(ShortName + " Cycle Period: " + EnumToString(cyclePeriod));
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
//
|
||||
// ReDraw Chart ...
|
||||
ChartRedraw();
|
||||
|
||||
//
|
||||
Comment("");
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(fastLength, slowLength);
|
||||
maxLength = MathMax(maxLength, 14);
|
||||
|
||||
//
|
||||
// Get Retrieved Values from indicators ...
|
||||
int maCalculatedBars = BarsCalculated(maHandler);
|
||||
int fastCalculatedBars = BarsCalculated(fastHandler);
|
||||
int slowCalculatedBars = BarsCalculated(slowHandler);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
if (
|
||||
maCalculatedBars < maxLength ||
|
||||
fastCalculatedBars < maxLength ||
|
||||
slowCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Copy Buffers from indicators ...
|
||||
int maCopiedItems = CopyBuffer(maHandler, 0, 0, limit + 1, maBuffer);
|
||||
int fastCopiedItems = CopyBuffer(fastHandler, 0, 0, limit + 1, fastBuffer);
|
||||
int slowCopiedItems = CopyBuffer(slowHandler, 0, 0, limit + 1, slowBuffer);
|
||||
|
||||
//
|
||||
// Check Copied Items Number ...
|
||||
if (
|
||||
maCopiedItems <= 0 ||
|
||||
fastCopiedItems <= 0 ||
|
||||
slowCopiedItems <= 0)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (fastLength >= 4 && slowLength > fastLength)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string fastBufferLabel = ShortName + " Fast (" + (string)fastLength + ")";
|
||||
string slowBufferLabel = ShortName + " Slow (" + (string)slowLength + ")";
|
||||
|
||||
//
|
||||
// MA Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Fast Buffer ...
|
||||
ArraySetAsSeries(fastBuffer, true);
|
||||
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, fastLength);
|
||||
PlotIndexSetString(fastBufferIndex, PLOT_LABEL, fastBufferLabel);
|
||||
|
||||
//
|
||||
// Slow Buffer ...
|
||||
ArraySetAsSeries(slowBuffer, true);
|
||||
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, slowLength);
|
||||
PlotIndexSetString(slowBufferIndex, PLOT_LABEL, slowBufferLabel);
|
||||
|
||||
//
|
||||
// State Buffer ...
|
||||
ArraySetAsSeries(stateBuffer, true);
|
||||
SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// here we must calculate required Buffers ...
|
||||
// Ma, Fast and Slow buffers filled using CopyBuffer ...
|
||||
// StateBuffer needs to Calculate ...
|
||||
|
||||
//
|
||||
// Retrieve Different State ...
|
||||
bool isFastCrossedOverSlow = IsCrossOver(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastOverSlow = IsOver(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastCrossedUnderSlow = IsCrossUnder(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastUnderSlow = IsUnder(fastBuffer, slowBuffer, bar_index);
|
||||
|
||||
//
|
||||
// Calculate State Buffer ...
|
||||
double stateValue = X_XCTD_NEUTURAL;
|
||||
if (isFastCrossedOverSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_CROSSED_OVER_SLOW;
|
||||
}
|
||||
else if (isFastCrossedUnderSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_CROSSED_UNDER_SLOW;
|
||||
}
|
||||
else if (isFastOverSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_OVER_SLOW;
|
||||
}
|
||||
else if (isFastUnderSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_UNDER_SLOW;
|
||||
}
|
||||
|
||||
//
|
||||
stateBuffer[bar_index] = stateValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,546 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Cycle Trend Detector Indicator
|
||||
// ---------------------------------------------------------
|
||||
// Name: XCTD
|
||||
// Description: trend detecting based on cycles ...
|
||||
//
|
||||
//
|
||||
// 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 XCTD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XCTD"
|
||||
|
||||
//
|
||||
// Including Models Library ...
|
||||
#include "..\Libraries\x-saherelm.models.lib.mq5"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
input int fastLength = 9; // Fast Length
|
||||
input int slowLength = 18; // Slow Length
|
||||
|
||||
//
|
||||
input ENUM_MA_METHOD method = MODE_EMA; // Calculation Method
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#define fastBufferIndex 0
|
||||
#define slowBufferIndex 1
|
||||
#define maBufferIndex 2
|
||||
#define stateBufferIndex 3
|
||||
#define fastPowerBufferIndex 4
|
||||
#define slowPowerBufferIndex 5
|
||||
|
||||
//
|
||||
double fastBuffer[];
|
||||
double slowBuffer[];
|
||||
|
||||
//
|
||||
// INDICATOR CALCULATIONS BUFFERS ...
|
||||
//
|
||||
// Just Holds a simple Moving Average for Chart Draw Long Cycles ...
|
||||
double maBuffer[];
|
||||
|
||||
//
|
||||
// holds Fast based On Slow States ...
|
||||
double stateBuffer[];
|
||||
|
||||
//
|
||||
// Holds Fast Summerize Value ...
|
||||
// if Fast[0] > Fast[1] => FastPow += Fast[1]
|
||||
// else FastPow -= Fast[1]
|
||||
double fastPowerBuffer[];
|
||||
|
||||
//
|
||||
// Holds Slow Summerize Value ...
|
||||
// if Slow[0] > Slow[1] => SlowPow += Slow[1]
|
||||
// else SlowPow -= Slow[1]
|
||||
double slowPowerBuffer[];
|
||||
|
||||
#property indicator_label1 "XCTD Fast"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XCTD Slow"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// XCTD States ...
|
||||
enum ENUM_X_XCTD_STATES
|
||||
{
|
||||
X_XCTD_FAST_CROSSED_OVER_SLOW = 2,
|
||||
X_XCTD_FAST_OVER_SLOW = 1,
|
||||
X_XCTD_NEUTURAL = 0,
|
||||
X_XCTD_FAST_UNDER_SLOW = -1,
|
||||
X_XCTD_FAST_CROSSED_UNDER_SLOW = -2,
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// XCTD Buffer Lines ...
|
||||
enum ENUM_X_XCTD_BUFFER_LINES
|
||||
{
|
||||
X_XCTD_FAST_LINE = 0,
|
||||
X_XCTD_SLOW_LINE = 1,
|
||||
X_XCTD_STATE_LINE = 2,
|
||||
};
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES cyclePeriod;
|
||||
int maHandler = INVALID_HANDLE;
|
||||
int fastHandler = INVALID_HANDLE;
|
||||
int slowHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Resetting Last Error ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Initialized Requirements ...
|
||||
cyclePeriod = GetFarestTimeFrame();
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
14,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_CLOSE);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Ma Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// fatst Handler ...
|
||||
fastHandler = iMA(
|
||||
_Symbol,
|
||||
cyclePeriod,
|
||||
fastLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (fastHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Fast Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// slow Handler ...
|
||||
slowHandler = iMA(
|
||||
_Symbol,
|
||||
cyclePeriod,
|
||||
slowLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (slowHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Slow Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
Comment(ShortName + " Cycle Period: " + EnumToString(cyclePeriod));
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
//
|
||||
// ReDraw Chart ...
|
||||
ChartRedraw();
|
||||
|
||||
//
|
||||
Comment("");
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(fastLength, slowLength);
|
||||
maxLength = MathMax(maxLength, 14);
|
||||
|
||||
//
|
||||
// Get Retrieved Values from indicators ...
|
||||
int maCalculatedBars = BarsCalculated(maHandler);
|
||||
int fastCalculatedBars = BarsCalculated(fastHandler);
|
||||
int slowCalculatedBars = BarsCalculated(slowHandler);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
if (
|
||||
maCalculatedBars < maxLength ||
|
||||
fastCalculatedBars < maxLength ||
|
||||
slowCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Copy Buffers from indicators ...
|
||||
int maCopiedItems = CopyBuffer(maHandler, 0, 0, limit + 1, maBuffer);
|
||||
int fastCopiedItems = CopyBuffer(fastHandler, 0, 0, limit + 1, fastBuffer);
|
||||
int slowCopiedItems = CopyBuffer(slowHandler, 0, 0, limit + 1, slowBuffer);
|
||||
|
||||
//
|
||||
// Check Copied Items Number ...
|
||||
if (
|
||||
maCopiedItems <= 0 ||
|
||||
fastCopiedItems <= 0 ||
|
||||
slowCopiedItems <= 0)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (fastLength >= 4 && slowLength > fastLength)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string fastBufferLabel = ShortName + " Fast (" + (string)fastLength + ")";
|
||||
string slowBufferLabel = ShortName + " Slow (" + (string)slowLength + ")";
|
||||
|
||||
//
|
||||
// MA Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Fast Buffer ...
|
||||
ArraySetAsSeries(fastBuffer, true);
|
||||
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, fastLength);
|
||||
PlotIndexSetString(fastBufferIndex, PLOT_LABEL, fastBufferLabel);
|
||||
|
||||
//
|
||||
// Slow Buffer ...
|
||||
ArraySetAsSeries(slowBuffer, true);
|
||||
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, slowLength);
|
||||
PlotIndexSetString(slowBufferIndex, PLOT_LABEL, slowBufferLabel);
|
||||
|
||||
//
|
||||
// State Buffer ...
|
||||
ArraySetAsSeries(stateBuffer, true);
|
||||
SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Fast Power Buffer ...
|
||||
ArraySetAsSeries(fastPowerBuffer, true);
|
||||
SetIndexBuffer(fastPowerBufferIndex, fastPowerBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Slow Power Buffer ...
|
||||
ArraySetAsSeries(slowPowerBuffer, true);
|
||||
SetIndexBuffer(slowPowerBufferIndex, slowPowerBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// here we must calculate required Buffers ...
|
||||
// Ma, Fast and Slow buffers filled using CopyBuffer ...
|
||||
// StateBuffer/FastPowerBuffer and SlowPowerBuffer needs to Calculate ...
|
||||
|
||||
//
|
||||
// Retrieve Different State ...
|
||||
bool isFastCrossedOverSlow = IsCrossOver(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastOverSlow = IsOver(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastCrossedUnderSlow = IsCrossUnder(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastUnderSlow = IsUnder(fastBuffer, slowBuffer, bar_index);
|
||||
|
||||
//
|
||||
// Calculate State Buffer ...
|
||||
double stateValue = X_XCTD_NEUTURAL;
|
||||
if (isFastCrossedOverSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_CROSSED_OVER_SLOW;
|
||||
}
|
||||
else if (isFastCrossedUnderSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_CROSSED_UNDER_SLOW;
|
||||
}
|
||||
else if (isFastOverSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_OVER_SLOW;
|
||||
}
|
||||
else if (isFastUnderSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_UNDER_SLOW;
|
||||
}
|
||||
|
||||
//
|
||||
stateBuffer[bar_index] = stateValue;
|
||||
|
||||
//
|
||||
// Calculate FastPower Buffer ...
|
||||
if (ArraySize(fastPowerBuffer) <= fastLength)
|
||||
{
|
||||
fastPowerBuffer[bar_index] = 0; // fastBuffer[bar_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double fastDiff = fastBuffer[bar_index] - fastBuffer[bar_index + 1];
|
||||
double fastPowerValue = fastPowerBuffer[bar_index + 1] + fastDiff;
|
||||
// //
|
||||
// if (fastBuffer[bar_index] > fastBuffer[bar_index + 1])
|
||||
// {
|
||||
// fastPowerValue += fastBuffer[bar_index];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fastPowerValue -= fastBuffer[bar_index];
|
||||
// }
|
||||
|
||||
//
|
||||
fastPowerBuffer[bar_index] = fastPowerValue;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate SlowPower Buffer ...
|
||||
if (ArraySize(slowPowerBuffer) <= slowLength)
|
||||
{
|
||||
slowPowerBuffer[bar_index] = 0; // slowBuffer[bar_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double slowDiff = slowBuffer[bar_index] - slowBuffer[bar_index + 1];
|
||||
double slowPowerValue = slowPowerBuffer[bar_index + 1] + slowDiff;
|
||||
|
||||
//
|
||||
// if (slowBuffer[bar_index] > slowBuffer[bar_index + 1])
|
||||
// {
|
||||
// slowPowerValue += slowBuffer[bar_index];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// slowPowerValue -= slowBuffer[bar_index];
|
||||
// }
|
||||
|
||||
//
|
||||
slowPowerBuffer[bar_index] = slowPowerValue;
|
||||
}
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,443 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Cycle Trend Detector Indicator
|
||||
// ---------------------------------------------------------
|
||||
// Name: XCTD
|
||||
// Description: trend detecting based on cycles ...
|
||||
//
|
||||
//
|
||||
// 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 XCTD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XCTD"
|
||||
|
||||
//
|
||||
// Including Models Library ...
|
||||
#include "..\Libraries\x-saherelm.models.lib.mq5"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
input int fastLength = 9; // Fast Length
|
||||
input int slowLength = 18; // Slow Length
|
||||
|
||||
//
|
||||
input ENUM_MA_METHOD method = MODE_EMA; // Calculation Method
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 4
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#define fastBufferIndex 0
|
||||
#define slowBufferIndex 1
|
||||
#define stateBufferIndex 2
|
||||
#define maBufferIndex 3
|
||||
|
||||
//
|
||||
double fastBuffer[];
|
||||
double slowBuffer[];
|
||||
double stateBuffer[];
|
||||
double maBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XCTD Fast"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XCTD Slow"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
ENUM_TIMEFRAMES cyclePeriod;
|
||||
int maHandler = INVALID_HANDLE;
|
||||
int fastHandler = INVALID_HANDLE;
|
||||
int slowHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Resetting Last Error ...
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Initialized Requirements ...
|
||||
cyclePeriod = GetFarestTimeFrame();
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
14,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_CLOSE);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Ma Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// fatst Handler ...
|
||||
fastHandler = iMA(
|
||||
_Symbol,
|
||||
cyclePeriod,
|
||||
fastLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (fastHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Fast Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// slow Handler ...
|
||||
slowHandler = iMA(
|
||||
_Symbol,
|
||||
cyclePeriod,
|
||||
slowLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (slowHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("Error in Slow Indicator initialization: " + (string)GetLastError());
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
Comment(ShortName + " Cycle Period: " + EnumToString(cyclePeriod));
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
//
|
||||
// ReDraw Chart ...
|
||||
ChartRedraw();
|
||||
|
||||
//
|
||||
Comment("");
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(fastLength, slowLength);
|
||||
maxLength = MathMax(maxLength, 14);
|
||||
|
||||
//
|
||||
// Get Retrieved Values from indicators ...
|
||||
int maCalculatedBars = BarsCalculated(maHandler);
|
||||
int fastCalculatedBars = BarsCalculated(fastHandler);
|
||||
int slowCalculatedBars = BarsCalculated(slowHandler);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
if (
|
||||
maCalculatedBars < maxLength ||
|
||||
fastCalculatedBars < maxLength ||
|
||||
slowCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Copy Buffers from indicators ...
|
||||
int maCopiedItems = CopyBuffer(maHandler, 0, 0, limit + 1, maBuffer);
|
||||
int fastCopiedItems = CopyBuffer(fastHandler, 0, 0, limit + 1, fastBuffer);
|
||||
int slowCopiedItems = CopyBuffer(slowHandler, 0, 0, limit + 1, slowBuffer);
|
||||
|
||||
//
|
||||
// Check Copied Items Number ...
|
||||
if (
|
||||
maCopiedItems <= 0 ||
|
||||
fastCopiedItems <= 0 ||
|
||||
slowCopiedItems <= 0)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (fastLength >= 4 && slowLength > fastLength)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string fastBufferLabel = ShortName + " Fast (" + (string)fastLength + ")";
|
||||
string slowBufferLabel = ShortName + " Slow (" + (string)slowLength + ")";
|
||||
|
||||
//
|
||||
// MA Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// Fast Buffer ...
|
||||
ArraySetAsSeries(fastBuffer, true);
|
||||
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, fastLength);
|
||||
PlotIndexSetString(fastBufferIndex, PLOT_LABEL, fastBufferLabel);
|
||||
|
||||
//
|
||||
// Slow Buffer ...
|
||||
ArraySetAsSeries(slowBuffer, true);
|
||||
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, slowLength);
|
||||
PlotIndexSetString(slowBufferIndex, PLOT_LABEL, slowBufferLabel);
|
||||
|
||||
//
|
||||
// State Buffer ...
|
||||
ArraySetAsSeries(stateBuffer, true);
|
||||
SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// here we must calculate required Buffers ...
|
||||
// Ma, Fast and Slow buffers filled using CopyBuffer ...
|
||||
// StateBuffer needs to Calculate ...
|
||||
|
||||
//
|
||||
// Retrieve Different State ...
|
||||
bool isFastCrossedOverSlow = IsCrossOver(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastOverSlow = IsOver(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastCrossedUnderSlow = IsCrossUnder(fastBuffer, slowBuffer, bar_index);
|
||||
bool isFastUnderSlow = IsUnder(fastBuffer, slowBuffer, bar_index);
|
||||
|
||||
//
|
||||
// Calculate State Buffer ...
|
||||
double stateValue = X_XCTD_NEUTURAL;
|
||||
if (isFastCrossedOverSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_CROSSED_OVER_SLOW;
|
||||
}
|
||||
else if (isFastCrossedUnderSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_CROSSED_UNDER_SLOW;
|
||||
}
|
||||
else if (isFastOverSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_OVER_SLOW;
|
||||
}
|
||||
else if (isFastUnderSlow)
|
||||
{
|
||||
stateValue = X_XCTD_FAST_UNDER_SLOW;
|
||||
}
|
||||
|
||||
//
|
||||
stateBuffer[bar_index] = stateValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,338 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XLH Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XLH
|
||||
// Description: Moving Average Indicator
|
||||
// Market Analysor ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XLH Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XLH"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Length
|
||||
input double thresholdInPips = 0.3; // Threshold In Pips
|
||||
input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method
|
||||
input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
// HH Buffer ...
|
||||
#define hhBufferIndex 0
|
||||
|
||||
//
|
||||
double hhBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XLH HH"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// LL Buffer ...
|
||||
#define llBufferIndex 1
|
||||
|
||||
//
|
||||
double llBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "XLH LL"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// HH Buffer ...
|
||||
string hhBufferLabel = ShortName + " HH " + "(" + (string)length + ")";
|
||||
ArraySetAsSeries(hhBuffer, true);
|
||||
SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(hhBufferIndex, PLOT_DRAW_BEGIN, length);
|
||||
PlotIndexSetString(hhBufferIndex, PLOT_LABEL, hhBufferLabel);
|
||||
|
||||
//
|
||||
// LL Buffer ...
|
||||
string llBufferLabel = ShortName + " LL " + "(" + (string)length + ")";
|
||||
ArraySetAsSeries(llBuffer, true);
|
||||
SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(llBufferIndex, PLOT_DRAW_BEGIN, length);
|
||||
PlotIndexSetString(llBufferIndex, PLOT_LABEL, llBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index // Selected Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
// Calculate Threshold ...
|
||||
double threshold = 0;
|
||||
if (thresholdInPips > 0)
|
||||
{
|
||||
threshold = PipsToPrice(thresholdInPips);
|
||||
}
|
||||
|
||||
//
|
||||
// HH Buffer ...
|
||||
int hhIndex = iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
hhMode,
|
||||
length,
|
||||
bar_index);
|
||||
double hhValue = GetAppliedPrice(
|
||||
hhIndex,
|
||||
hhMode);
|
||||
|
||||
//
|
||||
// Handle Multiplier ...
|
||||
if (threshold > 0)
|
||||
{
|
||||
//
|
||||
hhValue = hhValue + threshold;
|
||||
}
|
||||
|
||||
//
|
||||
hhBuffer[bar_index] = hhValue;
|
||||
|
||||
//
|
||||
// LL Buffer ...
|
||||
int llIndex = iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
llMode,
|
||||
length,
|
||||
bar_index);
|
||||
double llValue = GetAppliedPrice(
|
||||
llIndex,
|
||||
llMode);
|
||||
|
||||
//
|
||||
// Handle Multiplier ...
|
||||
if (threshold > 0)
|
||||
{
|
||||
llValue = llValue - threshold;
|
||||
}
|
||||
|
||||
//
|
||||
llBuffer[bar_index] = llValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,276 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XMA Candle Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XMA
|
||||
// Description: Moving Average 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 XMA Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XMA"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int maPeriod = 14; // Period
|
||||
input int maShift = 0; // Shift
|
||||
input ENUM_MA_METHOD maMethod = MODE_SMA; // Method
|
||||
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
// #property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// maBuffer ...
|
||||
#define maBufferIndex 0
|
||||
|
||||
double maBuffer[];
|
||||
|
||||
#property indicator_label1 "XMA"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int maHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handler ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
maPeriod,
|
||||
maShift,
|
||||
maMethod,
|
||||
maAppliedTo);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Handler ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, maPeriod);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
if (BarsCalculated(maHandler) < rates_total)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
if (CopyBuffer(maHandler, 0, 0, limit, maBuffer) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (maPeriod >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string maBufferLabel = "MA " + "(" + (string) maPeriod + ")";
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,351 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XMAP Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XMAP
|
||||
// Description: Moving Average Indicator
|
||||
// Market Analysor ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XMAP Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XMAP"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int fastLength = 20; // Fast Length
|
||||
input int slowLength = 50; // Slow Length
|
||||
input ENUM_MA_METHOD method = MODE_SMA; // Method
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
// Fast Buffers ...
|
||||
#define fastBufferIndex 0
|
||||
|
||||
//
|
||||
double fastBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XMAP F"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// Slow Buffers ...
|
||||
#define slowBufferIndex 1
|
||||
|
||||
//
|
||||
double slowBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "XMAP S"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int fastMAHandler = INVALID_HANDLE;
|
||||
int slowMAHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handlers ...
|
||||
|
||||
//
|
||||
// FAST MA ...
|
||||
fastMAHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
fastLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (fastMAHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Indicator ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// SLOW ...
|
||||
slowMAHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
slowLength,
|
||||
0,
|
||||
method,
|
||||
appliedTo);
|
||||
if (slowMAHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Indicator ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(fastLength, slowLength);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
int fastMACalculatedBars = BarsCalculated(fastMAHandler);
|
||||
int slowMACalculatedBars = BarsCalculated(slowMAHandler);
|
||||
if (
|
||||
fastMACalculatedBars < rates_total ||
|
||||
slowMACalculatedBars < rates_total)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
int fastMACopiedItems = CopyBuffer(fastMAHandler, 0, 0, limit, fastBuffer);
|
||||
int slowMACopiedItems = CopyBuffer(slowMAHandler, 0, 0, limit, slowBuffer);
|
||||
if (
|
||||
fastMACopiedItems <= 0 ||
|
||||
slowMACopiedItems <= 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 = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (fastLength >= 2 && fastLength < slowLength)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// FAST Buffers ...
|
||||
string fastBufferLabel = ShortName + " F " + "(" + (string)fastLength + ")";
|
||||
ArraySetAsSeries(fastBuffer, true);
|
||||
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, fastLength);
|
||||
PlotIndexSetString(fastBufferIndex, PLOT_LABEL, fastBufferLabel);
|
||||
|
||||
//
|
||||
// SLOW Buffers ...
|
||||
string slowBufferLabel = ShortName + " S " + "(" + (string)slowLength + ")";
|
||||
ArraySetAsSeries(slowBuffer, true);
|
||||
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, slowLength);
|
||||
PlotIndexSetString(slowBufferIndex, PLOT_LABEL, slowBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index // Selected Bar Index
|
||||
)
|
||||
{
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,494 @@
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 OrderBlock Detector Indicator
|
||||
// -----------------------------------------------------
|
||||
// Name: XOBD
|
||||
// Description: detect Order Blocks based on Swings ...
|
||||
//
|
||||
//
|
||||
// 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 XOBD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XOBD"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
input int length = 5; // Swing Length
|
||||
|
||||
//
|
||||
input uchar swingHighArrowCode = 108; // Swing High Arrow Code
|
||||
input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color
|
||||
|
||||
//
|
||||
input uchar swingLowArrowCode = 108; // Swing Low Arrow Code
|
||||
input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Common and Models Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 0
|
||||
|
||||
//
|
||||
#define swingBufferIndex 0
|
||||
double swingBuffer[];
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
datetime lastSwingHighTime = -1;
|
||||
datetime currentSwingHighTime = -1;
|
||||
|
||||
//
|
||||
datetime lastSwingLowTime = -1;
|
||||
datetime currentSwingLowTime = -1;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START 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
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length * 3);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
ArraySetAsSeries(swingBuffer, true);
|
||||
SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// GetCandleSwing(bar_index);
|
||||
ENUM_X_SWING_TYPE type = X_NO_SWING;
|
||||
|
||||
//
|
||||
// Try To Detect Order Blocks ...
|
||||
bool isSwingLow = false;
|
||||
bool isSwingHigh = false;
|
||||
|
||||
//
|
||||
// Reading Candles Data ...
|
||||
XOHCL candles[];
|
||||
for (int i = bar_index; i < bar_index + ((length * 2) + 2); i++)
|
||||
{
|
||||
//
|
||||
XOHCL iCandle = GetCandle(
|
||||
_Symbol,
|
||||
_Period,
|
||||
i);
|
||||
|
||||
//
|
||||
Add(
|
||||
iCandle,
|
||||
candles);
|
||||
}
|
||||
|
||||
//
|
||||
// Swing Low ...
|
||||
isSwingLow =
|
||||
//
|
||||
candles[1].close > candles[2].close &&
|
||||
candles[2].close > candles[3].close &&
|
||||
//
|
||||
candles[3].close < candles[4].close &&
|
||||
//
|
||||
candles[5].close > candles[4].close &&
|
||||
candles[6].close > candles[5].close
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (isSwingLow)
|
||||
{
|
||||
type = X_SWING_LOW;
|
||||
}
|
||||
|
||||
//
|
||||
if (!isSwingLow)
|
||||
{
|
||||
//
|
||||
// Swing High ...
|
||||
isSwingHigh =
|
||||
//
|
||||
candles[1].close < candles[2].close &&
|
||||
candles[2].close < candles[3].close &&
|
||||
//
|
||||
candles[3].close > candles[4].close &&
|
||||
//
|
||||
candles[5].close < candles[4].close &&
|
||||
candles[6].close < candles[5].close
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (isSwingHigh)
|
||||
{
|
||||
type = X_SWING_HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
datetime time =
|
||||
type != X_NO_SWING ? iTime(_Symbol, _Period, bar_index + 3) : -1;
|
||||
|
||||
//
|
||||
switch (type)
|
||||
{
|
||||
//
|
||||
// Swing High ...
|
||||
case X_SWING_HIGH:
|
||||
//
|
||||
if (time != -1)
|
||||
{
|
||||
//
|
||||
if (currentSwingHighTime != -1)
|
||||
{
|
||||
lastSwingHighTime = currentSwingHighTime;
|
||||
}
|
||||
|
||||
//
|
||||
currentSwingHighTime = time;
|
||||
}
|
||||
|
||||
//
|
||||
swingBuffer[bar_index] = type;
|
||||
DrawSwingArrow(1, bar_index);
|
||||
break;
|
||||
|
||||
//
|
||||
// Swinmg Low ...
|
||||
case X_SWING_LOW:
|
||||
//
|
||||
if (time != -1)
|
||||
{
|
||||
//
|
||||
if (currentSwingLowTime != -1)
|
||||
{
|
||||
lastSwingLowTime = currentSwingLowTime;
|
||||
}
|
||||
|
||||
//
|
||||
currentSwingLowTime = time;
|
||||
}
|
||||
|
||||
//
|
||||
swingBuffer[bar_index] = type;
|
||||
DrawSwingArrow(0, bar_index);
|
||||
break;
|
||||
|
||||
//
|
||||
// No Swing ...
|
||||
default:
|
||||
case X_NO_SWING:
|
||||
//
|
||||
swingBuffer[bar_index] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw a Swing Arrow Shape ...
|
||||
void DrawSwingArrow(
|
||||
int type, // Swing Type: 0 - Low / 1 - High ...
|
||||
int bar_index)
|
||||
{
|
||||
//
|
||||
bool isSwingHigh = type == 1;
|
||||
XOHCL candle = GetCandle(bar_index + 3);
|
||||
double arrowDistanceInPoint = 0;
|
||||
|
||||
//
|
||||
// Define Required Object Properties fro Draw an Arrow ...
|
||||
datetime time = iTime(_Symbol, _Period, bar_index + 3);
|
||||
double purePrice = isSwingHigh ? candle.high : candle.low;
|
||||
color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor;
|
||||
ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP;
|
||||
uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode);
|
||||
double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint;
|
||||
string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice;
|
||||
|
||||
//
|
||||
// Draw desired Arrow ...
|
||||
DrawArrow(
|
||||
0,
|
||||
name,
|
||||
0,
|
||||
time,
|
||||
price,
|
||||
arrowCode,
|
||||
anchor,
|
||||
clr);
|
||||
|
||||
//
|
||||
// Drawing Last two Swing Trend Line only for smallest than 500 candle ...
|
||||
if (bar_index > 200)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check can Draw Trend Line or not ...
|
||||
bool canDrawTrendLine =
|
||||
//
|
||||
isSwingHigh
|
||||
//
|
||||
?
|
||||
//
|
||||
currentSwingHighTime != -1 && lastSwingHighTime != -1
|
||||
//
|
||||
:
|
||||
//
|
||||
currentSwingLowTime != -1 && lastSwingLowTime != -1
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (!canDrawTrendLine)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
datetime time1 = isSwingHigh ? lastSwingHighTime : lastSwingLowTime;
|
||||
datetime time2 = isSwingHigh ? currentSwingHighTime : currentSwingLowTime;
|
||||
|
||||
//
|
||||
int lastSwingBar = iBarShift(_Symbol, _Period, time1);
|
||||
XOHCL lastSwingCandle = GetCandle(lastSwingBar);
|
||||
|
||||
//
|
||||
string sHTName = "SHTL";
|
||||
string sLTName = "SLTL";
|
||||
string tlName = isSwingHigh ? sHTName : sLTName;
|
||||
double price1 = isSwingHigh ? lastSwingCandle.high : lastSwingCandle.low;
|
||||
double price2 = purePrice;
|
||||
|
||||
//
|
||||
if (IsDrawExists(tlName))
|
||||
{
|
||||
RemoveDraws(tlName);
|
||||
}
|
||||
|
||||
//
|
||||
DrawTrendLine(
|
||||
0,
|
||||
tlName,
|
||||
0,
|
||||
time1,
|
||||
price1,
|
||||
time2,
|
||||
price2,
|
||||
clr,
|
||||
STYLE_SOLID,
|
||||
1,
|
||||
false,
|
||||
false,
|
||||
true // Ray Right ...
|
||||
);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,358 @@
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 OrderBlock Detector Indicator
|
||||
// -----------------------------------------------------
|
||||
// Name: XOBD
|
||||
// Description: detect Order Blocks based on Swings ...
|
||||
//
|
||||
//
|
||||
// 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 XOBD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XOBD"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
input int length = 5; // Market Length
|
||||
|
||||
//
|
||||
input double arrowDistanceFromPrice = 200; // Arrow Distrance from Price
|
||||
|
||||
//
|
||||
input uchar swingHighArrowCode = 108; // Swing High Arrow Code
|
||||
input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color
|
||||
|
||||
//
|
||||
input uchar swingLowArrowCode = 108; // Swing Low Arrow Code
|
||||
input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Common and Models Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 0
|
||||
|
||||
//
|
||||
#define swingBufferIndex 0
|
||||
double swingBuffer[];
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START 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
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
ArraySetAsSeries(swingBuffer, true);
|
||||
SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// Check Loopback for Swings ...
|
||||
bool hasLoopbackSwingHigh = false;
|
||||
bool hasLoopbackSwingLow = false;
|
||||
for (int i = bar_index + 1; i < bar_index + length + 1; i++)
|
||||
{
|
||||
//
|
||||
ENUM_X_SWING_TYPE type = GetCandleSwing(i);
|
||||
if (type == X_SWING_HIGH)
|
||||
{
|
||||
hasLoopbackSwingHigh = true;
|
||||
}
|
||||
else if (type == X_SWING_LOW)
|
||||
{
|
||||
hasLoopbackSwingLow = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
ENUM_X_SWING_TYPE type = GetCandleSwing(bar_index);
|
||||
switch (type)
|
||||
{
|
||||
//
|
||||
// Swing High ...
|
||||
case X_SWING_HIGH:
|
||||
//
|
||||
if (!hasLoopbackSwingHigh)
|
||||
{
|
||||
//
|
||||
swingBuffer[bar_index] = 1;
|
||||
DrawSwingArrow(1, bar_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
swingBuffer[bar_index] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Swinmg Low ...
|
||||
case X_SWING_LOW:
|
||||
//
|
||||
if (!hasLoopbackSwingLow)
|
||||
{
|
||||
//
|
||||
swingBuffer[bar_index] = -1;
|
||||
DrawSwingArrow(0, bar_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
swingBuffer[bar_index] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// No Swing ...
|
||||
default:
|
||||
case X_NO_SWING:
|
||||
//
|
||||
swingBuffer[bar_index] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw a Swing Arrow Shape ...
|
||||
void DrawSwingArrow(
|
||||
int type, // Swing Type: 0 - Low / 1 - High ...
|
||||
int bar_index)
|
||||
{
|
||||
//
|
||||
bool isSwingHigh = type == 1;
|
||||
XOHCL candle = GetCandle(bar_index + 3);
|
||||
double arrowDistanceInPoint = arrowDistanceFromPrice * _Point;
|
||||
|
||||
//
|
||||
// Define Required Object Properties fro Draw an Arrow ...
|
||||
datetime time = iTime(_Symbol, _Period, bar_index + 3);
|
||||
double purePrice = isSwingHigh ? candle.high : candle.low;
|
||||
color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor;
|
||||
ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP;
|
||||
uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode);
|
||||
double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint;
|
||||
string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice;
|
||||
|
||||
//
|
||||
// Draw desired Arrow ...
|
||||
DrawArrow(
|
||||
0,
|
||||
name,
|
||||
0,
|
||||
time,
|
||||
price,
|
||||
arrowCode,
|
||||
anchor,
|
||||
clr);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,358 @@
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 OrderBlock Detector Indicator
|
||||
// -----------------------------------------------------
|
||||
// Name: XOBD
|
||||
// Description: detect Order Blocks based on Swings ...
|
||||
//
|
||||
//
|
||||
// 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 XOBD Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XOBD"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
input int length = 5; // Market Length
|
||||
|
||||
//
|
||||
input double arrowDistanceFromPrice = 200; // Arrow Distrance from Price
|
||||
|
||||
//
|
||||
input uchar swingHighArrowCode = 108; // Swing High Arrow Code
|
||||
input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color
|
||||
|
||||
//
|
||||
input uchar swingLowArrowCode = 108; // Swing Low Arrow Code
|
||||
input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Common and Models Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 0
|
||||
|
||||
//
|
||||
#define swingBufferIndex 0
|
||||
double swingBuffer[];
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START 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
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
ArraySetAsSeries(swingBuffer, true);
|
||||
SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// Check Loopback for Swings ...
|
||||
bool hasLoopbackSwingHigh = false;
|
||||
bool hasLoopbackSwingLow = false;
|
||||
for (int i = bar_index + 1; i < bar_index + length + 1; i++)
|
||||
{
|
||||
//
|
||||
ENUM_X_SWING_TYPE type = GetCandleSwing(i);
|
||||
if (type == X_SWING_HIGH)
|
||||
{
|
||||
hasLoopbackSwingHigh = true;
|
||||
}
|
||||
else if (type == X_SWING_LOW)
|
||||
{
|
||||
hasLoopbackSwingLow = true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
ENUM_X_SWING_TYPE type = GetCandleSwing(bar_index);
|
||||
switch (type)
|
||||
{
|
||||
//
|
||||
// Swing High ...
|
||||
case X_SWING_HIGH:
|
||||
//
|
||||
if (!hasLoopbackSwingHigh)
|
||||
{
|
||||
//
|
||||
swingBuffer[bar_index] = 1;
|
||||
DrawSwingArrow(1, bar_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
swingBuffer[bar_index] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Swinmg Low ...
|
||||
case X_SWING_LOW:
|
||||
//
|
||||
if (!hasLoopbackSwingLow)
|
||||
{
|
||||
//
|
||||
swingBuffer[bar_index] = -1;
|
||||
DrawSwingArrow(0, bar_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
swingBuffer[bar_index] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// No Swing ...
|
||||
default:
|
||||
case X_NO_SWING:
|
||||
//
|
||||
swingBuffer[bar_index] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw a Swing Arrow Shape ...
|
||||
void DrawSwingArrow(
|
||||
int type, // Swing Type: 0 - Low / 1 - High ...
|
||||
int bar_index)
|
||||
{
|
||||
//
|
||||
bool isSwingHigh = type == 1;
|
||||
XOHCL candle = GetCandle(bar_index + 3);
|
||||
double arrowDistanceInPoint = arrowDistanceFromPrice * _Point;
|
||||
|
||||
//
|
||||
// Define Required Object Properties fro Draw an Arrow ...
|
||||
datetime time = iTime(_Symbol, _Period, bar_index + 3);
|
||||
double purePrice = isSwingHigh ? candle.high : candle.low;
|
||||
color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor;
|
||||
ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP;
|
||||
uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode);
|
||||
double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint;
|
||||
string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice;
|
||||
|
||||
//
|
||||
// Draw desired Arrow ...
|
||||
DrawArrow(
|
||||
0,
|
||||
name,
|
||||
0,
|
||||
time,
|
||||
price,
|
||||
arrowCode,
|
||||
anchor,
|
||||
clr);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,246 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Price Action Candle Indicator/Oscillator
|
||||
// ----------------------------------------------------------------
|
||||
// Name: XPRC
|
||||
// Description: find down and up candlestick patterns
|
||||
// based on pure price action ...
|
||||
//
|
||||
//
|
||||
// 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 XPRC Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XPRC"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// mBuffer ...
|
||||
#define mBufferIndex 0
|
||||
|
||||
double mBuffer[];
|
||||
|
||||
#property indicator_label1 "M"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrYellow
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 2
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START 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
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, 0);
|
||||
|
||||
//
|
||||
// input variable, we return 0 means nothing passed ...
|
||||
if (rates_total < maxLength)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// found which candles calculated before ...
|
||||
limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1;
|
||||
|
||||
//
|
||||
// this is the main loop of calculations, for each bar index ...
|
||||
for (int i = limit - 1; i >= 0; i--)
|
||||
{
|
||||
//
|
||||
// Start Calculation here ...
|
||||
// i is bar_index ...
|
||||
|
||||
//
|
||||
// Calculate mBuffer ...
|
||||
CalculateMBuffer(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// BUFFER_NAME ...
|
||||
ArraySetAsSeries(mBuffer, true);
|
||||
SetIndexBuffer(mBufferIndex, mBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate mBuffer ...
|
||||
void CalculateMBuffer(int bar_index) {}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,324 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XRMA Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XRMA
|
||||
// Description: Relative Moving Average 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 XRMA Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XRMA"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Length
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// maBuffer ...
|
||||
#define rmaBufferIndex 0
|
||||
#define maBufferIndex 1
|
||||
|
||||
double rmaBuffer[];
|
||||
double maBuffer[];
|
||||
|
||||
#property indicator_label1 "XRMA"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrYellow
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int maHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handler ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
length,
|
||||
0,
|
||||
MODE_SMA,
|
||||
appliedTo);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Indicator ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
if (BarsCalculated(maHandler) < rates_total)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
if (CopyBuffer(maHandler, 0, 0, limit, maBuffer) <= 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 = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string rmaBufferLabel = "XRMA " + "(" + (string)length + ")";
|
||||
|
||||
//
|
||||
// XRMA Buffer ...
|
||||
ArraySetAsSeries(rmaBuffer, true);
|
||||
SetIndexBuffer(rmaBufferIndex, rmaBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(rmaBufferIndex, PLOT_DRAW_BEGIN, length);
|
||||
PlotIndexSetString(rmaBufferIndex, PLOT_LABEL, rmaBufferLabel);
|
||||
|
||||
//
|
||||
// MA Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "(", length, ")");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index // Selected Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
// Calculate Alpha ...
|
||||
double alpha = 1 / length;
|
||||
|
||||
//
|
||||
// Retrieve Applied Price ...
|
||||
double price = GetAppliedPrice(bar_index, appliedTo);
|
||||
|
||||
//
|
||||
// Last RMA Value ...
|
||||
// LogMessage("rma Size: " + (string)ArraySize(rmaBuffer) + ", bar_index: " + (string)bar_index);
|
||||
double nzValue = ArraySize(rmaBuffer) == bar_index + 2 ? rmaBuffer[bar_index + 1] : 0;
|
||||
double prevRMA = nzValue > 0 ? nzValue : maBuffer[bar_index];
|
||||
|
||||
//
|
||||
// Calculate RMA Value for Bar Index ...
|
||||
double rmaValue = alpha * price + (1 - alpha) * prevRMA;
|
||||
rmaValue = NormalizeDouble(rmaValue, _Digits);
|
||||
|
||||
//
|
||||
// Fill Buffer ...
|
||||
rmaBuffer[bar_index] = rmaValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,352 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XRMAP Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XRMAP
|
||||
// Description: Relative Moving Average Indicator
|
||||
// Market Analysor ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XRMAP Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XRMAP"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int fastLength = 20; // Fast Length
|
||||
input int slowLength = 50; // Slow Length
|
||||
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
// Fast Buffers ...
|
||||
#define fastBufferIndex 0
|
||||
|
||||
//
|
||||
double fastBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XRMAP F"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// Slow Buffers ...
|
||||
#define slowBufferIndex 1
|
||||
|
||||
//
|
||||
double slowBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "XRMAP S"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrFuchsia
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int fastRMAHandler = INVALID_HANDLE;
|
||||
int slowRMAHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handlers ...
|
||||
|
||||
//
|
||||
// FAST RMA ...
|
||||
fastRMAHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xrma.indicator",
|
||||
//
|
||||
// Inputs ...
|
||||
fastLength,
|
||||
appliedTo);
|
||||
if (fastRMAHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing XRMA Indicator ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// SLOW RMA ...
|
||||
slowRMAHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xrma.indicator",
|
||||
//
|
||||
// Inputs ...
|
||||
slowLength,
|
||||
appliedTo);
|
||||
if (slowRMAHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Indicator ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(fastLength, slowLength);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
int fastRMACalculatedBars = BarsCalculated(fastRMAHandler);
|
||||
int slowRMACalculatedBars = BarsCalculated(slowRMAHandler);
|
||||
if (
|
||||
fastRMACalculatedBars < rates_total ||
|
||||
slowRMACalculatedBars < rates_total)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
int fastRMACopiedItems = CopyBuffer(fastRMAHandler, 0, 0, limit, fastBuffer);
|
||||
int slowRMACopiedItems = CopyBuffer(slowRMAHandler, 0, 0, limit, slowBuffer);
|
||||
if (
|
||||
fastRMACopiedItems <= 0 ||
|
||||
slowRMACopiedItems <= 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 = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (fastLength >= 2 && fastLength < slowLength)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// FAST Buffers ...
|
||||
string fastBufferLabel = ShortName + " F " + "(" + (string)fastLength + ")";
|
||||
ArraySetAsSeries(fastBuffer, true);
|
||||
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, fastLength);
|
||||
PlotIndexSetString(fastBufferIndex, PLOT_LABEL, fastBufferLabel);
|
||||
|
||||
//
|
||||
// SLOW Buffers ...
|
||||
string slowBufferLabel = ShortName + " S " + "(" + (string)slowLength + ")";
|
||||
ArraySetAsSeries(slowBuffer, true);
|
||||
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, slowLength);
|
||||
PlotIndexSetString(slowBufferIndex, PLOT_LABEL, slowBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, "");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index // Selected Bar Index
|
||||
)
|
||||
{
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,395 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Trend Detector Oscillator
|
||||
// --------------------------------------------------
|
||||
// Name: XTD
|
||||
// Description: trend detecting in both sides ...
|
||||
//
|
||||
//
|
||||
// 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 XTD Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XTD"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Models Library ...
|
||||
#include "../Libraries/x-saherelm.models.lib.mq5";
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Market Length
|
||||
input bool drawCrosses = true; // Draw Cross Arrows
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
input uchar bullishArrowCode = 228; // Cross Over Arrow Code
|
||||
input color bullishArrowColor = clrAqua; // Cross Over Arrow Color
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
input uchar bearishArrowCode = 230; // Cross Under Arrow Code
|
||||
input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Draw Library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
|
||||
//
|
||||
#define bullishBufferIndex 0
|
||||
#define bearishBufferIndex 1
|
||||
#define diffBufferIndex 2
|
||||
|
||||
//
|
||||
double bullishBuffer[];
|
||||
double bearishBuffer[];
|
||||
double diffBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XBullPower"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrLime
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XBearPower"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
#property indicator_label3 "XDiff"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrGold
|
||||
#property indicator_style3 STYLE_DOT
|
||||
#property indicator_width3 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
int xtdBullishCandleCount = 0;
|
||||
int xtdBearishCandleCount = 0;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START 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
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
//
|
||||
// De Init Draw Library ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i, close);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 5)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string bullishBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")";
|
||||
string bearishBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")";
|
||||
string diffBufferLabel = ShortName + "Diff " + "(" + (string)length + ")";
|
||||
|
||||
//
|
||||
// Bullish Buffer ...
|
||||
ArraySetAsSeries(bullishBuffer, true);
|
||||
SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel);
|
||||
|
||||
//
|
||||
// Bearish Buffer ...
|
||||
ArraySetAsSeries(bearishBuffer, true);
|
||||
SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel);
|
||||
|
||||
//
|
||||
// Diff Buffer ...
|
||||
ArraySetAsSeries(diffBuffer, true);
|
||||
SetIndexBuffer(diffBufferIndex, diffBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(diffBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(diffBufferIndex, PLOT_LABEL, diffBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index,
|
||||
const double &close[])
|
||||
{
|
||||
//
|
||||
// Reset Global Counters ...
|
||||
xtdBullishCandleCount = 0;
|
||||
xtdBearishCandleCount = 0;
|
||||
|
||||
//
|
||||
// Loop through Closes ...
|
||||
for (int i = bar_index; i <= bar_index + length; i++)
|
||||
{
|
||||
for (int j = i + 1; j <= bar_index + length; j++)
|
||||
{
|
||||
//
|
||||
if (close[i] > close[j])
|
||||
{
|
||||
xtdBullishCandleCount++;
|
||||
}
|
||||
|
||||
//
|
||||
if (close[i] < close[j])
|
||||
{
|
||||
xtdBearishCandleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bullish Power Buffer ...
|
||||
bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount);
|
||||
|
||||
//
|
||||
// Bearish Power Buffer ...
|
||||
bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount);
|
||||
|
||||
//
|
||||
// Diff Buffer ...
|
||||
diffBuffer[bar_index] = bullishBuffer[bar_index] - bearishBuffer[bar_index];
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Crosses ...
|
||||
void DrawCrosses(
|
||||
double stateValue, // trend state value which specified draw direction ...
|
||||
int bar_index // the bars which required to draw cross arrow on it ...
|
||||
)
|
||||
{
|
||||
//
|
||||
// Only Draw Crosses ...
|
||||
if (stateValue != 2 && stateValue != -2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
bool isOver = stateValue == 2;
|
||||
double low = iLow(_Symbol, _Period, bar_index);
|
||||
double high = iHigh(_Symbol, _Period, bar_index);
|
||||
|
||||
//
|
||||
double price = isOver ? low : high;
|
||||
datetime time = iTime(_Symbol, _Period, bar_index);
|
||||
ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM;
|
||||
uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode;
|
||||
color arrowColor = isOver ? bullishArrowColor : bearishArrowColor;
|
||||
string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price;
|
||||
|
||||
//
|
||||
DrawArrow(
|
||||
0,
|
||||
crossName,
|
||||
0,
|
||||
time,
|
||||
price,
|
||||
arrowCode,
|
||||
anchor,
|
||||
arrowColor);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,440 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Trend Detector Oscillator
|
||||
// --------------------------------------------------
|
||||
// Name: XTD
|
||||
// Description: trend detecting in both sides ...
|
||||
//
|
||||
//
|
||||
// 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 XTD Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XTD"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Models Library ...
|
||||
#include "../Libraries/x-saherelm.models.lib.mq5"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Market Length
|
||||
input bool drawCrosses = true; // Draw Cross Arrows
|
||||
|
||||
//
|
||||
// Bullish ...
|
||||
input uchar bullishArrowCode = 228; // Cross Over Arrow Code
|
||||
input color bullishArrowColor = clrAqua; // Cross Over Arrow Color
|
||||
|
||||
//
|
||||
// Bearish ...
|
||||
input uchar bearishArrowCode = 230; // Cross Under Arrow Code
|
||||
input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Draw Library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#define bullishBufferIndex 0
|
||||
#define bearishBufferIndex 1
|
||||
#define trendStateBufferIndex 2
|
||||
|
||||
//
|
||||
double bullishBuffer[];
|
||||
double bearishBuffer[];
|
||||
|
||||
//
|
||||
double trendStateBuffer[];
|
||||
|
||||
#property indicator_label1 "XBullPower"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrLime
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XBearPower"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
int xtdBullishCandleCount = 0;
|
||||
int xtdBearishCandleCount = 0;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START 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
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
|
||||
//
|
||||
// De Init Draw Library ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i, close);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 5)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string bullishBufferLabel = "BullPow " + "(" + (string)length + ")";
|
||||
string bearishBufferLabel = "BearPow " + "(" + (string)length + ")";
|
||||
|
||||
//
|
||||
// Bullish Buffer ...
|
||||
ArraySetAsSeries(bullishBuffer, true);
|
||||
SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel);
|
||||
|
||||
//
|
||||
// Bearish Buffer ...
|
||||
ArraySetAsSeries(bearishBuffer, true);
|
||||
SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel);
|
||||
|
||||
//
|
||||
// Trend State Buffer ...
|
||||
ArraySetAsSeries(trendStateBuffer, true);
|
||||
SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index,
|
||||
const double &close[])
|
||||
{
|
||||
//
|
||||
// Reset Global Counters ...
|
||||
xtdBullishCandleCount = 0;
|
||||
xtdBearishCandleCount = 0;
|
||||
|
||||
//
|
||||
// Loop through Closes ...
|
||||
for (int i = bar_index; i <= bar_index + length; i++)
|
||||
{
|
||||
for (int j = i + 1; j <= bar_index + length; j++)
|
||||
{
|
||||
//
|
||||
if (close[i] > close[j])
|
||||
{
|
||||
xtdBullishCandleCount++;
|
||||
}
|
||||
|
||||
//
|
||||
if (close[i] < close[j])
|
||||
{
|
||||
xtdBearishCandleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bullish Power Buffer ...
|
||||
bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount);
|
||||
|
||||
//
|
||||
// Bearish Trend Buffer ...
|
||||
bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount);
|
||||
|
||||
//
|
||||
// Check Cross Points ...
|
||||
// bullishCrossedOverBearish = 2;
|
||||
// bullishOverBearish = 1;
|
||||
// bullishCrossedUnderBearish = -2;
|
||||
// bullishUnderBearish = -1;
|
||||
// OtherWise = 0;
|
||||
bool isBullishCrossedOverBearish = IsCrossOver(
|
||||
bullishBuffer,
|
||||
bearishBuffer,
|
||||
bar_index);
|
||||
bool isBullishCrossedUnderBearish = IsCrossUnder(
|
||||
bullishBuffer,
|
||||
bearishBuffer,
|
||||
bar_index);
|
||||
bool isBullishOverBearish = IsOver(
|
||||
bullishBuffer,
|
||||
bearishBuffer,
|
||||
bar_index);
|
||||
bool isBullishUnderBearish = IsUnder(
|
||||
bullishBuffer,
|
||||
bearishBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double trendStateValue = 0;
|
||||
if (isBullishCrossedOverBearish)
|
||||
{
|
||||
trendStateValue = 2;
|
||||
}
|
||||
else if (isBullishCrossedUnderBearish)
|
||||
{
|
||||
trendStateValue = -2;
|
||||
}
|
||||
else if (isBullishOverBearish)
|
||||
{
|
||||
trendStateValue = 1;
|
||||
}
|
||||
else if (isBullishUnderBearish)
|
||||
{
|
||||
trendStateValue = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
trendStateValue = 0;
|
||||
}
|
||||
trendStateBuffer[bar_index] = trendStateValue;
|
||||
|
||||
//
|
||||
// Check and Draw Crosses if it's Specified ...
|
||||
if (drawCrosses)
|
||||
{
|
||||
DrawCrosses(
|
||||
trendStateValue,
|
||||
bar_index);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Crosses ...
|
||||
void DrawCrosses(
|
||||
double stateValue, // trend state value which specified draw direction ...
|
||||
int bar_index // the bars which required to draw cross arrow on it ...
|
||||
)
|
||||
{
|
||||
//
|
||||
// Only Draw Crosses ...
|
||||
if (stateValue != 2 && stateValue != -2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
bool isOver = stateValue == 2;
|
||||
double low = iLow(_Symbol, _Period, bar_index);
|
||||
double high = iHigh(_Symbol, _Period, bar_index);
|
||||
|
||||
//
|
||||
double price = isOver ? low : high;
|
||||
datetime time = iTime(_Symbol, _Period, bar_index);
|
||||
ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM;
|
||||
uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode;
|
||||
color arrowColor = isOver ? bullishArrowColor : bearishArrowColor;
|
||||
string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price;
|
||||
|
||||
//
|
||||
DrawArrow(
|
||||
0,
|
||||
crossName,
|
||||
0,
|
||||
time,
|
||||
price,
|
||||
arrowCode,
|
||||
anchor,
|
||||
arrowColor);
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,306 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Trend Volume Detector Oscillator
|
||||
// ---------------------------------------------------------
|
||||
// Name: XTDV
|
||||
// Description: trend detecting based on volumes in both sides ...
|
||||
//
|
||||
//
|
||||
// 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 XTDV Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XTDV"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Market Length
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 2
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#define bullishVolumeBufferIndex 0
|
||||
#define bearishVolumeBufferIndex 1
|
||||
|
||||
//
|
||||
double bullishVolumeBuffer[];
|
||||
double bearishVolumeBuffer[];
|
||||
|
||||
#property indicator_label1 "XBullVolume"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrAqua
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XBearVolume"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrMagenta
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
ulong xtdBullishCandleVolumes = 0;
|
||||
ulong xtdBearishCandleVolumes = 0;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i, close);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 5)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string bullishVolumeBufferLabel = "BullVol " + "(" + (string)length + ")";
|
||||
string bearishVolumeBufferLabel = "BearVol " + "(" + (string)length + ")";
|
||||
|
||||
//
|
||||
// Bullish Volume Buffer ...
|
||||
ArraySetAsSeries(bullishVolumeBuffer, true);
|
||||
SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bullishVolumeBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bullishVolumeBufferIndex, PLOT_LABEL, bullishVolumeBufferLabel);
|
||||
|
||||
//
|
||||
// Bearish Volume Buffer ...
|
||||
ArraySetAsSeries(bearishVolumeBuffer, true);
|
||||
SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bearishVolumeBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bearishVolumeBufferIndex, PLOT_LABEL, bearishVolumeBufferLabel);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index,
|
||||
const double &close[])
|
||||
{
|
||||
//
|
||||
// Reset Global Counters ...
|
||||
xtdBullishCandleVolumes = 0;
|
||||
xtdBearishCandleVolumes = 0;
|
||||
|
||||
//
|
||||
// Loop through Closes ...
|
||||
for (int i = bar_index; i <= bar_index + length; i++)
|
||||
{
|
||||
for (int j = i + 1; j <= bar_index + length; j++)
|
||||
{
|
||||
//
|
||||
if (close[i] > close[j])
|
||||
{
|
||||
xtdBullishCandleVolumes += iVolume(_Symbol, _Period, i);
|
||||
}
|
||||
|
||||
//
|
||||
if (close[i] < close[j])
|
||||
{
|
||||
xtdBearishCandleVolumes += iVolume(_Symbol, _Period, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bullish Volume Buffer ...
|
||||
bullishVolumeBuffer[bar_index] = (double)xtdBullishCandleVolumes;
|
||||
|
||||
//
|
||||
// Bearish Trend Buffer ...
|
||||
bearishVolumeBuffer[bar_index] = (double)xtdBearishCandleVolumes;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,340 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Candle Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: XTM
|
||||
// Description: Trend Magic Indicator ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XTM Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XTM"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int maPeriod = 14; // Period
|
||||
input int maShift = 0; // Shift
|
||||
input ENUM_MA_METHOD maMethod = MODE_SMA; // Method
|
||||
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 1
|
||||
|
||||
//
|
||||
// maBuffer ...
|
||||
#define maBufferIndex 0
|
||||
#define maColorBufferIndex 1
|
||||
#define stateBufferIndex 2
|
||||
|
||||
double maBuffer[];
|
||||
double maColorBuffer[];
|
||||
double stateBuffer[];
|
||||
|
||||
#property indicator_label1 "XTM"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrLime, clrGray, clrRed
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int maHandler = INVALID_HANDLE;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Initializing MA Handler ...
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
maPeriod,
|
||||
maShift,
|
||||
maMethod,
|
||||
maAppliedTo);
|
||||
if (maHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
string message = "Error Initializing Ma Handler ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, maPeriod);
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
int maCalculatedBars = BarsCalculated(maHandler);
|
||||
if (maCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer);
|
||||
if (copiedMas <= 0)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
// Do Buffers Calculation ...
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (maPeriod >= 2)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string maBufferLabel = "XTM " + "(" + (string)maPeriod + ")";
|
||||
|
||||
//
|
||||
// Ma Buffer ...
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel);
|
||||
|
||||
//
|
||||
// Ma Color Buffer ...
|
||||
ArraySetAsSeries(maColorBuffer, true);
|
||||
SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// State Buffer ...
|
||||
ArraySetAsSeries(stateBuffer, true);
|
||||
SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
// Requirements ...
|
||||
XOHCL candle = GetCandle(bar_index);
|
||||
|
||||
//
|
||||
double maValue = maBuffer[bar_index];
|
||||
|
||||
//
|
||||
double lineColorIndex =
|
||||
maValue < candle.low ? 0 : maValue > candle.high ? 2
|
||||
: 1;
|
||||
|
||||
//
|
||||
// Define State Value ...
|
||||
// lineColorIndex == 0 => Bullish => 1;
|
||||
// lineColorIndex == 1 => Neutural => 0;
|
||||
// lineColorIndex == 2 => Bearish => -1;
|
||||
double stateValue =
|
||||
lineColorIndex == 0 ? X_XTM_BULLISH : lineColorIndex == 2 ? X_XTM_BEARISH
|
||||
: X_XTM_NEUTURAL;
|
||||
|
||||
//
|
||||
// Set Ma Buffer Color Index ...
|
||||
maColorBuffer[bar_index] = lineColorIndex;
|
||||
|
||||
//
|
||||
// Set State Buffer Value ...
|
||||
stateBuffer[bar_index] = stateValue;
|
||||
}
|
||||
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,351 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Trend Power Detector Oscillator
|
||||
// ---------------------------------------------------------
|
||||
// Name: XTPD
|
||||
// Description: trend detecting based on volumes in both sides ...
|
||||
//
|
||||
//
|
||||
// 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 XTPD Oscillator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
#define ShortName "XTPD"
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input int length = 14; // Market Length
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Logging Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5";
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_separate_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 2
|
||||
|
||||
//
|
||||
#define bullishPowerBufferIndex 0
|
||||
#define bearishPowerBufferIndex 1
|
||||
#define stateBufferIndex 2
|
||||
|
||||
//
|
||||
double bullishPowerBuffer[];
|
||||
double bearishPowerBuffer[];
|
||||
double stateBuffer[];
|
||||
|
||||
#property indicator_label1 "XBullPower"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrLime
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
#property indicator_label2 "XBearPower"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// Here we can handle De Initialization Reasons ...
|
||||
}
|
||||
|
||||
//
|
||||
// Calculations ...
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// 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 ...
|
||||
int maxLength = MathMax(0, length);
|
||||
|
||||
//
|
||||
limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (length >= 5)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
string bullishPowerBufferLabel = "BullPow " + "(" + (string)length + ")";
|
||||
string bearishPowerBufferLabel = "BearPow " + "(" + (string)length + ")";
|
||||
|
||||
//
|
||||
// Bullish Volume Buffer ...
|
||||
ArraySetAsSeries(bullishPowerBuffer, true);
|
||||
SetIndexBuffer(bullishPowerBufferIndex, bullishPowerBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bullishPowerBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bullishPowerBufferIndex, PLOT_LABEL, bullishPowerBufferLabel);
|
||||
|
||||
//
|
||||
// Bearish Volume Buffer ...
|
||||
ArraySetAsSeries(bearishPowerBuffer, true);
|
||||
SetIndexBuffer(bearishPowerBufferIndex, bearishPowerBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(bearishPowerBufferIndex, PLOT_DRAW_BEGIN, length * 2);
|
||||
PlotIndexSetString(bearishPowerBufferIndex, PLOT_LABEL, bearishPowerBufferLabel);
|
||||
|
||||
//
|
||||
// State Buffer ...
|
||||
ArraySetAsSeries(stateBuffer, true);
|
||||
SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
//
|
||||
string indicatorShortName = "";
|
||||
StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )");
|
||||
|
||||
//
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(int bar_index)
|
||||
{
|
||||
//
|
||||
double xBullishPowerValue = 0;
|
||||
double xBearishPowerValue = 1;
|
||||
|
||||
//
|
||||
// Loop through bar index and Market Length ...
|
||||
for (int i = bar_index + length + 1; i > bar_index && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
XOHCL candle = GetCandle(i);
|
||||
|
||||
//
|
||||
bool isBullish = IsBullishCandle(candle);
|
||||
bool isBearish = IsBearishCandle(candle);
|
||||
|
||||
//
|
||||
if (isBullish)
|
||||
{
|
||||
xBullishPowerValue++;
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
xBearishPowerValue++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
bullishPowerBuffer[bar_index] = xBullishPowerValue;
|
||||
bearishPowerBuffer[bar_index] = xBearishPowerValue;
|
||||
|
||||
//
|
||||
// Calculate State ...
|
||||
bool isBullishCrossOverBearish = IsCrossOver(
|
||||
bullishPowerBuffer,
|
||||
bearishPowerBuffer,
|
||||
bar_index);
|
||||
bool isBullishOverBearish = IsOver(
|
||||
bullishPowerBuffer,
|
||||
bearishPowerBuffer,
|
||||
bar_index);
|
||||
bool isBullishCrossUnderBearish = IsCrossUnder(
|
||||
bullishPowerBuffer,
|
||||
bearishPowerBuffer,
|
||||
bar_index);
|
||||
bool isBullishUnderBearish = IsUnder(
|
||||
bullishPowerBuffer,
|
||||
bearishPowerBuffer,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double stateValue = X_XTPD_NEUTURAL;
|
||||
if (isBullishCrossOverBearish)
|
||||
{
|
||||
stateValue = X_XTPD_BULLISH_CROSSED_OVER_BEARISH;
|
||||
}
|
||||
else if (isBullishCrossUnderBearish)
|
||||
{
|
||||
stateValue = X_XTPD_BULLISH_CROSSED_UNDER_BEARISH;
|
||||
}
|
||||
else if (isBullishOverBearish)
|
||||
{
|
||||
stateValue = X_XTPD_BULLISH_OVER_BEARISH;
|
||||
}
|
||||
else if (isBullishUnderBearish)
|
||||
{
|
||||
stateValue = X_XTPD_BULLISH_UNDER_BEARISH;
|
||||
}
|
||||
|
||||
//
|
||||
stateBuffer[bar_index] = stateValue;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,197 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 = true; // Terminal Alerts
|
||||
input bool mailAlerts = true; // Mail Alerts
|
||||
input bool pushAlerts = true; // 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)
|
||||
{
|
||||
//
|
||||
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);
|
||||
}
|
||||
}
|
||||
void SendAlert(
|
||||
XSignal &signal, // the Signal Object which requred to Alert
|
||||
bool asExecuted = true // determines Alert Signal as Executed Signal or not
|
||||
)
|
||||
{
|
||||
//
|
||||
// Prepare Message ...
|
||||
string message = asExecuted ? ExecutedSignalToString(signal) : SignalToString(signal);
|
||||
|
||||
//
|
||||
// Do Alerting ...
|
||||
SendAlert(message);
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,953 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// --------------------------------------
|
||||
// Name: XClass
|
||||
// Description: provides all classes for use ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include <Trade\Trade.mqh>
|
||||
#include <Trade\AccountInfo.mqh>
|
||||
#include <Trade\PositionInfo.mqh>
|
||||
#include "x-saherelm.models.lib.mq5"
|
||||
//
|
||||
// END Model Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// XSaherElm Trade Class ...
|
||||
class XCTrade
|
||||
{
|
||||
//
|
||||
// all public features ...
|
||||
public:
|
||||
//
|
||||
// Constructor ...
|
||||
void XCTrade(
|
||||
string symbol,
|
||||
int slippage,
|
||||
ulong magicNumber)
|
||||
{
|
||||
//
|
||||
mSymbol = symbol;
|
||||
mSlippage = slippage;
|
||||
mMagicNumber = magicNumber;
|
||||
|
||||
//
|
||||
mTrader = new CTrade();
|
||||
|
||||
//
|
||||
mTrader.SetAsyncMode(false);
|
||||
mTrader.SetDeviationInPoints(mSlippage);
|
||||
mTrader.SetExpertMagicNumber(mMagicNumber);
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XCTrade()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Count Open Positions ...
|
||||
int Count()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int total = PositionsTotal();
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
//
|
||||
if (!mPositionInfo.SelectByIndex(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.Magic() != mMagicNumber)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.Symbol() != mSymbol)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
result++;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Longs ...
|
||||
int CountLongs()
|
||||
{
|
||||
int result = CountByType(X_SIGNAL_LONG);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count Shorts ...
|
||||
int CountShorts()
|
||||
{
|
||||
int result = CountByType(X_SIGNAL_SHORT);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count By Type ...
|
||||
int CountByType(ENUM_X_SIGNAL_TYPE type)
|
||||
{
|
||||
//
|
||||
// Validate Args ...
|
||||
ENUM_POSITION_TYPE mType = POSITION_TYPE_BUY;
|
||||
if (type == X_SIGNAL_LONG)
|
||||
{
|
||||
mType = POSITION_TYPE_BUY;
|
||||
}
|
||||
else if (type == X_SIGNAL_SHORT)
|
||||
{
|
||||
mType = POSITION_TYPE_SELL;
|
||||
}
|
||||
|
||||
//
|
||||
int result = CountByType(mType);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve all Positions ...
|
||||
void GetAllPositions(XSignal &result[])
|
||||
{
|
||||
//
|
||||
ArrayFree(result);
|
||||
|
||||
//
|
||||
int total = Count();
|
||||
ArrayResize(result, total);
|
||||
|
||||
//
|
||||
int filledIndex = 0;
|
||||
int totalPositions = PositionsTotal();
|
||||
for (int i = 0; i < totalPositions; i++)
|
||||
{
|
||||
//
|
||||
if (!mPositionInfo.SelectByIndex(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.Magic() != mMagicNumber)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.Symbol() != mSymbol)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
result[filledIndex] = PositionToSignal(i);
|
||||
filledIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve all Long Positions ...
|
||||
void GetLongPositions(XSignal &result[])
|
||||
{
|
||||
GetAllPositionsByType(POSITION_TYPE_BUY, result);
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve all Short Positions ...
|
||||
void GetShortPositions(XSignal &result[])
|
||||
{
|
||||
GetAllPositionsByType(POSITION_TYPE_SELL, result);
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Buy/Long Position ...
|
||||
bool Buy(
|
||||
double volume, // position volume
|
||||
double price, // execution price
|
||||
double sl = 0, // stop loss price
|
||||
double tp = 0, // take profit price
|
||||
const string comment = "" // comment
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = mTrader.Buy(
|
||||
volume,
|
||||
mSymbol,
|
||||
price,
|
||||
sl,
|
||||
tp,
|
||||
comment);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Sell/Short Position ...
|
||||
bool Sell(
|
||||
double volume, // position volume
|
||||
double price, // execution price
|
||||
double sl = 0, // stop loss price
|
||||
double tp = 0, // take profit price
|
||||
const string comment = "" // comment
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = mTrader.Sell(
|
||||
volume,
|
||||
mSymbol,
|
||||
price,
|
||||
sl,
|
||||
tp,
|
||||
comment);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Signal ...
|
||||
bool ValidateSignal(XSignal &signal)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Signal Type ...
|
||||
result = signal.type != X_SIGNAL_UNKNOWN;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Symbol ...
|
||||
result = StringLen(signal.symbol) == 0 ? true : signal.symbol == mSymbol;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check magic number ...
|
||||
result = signal.magicNumber <= 0 ? true : signal.magicNumber == mMagicNumber;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Entry ...
|
||||
result = signal.entry > 0;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check SL ...
|
||||
result = signal.sl == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.sl < signal.entry
|
||||
: signal.sl > signal.entry;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check TP ...
|
||||
result = signal.tp == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.tp > signal.entry
|
||||
: signal.tp < signal.entry;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Volume ...
|
||||
result = signal.volume > 0;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Time ...
|
||||
result = signal.time > 0;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Execute an Specific XSignal instance ...
|
||||
bool ExecuteSignal(XSignal &signal)
|
||||
{
|
||||
//
|
||||
bool result = ValidateSignal(signal);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
signal.symbol = mSymbol;
|
||||
|
||||
//
|
||||
result = signal.type == X_SIGNAL_LONG ? Buy(
|
||||
signal.volume,
|
||||
signal.entry,
|
||||
signal.sl,
|
||||
signal.tp,
|
||||
signal.comment)
|
||||
: signal.type == X_SIGNAL_SHORT ? Sell(
|
||||
signal.volume,
|
||||
signal.entry,
|
||||
signal.sl,
|
||||
signal.tp,
|
||||
signal.comment)
|
||||
: false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Modify Position ...
|
||||
bool Modify(
|
||||
const ulong ticket, // position ticket
|
||||
double sl = 0, // stop loss price
|
||||
double tp = 0 // take profit
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (tp <= 0 && sl <= 0)
|
||||
{
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = mTrader.PositionModify(
|
||||
ticket,
|
||||
sl,
|
||||
tp);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Close Position By Ticket ...
|
||||
bool Close(ulong ticket)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Try to Select Position ...
|
||||
if (!mPositionInfo.SelectByTicket(ticket))
|
||||
{
|
||||
//
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = mTrader.PositionClose(ticket);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Close Partial By Ticket ...
|
||||
bool ClosePartial(ulong ticket, double volume)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (!mPositionInfo.SelectByTicket(ticket))
|
||||
{
|
||||
//
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
mTrader.PositionClosePartial(
|
||||
ticket,
|
||||
volume);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Close All Positions ...
|
||||
void CloseAllPositions()
|
||||
{
|
||||
//
|
||||
// Count all Specified Positions ...
|
||||
int total = Count();
|
||||
if (total <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XSignal allPositions[];
|
||||
GetAllPositions(allPositions);
|
||||
|
||||
//
|
||||
int allPositionsSize = ArraySize(allPositions);
|
||||
if (allPositionsSize == 0 || allPositionsSize != total)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
//
|
||||
XSignal signal = allPositions[i];
|
||||
bool isClosed = Close(signal.ticket);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close All Longs Positions ...
|
||||
void CloseLongPositions()
|
||||
{
|
||||
//
|
||||
// Count all Specified Positions ...
|
||||
int total = CountLongs();
|
||||
if (total <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XSignal longPositions[];
|
||||
GetLongPositions(longPositions);
|
||||
|
||||
//
|
||||
int longPositionsSize = ArraySize(longPositions);
|
||||
if (longPositionsSize == 0 || longPositionsSize != total)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
//
|
||||
XSignal signal = longPositions[i];
|
||||
bool isClosed = Close(signal.ticket);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close All Shorts Positions ...
|
||||
void CloseShortPositions()
|
||||
{
|
||||
//
|
||||
// Count all Specified Positions ...
|
||||
int total = CountShorts();
|
||||
if (total <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XSignal shortPositions[];
|
||||
GetShortPositions(shortPositions);
|
||||
|
||||
//
|
||||
int shortPositionsSize = ArraySize(shortPositions);
|
||||
if (shortPositionsSize == 0 || shortPositionsSize != total)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
//
|
||||
XSignal signal = shortPositions[i];
|
||||
bool isClosed = Close(signal.ticket);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// all protected features ...
|
||||
protected:
|
||||
//
|
||||
// all private features ...
|
||||
private:
|
||||
//
|
||||
// which Symbol ...
|
||||
string mSymbol;
|
||||
|
||||
//
|
||||
// using deviation, it must be in Point ...
|
||||
int mSlippage;
|
||||
|
||||
//
|
||||
// using magic number ...
|
||||
ulong mMagicNumber;
|
||||
|
||||
//
|
||||
// using CTrade instance ...
|
||||
CTrade mTrader;
|
||||
|
||||
//
|
||||
// using PositionInfo instance ...
|
||||
CPositionInfo mPositionInfo;
|
||||
|
||||
//
|
||||
// Count Specific Type Of Positions ...
|
||||
int CountByType(ENUM_POSITION_TYPE type)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
int total = PositionsTotal();
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
//
|
||||
if (!mPositionInfo.SelectByIndex(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.Symbol() != mSymbol)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.PositionType() != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
result++;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Convert Position to Signal by Index ...
|
||||
XSignal PositionToSignal(int index)
|
||||
{
|
||||
//
|
||||
XSignal result = {};
|
||||
|
||||
//
|
||||
if (!mPositionInfo.SelectByIndex(index))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// ID ...
|
||||
result.id = mPositionInfo.Identifier();
|
||||
|
||||
//
|
||||
// Symbol ...
|
||||
result.symbol = mPositionInfo.Symbol();
|
||||
|
||||
//
|
||||
// Type ...
|
||||
ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType();
|
||||
ENUM_X_SIGNAL_TYPE type = pType == POSITION_TYPE_BUY ? X_SIGNAL_LONG : X_SIGNAL_SHORT;
|
||||
result.type = type;
|
||||
|
||||
//
|
||||
// MagicNumber ...
|
||||
result.magicNumber = mPositionInfo.Magic();
|
||||
|
||||
//
|
||||
// Ticket ...
|
||||
result.ticket = mPositionInfo.Ticket();
|
||||
|
||||
//
|
||||
// Entry/Open Price ...
|
||||
result.entry = mPositionInfo.PriceOpen();
|
||||
|
||||
//
|
||||
// Take Profit ...
|
||||
result.tp = mPositionInfo.TakeProfit();
|
||||
|
||||
//
|
||||
// Stop Loss ...
|
||||
result.sl = mPositionInfo.StopLoss();
|
||||
|
||||
//
|
||||
// Time ...
|
||||
result.time = mPositionInfo.Time();
|
||||
|
||||
//
|
||||
// Volume ...
|
||||
result.volume = mPositionInfo.Volume();
|
||||
|
||||
//
|
||||
// Comment ...
|
||||
result.comment = mPositionInfo.Comment();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Get all Positions based on Position Type ...
|
||||
void GetAllPositionsByType(ENUM_POSITION_TYPE type, XSignal &result[])
|
||||
{
|
||||
//
|
||||
int existsTotal = CountByType(type);
|
||||
|
||||
//
|
||||
ArrayFree(result);
|
||||
ArrayResize(result, existsTotal);
|
||||
|
||||
//
|
||||
int filledIndex = 0;
|
||||
int total = PositionsTotal();
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
//
|
||||
if (!mPositionInfo.SelectByIndex(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.Magic() != mMagicNumber)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.Symbol() != mSymbol)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
if (mPositionInfo.PositionType() != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
result[filledIndex] = PositionToSignal(i);
|
||||
filledIndex++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// XSaherElm Account Info Class ...
|
||||
class XCAccountInfo
|
||||
{
|
||||
//
|
||||
// Public properties ...
|
||||
public:
|
||||
//
|
||||
// Constructro ...
|
||||
void XCAccountInfo()
|
||||
{
|
||||
//
|
||||
mAccountInfo = new CAccountInfo();
|
||||
|
||||
//
|
||||
mInitialBalance = mAccountInfo.Balance();
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XCAccountInfo()
|
||||
{
|
||||
//
|
||||
mInitialBalance = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// 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) ...
|
||||
ENUM_ACCOUNT_TRADE_MODE GetTradeMode()
|
||||
{
|
||||
return mAccountInfo.TradeMode();
|
||||
}
|
||||
|
||||
//
|
||||
// Get Account Balance ...
|
||||
double GetBalance()
|
||||
{
|
||||
return mAccountInfo.Balance();
|
||||
}
|
||||
|
||||
//
|
||||
// Get Initial Deposit Balance ...
|
||||
double GetInitialBalance()
|
||||
{
|
||||
return mInitialBalance;
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected properties ...
|
||||
protected:
|
||||
//
|
||||
// Private properties ...
|
||||
private:
|
||||
//
|
||||
// Initial Account Balance ...
|
||||
double mInitialBalance;
|
||||
|
||||
//
|
||||
// Account Info ...
|
||||
CAccountInfo mAccountInfo;
|
||||
};
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,177 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Http Library
|
||||
// ------------------------------------------
|
||||
// Name: XHttp
|
||||
// Description: provide http communication
|
||||
// abilities ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Model Definition ...
|
||||
//
|
||||
enum X_HTTP_METHOD
|
||||
{
|
||||
X_HTTP_GET,
|
||||
X_HTTP_POST
|
||||
};
|
||||
//
|
||||
// END Model Definition ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool OnInInitHttpLibrary()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void OnDeinitHttpLibrary()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Convert enum to String ...
|
||||
string ToString(X_HTTP_METHOD method)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
switch (method)
|
||||
{
|
||||
//
|
||||
case X_HTTP_GET:
|
||||
result = "GET";
|
||||
break;
|
||||
|
||||
//
|
||||
case X_HTTP_POST:
|
||||
result = "POST";
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Send Global Request ...
|
||||
int SendRequest(
|
||||
X_HTTP_METHOD method, // Httm Request Method
|
||||
const string url, // Server Address
|
||||
const string headers, // Headers providing
|
||||
const char &payload[], // the Data which needs to Send
|
||||
char &response[], // Response of request
|
||||
string responseHeaders, // Response Headers
|
||||
int timeout = 500 // Timeout for response default is 500
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
string strMethod = ToString(method);
|
||||
if (StringLen(strMethod) == 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = WebRequest(
|
||||
strMethod,
|
||||
url,
|
||||
headers,
|
||||
timeout,
|
||||
payload,
|
||||
response,
|
||||
responseHeaders
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Get Request ...
|
||||
int GetRequest(
|
||||
const string url, // Server Address
|
||||
const string headers, // Headers providing
|
||||
const char &payload[], // the Data which needs to Send
|
||||
char &response[], // Response of request
|
||||
string responseHeaders, // Response Headers
|
||||
int timeout = 500 // Timeout for response default is 500
|
||||
) {
|
||||
//
|
||||
int result = SendRequest(
|
||||
X_HTTP_GET,
|
||||
url,
|
||||
headers,
|
||||
payload,
|
||||
response,
|
||||
responseHeaders,
|
||||
timeout
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Post Request ...
|
||||
int PostRequest(
|
||||
const string url, // Server Address
|
||||
const string headers, // Headers providing
|
||||
const char &payload[], // the Data which needs to Send
|
||||
char &response[], // Response of request
|
||||
string responseHeaders, // Response Headers
|
||||
int timeout = 500 // Timeout for response default is 500
|
||||
) {
|
||||
//
|
||||
int result = SendRequest(
|
||||
X_HTTP_POST,
|
||||
url,
|
||||
headers,
|
||||
payload,
|
||||
response,
|
||||
responseHeaders,
|
||||
timeout
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,161 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Logger Library
|
||||
// ---------------------------------------
|
||||
// Name: XLogger
|
||||
// Description: provides Logging 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 "Logging";
|
||||
input bool enableLogging = true; // Enable Logging
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Including Models ...
|
||||
#include "x-saherelm.models.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
string logTag = "X-Logger"; // LogTag
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Logging a Message ...
|
||||
void LogMessage(string message)
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, " > ", message);
|
||||
}
|
||||
void LogMessage(string tag, string message)
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(tag, " > ", message);
|
||||
}
|
||||
|
||||
//
|
||||
// Logging an Array ...
|
||||
void LogArray(int &array[])
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, ">");
|
||||
ArrayPrint(array);
|
||||
}
|
||||
void LogArray(double &array[])
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, ">");
|
||||
ArrayPrint(array);
|
||||
}
|
||||
void LogArray(string &array[])
|
||||
{
|
||||
//
|
||||
if (!enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Print(logTag, ">");
|
||||
ArrayPrint(array);
|
||||
}
|
||||
|
||||
//
|
||||
// Convert a Signal to String Message ...
|
||||
string SignalToString(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Convert an Executed Signal to String Message ...
|
||||
string ExecutedSignalToString(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal Executed provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Logging Signal ...
|
||||
void LogSignal(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string message = SignalToString(signal);
|
||||
|
||||
//
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
// Log Signal Execution ...
|
||||
void LogExecutedSignal(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string message = ExecutedSignalToString(signal);
|
||||
|
||||
//
|
||||
LogMessage(message);
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,226 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Model Definitions ...
|
||||
//
|
||||
//
|
||||
// OHCL Candel Model ...
|
||||
enum ENUM_X_PRICE
|
||||
{
|
||||
X_PRICE_HIGH,
|
||||
X_PRICE_OPEN,
|
||||
X_PRICE_CLOSE,
|
||||
X_PRICE_LOW
|
||||
};
|
||||
|
||||
struct XOHCL
|
||||
{
|
||||
double high;
|
||||
double open;
|
||||
double close;
|
||||
double low;
|
||||
};
|
||||
|
||||
//
|
||||
// Swing Types Enum ...
|
||||
enum ENUM_X_SWING_TYPE
|
||||
{
|
||||
X_NO_SWING = 0,
|
||||
X_SWING_HIGH = 1,
|
||||
X_SWING_LOW = -1,
|
||||
};
|
||||
|
||||
//
|
||||
// Signal Types ...
|
||||
enum ENUM_X_SIGNAL_TYPE
|
||||
{
|
||||
X_SIGNAL_LONG,
|
||||
X_SIGNAL_SHORT,
|
||||
X_SIGNAL_UNKNOWN,
|
||||
};
|
||||
|
||||
//
|
||||
// Signal Structure ...
|
||||
struct XSignal
|
||||
{
|
||||
//
|
||||
// Identifier ...
|
||||
ulong id;
|
||||
|
||||
//
|
||||
// Which Symbol used for Signal ...
|
||||
string symbol;
|
||||
|
||||
//
|
||||
// Which Type of operations ...
|
||||
ENUM_X_SIGNAL_TYPE type;
|
||||
|
||||
//
|
||||
// Magic Number ...
|
||||
ulong magicNumber;
|
||||
|
||||
//
|
||||
// Ticket ...
|
||||
ulong ticket;
|
||||
|
||||
//
|
||||
// Entry/Open Price ...
|
||||
double entry;
|
||||
|
||||
//
|
||||
// TP ...
|
||||
double tp;
|
||||
|
||||
//
|
||||
// SL ...
|
||||
double sl;
|
||||
|
||||
//
|
||||
// Time of Operation ...
|
||||
datetime time;
|
||||
|
||||
//
|
||||
// Volume ...
|
||||
double volume;
|
||||
|
||||
//
|
||||
// Comment ...
|
||||
string comment;
|
||||
};
|
||||
|
||||
//
|
||||
// TP/SL Struct ...
|
||||
struct XTPSL
|
||||
{
|
||||
ENUM_X_SIGNAL_TYPE type;
|
||||
double tp;
|
||||
double sl;
|
||||
double entry;
|
||||
double r2r;
|
||||
};
|
||||
|
||||
//
|
||||
// XTM Indicator States ...
|
||||
enum ENUM_X_XTM_STATES
|
||||
{
|
||||
X_XTM_BULLISH = 1,
|
||||
X_XTM_BEARISH = -1,
|
||||
X_XTM_NEUTURAL = 0,
|
||||
};
|
||||
|
||||
//
|
||||
// XTM Indicator Buffer Lines ...
|
||||
enum ENUM_X_XTM_BUFFER_LINES
|
||||
{
|
||||
X_XTM_MA_LINE = 0,
|
||||
X_XTM_MC_COLOR_LINE = 1,
|
||||
X_XTM_STATE_LINE = 2,
|
||||
};
|
||||
|
||||
//
|
||||
// XTD Oscillator States ...
|
||||
enum ENUM_X_XTD_STATES
|
||||
{
|
||||
X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2,
|
||||
X_XTD_BULLISH_OVER_BEARISH = 1,
|
||||
X_XTD_NEUTURAL = 0,
|
||||
X_XTD_BULLISH_UNDER_BEARISH = -1,
|
||||
X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2
|
||||
};
|
||||
|
||||
//
|
||||
// XTD Oscillator Buffer Lines ...
|
||||
enum ENUM_X_XTD_BUFFER_LINES
|
||||
{
|
||||
X_XTD_BULLISH_POWER_LINE = 0,
|
||||
X_XTD_BEARISH_POWER_LINE = 1,
|
||||
X_XTD_TREND_STATE_LINE = 2,
|
||||
};
|
||||
|
||||
//
|
||||
// XTPD States Enum ...
|
||||
enum ENUM_X_XTPD_STATES
|
||||
{
|
||||
X_XTPD_BULLISH_CROSSED_OVER_BEARISH = 2,
|
||||
X_XTPD_BULLISH_OVER_BEARISH = 1,
|
||||
X_XTPD_NEUTURAL = 0,
|
||||
X_XTPD_BULLISH_UNDER_BEARISH = -1,
|
||||
X_XTPD_BULLISH_CROSSED_UNDER_BEARISH = -2
|
||||
};
|
||||
|
||||
//
|
||||
// XTPD Buffer Lines Enum ...
|
||||
enum ENUM_X_XTPD_BUFFER_LINES
|
||||
{
|
||||
X_XTPD_BULLISH_POWER_LINE = 0,
|
||||
X_XTPD_BEARISH_POWER_LINE = 1,
|
||||
X_XTPD_STATE_LINE = 2,
|
||||
};
|
||||
|
||||
//
|
||||
// XCHMA Oscillator Cycles State Presentation ...
|
||||
enum ENUM_XCHMA_CYCLE_STATE
|
||||
{
|
||||
X_XCHMA_FAST_CROSSED_OVER_SLOW = 2,
|
||||
X_XCHMA_FAST_OVER_SLOW = 1,
|
||||
X_XCHMA_NEUTURAL = 0,
|
||||
X_XCHMA_FAST_UNDER_SLOW = -1,
|
||||
X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2,
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// XCHMA Oscillator Buffer Lines ...
|
||||
enum ENUM_X_XCHMA_BUFFER_LINES
|
||||
{
|
||||
X_XCHMA_LC_FAST_LINE = 0,
|
||||
X_XCHMA_LC_SLOW_LINE = 1,
|
||||
X_XCHMA_LC_STATE_LINE = 6,
|
||||
X_XCHMA_MC_FAST_LINE = 2,
|
||||
X_XCHMA_MC_SLOW_LINE = 3,
|
||||
X_XCHMA_MC_STATE_LINE = 7,
|
||||
X_XCHMA_SC_FAST_LINE = 4,
|
||||
X_XCHMA_SC_SLOW_LINE = 5,
|
||||
X_XCHMA_SC_STATE_LINE = 8,
|
||||
X_XCHMA_HOT_STATE_LINE = 9,
|
||||
};
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,258 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 NN Class Library
|
||||
// ----------------------------------------
|
||||
// Name: XNNClass
|
||||
// Description: provides all classes for implementing
|
||||
// Neural Network ...
|
||||
//
|
||||
//
|
||||
// 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 Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
class XCNNBase
|
||||
{
|
||||
//
|
||||
// Public Definitions ...
|
||||
public:
|
||||
//
|
||||
// Constructor ...
|
||||
void XCNNBase(
|
||||
int nodes = 10, // Number of Input Nodes
|
||||
double starterWeight = 0.5, // start weight for each input
|
||||
double coEfficient = 0.1, // COEfficient Multiplier
|
||||
double upperRange = 1, // Upper Normal Range Value
|
||||
double lowerRange = -1, // Lower Normal Range Value
|
||||
double learningRates = 0.1 // Back Propagation Learning Rate
|
||||
) {
|
||||
//
|
||||
mNodes = nodes;
|
||||
mUpperRange = upperRange;
|
||||
mLowerRange = lowerRange;
|
||||
mCoEfficient = coEfficient;
|
||||
mLearningRates = learningRates;
|
||||
mStarterWeight = starterWeight;
|
||||
|
||||
//
|
||||
ReConstructWeights();
|
||||
}
|
||||
|
||||
//
|
||||
// Deconstructor ...
|
||||
void ~XCNNBase() {}
|
||||
|
||||
//
|
||||
// Protected Definitions ...
|
||||
void NormalizeInputs(double &inputs[], double &result[])
|
||||
{
|
||||
//
|
||||
ArrayFree(result);
|
||||
ArrayResize(result, 1);
|
||||
|
||||
//
|
||||
// Validate inputs ...
|
||||
if (ArraySize(inputs) != mNodes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Result ...
|
||||
ArrayResize(result, mNodes);
|
||||
|
||||
//
|
||||
// Calculating min and max range value ...
|
||||
double minRangeValue = inputs[ArrayMinimum(inputs)];
|
||||
double maxRangeValue = inputs[ArrayMaximum(inputs)];
|
||||
|
||||
//
|
||||
// Loop through Inputs nd Normalize them ...
|
||||
for (int i = 0; i < mNodes; i++)
|
||||
{
|
||||
//
|
||||
double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange;
|
||||
result[i] = normalValue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Hyperbolic Tangent Activation Function ...
|
||||
double TanHActivationFunction(double weightedInputs)
|
||||
{
|
||||
//
|
||||
double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs));
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Weighted Inputs ...
|
||||
double CalculateWeightedInputs(
|
||||
double &inputs[],
|
||||
bool applyCOEfficient = true)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (ArraySize(inputs) != mNodes)
|
||||
{
|
||||
//
|
||||
result = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < mNodes; i++)
|
||||
{
|
||||
result += inputs[i] * mWeights[i];
|
||||
}
|
||||
|
||||
//
|
||||
// Multiply if required ...
|
||||
if (applyCOEfficient)
|
||||
{
|
||||
result *= mCoEfficient;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Hidden Layers ...
|
||||
virtual double CalculateHiddenLayer(double &inputs[])
|
||||
{
|
||||
//
|
||||
// this is Default Activation Function which used ...
|
||||
// you can override this by writing your own ...
|
||||
double totalWeightedInputs = CalculateWeightedInputs(inputs);
|
||||
double result = TanHActivationFunction(totalWeightedInputs);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Output Layers ...
|
||||
double CalculateOutputLayer(double &inputs[])
|
||||
{
|
||||
//
|
||||
double result = -1;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (ArraySize(inputs) != mNodes) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double normalizedInputs[];
|
||||
NormalizeInputs(inputs, normalizedInputs);
|
||||
if (ArraySize(normalizedInputs) != mNodes) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs);
|
||||
|
||||
//
|
||||
result = 1 * hiddenLayerResult;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Basck Propaggation Learning ...
|
||||
void BackPropagation(
|
||||
double &inputs[],
|
||||
double &outputs,
|
||||
double targetOutput
|
||||
) {
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (ArraySize(inputs) != mNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double normalizedInputs[];
|
||||
NormalizeInputs(inputs, normalizedInputs);
|
||||
if (ArraySize(normalizedInputs) != mNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double error = targetOutput - outputs;
|
||||
double derivative = 1 - MathPow(outputs, 2);
|
||||
|
||||
//
|
||||
for (int i = 0; i < mNodes; i++) {
|
||||
//
|
||||
double gradient = error * derivative * inputs[i];
|
||||
mWeights[i] = mLearningRates * gradient;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
//
|
||||
// Private Definitions ...
|
||||
private:
|
||||
//
|
||||
// Number of Input Nodes ...
|
||||
int mNodes;
|
||||
|
||||
//
|
||||
// Specify Upper range of Normal Values ...
|
||||
double mUpperRange;
|
||||
|
||||
//
|
||||
// Specify Lower range of Normal Values ...
|
||||
double mLowerRange;
|
||||
|
||||
//
|
||||
// Starter Weight for each input node ...
|
||||
double mStarterWeight;
|
||||
|
||||
//
|
||||
// double Input Node Weights ...
|
||||
double mWeights[];
|
||||
|
||||
//
|
||||
// CoEfficient is a multiplyer for weighted inputs ...
|
||||
double mCoEfficient;
|
||||
|
||||
//
|
||||
// Back Propagation Learning Rates ...
|
||||
double mLearningRates;
|
||||
|
||||
//
|
||||
// ReConstruct Weights ...
|
||||
void ReConstructWeights() {
|
||||
//
|
||||
ArrayFree(mWeights);
|
||||
ArrayResize(mWeights, mNodes);
|
||||
|
||||
//
|
||||
for (int i = 0; i< mNodes; i++) {
|
||||
mWeights[i] = mStarterWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
@@ -0,0 +1,947 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 RSI Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XRSISignalProvider
|
||||
// Description: RSI based 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
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "XRSI Provider";
|
||||
|
||||
//
|
||||
input group "XRSI Common";
|
||||
input bool enableRSIProvider = true; // Enable Provider
|
||||
input bool rsiEnableAlerts = true; // Enable Events Alert
|
||||
|
||||
//
|
||||
input group "XRSI Indicator";
|
||||
input int rsiPeriod = 14; // RSI Period
|
||||
input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To
|
||||
|
||||
//
|
||||
input group "XRSI Trader";
|
||||
input int rsiMagicNumber = 16940561; // RSI Trader MagicNumber
|
||||
input int rsiSlippage = 10; // RSI Trader Slippage
|
||||
input double rsiLongEntryLevel = 30; // RSI Long Entry Level
|
||||
input double rsiLongExitLevel = 60; // RSI Long Exit Level
|
||||
input double rsiShortEntryLevel = 70; // RSI Short Entry Level
|
||||
input double rsiShortExitLevel = 40; // RSI Short Exit Level
|
||||
|
||||
//
|
||||
input group "XRSI Neural Networks";
|
||||
input bool rsiUseNeuralNetworks = true; // Enable Neural Networks
|
||||
input bool rsiNNUseContinuesLearning = true; // Enable Continues Learning on Neural Networks
|
||||
input int rsiNNNumberOfNodes = 10; // Number Of Input Nodes
|
||||
input double rsiNNLongTargetOutput = 0.3; // BackPropagation Target Output for Long Trades
|
||||
input double rsiNNShortTargetOutput = -0.3; // BackPropagation Target Output for Short Trades
|
||||
|
||||
//
|
||||
input group "XRSI Trade Management";
|
||||
input bool rsiAllowLongTrades = true; // Allow Long Trades
|
||||
input bool rsiAllowShortTrades = true; // Allow Short Trades
|
||||
input bool rsiUseGridTrades = true; // Enable Grid Trades
|
||||
input double rsiGridVolumeMultiplier = 2; // Grid Volume Multiplier
|
||||
input double rsiGridDistancePips = 10; // Grid Position Distance in Pips
|
||||
|
||||
//
|
||||
input group "XRSI Risk Management";
|
||||
input bool rsiUseDynamicVolume = true; // Enable Dynamic Volume
|
||||
input double rsiStaticVolume = 0.01; // Static Volume
|
||||
// input double rsiBalanceIncreasedFactor = 0.1; // RSI Balance Increase Factor
|
||||
// input double rsiVolumeIncreasedFactor = 0.000001; // RSI Volume Increase Factor
|
||||
// //
|
||||
// // END Inputs ...
|
||||
// //
|
||||
input double rsiBalanceIncreased = 500; // RSI Balance Increase
|
||||
input double rsiVolumeIncreased = 0.01; // RSI Volume Increase
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Neural Networks Library ...
|
||||
#include "x-saherelm.nn.lib.mq5";
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
int rsiHandler = INVALID_HANDLE;
|
||||
double rsiBuffer[];
|
||||
|
||||
//
|
||||
XCTrade *rsiTrader;
|
||||
XCAccountInfo rsiAccountInfo;
|
||||
|
||||
//
|
||||
XCNNBase *rsiNN;
|
||||
|
||||
//
|
||||
double rsiGridLongPrice = 0;
|
||||
double rsiGridLongVolume = 0;
|
||||
|
||||
//
|
||||
double rsiGridShortPrice = 0;
|
||||
double rsiGridShortVolume = 0;
|
||||
|
||||
//
|
||||
// holds Neural Networks Output Value ...
|
||||
double rsiNNOutput;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool OnInInitXRSISignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Error Message ...
|
||||
string message = "";
|
||||
|
||||
//
|
||||
// Check RSI Period ...
|
||||
if (rsiPeriod < 5)
|
||||
{
|
||||
//
|
||||
message = "invalid rsi period ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check RSI Over Baught and Over Sold Levels ...
|
||||
if (
|
||||
rsiLongExitLevel <= 0 ||
|
||||
rsiLongEntryLevel <= 0 ||
|
||||
rsiShortExitLevel <= 0 ||
|
||||
rsiShortEntryLevel <= 0 ||
|
||||
rsiLongEntryLevel >= rsiLongExitLevel ||
|
||||
rsiLongEntryLevel >= rsiShortEntryLevel ||
|
||||
rsiShortEntryLevel <= rsiShortExitLevel ||
|
||||
rsiShortEntryLevel <= rsiLongEntryLevel)
|
||||
{
|
||||
//
|
||||
message = "invalid over baught / over seld level ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Risk Management ...
|
||||
if (rsiUseDynamicVolume)
|
||||
{
|
||||
//
|
||||
// if (rsiBalanceIncreasedFactor <= 0 || rsiVolumeIncreasedFactor <= 0)
|
||||
if (rsiBalanceIncreased <= 0 || rsiVolumeIncreased <= 0)
|
||||
{
|
||||
//
|
||||
message = "invalid volume increased factors ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
if (rsiStaticVolume > maxAvailableVolume || rsiStaticVolume < minAvailableVolume)
|
||||
{
|
||||
//
|
||||
message = "invalid static volume ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Neural Networks Inputs ...
|
||||
if (rsiUseNeuralNetworks)
|
||||
{
|
||||
//
|
||||
// Number Of Nodes ...
|
||||
if (rsiNNNumberOfNodes < 3)
|
||||
{
|
||||
//
|
||||
message = "invalid neurak networks inputs ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// if there is no error in nn inputs, make an instance of
|
||||
// Neural Networks Clsss ...
|
||||
rsiNN = new XCNNBase(
|
||||
rsiNNNumberOfNodes);
|
||||
}
|
||||
|
||||
//
|
||||
// Preparing RSI Handler ...
|
||||
rsiHandler = iRSI(_Symbol, _Period, rsiPeriod, rsiAppliedTo);
|
||||
if (rsiHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
message = "failed to initialize rsi indicator handler ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
rsiTrader = new XCTrade(
|
||||
_Symbol,
|
||||
rsiSlippage,
|
||||
rsiMagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
message = "Initializion of (" + "XRSI Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void OnDeinitXRSISignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "De Initializion of (" + "XRSI Provider" + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void HandleXSignalProviderTick()
|
||||
{
|
||||
//
|
||||
// Reading RSI Values ...
|
||||
ArraySetAsSeries(rsiBuffer, true);
|
||||
|
||||
//
|
||||
// Copy RSI Buffers based on NN Conditions ...
|
||||
if (rsiUseNeuralNetworks)
|
||||
{
|
||||
//
|
||||
CopyBuffer(rsiHandler, 0, 0, rsiNNNumberOfNodes, rsiBuffer);
|
||||
|
||||
//
|
||||
// Calculate Neural Network Output Layer based on Inputs ...
|
||||
// since here there is no any external inputs except rsiBuffer
|
||||
// we passed it directly to our Neural Networks as Inputs ...
|
||||
rsiNNOutput = rsiNN.CalculateOutputLayer(rsiBuffer);
|
||||
|
||||
//
|
||||
// Check Continues Learning is Enabled ...
|
||||
if (rsiNNUseContinuesLearning)
|
||||
{
|
||||
//
|
||||
// Handle Back Propagation (Continues Learning) ...
|
||||
double targetOutput = 0;
|
||||
if (rsiBuffer[1] >= 50)
|
||||
{
|
||||
targetOutput = rsiNNLongTargetOutput;
|
||||
}
|
||||
else if (rsiBuffer[1] < 50)
|
||||
{
|
||||
targetOutput = rsiNNShortTargetOutput;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Calculate Weights ...
|
||||
if (targetOutput != 0)
|
||||
{
|
||||
rsiNN.BackPropagation(rsiBuffer, rsiNNOutput, targetOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyBuffer(rsiHandler, 0, 0, 5, rsiBuffer);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
HandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
HandleCloseTrades();
|
||||
|
||||
//
|
||||
// Draw Signals ...
|
||||
// bool hasPrimaryLongSignal = HasPrimaryLongSignal();
|
||||
// bool hasPrimaryShortSignal = HasPrimaryShortSignal();
|
||||
// bool hasPrimarySignal = hasPrimaryLongSignal || hasPrimaryShortSignal;
|
||||
// if (hasPrimarySignal)
|
||||
// {
|
||||
// //
|
||||
// ENUM_X_SIGNAL_TYPE signalType = hasPrimaryLongSignal ? X_SIGNAL_LONG : X_SIGNAL_SHORT;
|
||||
// double signalPrice = signalType == X_SIGNAL_LONG ? GetAsk() : GetBid();
|
||||
// string signalName = logTag + "_" + EnumToString(signalType) + "_" + DoubleToString(signalPrice);
|
||||
// color signalColor = signalType == X_SIGNAL_LONG ? clrAqua : clrYellow;
|
||||
// datetime signalTime1 = iTime(_Symbol, _Period, 1);
|
||||
// datetime signalTime2 = iTime(_Symbol, _Period, 0);
|
||||
|
||||
// //
|
||||
// DrawTrendLine(
|
||||
// 0, // Chart Id ...
|
||||
// signalName, // Object Name ...
|
||||
// 0, // SubWindow ...
|
||||
// signalTime1, // Time 1 ...
|
||||
// signalPrice, // Price 1 ...
|
||||
// signalTime2, // Time 2 ...
|
||||
// signalPrice, // Price 2 ...
|
||||
// signalColor, // Color ...
|
||||
// STYLE_SOLID,
|
||||
// 5
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Primary Signals ...
|
||||
bool HasPrimaryLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
result = rsiBuffer[1] >= rsiLongEntryLevel && rsiBuffer[2] < rsiLongEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Primary Signals ...
|
||||
bool HasPrimaryShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
result = rsiBuffer[1] <= rsiShortEntryLevel && rsiBuffer[2] > rsiShortEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Grid Signals ...
|
||||
bool HasGridLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
result = rsiBuffer[1] >= rsiLongEntryLevel && rsiBuffer[2] < rsiLongEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Grid Signals ...
|
||||
bool HasGridShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
result = rsiBuffer[1] <= rsiShortEntryLevel && rsiBuffer[2] > rsiShortEntryLevel;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Long Trades ...
|
||||
bool CanCloseLongTrades()
|
||||
{
|
||||
//
|
||||
bool result = rsiBuffer[1] > rsiLongExitLevel && rsiBuffer[2] < rsiLongExitLevel;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Short Trades ...
|
||||
bool CanCloseShortTrades()
|
||||
{
|
||||
//
|
||||
bool result = rsiBuffer[1] < rsiShortExitLevel && rsiBuffer[2] > rsiShortExitLevel;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Primary Trades...
|
||||
bool HandlePrimaryLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Check Conditions of Neural Networks if it's enabled ...
|
||||
bool canForward = !rsiUseNeuralNetworks ? true : rsiNNOutput > 0;
|
||||
|
||||
//
|
||||
if (HasPrimaryLongSignal() && rsiTrader.CountLongs() == 0 && canForward)
|
||||
{
|
||||
//
|
||||
double entry = GetAsk();
|
||||
double volume = CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary XRSI Long";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowLongTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Primary Trades...
|
||||
bool HandlePrimaryShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// Check Conditions of Neural Networks if it's enabled ...
|
||||
bool canForward = !rsiUseNeuralNetworks ? true : rsiNNOutput < 0;
|
||||
|
||||
//
|
||||
if (HasPrimaryShortSignal() && rsiTrader.CountShorts() == 0 && canForward)
|
||||
{
|
||||
//
|
||||
double entry = GetBid();
|
||||
double volume = CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary XRSI Short";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowShortTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Grid Trades...
|
||||
bool HandleGridLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
bool canDoGridTrade = ask <= rsiGridLongPrice;
|
||||
if (HasGridLongSignal() && rsiTrader.CountLongs() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = ask;
|
||||
double volume = rsiGridLongVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid XRSI Long";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowLongTrades && rsiUseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Grid Trades...
|
||||
bool HandleGridShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double bid = GetBid();
|
||||
bool canDoGridTrade = bid >= rsiGridShortPrice;
|
||||
if (HasGridShortSignal() && rsiTrader.CountShorts() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = bid;
|
||||
double volume = rsiGridShortVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = rsiMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid XRSI Short";
|
||||
|
||||
//
|
||||
if (enableRSIProvider && rsiAllowShortTrades && rsiUseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = rsiTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void HandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
XSignal primaryLongSignal = {};
|
||||
bool isPrimaryLongSignalExecuted = HandlePrimaryLong(primaryLongSignal);
|
||||
if (isPrimaryLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
CalculateGridLongConditions(primaryLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
XSignal primaryShortSignal = {};
|
||||
bool isPrimaryShortSignalExecuted = HandlePrimaryShort(primaryShortSignal);
|
||||
if (isPrimaryShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
CalculateGridShortConditions(primaryShortSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Check Grid Trades ...
|
||||
if (rsiUseGridTrades)
|
||||
{
|
||||
//
|
||||
// Grid Long Trade ...
|
||||
XSignal gridLongSignal = {};
|
||||
bool isGridLongSignalExecuted = HandleGridLong(gridLongSignal);
|
||||
if (isGridLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
CalculateGridLongConditions(gridLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Grid Short Trade ...
|
||||
XSignal gridShortSignal = {};
|
||||
bool isGridShortSignalExecuted = HandleGridShort(gridShortSignal);
|
||||
if (isGridShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
CalculateGridShortConditions(gridShortSignal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void HandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (rsiTrader.CountLongs() > 0 && CanCloseLongTrades())
|
||||
{
|
||||
//
|
||||
rsiTrader.CloseLongPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Long Conditions ...
|
||||
rsiGridLongPrice = 0;
|
||||
rsiGridLongVolume = 0;
|
||||
|
||||
//
|
||||
string message = "XRSI Closing Long Trades ...";
|
||||
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (rsiTrader.CountShorts() > 0 && CanCloseShortTrades())
|
||||
{
|
||||
//
|
||||
rsiTrader.CloseShortPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Short Conditions ...
|
||||
rsiGridShortPrice = 0;
|
||||
rsiGridShortVolume = 0;
|
||||
|
||||
//
|
||||
string message = "XRSI Closing Short Trades ...";
|
||||
|
||||
//
|
||||
if (rsiEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double CalculateVolume()
|
||||
{
|
||||
//
|
||||
double result = rsiStaticVolume;
|
||||
if (!rsiUseDynamicVolume)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double accountBalance = rsiAccountInfo.GetBalance();
|
||||
// double accountInitialBalance = rsiAccountInfo.GetInitialBalance();
|
||||
// double balanceIncreased = accountInitialBalance * rsiBalanceIncreasedFactor;
|
||||
// double volumeIncreased = accountInitialBalance * rsiVolumeIncreasedFactor;
|
||||
double balanceIncreased = rsiBalanceIncreased;
|
||||
double volumeIncreased = rsiVolumeIncreased;
|
||||
|
||||
//
|
||||
result = (volumeIncreased * accountBalance) / balanceIncreased;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeDouble(result, 2);
|
||||
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
// Validate Result ...
|
||||
if (result > maxAvailableVolume)
|
||||
{
|
||||
result = maxAvailableVolume;
|
||||
}
|
||||
else if (result < minAvailableVolume)
|
||||
{
|
||||
result = minAvailableVolume;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Long Trades Price and Volume ...
|
||||
void CalculateGridLongConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!rsiUseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridLongPrice and GridLongVolume ...
|
||||
rsiGridLongVolume = NormalizeDouble(signal.volume * rsiGridVolumeMultiplier, 2);
|
||||
rsiGridLongPrice = NormalizeDouble(signal.entry - (rsiGridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Short Trades Price and Volume ...
|
||||
void CalculateGridShortConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!rsiUseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridShortPrice and GridShortVolume ...
|
||||
rsiGridShortVolume = NormalizeDouble(signal.volume * rsiGridVolumeMultiplier, 2);
|
||||
rsiGridShortPrice = NormalizeDouble(signal.entry + (rsiGridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Determine based on current account state
|
||||
bool CanDoTrade()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,758 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 _XPROVIDER_ Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: _XPROVIDER_SignalProvider
|
||||
// Description: _XPROVIDER_ based 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
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "_XPROVIDER_ Provider";
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Common";
|
||||
input bool enable_XPROVIDER_Provider = true; // Enable Provider
|
||||
input bool _xPROVIDER_EnableAlerts = true; // Enable Events Alert
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Indicator";
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Trader";
|
||||
input int _xPROVIDER_MagicNumber = 16940562; // Trader MagicNumber
|
||||
input int _xPROVIDER_Slippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Trade Management";
|
||||
input bool _xPROVIDER_AllowLongTrades = true; // Allow Long Trades
|
||||
input bool _xPROVIDER_AllowShortTrades = true; // Allow Short Trades
|
||||
input bool _xPROVIDER_UseGridTrades = true; // Enable Grid Trades
|
||||
input double _xPROVIDER_GridVolumeMultiplier = 2; // Grid Volume Multiplier
|
||||
input double _xPROVIDER_GridDistancePips = 10; // Grid Position Distance in Pips
|
||||
|
||||
//
|
||||
input group "_XPROVIDER_ Risk Management";
|
||||
input bool _xPROVIDER_UseDynamicVolume = true; // Enable Dynamic Volume
|
||||
input double _xPROVIDER_StaticVolume = 0.01; // Static Volume
|
||||
input double _xPROVIDER_BalanceIncreased = 500; // Balance Increase
|
||||
input double _xPROVIDER_VolumeIncreased = 0.01; // Volume Increase
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
XCTrade *_xPROVIDER_Trader;
|
||||
XCAccountInfo _xPROVIDER_AccountInfo;
|
||||
|
||||
//
|
||||
double _xPROVIDER_GridLongPrice = 0;
|
||||
double _xPROVIDER_GridLongVolume = 0;
|
||||
|
||||
//
|
||||
double _xPROVIDER_GridShortPrice = 0;
|
||||
double _xPROVIDER_GridShortVolume = 0;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool OnInInit_XPROVIDER_SignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Error Message ...
|
||||
string message = "";
|
||||
|
||||
//
|
||||
// Check Risk Management ...
|
||||
if (_xPROVIDER_UseDynamicVolume)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_BalanceIncreased <= 0 || _xPROVIDER_VolumeIncreased <= 0)
|
||||
{
|
||||
//
|
||||
message = "invalid volume increased factors ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
if (_xPROVIDER_StaticVolume > maxAvailableVolume || _xPROVIDER_StaticVolume < minAvailableVolume)
|
||||
{
|
||||
//
|
||||
message = "invalid static volume ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
_xPROVIDER_Trader = new XCTrade(
|
||||
_Symbol,
|
||||
_xPROVIDER_Slippage,
|
||||
_xPROVIDER_MagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
message = "Initializion of (" + "_XPROVIDER_ Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void OnDeinit_XPROVIDER_SignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "De Initializion of (" + "_XPROVIDER_ Provider" + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void Handle_XPROVIDER_SignalProviderTick()
|
||||
{
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
_XPROVIDER_HandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
_XPROVIDER_HandleCloseTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Primary Signals ...
|
||||
bool _XPROVIDER_HasPrimaryLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Primary Signals ...
|
||||
bool _XPROVIDER_HasPrimaryShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Grid Signals ...
|
||||
bool _XPROVIDER_HasGridLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Grid Signals ...
|
||||
bool _XPROVIDER_HasGridShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Long Trades ...
|
||||
bool _XPROVIDER_CanCloseLongTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Short Trades ...
|
||||
bool _XPROVIDER_CanCloseShortTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Primary Trades...
|
||||
bool _XPROVIDER_HandlePrimaryLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
if (_XPROVIDER_HasPrimaryLongSignal() && _xPROVIDER_Trader.CountLongs() == 0)
|
||||
{
|
||||
//
|
||||
double entry = GetAsk();
|
||||
double volume = _XPROVIDER_CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary _XPROVIDER_ Long";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowLongTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Primary Trades...
|
||||
bool _XPROVIDER_HandlePrimaryShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
if (_XPROVIDER_HasPrimaryShortSignal() && _xPROVIDER_Trader.CountShorts() == 0)
|
||||
{
|
||||
//
|
||||
double entry = GetBid();
|
||||
double volume = _XPROVIDER_CalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary _XPROVIDER_ Short";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowShortTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Grid Trades...
|
||||
bool _XPROVIDER_HandleGridLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double ask = GetAsk();
|
||||
bool canDoGridTrade = ask <= _xPROVIDER_GridLongPrice;
|
||||
if (_XPROVIDER_HasGridLongSignal() && _xPROVIDER_Trader.CountLongs() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = ask;
|
||||
double volume = _xPROVIDER_GridLongVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid _XPROVIDER_ Long";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowLongTrades && _xPROVIDER_UseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Grid Trades...
|
||||
bool _XPROVIDER_HandleGridShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
double bid = GetBid();
|
||||
bool canDoGridTrade = bid >= _xPROVIDER_GridShortPrice;
|
||||
if (_XPROVIDER_HasGridShortSignal() && _xPROVIDER_Trader.CountShorts() > 0 && canDoGridTrade)
|
||||
{
|
||||
//
|
||||
double entry = bid;
|
||||
double volume = _xPROVIDER_GridShortVolume;
|
||||
|
||||
//
|
||||
double canDoTrade = _XPROVIDER_CanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = _xPROVIDER_MagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Grid _XPROVIDER_ Short";
|
||||
|
||||
//
|
||||
if (enable_XPROVIDER_Provider && _xPROVIDER_AllowShortTrades && _xPROVIDER_UseGridTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = _xPROVIDER_Trader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void _XPROVIDER_HandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
XSignal primaryLongSignal = {};
|
||||
bool isPrimaryLongSignalExecuted = _XPROVIDER_HandlePrimaryLong(primaryLongSignal);
|
||||
if (isPrimaryLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
_XPROVIDER_CalculateGridLongConditions(primaryLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
XSignal primaryShortSignal = {};
|
||||
bool isPrimaryShortSignalExecuted = _XPROVIDER_HandlePrimaryShort(primaryShortSignal);
|
||||
if (isPrimaryShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
_XPROVIDER_CalculateGridShortConditions(primaryShortSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Check Grid Trades ...
|
||||
if (_xPROVIDER_UseGridTrades)
|
||||
{
|
||||
//
|
||||
// Grid Long Trade ...
|
||||
XSignal gridLongSignal = {};
|
||||
bool isGridLongSignalExecuted = _XPROVIDER_HandleGridLong(gridLongSignal);
|
||||
if (isGridLongSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Long Conditions ...
|
||||
_XPROVIDER_CalculateGridLongConditions(gridLongSignal);
|
||||
}
|
||||
|
||||
//
|
||||
// Grid Short Trade ...
|
||||
XSignal gridShortSignal = {};
|
||||
bool isGridShortSignalExecuted = _XPROVIDER_HandleGridShort(gridShortSignal);
|
||||
if (isGridShortSignalExecuted)
|
||||
{
|
||||
//
|
||||
// Calculate Grid Short Conditions ...
|
||||
_XPROVIDER_CalculateGridShortConditions(gridShortSignal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void _XPROVIDER_HandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (_xPROVIDER_Trader.CountLongs() > 0 && _XPROVIDER_CanCloseLongTrades())
|
||||
{
|
||||
//
|
||||
_xPROVIDER_Trader.CloseLongPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Long Conditions ...
|
||||
_xPROVIDER_GridLongPrice = 0;
|
||||
_xPROVIDER_GridLongVolume = 0;
|
||||
|
||||
//
|
||||
string message = "_XPROVIDER_ Closing Long Trades ...";
|
||||
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (_xPROVIDER_Trader.CountShorts() > 0 && _XPROVIDER_CanCloseShortTrades())
|
||||
{
|
||||
//
|
||||
_xPROVIDER_Trader.CloseShortPositions();
|
||||
|
||||
//
|
||||
// Reset Grid Short Conditions ...
|
||||
_xPROVIDER_GridShortPrice = 0;
|
||||
_xPROVIDER_GridShortVolume = 0;
|
||||
|
||||
//
|
||||
string message = "_XPROVIDER_ Closing Short Trades ...";
|
||||
|
||||
//
|
||||
if (_xPROVIDER_EnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double _XPROVIDER_CalculateVolume()
|
||||
{
|
||||
//
|
||||
double result = _xPROVIDER_StaticVolume;
|
||||
if (!_xPROVIDER_UseDynamicVolume)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double accountBalance = _xPROVIDER_AccountInfo.GetBalance();
|
||||
double balanceIncreased = _xPROVIDER_BalanceIncreased;
|
||||
double volumeIncreased = _xPROVIDER_VolumeIncreased;
|
||||
|
||||
//
|
||||
result = (volumeIncreased * accountBalance) / balanceIncreased;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeDouble(result, 2);
|
||||
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
// Validate Result ...
|
||||
if (result > maxAvailableVolume)
|
||||
{
|
||||
result = maxAvailableVolume;
|
||||
}
|
||||
else if (result < minAvailableVolume)
|
||||
{
|
||||
result = minAvailableVolume;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Long Trades Price and Volume ...
|
||||
void _XPROVIDER_CalculateGridLongConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!_xPROVIDER_UseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridLongPrice and GridLongVolume ...
|
||||
_xPROVIDER_GridLongVolume = NormalizeDouble(signal.volume * _xPROVIDER_GridVolumeMultiplier, 2);
|
||||
_xPROVIDER_GridLongPrice = NormalizeDouble(signal.entry - (_xPROVIDER_GridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Grid Short Trades Price and Volume ...
|
||||
void _XPROVIDER_CalculateGridShortConditions(XSignal &signal)
|
||||
{
|
||||
//
|
||||
// Check Grid Trades Enable ...
|
||||
if (!_xPROVIDER_UseGridTrades)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate GridShortPrice and GridShortVolume ...
|
||||
_xPROVIDER_GridShortVolume = NormalizeDouble(signal.volume * _xPROVIDER_GridVolumeMultiplier, 2);
|
||||
_xPROVIDER_GridShortPrice = NormalizeDouble(signal.entry + (_xPROVIDER_GridDistancePips * 10 * _Point), _Digits);
|
||||
}
|
||||
|
||||
//
|
||||
// Determine based on current account state
|
||||
bool _XPROVIDER_CanDoTrade()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,756 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XOBD Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XSignalProvider
|
||||
// Description: based 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
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
input group "XOBD Provider";
|
||||
|
||||
//
|
||||
input group "XOBD Common";
|
||||
input bool enableXOBDProvider = true; // Enable Provider
|
||||
input bool xOBDEnableAlerts = true; // Enable Events Alert
|
||||
|
||||
//
|
||||
input group "XOBD Indicator";
|
||||
input int xOBDLength = 5; // Market Length
|
||||
input double xOBDArrowDistanceFromPrice = 0; // Arrow Distrance from Price
|
||||
input uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code
|
||||
input color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color
|
||||
input uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code
|
||||
input color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color
|
||||
|
||||
//
|
||||
input group "XOBD Trader";
|
||||
input int xOBDMagicNumber = 16940562; // Trader MagicNumber
|
||||
input int xOBDSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XOBD Trade Management";
|
||||
input bool xOBDAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xOBDAllowShortTrades = false; // Allow Short Trades
|
||||
input int xOBDMaxOpenTrades = 4; // Max Open Trades at Same Time
|
||||
|
||||
//
|
||||
input group "XOBD Risk Management";
|
||||
input bool xOBDUseTPSL = true; // Allow use TP and SL
|
||||
input bool xOBDUseVirtualTPSL = false; // Allow Use Virtual TP and SL
|
||||
input bool xOBDDrawTPSL = true; // Draw TP and SL
|
||||
input double xOBDR2r = 1.5; // Risk To Reward Ratio
|
||||
input int xOBDLoopback = 3; // Loopback Length for TP/SL Calculation
|
||||
input double xOBDMinRiskPerTrade = 100; // Min Risk Per Trade in Points
|
||||
input double xOBDMaxRiskPerTrade = 1000; // Max Risk Per Trade in Points
|
||||
input bool xOBDUseDynamicVolume = false; // Enable Dynamic Volume
|
||||
input double xOBDStaticVolume = 0.01; // Static Volume
|
||||
input double xOBDBalanceIncreased = 500; // Balance Increase
|
||||
input double xOBDVolumeIncreased = 0.01; // Volume Increase
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Include Common Library ...
|
||||
#include "x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Logger Library ...
|
||||
#include "x-saherelm.log.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Alert Library ...
|
||||
#include "x-saherelm.alert.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Draw Library ...
|
||||
#include "x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// Include Class Libraries ...
|
||||
#include "x-saherelm.class.lib.mq5"
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
//
|
||||
int xOBDHandler = INVALID_HANDLE;
|
||||
double xOBDBuffer[];
|
||||
|
||||
//
|
||||
XCTrade *xOBDTrader;
|
||||
XCAccountInfo xOBDAccountInfo;
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool OnInInitXOBDSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Error Message ...
|
||||
string message = "";
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
xOBDHandler = iCustom(
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xobd.indicator",
|
||||
//
|
||||
xOBDLength,
|
||||
xOBDArrowDistanceFromPrice,
|
||||
xOBDSwingHighArrowCode,
|
||||
xOBDSwingHighArrowColor,
|
||||
xOBDSwingLowArrowCode,
|
||||
xOBDSwingLowArrowColor);
|
||||
if (xOBDHandler == INVALID_HANDLE)
|
||||
{
|
||||
//
|
||||
LogMessage("error initializing XOBD Indicator: " + (string)GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Risk Management ...
|
||||
if (xOBDUseDynamicVolume)
|
||||
{
|
||||
//
|
||||
if (xOBDBalanceIncreased <= 0 || xOBDVolumeIncreased <= 0)
|
||||
{
|
||||
//
|
||||
message = "invalid volume increased factors ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
if (xOBDStaticVolume > maxAvailableVolume || xOBDStaticVolume < minAvailableVolume)
|
||||
{
|
||||
//
|
||||
message = "invalid static volume ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Validate use TPSL ...
|
||||
if (xOBDUseTPSL)
|
||||
{
|
||||
//
|
||||
if (xOBDR2r < 1.2)
|
||||
{
|
||||
//
|
||||
LogMessage("Risk to Rewadrd Ratio is too small ...");
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
xOBDTrader = new XCTrade(
|
||||
_Symbol,
|
||||
xOBDSlippage,
|
||||
xOBDMagicNumber);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
message = "Initializion of (" + "XOBD Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void OnDeinitXOBDSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "De Initializion of (" + "XOBD Provider" + ") Succeeded ...";
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void HandleXOBDSignalProviderTick()
|
||||
{
|
||||
//
|
||||
// Reding XOBD Buffer ...
|
||||
CopyBuffer(xOBDHandler, 0, 0, 5, xOBDBuffer);
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
XOBDHandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
XOBDHandleCloseTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Long Primary Signals ...
|
||||
bool XOBDHasPrimaryLongSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Buy/Long Conditions ...
|
||||
// Swing Low is a sign of Bullish Trend ...
|
||||
result = xOBDBuffer[4] == -1;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions to find Short Primary Signals ...
|
||||
bool XOBDHasPrimaryShortSignal()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Sell/Short Conditions ...
|
||||
// Swing High is a sign of Bearish Trend ...
|
||||
result = xOBDBuffer[4] == 1;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Long Trades ...
|
||||
bool XOBDCanCloseLongTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Market Conditions for Closing
|
||||
// Long Trades ...
|
||||
// result = xOBDBuffer[4] == 1;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Market Conditions for closing Short Trades ...
|
||||
bool XOBDCanCloseShortTrades()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Market Conditions for Closing
|
||||
// Short Trades ...
|
||||
// result = xOBDBuffer[4] == -1;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Long/Buy for Primary Trades...
|
||||
bool XOBDHandlePrimaryLong(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// && xOBDTrader.CountLongs() == 0
|
||||
if (XOBDHasPrimaryLongSignal())
|
||||
{
|
||||
//
|
||||
double entry = GetAsk();
|
||||
double volume = XOBDCalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = XOBDCanDoTrade();
|
||||
|
||||
//
|
||||
// Handle TP SL if it's enabled ...
|
||||
if (xOBDUseTPSL)
|
||||
{
|
||||
XTPSL mTpSl = XOBDCalculateTPSL(X_SIGNAL_LONG, entry);
|
||||
if (IsValid(mTpSl))
|
||||
{
|
||||
//
|
||||
// Check for Draw TP and SL ...
|
||||
if (xOBDDrawTPSL)
|
||||
{
|
||||
XOBDDrawTPSL(mTpSl);
|
||||
}
|
||||
|
||||
//
|
||||
// Set TP SL in Signal if it's required to add directly ...
|
||||
if (!xOBDUseVirtualTPSL)
|
||||
{
|
||||
//
|
||||
signal.tp = mTpSl.tp;
|
||||
signal.sl = mTpSl.sl;
|
||||
}
|
||||
//
|
||||
// Draw Virtual TP SL for Closing Trades ...
|
||||
else
|
||||
{
|
||||
//
|
||||
// TODO: implement this ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_LONG;
|
||||
signal.magicNumber = xOBDMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary XOBD Long";
|
||||
|
||||
//
|
||||
if (enableXOBDProvider && xOBDAllowLongTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = xOBDTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Long signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (xOBDEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell for Primary Trades...
|
||||
bool XOBDHandlePrimaryShort(
|
||||
XSignal &signal, // return structure if signal founded
|
||||
bool doTrade = true // do trade on signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
ResetLastError();
|
||||
|
||||
//
|
||||
// && xOBDTrader.CountShorts() == 0
|
||||
if (XOBDHasPrimaryShortSignal())
|
||||
{
|
||||
//
|
||||
double entry = GetBid();
|
||||
double volume = XOBDCalculateVolume();
|
||||
|
||||
//
|
||||
double canDoTrade = XOBDCanDoTrade();
|
||||
|
||||
//
|
||||
signal.entry = entry;
|
||||
signal.volume = volume;
|
||||
signal.symbol = _Symbol;
|
||||
signal.type = X_SIGNAL_SHORT;
|
||||
signal.magicNumber = xOBDMagicNumber;
|
||||
signal.time = iTime(_Symbol, _Period, 0);
|
||||
signal.comment = "Primary XOBD Short";
|
||||
|
||||
//
|
||||
if (enableXOBDProvider && xOBDAllowShortTrades && doTrade && canDoTrade)
|
||||
{
|
||||
//
|
||||
// Execute Signal ...
|
||||
result = xOBDTrader.ExecuteSignal(signal);
|
||||
|
||||
//
|
||||
// Since this means an error happens, we have to log this error ...
|
||||
if (!result)
|
||||
{
|
||||
string errMessage = "failed to execute Short signal: " + (string)GetLastError();
|
||||
LogMessage(errMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Alerts ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
if (xOBDEnableAlerts)
|
||||
{
|
||||
SendAlert(signal, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogExecutedSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void XOBDHandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Primary Long Trade ...
|
||||
XSignal primaryLongSignal = {};
|
||||
bool isPrimaryLongSignalExecuted = XOBDHandlePrimaryLong(primaryLongSignal);
|
||||
if (isPrimaryLongSignalExecuted)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Primary Short Trade ...
|
||||
XSignal primaryShortSignal = {};
|
||||
bool isPrimaryShortSignalExecuted = XOBDHandlePrimaryShort(primaryShortSignal);
|
||||
if (isPrimaryShortSignalExecuted)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void XOBDHandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// Handle Long/Buy Close ...
|
||||
if (xOBDTrader.CountLongs() > 0 && XOBDCanCloseLongTrades())
|
||||
{
|
||||
//
|
||||
xOBDTrader.CloseLongPositions();
|
||||
|
||||
//
|
||||
string message = "XOBD Closing Long Trades ...";
|
||||
|
||||
//
|
||||
if (xOBDEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Short/Sell Close ...
|
||||
if (xOBDTrader.CountShorts() > 0 && XOBDCanCloseShortTrades())
|
||||
{
|
||||
//
|
||||
xOBDTrader.CloseShortPositions();
|
||||
|
||||
//
|
||||
string message = "XOBD Closing Short Trades ...";
|
||||
|
||||
//
|
||||
if (xOBDEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double XOBDCalculateVolume()
|
||||
{
|
||||
//
|
||||
double result = xOBDStaticVolume;
|
||||
if (!xOBDUseDynamicVolume)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double accountBalance = xOBDAccountInfo.GetBalance();
|
||||
double balanceIncreased = xOBDBalanceIncreased;
|
||||
double volumeIncreased = xOBDVolumeIncreased;
|
||||
|
||||
//
|
||||
result = (volumeIncreased * accountBalance) / balanceIncreased;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeDouble(result, 2);
|
||||
|
||||
//
|
||||
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||
|
||||
//
|
||||
// Validate Result ...
|
||||
if (result > maxAvailableVolume)
|
||||
{
|
||||
result = maxAvailableVolume;
|
||||
}
|
||||
else if (result < minAvailableVolume)
|
||||
{
|
||||
result = minAvailableVolume;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate TP and SL ...
|
||||
XTPSL XOBDCalculateTPSL(
|
||||
ENUM_X_SIGNAL_TYPE type, // Which Type to Calculate TP and SL
|
||||
double entry // Signal Entry Price
|
||||
)
|
||||
{
|
||||
//
|
||||
XTPSL result = {};
|
||||
result.type = X_SIGNAL_UNKNOWN;
|
||||
result.tp = 0;
|
||||
result.sl = 0;
|
||||
result.r2r = 0;
|
||||
result.entry = 0;
|
||||
|
||||
//
|
||||
if (!xOBDUseTPSL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (entry <= 0 || type == X_SIGNAL_UNKNOWN)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result.type = type;
|
||||
result.r2r = xOBDR2r;
|
||||
result.entry = entry;
|
||||
|
||||
//
|
||||
bool isLong = type == X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
// Retrieve Market Highest High and Lowest Low ...
|
||||
double hh = GetHighestHigh(
|
||||
xOBDLoopback,
|
||||
0);
|
||||
double ll = GetLowestLow(
|
||||
xOBDLoopback,
|
||||
0);
|
||||
|
||||
//
|
||||
double maxRisk = xOBDMaxRiskPerTrade * _Point;
|
||||
double minRisk = xOBDMinRiskPerTrade * _Point;
|
||||
|
||||
//
|
||||
// Calculate and Normalize risk ...
|
||||
double risk = isLong ? entry - ll : hh - entry;
|
||||
// if (risk > maxRisk)
|
||||
// {
|
||||
// risk = maxRisk;
|
||||
// }
|
||||
// else if (risk < minRisk)
|
||||
// {
|
||||
// risk = minRisk;
|
||||
// }
|
||||
|
||||
//
|
||||
double reward = risk * xOBDR2r;
|
||||
|
||||
//
|
||||
double tp = isLong ? entry + reward : entry - reward;
|
||||
double sl = isLong ? entry - risk : entry + risk;
|
||||
|
||||
//
|
||||
tp = NormalizeDouble(tp, _Digits);
|
||||
sl = NormalizeDouble(sl, _Digits);
|
||||
|
||||
//
|
||||
result.tp = tp;
|
||||
result.sl = sl;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine based on current account state
|
||||
bool XOBDCanDoTrade()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Check Max Open Trades ...
|
||||
int totalOpenTrades = xOBDTrader.Count();
|
||||
result = totalOpenTrades <= xOBDMaxOpenTrades;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// START Draw Functions ...
|
||||
//
|
||||
void XOBDDrawTPSL(
|
||||
XTPSL &model // an instance of XTPS structure
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!IsValid(model))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string entryName = "T_" + EnumToString(model.type) + "_Entry_" + (string)model.entry;
|
||||
string slName = entryName + "_SL_" + (string)model.sl;
|
||||
string tpName = entryName + "_TP_" + (string)model.tp;
|
||||
datetime time1 = iTime(_Symbol, _Period, 2);
|
||||
datetime time2 = iTime(_Symbol, _Period, 0);
|
||||
color tpColor = xOBDSwingLowArrowColor;
|
||||
color slColor = xOBDSwingHighArrowColor;
|
||||
|
||||
//
|
||||
// Draw Entry ...
|
||||
DrawTrendLine(
|
||||
0,
|
||||
entryName,
|
||||
0,
|
||||
time1,
|
||||
model.entry,
|
||||
time2,
|
||||
model.entry,
|
||||
clrYellow);
|
||||
|
||||
//
|
||||
// Draw TP ...
|
||||
if (model.tp > 0)
|
||||
{
|
||||
//
|
||||
DrawTrendLine(
|
||||
0,
|
||||
tpName,
|
||||
0,
|
||||
time1,
|
||||
model.tp,
|
||||
time2,
|
||||
model.tp,
|
||||
tpColor);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw SL ...
|
||||
if (model.sl > 0)
|
||||
{
|
||||
//
|
||||
DrawTrendLine(
|
||||
0,
|
||||
slName,
|
||||
0,
|
||||
time1,
|
||||
model.sl,
|
||||
time2,
|
||||
model.sl,
|
||||
slColor);
|
||||
}
|
||||
}
|
||||
//
|
||||
// END Draw Functions ...
|
||||
//
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
@@ -0,0 +1,146 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTM Signal Provider Inputs Library
|
||||
// -----------------------------------------------------------
|
||||
// Name: XTMSignalProviderInputs
|
||||
// Description: all Inputs for XTM based signal provider ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
input group "XTM Provider";
|
||||
|
||||
//
|
||||
input group "XTM Common";
|
||||
input bool enableXTMProvider = true; // Enable Provider
|
||||
input bool xTMEnableAlerts = true; // Enable Events Alert
|
||||
input int xTMNumberOfItemsPerTick = 5; // Number of reading Items per Tick
|
||||
|
||||
//
|
||||
input group "XTM Indicator";
|
||||
input int xTMMaPeriod = 28; // Period
|
||||
input int xTMMaShift = 0; // Shift
|
||||
input ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method
|
||||
input ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_CLOSE; // Applied To
|
||||
|
||||
//
|
||||
input group "XOBD Indicator";
|
||||
input int xOBDLength = 5; // Market Length
|
||||
input double xOBDArrowDistanceFromPrice = 0; // Arrow Distrance from Price
|
||||
input uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code
|
||||
input color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color
|
||||
input uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code
|
||||
input color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color
|
||||
|
||||
//
|
||||
input group "XTD Oscillator";
|
||||
input int xTDLength = 14; // Market Length
|
||||
input bool xTDDrawCrosses = false; // Draw Cross Arrows
|
||||
input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code
|
||||
input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color
|
||||
input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code
|
||||
input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color
|
||||
|
||||
//
|
||||
input group "XTPD Oscillatro";
|
||||
input int xTPDLength = 14;
|
||||
|
||||
//
|
||||
input group "XCHMA Oscillator";
|
||||
input group "XCHMA Hot Areas";
|
||||
input bool xCHMADrawHotAreas = true; // Draw Hot Areas Symbol
|
||||
input uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code
|
||||
input color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color
|
||||
input uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code
|
||||
input color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color
|
||||
|
||||
//
|
||||
// LC Inputs ...
|
||||
input group "XCHMA Long Cycle";
|
||||
input group "XCHMA LC Market";
|
||||
input int xCHMALcFastLength = 20; // Fast Length
|
||||
input int xCHMALcSlowLength = 50; // Slow Length
|
||||
input ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method
|
||||
input ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To
|
||||
input group "XCHMA LC Style";
|
||||
input int xCHMALcDrawWidth = 1; // Draw Width
|
||||
input ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type
|
||||
input ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style
|
||||
input color xCHMALcFastColor = clrAqua; // Fast Color
|
||||
input color xCHMALcSlowColor = clrFuchsia; // Slow Color
|
||||
input group "XCHMA LC Drawings";
|
||||
input bool xCHMALcDrawFast = true; // Draw Fast
|
||||
input bool xCHMALcDrawSlow = true; // Draw Slow
|
||||
input bool xCHMALcDrawCrosses = true; // Draw Cross Lines
|
||||
|
||||
//
|
||||
// MC Inputs ...
|
||||
input group "XCHMA Medium Cycle";
|
||||
input group "XCHMA MC Market";
|
||||
input int xCHMAMcFastLength = 10; // Fast Length
|
||||
input int xCHMAMcSlowLength = 30; // Slow Length
|
||||
input ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method
|
||||
input ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To
|
||||
input group "XCHMA MC Style";
|
||||
input int xCHMAMcDrawWidth = 1; // Draw Width
|
||||
input ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type
|
||||
input ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style
|
||||
input color xCHMAMcFastColor = clrLime; // Fast Color
|
||||
input color xCHMAMcSlowColor = clrRed; // Slow Color
|
||||
input group "XCHMA MC Drawings";
|
||||
input bool xCHMAMcDrawFast = true; // Draw Fast
|
||||
input bool xCHMAMcDrawSlow = true; // Draw Slow
|
||||
input bool xCHMAMcDrawCrosses = false; // Draw Cross Lines
|
||||
|
||||
//
|
||||
// SC Inputs ...
|
||||
input group "XCHMA Short Cycle";
|
||||
input group "XCHMA SC Market";
|
||||
input int xCHMAScFastLength = 7; // Fast Length
|
||||
input int xCHMAScSlowLength = 14; // Slow Length
|
||||
input ENUM_MA_METHOD xCHMAScMethod = MODE_EMA; // Calculation Method
|
||||
input ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To
|
||||
input group "XCHMA SC Style";
|
||||
input int xCHMAScDrawWidth = 1; // Draw Width
|
||||
input ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type
|
||||
input ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style
|
||||
input color xCHMAScFastColor = clrLightBlue; // Fast Color
|
||||
input color xCHMAScSlowColor = clrLightSalmon; // Slow Color
|
||||
input group "XCHMA SC Drawings";
|
||||
input bool xCHMAScDrawFast = true; // Draw Fast
|
||||
input bool xCHMAScDrawSlow = true; // Draw Slow
|
||||
input bool xCHMAScDrawCrosses = false; // Draw Cross Lines
|
||||
|
||||
//
|
||||
input group "XTM Trader";
|
||||
input int xTMMagicNumber = 16940563; // Trader MagicNumber
|
||||
input int xTMSlippage = 10; // Trader Slippage
|
||||
|
||||
//
|
||||
input group "XTM Trade Management";
|
||||
input bool xTMAllowLongTrades = true; // Allow Long Trades
|
||||
input bool xTMAllowShortTrades = false; // Allow Short Trades
|
||||
input int xTMMaxOpenTrades = 1; // Max Open Trades at Same Time
|
||||
input bool xTMEnableGridTrades = true; // Enable Grid Trades
|
||||
input double xTMGridDistanceInPips = 20; // Grid to Long Price Distance in Pips
|
||||
input double xTMGridVolumeMultiplier = 2; // Grid Volume Multiplier at Distance
|
||||
|
||||
//
|
||||
input group "XTM Risk Management";
|
||||
input double xTMR2r = 2; // Risk To Reward Ratio
|
||||
input int xTMLoopback = 7; // Loopback Length for TP/SL Calculation
|
||||
input int xTMMaximumTradeLife = 0; // Maximum Trade Life in Candles
|
||||
input double xTMMaximumAllowedDrawDownFactorPerTrade = 0; // Maximum Allowed DrawDown per Trade
|
||||
input double xTMMinimumBalanceFactorForTrade = 0.5; // Minimum required Balance for Trading
|
||||
input double xTMMaximumEquityFactorForTrade = 0.2; // Minimum required Equity for Trading
|
||||
input double xTMStaticVolume = 0.01; // Static Volume
|
||||
input bool xTMUseDynamicVolume = true; // Enable Dynamic Volume
|
||||
input double xTMBalanceIncreasedFactor = 0.5; // Balance Increase Multiplier
|
||||
input double xTMVolumeIncreasedFactor = 0.01; // Volume Increase Multiplier
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user