Initial Commit ...
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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";
|
||||
|
||||
//
|
||||
// XRSI Signal Provider ...
|
||||
// #include "..\Libraries\x-saherelm.rsi.provider.lib.mq5"
|
||||
|
||||
//
|
||||
// XODB Signal Provider ...
|
||||
// #include "..\Libraries\x-saherelm.xobd.provider.lib.mq5"
|
||||
|
||||
//
|
||||
// XTM Signal Provider ...
|
||||
#include "..\Libraries\x-saherelm.xtm.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 XRSI Provider ...
|
||||
// if (!OnInInitXRSISignalProviderLibrary())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
//
|
||||
// Initialize XOBD Provider ...
|
||||
// if (!OnInInitXOBDSignalProviderLibrary())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
//
|
||||
// Initialize XTM Provider ...
|
||||
if (!OnInInitXTMSignalProviderLibrary())
|
||||
{
|
||||
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 XRSI Provider ...
|
||||
// OnDeinitXRSISignalProviderLibrary();
|
||||
|
||||
//
|
||||
// De Initialize XOBD Provider ...
|
||||
// OnDeinitXOBDSignalProviderLibrary();
|
||||
|
||||
//
|
||||
// De Initialize XTM Provider ...
|
||||
OnDeinitXTMSignalProviderLibrary();
|
||||
|
||||
//
|
||||
// De Init XDraw Library ...
|
||||
OnDeinitDrawLibrary();
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!IsNewCandle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Processing on XRSI Signal Provider ...
|
||||
// HandleXSignalProviderTick();
|
||||
|
||||
//
|
||||
// Handle Processing on XOBD Signal Provider ...
|
||||
// HandleXOBDSignalProviderTick();
|
||||
|
||||
//
|
||||
// Handle Processing on XTM Signal Provider ...
|
||||
HandleXTMSignalProviderTick();
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "Validation of (" + "XEA" + ") Inputs " + (result ? "Succeeded" : "Failed") + " ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
Binary file not shown.
@@ -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,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 ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,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,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 ...
|
||||
//
|
||||
Binary file not shown.
@@ -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,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,225 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user