update workspace ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,348 @@
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: X121_XDEMA
|
||||
// Description: Super Trend Indicator ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm X121_XAMA Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
|
||||
#define ShortName "X121_XDEMA"
|
||||
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Market ...
|
||||
input group "Market";
|
||||
input int length = 200; // Length
|
||||
input int shift = 0; // Shift
|
||||
|
||||
//
|
||||
// Presentation ...
|
||||
input group "Presentation";
|
||||
input bool showDema = true; // Show Dema
|
||||
input bool showEMA = false; // Show EMA
|
||||
input bool showEMAOfEMA = false; // Show EMA of EMA
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include <MovingAverages.mqh>
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 6
|
||||
|
||||
//
|
||||
#define demaBufferIndex 0
|
||||
double demaBuffer[];
|
||||
|
||||
//
|
||||
#define demaColorBufferIndex 1
|
||||
double demaColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "X121_XDEMA DEMA"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrDodgerBlue, CLR_NONE
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
#define emaBufferIndex 2
|
||||
double emaBuffer[];
|
||||
|
||||
//
|
||||
#define emaColorBufferIndex 3
|
||||
double emaColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "X121_XDEMA EMA"
|
||||
#property indicator_type2 DRAW_COLOR_LINE
|
||||
#property indicator_color2 clrBlue, CLR_NONE
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
#define emaOfEMABufferIndex 4
|
||||
double emaOfEMABuffer[];
|
||||
|
||||
//
|
||||
#define emaOfEMAColorBufferIndex 5
|
||||
double emaOfEMAColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label3 "X121_XDEMA EMA of EMA"
|
||||
#property indicator_type3 DRAW_COLOR_LINE
|
||||
#property indicator_color3 clrOrange, CLR_NONE
|
||||
#property indicator_style3 STYLE_DOT
|
||||
#property indicator_width3 1
|
||||
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
int maxLength;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
maxLength = ExtractMaxLengthOfInputs();
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
}
|
||||
|
||||
//
|
||||
// Do Calculations ...
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const int begin,
|
||||
const double &price[])
|
||||
{
|
||||
//
|
||||
ArraySetAsSeries(price, true);
|
||||
|
||||
//
|
||||
// check for data ...
|
||||
if (rates_total < 2 * length - 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
int limit;
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// calculate EMA ...
|
||||
ExponentialMAOnBuffer(rates_total, prev_calculated, 0, length, price, emaBuffer);
|
||||
|
||||
//
|
||||
// calculate EMA on EMA array ...
|
||||
ExponentialMAOnBuffer(rates_total, prev_calculated, length - 1, length, emaBuffer, emaOfEMABuffer);
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
// calculate DEMA ...
|
||||
demaBuffer[i] = 2 * emaBuffer[i] - emaOfEMABuffer[i];
|
||||
|
||||
//
|
||||
double showColorIDX = 0;
|
||||
double hideColorIDX = 1;
|
||||
|
||||
//
|
||||
demaColorBuffer[i] = hideColorIDX;
|
||||
emaColorBuffer[i] = hideColorIDX;
|
||||
emaOfEMAColorBuffer[i] = hideColorIDX;
|
||||
|
||||
//
|
||||
if (showDema)
|
||||
{
|
||||
demaColorBuffer[i] = showColorIDX;
|
||||
}
|
||||
|
||||
//
|
||||
if (showEMA)
|
||||
{
|
||||
emaColorBuffer[i] = showColorIDX;
|
||||
}
|
||||
|
||||
//
|
||||
if (showEMAOfEMA)
|
||||
{
|
||||
emaOfEMAColorBuffer[i] = showColorIDX;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result =
|
||||
//
|
||||
(length > 2 &&
|
||||
shift >= 0)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve all Exists Input Max Length ...
|
||||
// use for Start Of Drawing ...
|
||||
int ExtractMaxLengthOfInputs()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Peaks and Vales ...
|
||||
result = length;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// DEMA ...
|
||||
|
||||
//
|
||||
// Buffer ...
|
||||
ArraySetAsSeries(demaBuffer, true);
|
||||
SetIndexBuffer(demaBufferIndex, demaBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(demaBufferIndex, PLOT_SHOW_DATA, showDema);
|
||||
|
||||
//
|
||||
// Color Buffer ...
|
||||
ArraySetAsSeries(demaColorBuffer, true);
|
||||
SetIndexBuffer(demaColorBufferIndex, demaColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// EMA ...
|
||||
|
||||
//
|
||||
// Buffer ...
|
||||
ArraySetAsSeries(emaBuffer, true);
|
||||
SetIndexBuffer(emaBufferIndex, emaBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(emaBufferIndex, PLOT_SHOW_DATA, showEMA);
|
||||
|
||||
//
|
||||
// Color Buffer ...
|
||||
ArraySetAsSeries(emaColorBuffer, true);
|
||||
SetIndexBuffer(emaColorBufferIndex, emaColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// EMA of EMA ...
|
||||
|
||||
//
|
||||
// Buffer ...
|
||||
ArraySetAsSeries(emaOfEMABuffer, true);
|
||||
SetIndexBuffer(emaOfEMABufferIndex, emaOfEMABuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(emaOfEMABufferIndex, PLOT_SHOW_DATA, showEMAOfEMA);
|
||||
|
||||
//
|
||||
// Color Buffer ...
|
||||
ArraySetAsSeries(emaOfEMAColorBuffer, true);
|
||||
SetIndexBuffer(emaOfEMAColorBufferIndex, emaOfEMAColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
}
|
||||
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
@@ -0,0 +1,365 @@
|
||||
///////////////////////////////////////////////////////
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// -------------------------------------------
|
||||
// Name: XDON
|
||||
// Description: DONCHAIN Channel ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XDON Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#define ShortName "XDON"
|
||||
|
||||
//
|
||||
// INPUT ...
|
||||
|
||||
//
|
||||
input int length = 52; // Market Length
|
||||
input double offset = 0; // Offset
|
||||
|
||||
//
|
||||
// BUFFERS ...
|
||||
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 8
|
||||
#property indicator_plots 8
|
||||
|
||||
//
|
||||
#define upperOBufferIndex 0
|
||||
double upperOBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "XDON OU"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrCornflowerBlue
|
||||
#property indicator_width1 2
|
||||
|
||||
//
|
||||
#define lowerOBufferIndex 1
|
||||
double lowerOBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "XDON OL"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrCornflowerBlue
|
||||
#property indicator_width2 2
|
||||
|
||||
//
|
||||
#define upperCBufferIndex 2
|
||||
double upperCBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label3 "XDON CU"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrCoral
|
||||
#property indicator_width3 2
|
||||
|
||||
//
|
||||
#define lowerCBufferIndex 3
|
||||
double lowerCBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label4 "XDON CL"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrCoral
|
||||
#property indicator_width4 2
|
||||
|
||||
//
|
||||
#define upperHBufferIndex 4
|
||||
double upperHBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label5 "XDON HU"
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 clrAquamarine
|
||||
#property indicator_width5 2
|
||||
|
||||
//
|
||||
#define lowerHBufferIndex 5
|
||||
double lowerHBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label6 "XDON HL"
|
||||
#property indicator_type6 DRAW_LINE
|
||||
#property indicator_color6 clrAquamarine
|
||||
#property indicator_width6 2
|
||||
|
||||
//
|
||||
#define upperLBufferIndex 6
|
||||
double upperLBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label7 "XDON LU"
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 clrDarkOrchid
|
||||
#property indicator_width7 2
|
||||
|
||||
//
|
||||
#define lowerLBufferIndex 7
|
||||
double lowerLBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label8 "XDON LL"
|
||||
#property indicator_type8 DRAW_LINE
|
||||
#property indicator_color8 clrDarkOrchid
|
||||
#property indicator_width8 2
|
||||
|
||||
//
|
||||
// EVENT Handlers ...
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
if (rates_total < length - 1)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
int start = prev_calculated == 0
|
||||
? length
|
||||
: prev_calculated - 1;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int barIndex = start; barIndex < rates_total; barIndex++)
|
||||
{
|
||||
//
|
||||
// OPEN ...
|
||||
|
||||
//
|
||||
double upperOValue = open[ArrayMaximum(open, barIndex - length + 1, length)];
|
||||
double lowerOValue = open[ArrayMinimum(open, barIndex - length + 1, length)];
|
||||
|
||||
//
|
||||
double oDelta = MathAbs(upperOValue - lowerOValue);
|
||||
double oOffsetValue = oDelta * (offset) * 0.01;
|
||||
|
||||
//
|
||||
upperOBuffer[barIndex] = upperOValue - oOffsetValue;
|
||||
lowerOBuffer[barIndex] = lowerOValue + oOffsetValue;
|
||||
|
||||
//
|
||||
// CLOSE ...
|
||||
|
||||
//
|
||||
double upperCValue = close[ArrayMaximum(close, barIndex - length + 1, length)];
|
||||
double lowerCValue = close[ArrayMinimum(close, barIndex - length + 1, length)];
|
||||
|
||||
//
|
||||
double cDelta = MathAbs(upperCValue - lowerCValue);
|
||||
double cOffsetValue = cDelta * (offset) * 0.01;
|
||||
|
||||
//
|
||||
upperCBuffer[barIndex] = upperCValue - cOffsetValue;
|
||||
lowerCBuffer[barIndex] = lowerCValue + cOffsetValue;
|
||||
|
||||
//
|
||||
// HIGH ...
|
||||
|
||||
//
|
||||
double upperHValue = high[ArrayMaximum(high, barIndex - length + 1, length)];
|
||||
double lowerHValue = high[ArrayMinimum(high, barIndex - length + 1, length)];
|
||||
|
||||
//
|
||||
double hDelta = MathAbs(upperHValue - lowerHValue);
|
||||
double hOffsetValue = hDelta * (offset) * 0.01;
|
||||
|
||||
//
|
||||
upperHBuffer[barIndex] = upperHValue - hOffsetValue;
|
||||
lowerHBuffer[barIndex] = lowerHValue + hOffsetValue;
|
||||
|
||||
//
|
||||
// LOW ...
|
||||
|
||||
//
|
||||
double upperLValue = low[ArrayMaximum(low, barIndex - length + 1, length)];
|
||||
double lowerLValue = low[ArrayMinimum(low, barIndex - length + 1, length)];
|
||||
|
||||
//
|
||||
double lDelta = MathAbs(upperLValue - lowerLValue);
|
||||
double lOffsetValue = lDelta * (offset) * 0.01;
|
||||
|
||||
//
|
||||
upperLBuffer[barIndex] = upperLValue - lOffsetValue;
|
||||
lowerLBuffer[barIndex] = lowerLValue + lOffsetValue;
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// CUSTOM Functions ...
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = length >= 7;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
// UPPER ...
|
||||
SetIndexBuffer(upperOBufferIndex, upperOBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(upperOBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(upperOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
|
||||
//
|
||||
// LOWER ...
|
||||
SetIndexBuffer(lowerOBufferIndex, lowerOBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(lowerOBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(lowerOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
//
|
||||
// UPPER ...
|
||||
SetIndexBuffer(upperCBufferIndex, upperCBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(upperCBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(upperCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
|
||||
//
|
||||
// LOWER ...
|
||||
SetIndexBuffer(lowerCBufferIndex, lowerCBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(lowerCBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(lowerCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
|
||||
//
|
||||
// High ...
|
||||
|
||||
//
|
||||
// UPPER ...
|
||||
SetIndexBuffer(upperHBufferIndex, upperHBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(upperHBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(upperHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
|
||||
//
|
||||
// LOWER ...
|
||||
SetIndexBuffer(lowerHBufferIndex, lowerHBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(lowerHBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(lowerHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
|
||||
//
|
||||
// Low ...
|
||||
|
||||
//
|
||||
// UPPER ...
|
||||
SetIndexBuffer(upperLBufferIndex, upperLBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(upperLBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(upperLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
|
||||
//
|
||||
// LOWER ...
|
||||
SetIndexBuffer(lowerLBufferIndex, lowerLBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(lowerLBufferIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetDouble(lowerLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
@@ -0,0 +1,964 @@
|
||||
///////////////////////////////////////////////////////
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// -------------------------------------------
|
||||
// Name: XDSR
|
||||
// Description: Dynamic Support and Resistances ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XDSR Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#define ShortName "XDSR"
|
||||
|
||||
//
|
||||
// Includes ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// INPUT ...
|
||||
|
||||
//
|
||||
// Maarket ...
|
||||
input group "Cycles";
|
||||
|
||||
//
|
||||
// Short ...
|
||||
input group "Short";
|
||||
input ENUM_X_PERIOD_METHOD scMode = X_PERIOD_MANUALLY; // Method
|
||||
input ENUM_TIMEFRAMES scPeriod = PERIOD_H4; // Period
|
||||
|
||||
//
|
||||
// Medium ...
|
||||
input group "Medium";
|
||||
input ENUM_X_PERIOD_METHOD mcMode = X_PERIOD_MANUALLY; // Method
|
||||
input ENUM_TIMEFRAMES mcPeriod = PERIOD_H12; // Mid Period
|
||||
|
||||
//
|
||||
// Long ...
|
||||
input group "Long";
|
||||
input ENUM_X_PERIOD_METHOD lcMode = X_PERIOD_MANUALLY; // Method
|
||||
input ENUM_TIMEFRAMES lcPeriod = PERIOD_D1; // Long Period
|
||||
|
||||
//
|
||||
// Hind ...
|
||||
input group "Hind";
|
||||
input ENUM_X_PERIOD_METHOD hcMode = X_PERIOD_MANUALLY; // Method
|
||||
input ENUM_TIMEFRAMES hcPeriod = PERIOD_W1; // Hind Period
|
||||
|
||||
//
|
||||
// BUFFERS ...
|
||||
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 24
|
||||
#property indicator_plots 24
|
||||
|
||||
//
|
||||
// Short ...
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
#define scOpenBufferIndex 0
|
||||
#define scOpenBufferPlotIndex 0
|
||||
double scOpenBuffer[];
|
||||
|
||||
//
|
||||
#define scOpenColorBufferIndex 1
|
||||
double scOpenColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "X121_XDSR SC O"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrGreen, clrRed
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// High ...
|
||||
#define scHighBufferIndex 2
|
||||
#define scHighBufferPlotIndex 1
|
||||
double scHighBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "X121_XDSR SC H"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrAqua
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
//
|
||||
#define scCloseBufferIndex 3
|
||||
#define scCloseBufferPlotIndex 2
|
||||
double scCloseBuffer[];
|
||||
|
||||
//
|
||||
#define scCloseColorBufferIndex 4
|
||||
double scCloseColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label3 "X121_XDSR SC C"
|
||||
#property indicator_type3 DRAW_COLOR_LINE
|
||||
#property indicator_color3 clrGreen, clrRed
|
||||
#property indicator_width3 1
|
||||
|
||||
//
|
||||
// Low ...
|
||||
#define scLowBufferIndex 5
|
||||
#define scLowBufferPlotIndex 3
|
||||
double scLowBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label4 "X121_XDSR SC L"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrMagenta
|
||||
#property indicator_width4 1
|
||||
|
||||
//
|
||||
// Medium ...
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
#define mcOpenBufferIndex 6
|
||||
#define mcOpenBufferPlotIndex 4
|
||||
double mcOpenBuffer[];
|
||||
|
||||
//
|
||||
#define mcOpenColorBufferIndex 7
|
||||
double mcOpenColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label5 "X121_XDSR MC O"
|
||||
#property indicator_type5 DRAW_COLOR_LINE
|
||||
#property indicator_color5 clrGreen, clrRed
|
||||
#property indicator_width5 1
|
||||
|
||||
//
|
||||
// High ...
|
||||
#define mcHighBufferIndex 8
|
||||
#define mcHighBufferPlotIndex 5
|
||||
double mcHighBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label6 "X121_XDSR MC H"
|
||||
#property indicator_type6 DRAW_LINE
|
||||
#property indicator_color6 clrAqua
|
||||
#property indicator_width6 1
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
//
|
||||
#define mcCloseBufferIndex 9
|
||||
#define mcCloseBufferPlotIndex 6
|
||||
double mcCloseBuffer[];
|
||||
|
||||
//
|
||||
#define mcCloseColorBufferIndex 10
|
||||
double mcCloseColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label7 "X121_XDSR MC C"
|
||||
#property indicator_type7 DRAW_COLOR_LINE
|
||||
#property indicator_color7 clrGreen, clrRed
|
||||
#property indicator_width7 1
|
||||
|
||||
//
|
||||
// Low ...
|
||||
#define mcLowBufferIndex 11
|
||||
#define mcLowBufferPlotIndex 7
|
||||
double mcLowBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label8 "X121_XDSR MC L"
|
||||
#property indicator_type8 DRAW_LINE
|
||||
#property indicator_color8 clrMagenta
|
||||
#property indicator_width8 1
|
||||
|
||||
//
|
||||
// Long ...
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
#define lcOpenBufferIndex 12
|
||||
#define lcOpenBufferPlotIndex 8
|
||||
double lcOpenBuffer[];
|
||||
|
||||
//
|
||||
#define lcOpenColorBufferIndex 13
|
||||
double lcOpenColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label9 "X121_XDSR LC O"
|
||||
#property indicator_type9 DRAW_COLOR_LINE
|
||||
#property indicator_color9 clrGreen, clrRed
|
||||
#property indicator_width9 1
|
||||
|
||||
//
|
||||
// High ...
|
||||
#define lcHighBufferIndex 14
|
||||
#define lcHighBufferPlotIndex 9
|
||||
double lcHighBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label10 "X121_XDSR LC H"
|
||||
#property indicator_type10 DRAW_LINE
|
||||
#property indicator_color10 clrAqua
|
||||
#property indicator_width10 1
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
//
|
||||
#define lcCloseBufferIndex 15
|
||||
#define lcCloseBufferPlotIndex 10
|
||||
double lcCloseBuffer[];
|
||||
|
||||
//
|
||||
#define lcCloseColorBufferIndex 16
|
||||
double lcCloseColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label11 "X121_XDSR LC C"
|
||||
#property indicator_type11 DRAW_COLOR_LINE
|
||||
#property indicator_color11 clrGreen, clrRed
|
||||
#property indicator_width11 1
|
||||
|
||||
//
|
||||
// Low ...
|
||||
#define lcLowBufferIndex 17
|
||||
#define lcLowBufferPlotIndex 11
|
||||
double lcLowBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label12 "X121_XDSR LC L"
|
||||
#property indicator_type12 DRAW_LINE
|
||||
#property indicator_color12 clrMagenta
|
||||
#property indicator_width12 1
|
||||
|
||||
//
|
||||
// Hind ...
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
#define hcOpenBufferIndex 18
|
||||
#define hcOpenBufferPlotIndex 12
|
||||
double hcOpenBuffer[];
|
||||
|
||||
//
|
||||
#define hcOpenColorBufferIndex 19
|
||||
double hcOpenColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label13 "X121_XDSR HC O"
|
||||
#property indicator_type13 DRAW_COLOR_LINE
|
||||
#property indicator_color13 clrGreen, clrRed
|
||||
#property indicator_width13 1
|
||||
|
||||
//
|
||||
// High ...
|
||||
#define hcHighBufferIndex 20
|
||||
#define hcHighBufferPlotIndex 13
|
||||
double hcHighBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label14 "X121_XDSR HC H"
|
||||
#property indicator_type14 DRAW_LINE
|
||||
#property indicator_color14 clrAqua
|
||||
#property indicator_width14 1
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
//
|
||||
#define hcCloseBufferIndex 21
|
||||
#define hcCloseBufferPlotIndex 14
|
||||
double hcCloseBuffer[];
|
||||
|
||||
//
|
||||
#define hcCloseColorBufferIndex 22
|
||||
double hcCloseColorBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label15 "X121_XDSR HC C"
|
||||
#property indicator_type15 DRAW_COLOR_LINE
|
||||
#property indicator_color15 clrGreen, clrRed
|
||||
#property indicator_width15 1
|
||||
|
||||
//
|
||||
// Low ...
|
||||
#define hcLowBufferIndex 23
|
||||
#define hcLowBufferPlotIndex 15
|
||||
double hcLowBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label16 "X121_XDSR HC L"
|
||||
#property indicator_type16 DRAW_LINE
|
||||
#property indicator_color16 clrMagenta
|
||||
#property indicator_width16 1
|
||||
|
||||
//
|
||||
// VARIABLES ...
|
||||
|
||||
//
|
||||
// Cycles Definitions ...
|
||||
XMarketCycle sc;
|
||||
XMarketCycle mc;
|
||||
XMarketCycle lc;
|
||||
XMarketCycle hc;
|
||||
|
||||
//
|
||||
// EVENT Handlers ...
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Initial Market Cycles ...
|
||||
if (!InitMarketCycles())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||
? rates_total - 1
|
||||
: (rates_total - prev_calculated);
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
CalculateBuffer(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// CUSTOM Functions ...
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// Short ...
|
||||
IsValidCycle(
|
||||
scMode,
|
||||
scPeriod)
|
||||
//
|
||||
&&
|
||||
//
|
||||
// Medium ...
|
||||
IsValidCycle(
|
||||
mcMode,
|
||||
mcPeriod)
|
||||
//
|
||||
&&
|
||||
//
|
||||
// Long ...
|
||||
IsValidCycle(
|
||||
lcMode,
|
||||
lcPeriod)
|
||||
//
|
||||
&&
|
||||
//
|
||||
// Hind ...
|
||||
IsValidCycle(
|
||||
hcMode,
|
||||
hcPeriod)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// Short ...
|
||||
|
||||
//
|
||||
// High ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(scHighBuffer, true);
|
||||
SetIndexBuffer(scHighBufferIndex, scHighBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(scHighBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(scHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(scHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Low ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(scLowBuffer, true);
|
||||
SetIndexBuffer(scLowBufferIndex, scLowBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(scLowBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(scLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(scLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(scOpenBuffer, true);
|
||||
SetIndexBuffer(scOpenBufferIndex, scOpenBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(scOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(scOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(scOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(scOpenColorBuffer, true);
|
||||
SetIndexBuffer(scOpenColorBufferIndex, scOpenColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
ArraySetAsSeries(scCloseBuffer, true);
|
||||
SetIndexBuffer(scCloseBufferIndex, scCloseBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(scCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(scCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(scCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(scCloseColorBuffer, true);
|
||||
SetIndexBuffer(scCloseColorBufferIndex, scCloseColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Medium ...
|
||||
|
||||
//
|
||||
// High ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mcHighBuffer, true);
|
||||
SetIndexBuffer(mcHighBufferIndex, mcHighBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(mcHighBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(mcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(mcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Low ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mcLowBuffer, true);
|
||||
SetIndexBuffer(mcLowBufferIndex, mcLowBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(mcLowBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(mcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(mcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mcOpenBuffer, true);
|
||||
SetIndexBuffer(mcOpenBufferIndex, mcOpenBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(mcOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(mcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(mcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mcOpenColorBuffer, true);
|
||||
SetIndexBuffer(mcOpenColorBufferIndex, mcOpenColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
ArraySetAsSeries(mcCloseBuffer, true);
|
||||
SetIndexBuffer(mcCloseBufferIndex, mcCloseBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(mcCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(mcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(mcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mcCloseColorBuffer, true);
|
||||
SetIndexBuffer(mcCloseColorBufferIndex, mcCloseColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Long ...
|
||||
|
||||
//
|
||||
// High ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lcHighBuffer, true);
|
||||
SetIndexBuffer(lcHighBufferIndex, lcHighBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(lcHighBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(lcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(lcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Low ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lcLowBuffer, true);
|
||||
SetIndexBuffer(lcLowBufferIndex, lcLowBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(lcLowBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(lcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(lcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lcOpenBuffer, true);
|
||||
SetIndexBuffer(lcOpenBufferIndex, lcOpenBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(lcOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(lcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(lcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lcOpenColorBuffer, true);
|
||||
SetIndexBuffer(lcOpenColorBufferIndex, lcOpenColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
ArraySetAsSeries(lcCloseBuffer, true);
|
||||
SetIndexBuffer(lcCloseBufferIndex, lcCloseBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(lcCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(lcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(lcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lcCloseColorBuffer, true);
|
||||
SetIndexBuffer(lcCloseColorBufferIndex, lcCloseColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Hind ...
|
||||
|
||||
//
|
||||
// High ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hcHighBuffer, true);
|
||||
SetIndexBuffer(hcHighBufferIndex, hcHighBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(hcHighBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(hcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(hcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Low ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hcLowBuffer, true);
|
||||
SetIndexBuffer(hcLowBufferIndex, hcLowBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(hcLowBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(hcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(hcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
// Open ...
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hcOpenBuffer, true);
|
||||
SetIndexBuffer(hcOpenBufferIndex, hcOpenBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(hcOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(hcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(hcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hcOpenColorBuffer, true);
|
||||
SetIndexBuffer(hcOpenColorBufferIndex, hcOpenColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
|
||||
//
|
||||
// Close ...
|
||||
|
||||
ArraySetAsSeries(hcCloseBuffer, true);
|
||||
SetIndexBuffer(hcCloseBufferIndex, hcCloseBuffer, INDICATOR_DATA);
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(hcCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
|
||||
PlotIndexSetInteger(hcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
|
||||
PlotIndexSetDouble(hcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hcCloseColorBuffer, true);
|
||||
SetIndexBuffer(hcCloseColorBufferIndex, hcCloseColorBuffer, INDICATOR_COLOR_INDEX);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
//
|
||||
void CalculateBuffer(const int barIndex)
|
||||
{
|
||||
//
|
||||
// First Update Market Cycles ...
|
||||
UpdateMarketCycles(barIndex);
|
||||
|
||||
//
|
||||
double bullishColorIDX = 0;
|
||||
double bearishColorIDX = 1;
|
||||
|
||||
//
|
||||
// Short ...
|
||||
int scBarIndex = sc.GetBarIndex(barIndex);
|
||||
XOHCL scBar1 = sc.GetBar(scBarIndex + 1);
|
||||
|
||||
//
|
||||
bool isSCBar1Bullish = scBar1.open < scBar1.close;
|
||||
|
||||
//
|
||||
scOpenBuffer[barIndex] = scBar1.open;
|
||||
scHighBuffer[barIndex] = scBar1.high;
|
||||
scCloseBuffer[barIndex] = scBar1.close;
|
||||
scLowBuffer[barIndex] = scBar1.low;
|
||||
|
||||
//
|
||||
scOpenColorBuffer[barIndex] =
|
||||
isSCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
|
||||
//
|
||||
scCloseColorBuffer[barIndex] =
|
||||
isSCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
|
||||
//
|
||||
// Medium ...
|
||||
int mcBarIndex = mc.GetBarIndex(barIndex);
|
||||
XOHCL mcBar1 = mc.GetBar(mcBarIndex + 1);
|
||||
|
||||
//
|
||||
bool isMCBar1Bullish = mcBar1.open < mcBar1.close;
|
||||
|
||||
//
|
||||
mcOpenBuffer[barIndex] = mcBar1.open;
|
||||
mcHighBuffer[barIndex] = mcBar1.high;
|
||||
mcCloseBuffer[barIndex] = mcBar1.close;
|
||||
mcLowBuffer[barIndex] = mcBar1.low;
|
||||
|
||||
//
|
||||
mcOpenColorBuffer[barIndex] =
|
||||
isMCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
|
||||
//
|
||||
mcCloseColorBuffer[barIndex] =
|
||||
isMCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
|
||||
//
|
||||
// Long ...
|
||||
int lcBarIndex = lc.GetBarIndex(barIndex);
|
||||
XOHCL lcBar1 = lc.GetBar(lcBarIndex + 1);
|
||||
|
||||
//
|
||||
bool isLCBar1Bullish = lcBar1.open < lcBar1.close;
|
||||
|
||||
//
|
||||
lcOpenBuffer[barIndex] = lcBar1.open;
|
||||
lcHighBuffer[barIndex] = lcBar1.high;
|
||||
lcCloseBuffer[barIndex] = lcBar1.close;
|
||||
lcLowBuffer[barIndex] = lcBar1.low;
|
||||
|
||||
//
|
||||
lcOpenColorBuffer[barIndex] =
|
||||
isLCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
|
||||
//
|
||||
lcCloseColorBuffer[barIndex] =
|
||||
isLCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
|
||||
//
|
||||
// Hind ...
|
||||
int hcBarIndex = hc.GetBarIndex(barIndex);
|
||||
XOHCL hcBar1 = hc.GetBar(hcBarIndex + 1);
|
||||
|
||||
//
|
||||
bool isHCBar1Bullish = hcBar1.open < hcBar1.close;
|
||||
|
||||
//
|
||||
hcOpenBuffer[barIndex] = hcBar1.open;
|
||||
hcHighBuffer[barIndex] = hcBar1.high;
|
||||
hcCloseBuffer[barIndex] = hcBar1.close;
|
||||
hcLowBuffer[barIndex] = hcBar1.low;
|
||||
|
||||
//
|
||||
hcOpenColorBuffer[barIndex] =
|
||||
isHCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
|
||||
//
|
||||
hcCloseColorBuffer[barIndex] =
|
||||
isHCBar1Bullish
|
||||
? bullishColorIDX
|
||||
: bearishColorIDX;
|
||||
}
|
||||
|
||||
//
|
||||
// TOOLS ...
|
||||
|
||||
//
|
||||
// Initial Market Cycles ...
|
||||
bool InitMarketCycles()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Short ...
|
||||
sc.method = scMode;
|
||||
sc.period = scPeriod;
|
||||
result = sc.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
X_MARKET_CYCLE_SHORT);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Medium ...
|
||||
mc.method = mcMode;
|
||||
mc.period = mcPeriod;
|
||||
result = mc.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
X_MARKET_CYCLE_MEDIUM);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Long ...
|
||||
lc.method = lcMode;
|
||||
lc.period = lcPeriod;
|
||||
result = lc.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
X_MARKET_CYCLE_LONG);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Hind ...
|
||||
hc.method = hcMode;
|
||||
hc.period = hcPeriod;
|
||||
result = hc.Init(
|
||||
_Symbol,
|
||||
_Period,
|
||||
X_MARKET_CYCLE_HIND);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Update Market Cycles ...
|
||||
bool UpdateMarketCycles(int barIndex)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Short ...
|
||||
result = sc.Update(barIndex);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Medium ...
|
||||
result = mc.Update(barIndex);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Long ...
|
||||
result = lc.Update(barIndex);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Hind ...
|
||||
result = hc.Update(barIndex);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,836 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// -------------------------------------------------
|
||||
// Name: X121_XICH
|
||||
// Description: Ichimoku Kinko Hyo ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm X121_XICH Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// Indicator Short Name ...
|
||||
#define ShortName "X121_XICH"
|
||||
|
||||
//
|
||||
// Ichimoku Golden Numbers ...
|
||||
enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS
|
||||
{
|
||||
X_ICH_BASE = 9,
|
||||
X_ICH_GOLDEN = 17,
|
||||
X_ICH_CYCLE = 26,
|
||||
X_ICH_PERIOD = 35,
|
||||
X_ICH_STAR = 45,
|
||||
X_ICH_MED = 52,
|
||||
X_ICH_LONG = 63,
|
||||
X_ICH_FULL = 72
|
||||
};
|
||||
|
||||
//
|
||||
// Ichimoku Lines Calculator Mode ...
|
||||
enum ENUM_X_ICHIMOKU_CALCULATION_MODE
|
||||
{
|
||||
//
|
||||
X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low
|
||||
X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close
|
||||
};
|
||||
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// ICHIMOKU Kinko Hyo ...
|
||||
|
||||
//
|
||||
// TENKANSEN ...
|
||||
input group "Tenkan Sen";
|
||||
input int tenkanSenLength = 9; // Length
|
||||
input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode
|
||||
|
||||
//
|
||||
// KIJUNSEN ...
|
||||
input group "Kijun Sen";
|
||||
input int kijunSenLength = 26; // Length
|
||||
input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode
|
||||
|
||||
//
|
||||
// SENKOUSPANB ...
|
||||
input group "Senkou Span B";
|
||||
input int senkouSpanBLength = 52; // Length
|
||||
input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode
|
||||
|
||||
//
|
||||
// CHIKOUSPAN ...
|
||||
input group "Chikou Span";
|
||||
input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type
|
||||
|
||||
//
|
||||
input group "Presentation";
|
||||
input bool showTenkanSen = true; // Show Tenkan Sen
|
||||
input bool showKijunSen = true; // Show Kijun Sen
|
||||
input bool showKijunSenPlus = false; // Show Kijun Sen +
|
||||
input bool showKijunSenNegative = false; // Show Kijun Sen -
|
||||
input bool showChikouSpan = true; // Show Chikou Span
|
||||
input bool showSenkouSpanA = true; // Show Senkou Span A
|
||||
input bool showSenkouSpanB = true; // Show Senkou Span B
|
||||
input bool showKumo = true; // Show Kumo
|
||||
input bool shiftKumo = true; // Shift Kumo to Future
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Includes and Imports ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// END Includes and Imports ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 15
|
||||
#property indicator_plots 8
|
||||
|
||||
//
|
||||
// PLOTTED Buffers ...
|
||||
|
||||
//
|
||||
// ICHIMOKU ...
|
||||
|
||||
//
|
||||
// TENKANSEN ...
|
||||
|
||||
//
|
||||
#define tenkanSenBufferIndex 0
|
||||
double tenkanSenBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "X121_XICH TK"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBrown
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// KIJUNSEN ...
|
||||
|
||||
//
|
||||
#define kijunSenBufferIndex 1
|
||||
double kijunSenBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "X121_XICH KJ"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrDodgerBlue
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
#define kijunSenPlusBufferIndex 2
|
||||
double kijunSenPlusBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label3 "X121_XICH KJ+"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrMediumTurquoise
|
||||
#property indicator_style3 STYLE_DOT
|
||||
#property indicator_width3 1
|
||||
|
||||
//
|
||||
#define kijunSenNegativeBufferIndex 3
|
||||
double kijunSenNegativeBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label4 "X121_XICH KJ-"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrDarkSeaGreen
|
||||
#property indicator_style4 STYLE_DOT
|
||||
#property indicator_width4 1
|
||||
|
||||
//
|
||||
// CHIKOUSPAN ...
|
||||
|
||||
//
|
||||
#define chikouSpanBufferIndex 4
|
||||
double chikouSpanBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label5 "X121_XICH CS"
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 clrDarkGreen
|
||||
#property indicator_style5 STYLE_SOLID
|
||||
#property indicator_width5 1
|
||||
|
||||
//
|
||||
#define senkouABufferIndex 5
|
||||
double senkouABuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label6 "X121_XICH SSA"
|
||||
#property indicator_type6 DRAW_LINE
|
||||
#property indicator_color6 clrLightGray
|
||||
#property indicator_style6 STYLE_DASHDOTDOT
|
||||
#property indicator_width6 1
|
||||
|
||||
//
|
||||
#define senkouBBufferIndex 6
|
||||
double senkouBBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label7 "X121_XICH SSB"
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 clrLightGray
|
||||
#property indicator_style7 STYLE_DASHDOTDOT
|
||||
#property indicator_width7 1
|
||||
|
||||
//
|
||||
// KUMO ...
|
||||
|
||||
//
|
||||
// SENKOUSPANA ...
|
||||
|
||||
//
|
||||
#define senkouSpanABufferIndex 7
|
||||
double senkouSpanABuffer[];
|
||||
|
||||
//
|
||||
// SENKOUSPANB ...
|
||||
|
||||
//
|
||||
#define senkouSpanBBufferIndex 8
|
||||
double senkouSpanBBuffer[];
|
||||
|
||||
//
|
||||
// KUMOCLOUD ...
|
||||
|
||||
//
|
||||
#define kumoBufferIndex 7
|
||||
|
||||
//
|
||||
#property indicator_label8 "X121_XICH Kumo"
|
||||
#property indicator_type8 DRAW_FILLING
|
||||
#property indicator_color8 clrAqua, clrMagenta
|
||||
#property indicator_style8 STYLE_SOLID
|
||||
#property indicator_width8 1
|
||||
|
||||
//
|
||||
// DATA Buffers ...
|
||||
|
||||
//
|
||||
#define dTenkanBufferIndex 9
|
||||
double dTenkanBuffer[];
|
||||
|
||||
//
|
||||
#define dKijunBufferIndex 10
|
||||
double dKijunBuffer[];
|
||||
|
||||
//
|
||||
#define dChikouBufferIndex 11
|
||||
double dChikouBuffer[];
|
||||
|
||||
//
|
||||
#define dSSABufferIndex 12
|
||||
double dSSABuffer[];
|
||||
|
||||
//
|
||||
#define dSSBBufferIndex 13
|
||||
double dSSBBuffer[];
|
||||
|
||||
//
|
||||
// END Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
int maxLength;
|
||||
int mHandler;
|
||||
|
||||
//
|
||||
ENUM_SERIESMODE mTenkanSenTopMode = NULL;
|
||||
ENUM_SERIESMODE mTenkanSenBottomMode = NULL;
|
||||
|
||||
//
|
||||
ENUM_SERIESMODE mKijunSenTopMode = NULL;
|
||||
ENUM_SERIESMODE mKijunSenBottomMode = NULL;
|
||||
|
||||
//
|
||||
ENUM_SERIESMODE mSenkouSpanBTopMode = NULL;
|
||||
ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
maxLength = ExtractMaxLengthOfInputs();
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Init Handler ...
|
||||
mHandler = iIchimoku(
|
||||
_Symbol,
|
||||
_Period,
|
||||
tenkanSenLength,
|
||||
kijunSenLength,
|
||||
senkouSpanBLength);
|
||||
if (mHandler == INVALID_HANDLE)
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
IndicatorRelease(mHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculating what we want ...
|
||||
int OnCalculate(
|
||||
//
|
||||
// total Candles on chart ...
|
||||
const int rates_total,
|
||||
//
|
||||
// total calculated Candles on charts ...
|
||||
const int prev_calculated,
|
||||
//
|
||||
// history of Candles Open Time ...
|
||||
const datetime &time[],
|
||||
//
|
||||
// history of Candles Open Price ...
|
||||
const double &open[],
|
||||
//
|
||||
// history of Candles High Price ...
|
||||
const double &high[],
|
||||
//
|
||||
// history of Candles Low Price ...
|
||||
const double &low[],
|
||||
//
|
||||
// history of Candles Close Price ...
|
||||
const double &close[],
|
||||
//
|
||||
// history of Tick Volumes on Candle ...
|
||||
const long &tick_volume[],
|
||||
//
|
||||
// history of Trade Volumes ...
|
||||
const long &volume[],
|
||||
//
|
||||
// history of Candles Spread Price ...
|
||||
const int &spread[])
|
||||
{
|
||||
//
|
||||
// Prepare Buffers ...
|
||||
ArraySetAsSeries(time, true);
|
||||
ArraySetAsSeries(open, true);
|
||||
ArraySetAsSeries(high, true);
|
||||
ArraySetAsSeries(low, true);
|
||||
ArraySetAsSeries(close, true);
|
||||
ArraySetAsSeries(tick_volume, true);
|
||||
ArraySetAsSeries(volume, true);
|
||||
ArraySetAsSeries(spread, true);
|
||||
|
||||
//
|
||||
// this counts Available Bars ...
|
||||
int limit;
|
||||
|
||||
//
|
||||
// Check Calculated Bars ...
|
||||
int ichCalculatedBars = BarsCalculated(mHandler);
|
||||
if (ichCalculatedBars < maxLength)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||
|
||||
//
|
||||
// Buffers Copy ...
|
||||
int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer);
|
||||
int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer);
|
||||
int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer);
|
||||
int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer);
|
||||
int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer);
|
||||
if (
|
||||
copiedSSAs < 0 ||
|
||||
copiedSSBs < 0 ||
|
||||
copiedKijuns < 0 ||
|
||||
copiedTenkans < 0 ||
|
||||
copiedChikous < 0)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||
{
|
||||
CalculateBuffers(i);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result =
|
||||
//
|
||||
(tenkanSenLength > 2 &&
|
||||
kijunSenLength > tenkanSenLength &&
|
||||
senkouSpanBLength > kijunSenLength)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve all Exists Input Max Length ...
|
||||
// use for Start Of Drawing ...
|
||||
int ExtractMaxLengthOfInputs()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Ichimoku ...
|
||||
result = MathMax(result, tenkanSenLength);
|
||||
result = MathMax(result, kijunSenLength);
|
||||
result = MathMax(result, senkouSpanBLength);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
//
|
||||
// ICHIMOKU ...
|
||||
|
||||
//
|
||||
// TENKANSEN ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(tenkanSenBuffer, true);
|
||||
SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
|
||||
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen);
|
||||
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType);
|
||||
|
||||
//
|
||||
// KIJUNSEN ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(kijunSenBuffer, true);
|
||||
SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
|
||||
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen);
|
||||
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType);
|
||||
|
||||
//
|
||||
// KIJUNSEN Plus ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(kijunSenPlusBuffer, true);
|
||||
SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength);
|
||||
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength);
|
||||
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false);
|
||||
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType);
|
||||
|
||||
//
|
||||
// KIJUNSEN Negative ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(kijunSenNegativeBuffer, true);
|
||||
SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength);
|
||||
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength);
|
||||
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false);
|
||||
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType);
|
||||
|
||||
//
|
||||
// CHIKOUSPAN ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE;
|
||||
|
||||
//
|
||||
ArraySetAsSeries(chikouSpanBuffer, true);
|
||||
SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength);
|
||||
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength);
|
||||
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan);
|
||||
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType);
|
||||
|
||||
//
|
||||
// SENKOUSPAN A and B ...
|
||||
int shiftSize = shiftKumo ? kijunSenLength : 0;
|
||||
|
||||
//
|
||||
// SENKOUSPANA ...
|
||||
ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE;
|
||||
ArraySetAsSeries(senkouABuffer, true);
|
||||
SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize);
|
||||
PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA);
|
||||
PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType);
|
||||
|
||||
//
|
||||
// SENKOUSPANB ...
|
||||
ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE;
|
||||
ArraySetAsSeries(senkouBBuffer, true);
|
||||
SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize);
|
||||
PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB);
|
||||
PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType);
|
||||
|
||||
//
|
||||
// KUMO ...
|
||||
|
||||
//
|
||||
// SENKOUSPANA ...
|
||||
ArraySetAsSeries(senkouSpanABuffer, true);
|
||||
SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength);
|
||||
|
||||
//
|
||||
// SENKOUSPANB ...
|
||||
ArraySetAsSeries(senkouSpanBBuffer, true);
|
||||
SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA);
|
||||
PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength);
|
||||
|
||||
//
|
||||
// KUMO ...
|
||||
|
||||
//
|
||||
ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE;
|
||||
|
||||
//
|
||||
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize);
|
||||
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false);
|
||||
PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType);
|
||||
|
||||
//
|
||||
// DATA Buffers ...
|
||||
|
||||
//
|
||||
// D Tenkan ...
|
||||
ArraySetAsSeries(dTenkanBuffer, true);
|
||||
SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// D Kijun ...
|
||||
ArraySetAsSeries(dKijunBuffer, true);
|
||||
SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// D Chikou ...
|
||||
ArraySetAsSeries(dChikouBuffer, true);
|
||||
SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// D SSA ...
|
||||
ArraySetAsSeries(dSSABuffer, true);
|
||||
SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
// D SSB ...
|
||||
ArraySetAsSeries(dSSBBuffer, true);
|
||||
SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index // Selected Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
// ICHIMOKU ...
|
||||
|
||||
//
|
||||
double topValue;
|
||||
double bottomValue;
|
||||
|
||||
//
|
||||
// TENKANSEN ...
|
||||
|
||||
//
|
||||
// Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ...
|
||||
if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL)
|
||||
{
|
||||
//
|
||||
switch (tenkanSenMode)
|
||||
{
|
||||
//
|
||||
case X_XICH_HH_LL_MODE:
|
||||
//
|
||||
mTenkanSenTopMode = MODE_HIGH;
|
||||
mTenkanSenBottomMode = MODE_LOW;
|
||||
break;
|
||||
|
||||
//
|
||||
case X_XICH_HO_LC_MODE:
|
||||
//
|
||||
mTenkanSenTopMode = MODE_OPEN;
|
||||
mTenkanSenBottomMode = MODE_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Top ...
|
||||
topValue = GetHighestHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mTenkanSenTopMode,
|
||||
tenkanSenLength,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
// Calculate Bottom ...
|
||||
bottomValue = GetLowestLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mTenkanSenBottomMode,
|
||||
tenkanSenLength,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double tenkanSenValue = (topValue + bottomValue) / 2;
|
||||
tenkanSenBuffer[bar_index] = tenkanSenValue;
|
||||
|
||||
//
|
||||
// KIJUNSEN ...
|
||||
|
||||
//
|
||||
// Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ...
|
||||
if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL)
|
||||
{
|
||||
//
|
||||
switch (kijunSenMode)
|
||||
{
|
||||
//
|
||||
case X_XICH_HH_LL_MODE:
|
||||
//
|
||||
mKijunSenTopMode = MODE_HIGH;
|
||||
mKijunSenBottomMode = MODE_LOW;
|
||||
break;
|
||||
|
||||
//
|
||||
case X_XICH_HO_LC_MODE:
|
||||
//
|
||||
mKijunSenTopMode = MODE_OPEN;
|
||||
mKijunSenBottomMode = MODE_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Top ...
|
||||
topValue = GetHighestHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mKijunSenTopMode,
|
||||
kijunSenLength,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
// Calculate Bottom ...
|
||||
bottomValue = GetLowestLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mKijunSenBottomMode,
|
||||
kijunSenLength,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double kijunSenValue = (topValue + bottomValue) / 2;
|
||||
kijunSenBuffer[bar_index] = kijunSenValue;
|
||||
|
||||
//
|
||||
kijunSenPlusBuffer[bar_index] = kijunSenValue;
|
||||
kijunSenNegativeBuffer[bar_index] = kijunSenValue;
|
||||
|
||||
//
|
||||
// CHIKOUSPAN ...
|
||||
double chikouSpanValue = GetAppliedPrice(
|
||||
bar_index,
|
||||
chikuoSpanAppliedTo);
|
||||
chikouSpanBuffer[bar_index] = chikouSpanValue;
|
||||
|
||||
//
|
||||
// KUMO ...
|
||||
|
||||
//
|
||||
// SENKOUSPANA ...
|
||||
double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2;
|
||||
senkouABuffer[bar_index] = senkouSpanAValue;
|
||||
senkouSpanABuffer[bar_index] = senkouSpanAValue;
|
||||
|
||||
//
|
||||
// SENKOUSPANB ...
|
||||
|
||||
//
|
||||
// Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ...
|
||||
if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL)
|
||||
{
|
||||
//
|
||||
switch (senkouSpanBMode)
|
||||
{
|
||||
//
|
||||
case X_XICH_HH_LL_MODE:
|
||||
//
|
||||
mSenkouSpanBTopMode = MODE_HIGH;
|
||||
mSenkouSpanBBottomMode = MODE_LOW;
|
||||
break;
|
||||
|
||||
//
|
||||
case X_XICH_HO_LC_MODE:
|
||||
//
|
||||
mSenkouSpanBTopMode = MODE_OPEN;
|
||||
mSenkouSpanBBottomMode = MODE_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Top ...
|
||||
topValue = GetHighestHigh(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mSenkouSpanBTopMode,
|
||||
senkouSpanBLength,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
// Calculate Bottom ...
|
||||
bottomValue = GetLowestLow(
|
||||
_Symbol,
|
||||
_Period,
|
||||
mSenkouSpanBBottomMode,
|
||||
senkouSpanBLength,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
double senkouSpanBValue = (topValue + bottomValue) / 2;
|
||||
senkouBBuffer[bar_index] = senkouSpanBValue;
|
||||
senkouSpanBBuffer[bar_index] = senkouSpanBValue;
|
||||
}
|
||||
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
+603
@@ -0,0 +1,603 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Seriallize Library
|
||||
// ---------------------------------------
|
||||
// Name: XSeriallizer
|
||||
// Description: provides Seriallizing EA abilities ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.models.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||
|
||||
//
|
||||
string XProviderToken = "PRV";
|
||||
string XSupportToken = "SP";
|
||||
string XSLTrailToken = "SLT";
|
||||
string XPeriodToken = "PR";
|
||||
|
||||
//
|
||||
string XConfigToken = "XPV";
|
||||
string XItemSeparator = "|";
|
||||
string XItemContentSeparator = ",";
|
||||
|
||||
//
|
||||
string XFirstGenToken = "0";
|
||||
|
||||
//
|
||||
// PERIOD ...
|
||||
|
||||
//
|
||||
// Detect a Comment has period or not ...
|
||||
bool HasPeriod(string comment)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (StringLen(comment) == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int tokenPos = StringFind(
|
||||
comment,
|
||||
XPeriodToken);
|
||||
result = tokenPos >= 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract Period String ...
|
||||
string ExtractPeriodString(string comment)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
bool hasPeriod = HasPeriod(comment);
|
||||
if (!hasPeriod)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = ExtractString(
|
||||
comment,
|
||||
XPeriodToken + "(",
|
||||
")");
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract Time Frame From Comment ...
|
||||
ENUM_TIMEFRAMES ExtractPeriod(string comment)
|
||||
{
|
||||
//
|
||||
ENUM_TIMEFRAMES result = NULL;
|
||||
|
||||
//
|
||||
if (StringLen(comment) <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string periodStr = ExtractPeriodString(comment);
|
||||
if (StringLen(periodStr) <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = ToPeriod(periodStr);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// PROVIDER ...
|
||||
|
||||
//
|
||||
// Extract a Provider name if exists from a Comment ...
|
||||
string ExtractProvider(string comment)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
if (StringLen(comment) <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = ExtractString(
|
||||
comment,
|
||||
XProviderToken + "(",
|
||||
")");
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate Provider String for Using in Positions Comment ...
|
||||
// NOTE: if there is more than One Provider, it takes first
|
||||
// provider as main and the others used to increase volume ...
|
||||
string GenerateProvidersString(XSignal &signal)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
int providersCount = ArraySize(signal.providers);
|
||||
if (providersCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = XProviderToken + "(" + signal.providers[0] + ")";
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SLTRAIL ...
|
||||
|
||||
//
|
||||
string GenerateSLTrailComment(int level)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
if (level <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = XSLTrailToken + "(" + ToString(level) + ")";
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int ExtractSLTrailLevel(string comment)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
if (StringLen(comment) == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string levelStr = ExtractString(
|
||||
comment,
|
||||
XSLTrailToken + "(",
|
||||
")");
|
||||
if (StringLen(levelStr) == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = (int)levelStr;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string PrepareSLTrailComment(
|
||||
const string comment // Original Position Comment ...
|
||||
)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
if (StringLen(comment) == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int level = 0;
|
||||
result = comment;
|
||||
|
||||
//
|
||||
// Check Comment Contains SL Trailing or not ...
|
||||
int lastTrailLevel = ExtractSLTrailLevel(comment);
|
||||
if (lastTrailLevel <= 0)
|
||||
{
|
||||
level++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
level = lastTrailLevel + 1;
|
||||
string lastLevelStr = GenerateSLTrailComment(lastTrailLevel);
|
||||
StringReplace(
|
||||
result,
|
||||
lastLevelStr,
|
||||
"");
|
||||
}
|
||||
|
||||
//
|
||||
// Generate level Comment ...
|
||||
string levelStr = GenerateSLTrailComment(level);
|
||||
result += levelStr;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SUPPORT ...
|
||||
|
||||
//
|
||||
// Generate Specific Position's Support Comment
|
||||
// index is number of Supports ...
|
||||
string GenerateSupportSignalComment(
|
||||
ulong ticket, // Position/Order Ticket
|
||||
int index // Support Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
result = XSupportToken + "(" + (string)ticket + "," + ToString(index) + ")";
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract Support Parameters String from specified Comment ...
|
||||
string ExtractSupportParam(string comment)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
if (StringLen(comment) <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = ExtractString(
|
||||
comment,
|
||||
XSupportToken + "(",
|
||||
")");
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract Support Info as String array for Specific Comment ...
|
||||
bool ExtractSupportParams(
|
||||
string comment, // Specified Comment ...
|
||||
string ¶ms[] // Hold Result ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
string supParam = ExtractSupportParam(comment);
|
||||
if (StringLen(supParam) == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
SplitContent(
|
||||
params,
|
||||
supParam);
|
||||
int paramsCount = ArraySize(params);
|
||||
|
||||
//
|
||||
result = paramsCount == 2;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract Support Parent Ticket ...
|
||||
ulong ExtractParentTicket(string comment)
|
||||
{
|
||||
//
|
||||
ulong result = 0;
|
||||
|
||||
//
|
||||
string params[];
|
||||
bool isSupport = ExtractSupportParams(
|
||||
comment,
|
||||
params);
|
||||
if (!isSupport)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = (ulong)params[0];
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract Support Index ...
|
||||
int ExtractSupportIndex(string comment)
|
||||
{
|
||||
//
|
||||
int result = -1;
|
||||
|
||||
//
|
||||
string params[];
|
||||
bool isSupport = ExtractSupportParams(
|
||||
comment,
|
||||
params);
|
||||
if (!isSupport)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = (int)params[1];
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// START XEQM Support ...
|
||||
//
|
||||
|
||||
//
|
||||
string XEQMSupportToken = "XEQM";
|
||||
|
||||
//
|
||||
// Generate String Tag for EQM Support Signals ...
|
||||
string GenerateXEQMSupportComment()
|
||||
{
|
||||
//
|
||||
string result = XEQMSupportToken;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check a Comment belongs to a EQM Support or not ...
|
||||
bool IsEQMSupport(string comment)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
if (StringLen(comment) <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int tokenPosition = StringFind(
|
||||
comment,
|
||||
XEQMSupportToken);
|
||||
result = tokenPosition >= 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Select EQM Support Orders ...
|
||||
int GetEQMSupportOrders(
|
||||
XOrder &supports[], // Hold Result ...
|
||||
XOrder &orders[], // List of All Orders ...
|
||||
ENUM_TIMEFRAMES period = NULL // Specified Period ...
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Cleanup Array ...
|
||||
Clean(supports);
|
||||
|
||||
//
|
||||
// Count Orders ...
|
||||
int ordersCount = ArraySize(orders);
|
||||
if (ordersCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop through Orders ...
|
||||
for (int i = 0; i < ordersCount; i++)
|
||||
{
|
||||
//
|
||||
// Select Indexed Order ...
|
||||
XOrder iOrder = orders[i];
|
||||
|
||||
//
|
||||
// Check Order is Support or not ...
|
||||
bool isSupport = IsEQMSupport(iOrder.comment);
|
||||
if (!isSupport)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Order is not Triggered ...
|
||||
if (iOrder.state != ORDER_STATE_PLACED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Period ...
|
||||
if (period != NULL && iOrder.period != period)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// we now sure this order is EQM Support ...
|
||||
Add(
|
||||
iOrder,
|
||||
supports);
|
||||
}
|
||||
|
||||
//
|
||||
// Count Result ...
|
||||
result = ArraySize(supports);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Select EQM Support Positions ...
|
||||
int GetEQMSupportPositions(
|
||||
XPosition &supports[], // Hold Result ...
|
||||
XPosition &positions[], // List of All Positions ...
|
||||
ENUM_TIMEFRAMES period = NULL // Specified Period ...
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Cleanup Array ...
|
||||
Clean(supports);
|
||||
|
||||
//
|
||||
// Count Positions ...
|
||||
int positionsCount = ArraySize(positions);
|
||||
if (positionsCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Loop through Positions ...
|
||||
for (int i = 0; i < positionsCount; i++)
|
||||
{
|
||||
//
|
||||
// Select Indexed Position ...
|
||||
XPosition iPosition = positions[i];
|
||||
|
||||
//
|
||||
// Check Position is Support or not ...
|
||||
bool isSupport = IsEQMSupport(iPosition.comment);
|
||||
if (!isSupport)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Period ...
|
||||
if (period != NULL && iPosition.period != period)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// we now sure this order is EQM Support ...
|
||||
Add(
|
||||
iPosition,
|
||||
supports);
|
||||
}
|
||||
|
||||
//
|
||||
// Count Result ...
|
||||
result = ArraySize(supports);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END XEQM Support ...
|
||||
//
|
||||
|
||||
//
|
||||
// START FirstGen ...
|
||||
//
|
||||
|
||||
//
|
||||
string GenerateFirstGenIdentifier(const string signaller)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
if (StringLen(signaller) <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return signaller + XFirstGenToken;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool IsFirstGenOf(
|
||||
const string signaller, // Specified Signaller
|
||||
const string comment // Comment
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
string id = GenerateFirstGenIdentifier(signaller);
|
||||
|
||||
//
|
||||
int idPos = StringFind(
|
||||
comment,
|
||||
id
|
||||
);
|
||||
result = idPos >= 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END FirstGen ...
|
||||
//
|
||||
@@ -0,0 +1,294 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ZigZag.mq5 |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 1
|
||||
//--- plot ZigZag
|
||||
#property indicator_label1 "ZigZag"
|
||||
#property indicator_type1 DRAW_SECTION
|
||||
#property indicator_color1 clrYellow
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//--- input parameters
|
||||
input int InpDepth =12; // Depth
|
||||
input int InpDeviation=5; // Deviation
|
||||
input int InpBackstep =3; // Back Step
|
||||
//--- indicator buffers
|
||||
double ZigZagBuffer[]; // main buffer
|
||||
double HighMapBuffer[]; // ZigZag high extremes (peaks)
|
||||
double LowMapBuffer[]; // ZigZag low extremes (bottoms)
|
||||
|
||||
int ExtRecalc=3; // number of last extremes for recalculation
|
||||
|
||||
enum EnSearchMode
|
||||
{
|
||||
Extremum=0, // searching for the first extremum
|
||||
Peak=1, // searching for the next ZigZag peak
|
||||
Bottom=-1 // searching for the next ZigZag bottom
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ZigZagBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
|
||||
//--- set short name and digits
|
||||
string short_name=StringFormat("ZigZag(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- set an empty value
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| ZigZag calculation |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total<100)
|
||||
return(0);
|
||||
//---
|
||||
int i=0;
|
||||
int start=0,extreme_counter=0,extreme_search=Extremum;
|
||||
int shift=0,back=0,last_high_pos=0,last_low_pos=0;
|
||||
double val=0,res=0;
|
||||
double curlow=0,curhigh=0,last_high=0,last_low=0;
|
||||
//--- initializing
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
ArrayInitialize(ZigZagBuffer,0.0);
|
||||
ArrayInitialize(HighMapBuffer,0.0);
|
||||
ArrayInitialize(LowMapBuffer,0.0);
|
||||
start=InpDepth;
|
||||
}
|
||||
|
||||
//--- ZigZag was already calculated before
|
||||
if(prev_calculated>0)
|
||||
{
|
||||
i=rates_total-1;
|
||||
//--- searching for the third extremum from the last uncompleted bar
|
||||
while(extreme_counter<ExtRecalc && i>rates_total-100)
|
||||
{
|
||||
res=ZigZagBuffer[i];
|
||||
if(res!=0.0)
|
||||
extreme_counter++;
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
start=i;
|
||||
|
||||
//--- what type of exremum we search for
|
||||
if(LowMapBuffer[i]!=0.0)
|
||||
{
|
||||
curlow=LowMapBuffer[i];
|
||||
extreme_search=Peak;
|
||||
}
|
||||
else
|
||||
{
|
||||
curhigh=HighMapBuffer[i];
|
||||
extreme_search=Bottom;
|
||||
}
|
||||
//--- clear indicator values
|
||||
for(i=start+1; i<rates_total && !IsStopped(); i++)
|
||||
{
|
||||
ZigZagBuffer[i] =0.0;
|
||||
LowMapBuffer[i] =0.0;
|
||||
HighMapBuffer[i]=0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//--- searching for high and low extremes
|
||||
for(shift=start; shift<rates_total && !IsStopped(); shift++)
|
||||
{
|
||||
//--- low
|
||||
val=low[Lowest(low,InpDepth,shift)];
|
||||
if(val==last_low)
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
last_low=val;
|
||||
if((low[shift]-val)>InpDeviation*_Point)
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=1; back<=InpBackstep; back++)
|
||||
{
|
||||
res=LowMapBuffer[shift-back];
|
||||
if((res!=0) && (res>val))
|
||||
LowMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(low[shift]==val)
|
||||
LowMapBuffer[shift]=val;
|
||||
else
|
||||
LowMapBuffer[shift]=0.0;
|
||||
//--- high
|
||||
val=high[Highest(high,InpDepth,shift)];
|
||||
if(val==last_high)
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
last_high=val;
|
||||
if((val-high[shift])>InpDeviation*_Point)
|
||||
val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=1; back<=InpBackstep; back++)
|
||||
{
|
||||
res=HighMapBuffer[shift-back];
|
||||
if((res!=0) && (res<val))
|
||||
HighMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(high[shift]==val)
|
||||
HighMapBuffer[shift]=val;
|
||||
else
|
||||
HighMapBuffer[shift]=0.0;
|
||||
}
|
||||
|
||||
//--- set last values
|
||||
if(extreme_search==0) // undefined values
|
||||
{
|
||||
last_low=0.0;
|
||||
last_high=0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_low=curlow;
|
||||
last_high=curhigh;
|
||||
}
|
||||
|
||||
//--- final selection of extreme points for ZigZag
|
||||
for(shift=start; shift<rates_total && !IsStopped(); shift++)
|
||||
{
|
||||
res=0.0;
|
||||
switch(extreme_search)
|
||||
{
|
||||
case Extremum:
|
||||
if(last_low==0.0 && last_high==0.0)
|
||||
{
|
||||
if(HighMapBuffer[shift]!=0)
|
||||
{
|
||||
last_high=high[shift];
|
||||
last_high_pos=shift;
|
||||
extreme_search=Bottom;
|
||||
ZigZagBuffer[shift]=last_high;
|
||||
res=1;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0.0)
|
||||
{
|
||||
last_low=low[shift];
|
||||
last_low_pos=shift;
|
||||
extreme_search=Peak;
|
||||
ZigZagBuffer[shift]=last_low;
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Peak:
|
||||
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low && HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigZagBuffer[last_low_pos]=0.0;
|
||||
last_low_pos=shift;
|
||||
last_low=LowMapBuffer[shift];
|
||||
ZigZagBuffer[shift]=last_low;
|
||||
res=1;
|
||||
}
|
||||
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
last_high=HighMapBuffer[shift];
|
||||
last_high_pos=shift;
|
||||
ZigZagBuffer[shift]=last_high;
|
||||
extreme_search=Bottom;
|
||||
res=1;
|
||||
}
|
||||
break;
|
||||
case Bottom:
|
||||
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>last_high && LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigZagBuffer[last_high_pos]=0.0;
|
||||
last_high_pos=shift;
|
||||
last_high=HighMapBuffer[shift];
|
||||
ZigZagBuffer[shift]=last_high;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
last_low=LowMapBuffer[shift];
|
||||
last_low_pos=shift;
|
||||
ZigZagBuffer[shift]=last_low;
|
||||
extreme_search=Peak;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return(rates_total);
|
||||
}
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Search for the index of the highest bar |
|
||||
//+------------------------------------------------------------------+
|
||||
int Highest(const double &array[],const int depth,const int start)
|
||||
{
|
||||
if(start<0)
|
||||
return(0);
|
||||
|
||||
double max=array[start];
|
||||
int index=start;
|
||||
//--- start searching
|
||||
for(int i=start-1; i>start-depth && i>=0; i--)
|
||||
{
|
||||
if(array[i]>max)
|
||||
{
|
||||
index=i;
|
||||
max=array[i];
|
||||
}
|
||||
}
|
||||
//--- return index of the highest bar
|
||||
return(index);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Search for the index of the lowest bar |
|
||||
//+------------------------------------------------------------------+
|
||||
int Lowest(const double &array[],const int depth,const int start)
|
||||
{
|
||||
if(start<0)
|
||||
return(0);
|
||||
|
||||
double min=array[start];
|
||||
int index=start;
|
||||
//--- start searching
|
||||
for(int i=start-1; i>start-depth && i>=0; i--)
|
||||
{
|
||||
if(array[i]<min)
|
||||
{
|
||||
index=i;
|
||||
min=array[i];
|
||||
}
|
||||
}
|
||||
//--- return index of the lowest bar
|
||||
return(index);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,34 @@
|
||||
void CommentLab(string CommentText)
|
||||
{
|
||||
//
|
||||
string CommentLabel;
|
||||
int CommentIndex = 0;
|
||||
|
||||
//
|
||||
if (CommentText == "")
|
||||
{
|
||||
//
|
||||
// delete all Comment texts
|
||||
while (ObjectFind(StringConcatenate("CommentLabel", CommentIndex)) >= 0)
|
||||
{
|
||||
//
|
||||
ObjectDelete(StringConcatenate("CommentLabel", CommentIndex));
|
||||
CommentIndex++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
while (ObjectFind(StringConcatenate("CommentLabel", CommentIndex)) >= 0)
|
||||
{
|
||||
CommentIndex++;
|
||||
}
|
||||
|
||||
//
|
||||
CommentLabel = StringConcatenate("CommentLabel", CommentIndex);
|
||||
ObjectCreate(CommentLabel, OBJ_LABEL, 0, 0, 0);
|
||||
ObjectSet(CommentLabel, OBJPROP_CORNER, 0);
|
||||
ObjectSet(CommentLabel, OBJPROP_XDISTANCE, 5);
|
||||
ObjectSet(CommentLabel, OBJPROP_YDISTANCE, 15 + (CommentIndex * 15));
|
||||
ObjectSetText(CommentLabel, CommentText, 10, "Tahoma", Status_Color);
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,102 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Models Library
|
||||
// ---------------------------------------
|
||||
// Name: XModels
|
||||
// Description: provides all required models ...
|
||||
//
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Properties ...
|
||||
#property library
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://www.saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// How To Calculate Static Volume ...
|
||||
enum ENUM_STATIC_VOLUME_METHODS
|
||||
{
|
||||
//
|
||||
// Based On Deposit ...
|
||||
X_STATIC_VOLUME_BASED_ON_DEPOSIT,
|
||||
//
|
||||
// Based On Balance ...
|
||||
X_STATIC_VOLUME_BASED_ON_BALANCE,
|
||||
};
|
||||
|
||||
//
|
||||
// START Model Definitions ...
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Select Positions Type ...
|
||||
enum ENUM_X_POSITION_SELECT_METHODS
|
||||
{
|
||||
X_POSITION_SELECT_NONE, // None
|
||||
X_POSITION_SELECT_MAX, // Max
|
||||
X_POSITION_SELECT_MIN, // Min
|
||||
X_POSITION_SELECT_ALL, // Min
|
||||
};
|
||||
|
||||
//
|
||||
// Available Guard Action ...
|
||||
enum ENUM_X_GUARD_ACTIONS
|
||||
{
|
||||
X_GUARD_ACTION_NOTHING, // Nothing
|
||||
X_GUARD_ACTION_HEDGE, // Hedge
|
||||
X_GUARD_PARTIAL_CLOSE, // Partial Close
|
||||
X_GUARD_ACTION_TRAIL_STOP, // Trail StopLoss
|
||||
X_GUARD_ACTION_FORCE_CLOSE, // Force Close
|
||||
X_GUARD_ACTION_ADD_SUPPORT_SIGNAL, // Add Support Signal
|
||||
X_GUARD_ACTION_CANCEL_PENDING_ORDERS, // Cancel Pending Orders
|
||||
};
|
||||
|
||||
//
|
||||
// Model Guard Info ...
|
||||
struct XGuard
|
||||
{
|
||||
string symbol;
|
||||
string provider;
|
||||
ENUM_TIMEFRAMES period;
|
||||
ENUM_POSITION_TYPE type;
|
||||
ENUM_X_GUARD_ACTIONS action;
|
||||
|
||||
//
|
||||
double dblPayLoad;
|
||||
string strPayload;
|
||||
};
|
||||
|
||||
//
|
||||
// EXTENSION Methods ...
|
||||
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,728 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XSAMPLE MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XSAMPLE
|
||||
// Description: an Exper Advisor which used RSI and MA
|
||||
// to Analyse Market ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////x
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XSAMPLE"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#define ShortName "XSAMPLE"
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||
|
||||
//
|
||||
#include "../Helpers/x-saherelm.x121.xmc.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.x121.xstr.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.x121.xche.helper.mq5"
|
||||
#include "../Helpers/x-saherelm.x121.xosc.helper.mq5"
|
||||
|
||||
//
|
||||
#include "../Classes/x-saherelm.x121.xmcycle.class.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
long xSampleEAMagicNumber = 78692110; // Magic Number
|
||||
int xSampleEASlippage = 10; // Slippgae
|
||||
|
||||
//
|
||||
double xSampleEAVolume = 0.01;
|
||||
|
||||
//
|
||||
// Vars ...
|
||||
string xSampleEASymbol;
|
||||
ENUM_TIMEFRAMES xSampleEAPeriod;
|
||||
|
||||
//
|
||||
int maxBuys = 1;
|
||||
int maxSells = 1;
|
||||
int buyCount = 0;
|
||||
int sellCount = 0;
|
||||
|
||||
//
|
||||
double _tp = 0;
|
||||
double _sl = 0;
|
||||
double _entry = 0;
|
||||
ENUM_POSITION_TYPE _type = NULL;
|
||||
|
||||
//
|
||||
MqlTick xSampleEATick;
|
||||
XSCTrade *xSampleEATrader;
|
||||
|
||||
// //
|
||||
// // XCHE ...
|
||||
// X121CHEInputs xSampleEACHEInputs;
|
||||
// XSCX121CHEHelper xSampleEACHEHelper;
|
||||
|
||||
// //
|
||||
// // XMC ...
|
||||
// X121MCInputs xSampleEAMCInputs;
|
||||
// XSCX121MCHelper xSampleEAMCHelper;
|
||||
|
||||
// //
|
||||
// // XSTR ...
|
||||
// X121STRInputs xSampleEASTRInputs;
|
||||
// XSCX121STRHelper xSampleEASTRHelper;
|
||||
|
||||
// //
|
||||
// // XOSC ...
|
||||
// X121OSCInputs xSampleEAOSCInputs;
|
||||
// XSCX121OSCHelper xSampleEAOSCHelper;
|
||||
|
||||
// //
|
||||
// // XICH ...
|
||||
// X121ICHInputs xSampleEAICHInputs;
|
||||
// XSCX121ICHHelper xSampleEAICHHelper;
|
||||
|
||||
//
|
||||
// X121MCycle ...
|
||||
X121MCycleInputs xSampleEA121MCInputs;
|
||||
XSC121Market xSampleEA121MC;
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
if (xSampleEASymbol == NULL || StringLen(xSampleEASymbol) <= 0)
|
||||
{
|
||||
xSampleEASymbol = _Symbol;
|
||||
}
|
||||
|
||||
//
|
||||
if (xSampleEAPeriod == NULL)
|
||||
{
|
||||
xSampleEAPeriod = _Period;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!XSampleEAValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
drawPrefix = ShortName;
|
||||
|
||||
// //
|
||||
// // XCHE ...
|
||||
|
||||
// //
|
||||
// xSampleEACHEInputs.Default();
|
||||
// if (!xSampleEACHEInputs.IsValid())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (!xSampleEACHEHelper.Init(
|
||||
// xSampleEASymbol,
|
||||
// xSampleEAPeriod,
|
||||
// xSampleEACHEInputs))
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // XMC ...
|
||||
|
||||
// //
|
||||
// xSampleEAMCInputs.Default();
|
||||
// if (!xSampleEAMCInputs.IsValid())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (!xSampleEAMCHelper.Init(
|
||||
// xSampleEASymbol,
|
||||
// xSampleEAPeriod,
|
||||
// xSampleEAMCInputs))
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // XSTR ...
|
||||
|
||||
// //
|
||||
// xSampleEASTRInputs.Default();
|
||||
// if (!xSampleEASTRInputs.IsValid())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (!xSampleEASTRHelper.Init(
|
||||
// xSampleEASymbol,
|
||||
// xSampleEAPeriod,
|
||||
// xSampleEASTRInputs))
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// // XOSC ...
|
||||
|
||||
// //
|
||||
// xSampleEAOSCInputs.Default();
|
||||
// if (!xSampleEAOSCInputs.IsValid())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (!xSampleEAOSCHelper.Init(
|
||||
// xSampleEASymbol,
|
||||
// xSampleEAPeriod,
|
||||
// xSampleEAOSCInputs))
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
//
|
||||
// XICH ...
|
||||
|
||||
// //
|
||||
// xSampleEAICHInputs.Default();
|
||||
// if (!xSampleEAICHInputs.IsValid())
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
// //
|
||||
// if (!xSampleEAICHHelper.Init(
|
||||
// xSampleEASymbol,
|
||||
// xSampleEAPeriod,
|
||||
// xSampleEAICHInputs))
|
||||
// {
|
||||
// return INIT_PARAMETERS_INCORRECT;
|
||||
// }
|
||||
|
||||
//
|
||||
// X121Market Cycle ...
|
||||
bool result = xSampleEA121MCInputs.Init(
|
||||
xSampleEASymbol,
|
||||
xSampleEAPeriod,
|
||||
X_MARKET_CYCLE_SHORT,
|
||||
PERIOD_H1,
|
||||
X_PERIOD_MANUALLY //
|
||||
);
|
||||
|
||||
//
|
||||
// after Inputs Initialize Successfully we must prepare Styling for Draw ...
|
||||
ApplyMCDrawStyles();
|
||||
|
||||
//
|
||||
result = xSampleEA121MC.Init(
|
||||
xSampleEA121MCInputs
|
||||
//
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize XTrader ...
|
||||
xSampleEATrader = new XSCTrade(
|
||||
xSampleEASlippage,
|
||||
xSampleEAMagicNumber);
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// De Initialize XSampleEA Providers ...
|
||||
delete xSampleEATrader;
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!IsNewCandle(
|
||||
xSampleEASymbol,
|
||||
xSampleEAPeriod))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Tick ...
|
||||
if (!SymbolInfoTick(xSampleEASymbol, xSampleEATick))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Counting Currently Open Positions ...
|
||||
buyCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_BUY);
|
||||
sellCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_SELL);
|
||||
|
||||
//
|
||||
// TestMC();
|
||||
// TestCHE();
|
||||
// TestSTR();
|
||||
// TestOSC();
|
||||
// TestICH();
|
||||
|
||||
//
|
||||
// TestMCycle();
|
||||
|
||||
//
|
||||
// Draw Market Cycle Bars On Chart ...
|
||||
int offset = 0;
|
||||
xSampleEA121MC.Draw(
|
||||
ChartID(),
|
||||
0,
|
||||
offset
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
if (buyCount < maxBuys)
|
||||
{
|
||||
//
|
||||
// Check For Buy Signals ...
|
||||
}
|
||||
|
||||
//
|
||||
if (sellCount < maxSells)
|
||||
{
|
||||
//
|
||||
// Check for Sell Signals ...
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
//
|
||||
// Validate Variables nd Inputs ...
|
||||
bool XSampleEAValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
xSampleEASlippage > 0 &&
|
||||
xSampleEAMagicNumber > 0
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Tools ...
|
||||
|
||||
// //
|
||||
// void TestCHE()
|
||||
// {
|
||||
// //
|
||||
// double longExit1 = xSampleEACHEHelper.GetLongExit1(0);
|
||||
// if (NotEmpty(longExit1))
|
||||
// {
|
||||
// Print("LE1: " + ToString(longExit1));
|
||||
// }
|
||||
|
||||
// //
|
||||
// double lEs[];
|
||||
// int lEsCount = xSampleEACHEHelper.CopyLongExit1(
|
||||
// 0,
|
||||
// 2,
|
||||
// lEs);
|
||||
// if (lEsCount > 0)
|
||||
// {
|
||||
// //
|
||||
// for (int i = 0; i < lEsCount; i++)
|
||||
// {
|
||||
// //
|
||||
// double iVal = lEs[i];
|
||||
|
||||
// //
|
||||
// if (NotEmpty(iVal))
|
||||
// {
|
||||
// //
|
||||
// Print("LE " + ToString(i) + ": " + ToString(iVal));
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// Print(" ");
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// void TestMC()
|
||||
// {
|
||||
// //
|
||||
// double fast = xSampleEAMCHelper.GetFast(0);
|
||||
// if (NotEmpty(fast))
|
||||
// {
|
||||
// Print("Fast: " + ToString(fast));
|
||||
// }
|
||||
|
||||
// //
|
||||
// double slow = xSampleEAMCHelper.GetSlow(0);
|
||||
// if (NotEmpty(slow))
|
||||
// {
|
||||
// Print("Slow: " + ToString(slow));
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// void TestSTR()
|
||||
// {
|
||||
// //
|
||||
// double trend = xSampleEASTRHelper.GetTrend(0);
|
||||
// if (NotEmpty(trend))
|
||||
// {
|
||||
// Print("Trend: " + ToString(trend));
|
||||
// }
|
||||
|
||||
// //
|
||||
// double state = xSampleEASTRHelper.GetState(0);
|
||||
// if (NotEmpty(state))
|
||||
// {
|
||||
// Print("State: " + EnumToString(xSampleEASTRHelper.ToState(state)));
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// void TestOSC()
|
||||
// {
|
||||
// //
|
||||
// double rsi = xSampleEAOSCHelper.GetRSI(0);
|
||||
// if (NotEmpty(rsi))
|
||||
// {
|
||||
// Print("RSI: " + ToString(rsi));
|
||||
// }
|
||||
|
||||
// //
|
||||
// double cci = xSampleEAOSCHelper.GetCCI(0);
|
||||
// if (NotEmpty(cci))
|
||||
// {
|
||||
// Print("CCI: " + ToString(cci));
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// void TestICH()
|
||||
// {
|
||||
// //
|
||||
// double tenkanSen = xSampleEAICHHelper.GetTenkanSen(1);
|
||||
// double tenkanSenLast = xSampleEAICHHelper.GetTenkanSen(2);
|
||||
// //
|
||||
// double kijunSen = xSampleEAICHHelper.GetKijunSen(1);
|
||||
// double kijunSenLast = xSampleEAICHHelper.GetKijunSen(2);
|
||||
// //
|
||||
// double chikouSpan = xSampleEAICHHelper.GetChikouSpan(1);
|
||||
// //
|
||||
// double senkouSpanA = xSampleEAICHHelper.GetSenkouSpanA(1);
|
||||
// double senkouSpanALast = xSampleEAICHHelper.GetSenkouSpanA(2);
|
||||
// //
|
||||
// double senkouSpanB = xSampleEAICHHelper.GetSenkouSpanB(1);
|
||||
// double senkouSpanBLast = xSampleEAICHHelper.GetSenkouSpanB(2);
|
||||
// //
|
||||
// double futureSenkouSpanA = xSampleEAICHHelper.GetFutureSenkouSpanA(1);
|
||||
// double futureSenkouSpanALast = xSampleEAICHHelper.GetFutureSenkouSpanA(2);
|
||||
// //
|
||||
// double futureSenkouSpanB = xSampleEAICHHelper.GetFutureSenkouSpanB(1);
|
||||
// double futureSenkouSpanBLast = xSampleEAICHHelper.GetFutureSenkouSpanB(2);
|
||||
|
||||
// //
|
||||
// bool isTenkanSenCrossedOverKijunSen =
|
||||
// //
|
||||
// tenkanSen > kijunSen &&
|
||||
// tenkanSenLast <= kijunSenLast
|
||||
// //
|
||||
// ;
|
||||
// if (isTenkanSenCrossedOverKijunSen)
|
||||
// {
|
||||
// Print("isTenkanSenCrossedOverKijunSen");
|
||||
// }
|
||||
|
||||
// //
|
||||
// bool isTenkanSenCrossedUnderKijunSen =
|
||||
// //
|
||||
// tenkanSen < kijunSen &&
|
||||
// tenkanSenLast >= kijunSenLast
|
||||
// //
|
||||
// ;
|
||||
// if (isTenkanSenCrossedUnderKijunSen)
|
||||
// {
|
||||
// Print("isTenkanSenCrossedUnderKijunSen");
|
||||
// }
|
||||
|
||||
// //
|
||||
// bool isKumoSwitchedToBullish =
|
||||
// //
|
||||
// senkouSpanA > senkouSpanB &&
|
||||
// senkouSpanALast <= senkouSpanBLast
|
||||
// //
|
||||
// ;
|
||||
// if (isKumoSwitchedToBullish)
|
||||
// {
|
||||
// Print("isKumoSwitchedToBullish");
|
||||
// }
|
||||
|
||||
// //
|
||||
// bool isKumoSwitchedToBearish =
|
||||
// //
|
||||
// senkouSpanA < senkouSpanB &&
|
||||
// senkouSpanALast >= senkouSpanBLast
|
||||
// //
|
||||
// ;
|
||||
// if (isKumoSwitchedToBearish)
|
||||
// {
|
||||
// Print("isKumoSwitchedToBearish");
|
||||
// }
|
||||
|
||||
// //
|
||||
// bool isFutureKumoSwitchedToBullish =
|
||||
// //
|
||||
// futureSenkouSpanA > futureSenkouSpanB &&
|
||||
// futureSenkouSpanALast <= futureSenkouSpanBLast
|
||||
// //
|
||||
// ;
|
||||
// if (isFutureKumoSwitchedToBullish)
|
||||
// {
|
||||
// Print("isFutureKumoSwitchedToBullish");
|
||||
// }
|
||||
|
||||
// //
|
||||
// bool isFutureKumoSwitchedToBearish =
|
||||
// //
|
||||
// futureSenkouSpanA < futureSenkouSpanB &&
|
||||
// futureSenkouSpanALast >= futureSenkouSpanBLast
|
||||
// //
|
||||
// ;
|
||||
// if (isFutureKumoSwitchedToBearish)
|
||||
// {
|
||||
// Print("isFutureKumoSwitchedToBearish");
|
||||
// }
|
||||
// }
|
||||
|
||||
// //
|
||||
// void TestMCycle()
|
||||
// {
|
||||
// //
|
||||
// // double fast0 = xSampleEA121MC.mc.GetFast(0);
|
||||
// // double fast1 = xSampleEA121MC.mc.GetFast(1);
|
||||
|
||||
// // //
|
||||
// // double slow0 = xSampleEA121MC.mc.GetSlow(0);
|
||||
// // double slow1 = xSampleEA121MC.mc.GetSlow(1);
|
||||
|
||||
// // //
|
||||
// // double tenkanSen = xSampleEA121MC.ich.GetTenkanSen(0);
|
||||
|
||||
// // //
|
||||
// // Print("Fast0: " + ToString(fast0));
|
||||
// // Print("Slow0: " + ToString(slow0));
|
||||
|
||||
// // //
|
||||
// // Print("Fast1: " + ToString(fast1));
|
||||
// // Print("Slow1: " + ToString(slow1));
|
||||
|
||||
// // //
|
||||
// // Print("TenkanSen: " + ToString(tenkanSen));
|
||||
|
||||
// // //
|
||||
// // bool isFastCrossedOverSlow =
|
||||
// // //
|
||||
// // fast0 > slow0 &&
|
||||
// // fast1 <= slow1
|
||||
// // //
|
||||
// // ;
|
||||
// // if (isFastCrossedOverSlow)
|
||||
// // {
|
||||
// // //
|
||||
// // Print("Fast Crossed Over Slow");
|
||||
// // }
|
||||
|
||||
// //
|
||||
// X121MCycleConditions conditions = xSampleEA121MC.GetMarketConditions(0);
|
||||
// string mcSummary = conditions.GenerateSummary();
|
||||
// Print(mcSummary);
|
||||
|
||||
// //
|
||||
// Print(" ");
|
||||
// }
|
||||
|
||||
void ApplyMCDrawStyles()
|
||||
{
|
||||
//
|
||||
// Here we Apply All Draw Styles on Input of Market Cycle ...
|
||||
xSampleEA121MCInputs.drawCBar = true;
|
||||
xSampleEA121MCInputs.drawPBar = true;
|
||||
xSampleEA121MCInputs.drawLabels = true;
|
||||
xSampleEA121MCInputs.drawCBarMid = true;
|
||||
xSampleEA121MCInputs.drawPBarMid = true;
|
||||
|
||||
//
|
||||
// Current ...
|
||||
|
||||
//
|
||||
// MidLine ...
|
||||
xSampleEA121MCInputs.cBarMidDrawSpecs.width = 1;
|
||||
xSampleEA121MCInputs.cBarMidDrawSpecs.style = STYLE_DOT;
|
||||
xSampleEA121MCInputs.cBarMidDrawSpecs.clr = clrSpringGreen;
|
||||
xSampleEA121MCInputs.cBarMidDrawSpecs.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_C MID",
|
||||
xSampleEA121MCInputs.cBarMidDrawSpecs.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
// XOHCL ...
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.Default();
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.Width(1);
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.Style(STYLE_DOT);
|
||||
//
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.openStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_C O",
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.openStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.highStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_C H",
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.highStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.closeStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_C C",
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.closeStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.lowStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_C L",
|
||||
xSampleEA121MCInputs.cBarDrawSpecs.lowStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
// Prev ...
|
||||
|
||||
//
|
||||
// MidLine ...
|
||||
xSampleEA121MCInputs.pBarMidDrawSpecs.width = 2;
|
||||
xSampleEA121MCInputs.pBarMidDrawSpecs.style = STYLE_SOLID;
|
||||
xSampleEA121MCInputs.pBarMidDrawSpecs.clr = clrLimeGreen;
|
||||
xSampleEA121MCInputs.pBarMidDrawSpecs.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_P MID",
|
||||
xSampleEA121MCInputs.pBarMidDrawSpecs.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
// XOHCL ...
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.Default();
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.Width(2);
|
||||
//
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.openStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_P O",
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.openStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.highStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_P H",
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.highStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.closeStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_P C",
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.closeStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.lowStyle.Label(
|
||||
xSampleEA121MCInputs.cycle.prefix + "_P L",
|
||||
xSampleEA121MCInputs.pBarDrawSpecs.lowStyle.clr,
|
||||
"Arial",
|
||||
8,
|
||||
ANCHOR_LEFT_UPPER,
|
||||
90
|
||||
//
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center XSAMPLE MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XSAMPLE
|
||||
// Description: an Exper Advisor which used RSI and MA
|
||||
// to Analyse Market ...
|
||||
//
|
||||
// Maintainer:
|
||||
// ------------
|
||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||
//
|
||||
//////////////////////////////////////////////////////x
|
||||
//
|
||||
// Global Properties ...
|
||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||
#property link "https://saherelm.ir"
|
||||
#property version "1.00"
|
||||
#property description "SaherElm XSAMPLE"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#define ShortName "XSAMPLE"
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
long xSampleEAMagicNumber = 78692110; // Magic Number
|
||||
int xSampleEASlippage = 10; // Slippgae
|
||||
|
||||
//
|
||||
double xSampleEAVolume = 0.01;
|
||||
|
||||
//
|
||||
// Vars ...
|
||||
string xSampleEASymbol;
|
||||
ENUM_TIMEFRAMES xSampleEAPeriod;
|
||||
|
||||
//
|
||||
int maxBuys = 1;
|
||||
int maxSells = 1;
|
||||
int buyCount = 0;
|
||||
int sellCount = 0;
|
||||
|
||||
//
|
||||
double _tp = 0;
|
||||
double _sl = 0;
|
||||
double _entry = 0;
|
||||
ENUM_POSITION_TYPE _type = NULL;
|
||||
|
||||
//
|
||||
MqlTick xSampleEATick;
|
||||
XSCTrade *xSampleEATrader;
|
||||
|
||||
//
|
||||
// Event Handlers ...
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
if (xSampleEASymbol == NULL || StringLen(xSampleEASymbol) <= 0)
|
||||
{
|
||||
xSampleEASymbol = _Symbol;
|
||||
}
|
||||
|
||||
//
|
||||
if (xSampleEAPeriod == NULL)
|
||||
{
|
||||
xSampleEAPeriod = _Period;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!XSampleEAValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
drawPrefix = ShortName;
|
||||
|
||||
//
|
||||
// Initialize XTrader ...
|
||||
xSampleEATrader = new XSCTrade(
|
||||
xSampleEASlippage,
|
||||
xSampleEAMagicNumber);
|
||||
|
||||
//
|
||||
// Init Succeed ...
|
||||
return INIT_SUCCEEDED;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitialization ...
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||
// REASON_REMOVE 1 Program removed from a chart
|
||||
// REASON_RECOMPILE 2 Program recompiled
|
||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||
// REASON_CHARTCLOSE 4 Chart closed
|
||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||
// REASON_TEMPLATE 7 Another chart template applied
|
||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||
// REASON_CLOSE 9 Terminal closed
|
||||
|
||||
//
|
||||
// De Initialize XSampleEA Providers ...
|
||||
delete xSampleEATrader;
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!IsNewCandle(
|
||||
xSampleEASymbol,
|
||||
xSampleEAPeriod))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Tick ...
|
||||
if (!SymbolInfoTick(xSampleEASymbol, xSampleEATick))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Counting Currently Open Positions ...
|
||||
buyCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_BUY);
|
||||
sellCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_SELL);
|
||||
|
||||
//
|
||||
if (buyCount < maxBuys)
|
||||
{
|
||||
//
|
||||
// Check For Buy Signals ...
|
||||
}
|
||||
|
||||
//
|
||||
if (sellCount < maxSells)
|
||||
{
|
||||
//
|
||||
// Check for Sell Signals ...
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Custom Functions ...
|
||||
|
||||
//
|
||||
// Validate Variables nd Inputs ...
|
||||
bool XSampleEAValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
xSampleEASlippage > 0 &&
|
||||
xSampleEAMagicNumber > 0
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| ZigZag.mq5 |
|
||||
//| Copyright 2009, MetaQuotes Software Corp. |
|
||||
//| http://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009, MetaQuotes Software Corp."
|
||||
#property link "http://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 1
|
||||
//---- plot Zigzag
|
||||
#property indicator_label1 "Zigzag"
|
||||
#property indicator_type1 DRAW_SECTION
|
||||
#property indicator_color1 Red
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
//--- input parameters
|
||||
input int ExtDepth=12;
|
||||
input int ExtDeviation=5;
|
||||
input int ExtBackstep=3;
|
||||
//--- indicator buffers
|
||||
double ZigzagBuffer[]; // main buffer
|
||||
double HighMapBuffer[]; // highs
|
||||
double LowMapBuffer[]; // lows
|
||||
int level=3; // recounting depth
|
||||
double deviation; // deviation in points
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- indicator buffers mapping
|
||||
SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA);
|
||||
SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
|
||||
|
||||
//--- set short name and digits
|
||||
PlotIndexSetString(0,PLOT_LABEL,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")");
|
||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||
//--- set empty value
|
||||
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
|
||||
//--- to use in cycle
|
||||
deviation=ExtDeviation*_Point;
|
||||
//---
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| searching index of the highest bar |
|
||||
//+------------------------------------------------------------------+
|
||||
int iHighest(const double &array[],
|
||||
int depth,
|
||||
int startPos)
|
||||
{
|
||||
int index=startPos;
|
||||
//--- start index validation
|
||||
if(startPos<0)
|
||||
{
|
||||
Print("Invalid parameter in the function iHighest, startPos =",startPos);
|
||||
return 0;
|
||||
}
|
||||
int size=ArraySize(array);
|
||||
//--- depth correction if need
|
||||
if(startPos-depth<0) depth=startPos;
|
||||
double max=array[startPos];
|
||||
//--- start searching
|
||||
for(int i=startPos;i>startPos-depth;i--)
|
||||
{
|
||||
if(array[i]>max)
|
||||
{
|
||||
index=i;
|
||||
max=array[i];
|
||||
}
|
||||
}
|
||||
//--- return index of the highest bar
|
||||
return(index);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| searching index of the lowest bar |
|
||||
//+------------------------------------------------------------------+
|
||||
int iLowest(const double &array[],
|
||||
int depth,
|
||||
int startPos)
|
||||
{
|
||||
int index=startPos;
|
||||
//--- start index validation
|
||||
if(startPos<0)
|
||||
{
|
||||
Print("Invalid parameter in the function iLowest, startPos =",startPos);
|
||||
return 0;
|
||||
}
|
||||
int size=ArraySize(array);
|
||||
//--- depth correction if need
|
||||
if(startPos-depth<0) depth=startPos;
|
||||
double min=array[startPos];
|
||||
//--- start searching
|
||||
for(int i=startPos;i>startPos-depth;i--)
|
||||
{
|
||||
if(array[i]<min)
|
||||
{
|
||||
index=i;
|
||||
min=array[i];
|
||||
}
|
||||
}
|
||||
//--- return index of the lowest bar
|
||||
return(index);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator iteration function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
int i=0;
|
||||
int limit=0,counterZ=0,whatlookfor=0;
|
||||
int shift=0,back=0,lasthighpos=0,lastlowpos=0;
|
||||
double val=0,res=0;
|
||||
double curlow=0,curhigh=0,lasthigh=0,lastlow=0;
|
||||
//--- auxiliary enumeration
|
||||
enum looling_for
|
||||
{
|
||||
Pike=1, // searching for next high
|
||||
Sill=-1 // searching for next low
|
||||
};
|
||||
//--- initializing
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
ArrayInitialize(ZigzagBuffer,0.0);
|
||||
ArrayInitialize(HighMapBuffer,0.0);
|
||||
ArrayInitialize(LowMapBuffer,0.0);
|
||||
}
|
||||
//---
|
||||
if(rates_total<100) return(0);
|
||||
//--- set start position for calculations
|
||||
if(prev_calculated==0) limit=ExtDepth;
|
||||
|
||||
//--- ZigZag was already counted before
|
||||
if(prev_calculated>0)
|
||||
{
|
||||
i=rates_total-1;
|
||||
//--- searching third extremum from the last uncompleted bar
|
||||
while(counterZ<level && i>rates_total-100)
|
||||
{
|
||||
res=ZigzagBuffer[i];
|
||||
if(res!=0) counterZ++;
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
limit=i;
|
||||
|
||||
//--- what type of exremum we are going to find
|
||||
if(LowMapBuffer[i]!=0)
|
||||
{
|
||||
curlow=LowMapBuffer[i];
|
||||
whatlookfor=Pike;
|
||||
}
|
||||
else
|
||||
{
|
||||
curhigh=HighMapBuffer[i];
|
||||
whatlookfor=Sill;
|
||||
}
|
||||
//--- chipping
|
||||
for(i=limit+1;i<rates_total && !IsStopped();i++)
|
||||
{
|
||||
ZigzagBuffer[i]=0.0;
|
||||
LowMapBuffer[i]=0.0;
|
||||
HighMapBuffer[i]=0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//--- searching High and Low
|
||||
for(shift=limit;shift<rates_total && !IsStopped();shift++)
|
||||
{
|
||||
val=low[iLowest(low,ExtDepth,shift)];
|
||||
if(val==lastlow) val=0.0;
|
||||
else
|
||||
{
|
||||
lastlow=val;
|
||||
if((low[shift]-val)>deviation) val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=1;back<=ExtBackstep;back++)
|
||||
{
|
||||
res=LowMapBuffer[shift-back];
|
||||
if((res!=0) && (res>val)) LowMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
|
||||
//--- high
|
||||
val=high[iHighest(high,ExtDepth,shift)];
|
||||
if(val==lasthigh) val=0.0;
|
||||
else
|
||||
{
|
||||
lasthigh=val;
|
||||
if((val-high[shift])>deviation) val=0.0;
|
||||
else
|
||||
{
|
||||
for(back=1;back<=ExtBackstep;back++)
|
||||
{
|
||||
res=HighMapBuffer[shift-back];
|
||||
if((res!=0) && (res<val)) HighMapBuffer[shift-back]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(high[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
|
||||
}
|
||||
|
||||
//--- last preparation
|
||||
if(whatlookfor==0)// uncertain quantity
|
||||
{
|
||||
lastlow=0;
|
||||
lasthigh=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastlow=curlow;
|
||||
lasthigh=curhigh;
|
||||
}
|
||||
|
||||
//--- final rejection
|
||||
for(shift=limit;shift<rates_total && !IsStopped();shift++)
|
||||
{
|
||||
res=0.0;
|
||||
switch(whatlookfor)
|
||||
{
|
||||
case 0: // search for peak or lawn
|
||||
if(lastlow==0 && lasthigh==0)
|
||||
{
|
||||
if(HighMapBuffer[shift]!=0)
|
||||
{
|
||||
lasthigh=high[shift];
|
||||
lasthighpos=shift;
|
||||
whatlookfor=Sill;
|
||||
ZigzagBuffer[shift]=lasthigh;
|
||||
res=1;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0)
|
||||
{
|
||||
lastlow=low[shift];
|
||||
lastlowpos=shift;
|
||||
whatlookfor=Pike;
|
||||
ZigzagBuffer[shift]=lastlow;
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Pike: // search for peak
|
||||
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigzagBuffer[lastlowpos]=0.0;
|
||||
lastlowpos=shift;
|
||||
lastlow=LowMapBuffer[shift];
|
||||
ZigzagBuffer[shift]=lastlow;
|
||||
res=1;
|
||||
}
|
||||
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
lasthigh=HighMapBuffer[shift];
|
||||
lasthighpos=shift;
|
||||
ZigzagBuffer[shift]=lasthigh;
|
||||
whatlookfor=Sill;
|
||||
res=1;
|
||||
}
|
||||
break;
|
||||
case Sill: // search for lawn
|
||||
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
|
||||
{
|
||||
ZigzagBuffer[lasthighpos]=0.0;
|
||||
lasthighpos=shift;
|
||||
lasthigh=HighMapBuffer[shift];
|
||||
ZigzagBuffer[shift]=lasthigh;
|
||||
}
|
||||
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
|
||||
{
|
||||
lastlow=LowMapBuffer[shift];
|
||||
lastlowpos=shift;
|
||||
ZigzagBuffer[shift]=lastlow;
|
||||
whatlookfor=Pike;
|
||||
}
|
||||
break;
|
||||
default: return(rates_total);
|
||||
}
|
||||
}
|
||||
|
||||
//--- return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,506 @@
|
||||
/**
|
||||
* XColor Tools Module ...
|
||||
* a module for handle colorify text contents in node js ...
|
||||
*
|
||||
* Maintainer
|
||||
*
|
||||
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||
*/
|
||||
|
||||
//
|
||||
//#region Module Imports ...
|
||||
const XValueTools = require("./x-value.tools");
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constants ...
|
||||
/**
|
||||
* these are available style which can applied to an string ...
|
||||
*/
|
||||
const AVAILABLE_STYLES = {
|
||||
//
|
||||
Bold: "\x1b[1m",
|
||||
Dim: "\x1b[2m",
|
||||
Underlined: "\x1b[4m",
|
||||
Blink: "\x1b[5m",
|
||||
ReverseFandB: "\x1b[7m",
|
||||
Hidden: "\x1b[8m",
|
||||
//
|
||||
// Commonly used for reset all Styles ...
|
||||
Reset: "\x1b[0m"
|
||||
};
|
||||
|
||||
/**
|
||||
* these are available foreground colors which can applied to an string ...
|
||||
*/
|
||||
const AVAILABLE_FOREGROUND_COLORS = {
|
||||
Default: "\x1b[39m",
|
||||
Black: "\x1b[30m",
|
||||
Red: "\x1b[31m",
|
||||
Green: "\x1b[32m",
|
||||
Yellow: "\x1b[33m",
|
||||
Blue: "\x1b[34m",
|
||||
Magenta: "\x1b[35m",
|
||||
Cyan: "\x1b[36m",
|
||||
LightGray: "\x1b[37m",
|
||||
DarkGray: "\x1b[90m",
|
||||
LightRed: "\x1b[91m",
|
||||
LightGreen: "\x1b[92m",
|
||||
LightYellow: "\x1b[93m",
|
||||
LightBlue: "\x1b[94m",
|
||||
LightMagenta: "\x1b[95m",
|
||||
LightCyan: "\x1b[96m",
|
||||
White: "\x1b[97m",
|
||||
};
|
||||
|
||||
/**
|
||||
* these are available background colors which can applied to an string ...
|
||||
*/
|
||||
const AVAILABLE_BACKGROUND_COLORS = {
|
||||
Default: "\x1b[49m",
|
||||
Black: "\x1b[40m",
|
||||
Red: "\x1b[41m",
|
||||
Green: "\x1b[42m",
|
||||
Yellow: "\x1b[43m",
|
||||
Blue: "\x1b[44m",
|
||||
Magenta: "\x1b[45m",
|
||||
Cyan: "\x1b[46m",
|
||||
LightGray: "\x1b[47m",
|
||||
DarkGray: "\x1b[100m",
|
||||
LightRed: "\x1b[101m",
|
||||
LightGreen: "\x1b[102m",
|
||||
LightYellow: "\x1b[103m",
|
||||
LightBlue: "\x1b[104m",
|
||||
LightMagenta: "\x1b[105m",
|
||||
LightCyan: "\x1b[106m",
|
||||
White: "\x1b[107m",
|
||||
};
|
||||
|
||||
/**
|
||||
* these are available style names, which exports from module and
|
||||
* users can use them ...
|
||||
*/
|
||||
const STYLE_NAMES = {
|
||||
Bold: "Bold",
|
||||
Dim: "Dim",
|
||||
Underlined: "Underlined",
|
||||
Blink: "Blink",
|
||||
ReverseFandB: "ReverseFandB",
|
||||
Hidden: "Hidden",
|
||||
Reset: "Reset",
|
||||
};
|
||||
|
||||
/**
|
||||
* these are available color names, which exports from module and
|
||||
* users can use them ...
|
||||
*/
|
||||
const COLOR_NAMES = {
|
||||
Default: "Default",
|
||||
Black: "Black",
|
||||
Red: "Red",
|
||||
Green: "Green",
|
||||
Yellow: "Yellow",
|
||||
Blue: "Blue",
|
||||
Magenta: "Magenta",
|
||||
Cyan: "Cyan",
|
||||
LightGray: "LightGray",
|
||||
DarkGray: "DarkGray",
|
||||
LightRed: "LightRed",
|
||||
LightGreen: "LightGreen",
|
||||
LightYellow: "LightYellow",
|
||||
LightBlue: "LightBlue",
|
||||
LightMagenta: "LightMagenta",
|
||||
LightCyan: "LightCyan",
|
||||
White: "White",
|
||||
};
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
/**
|
||||
* apply specified style and color on a content ...
|
||||
*
|
||||
* @param {string} content specified content for styling ...
|
||||
* @param {string} color specific color name for using to styling ...
|
||||
* @param {string} style soecufic style name to use ...
|
||||
* @param {boolean} toForeground apply specified color as foreground ...
|
||||
* @param {boolean} toBackground apply specified color as background ...
|
||||
* @returns {string} styled content ...
|
||||
*/
|
||||
function apply(
|
||||
content,
|
||||
color,
|
||||
style,
|
||||
toForeground = true,
|
||||
toBackground = false
|
||||
) {
|
||||
//
|
||||
let result = content;
|
||||
|
||||
//
|
||||
// Validate Arg ...
|
||||
if (!XValueTools.isValidArg(content)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Style and Apply it ...
|
||||
let eStyle = AVAILABLE_STYLES[style];
|
||||
if (XValueTools.isValidArg(eStyle)) {
|
||||
result = `${eStyle}${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Foreground Color and Apply it ...
|
||||
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||
if (
|
||||
!!toForeground
|
||||
&& XValueTools.isValidArg(eFColor)
|
||||
) {
|
||||
result = `${eFColor}${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Background Color and Apply it ...
|
||||
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||
if (
|
||||
!!toBackground
|
||||
&& XValueTools.isValidArg(eBColor)
|
||||
) {
|
||||
result = `${eBColor}${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* apply specific style on a content ...
|
||||
*
|
||||
* @param {string} content specific content which going to styled ...
|
||||
* @param {string} style a member of STYLE_NAMES which specified that which style going to applied to content ...
|
||||
* @returns {string} styled content ...
|
||||
*/
|
||||
function applyStyle(content, style) {
|
||||
//
|
||||
// Validate Arg ...
|
||||
if (!XValueTools.isValidArg(content)) {
|
||||
return content;
|
||||
}
|
||||
|
||||
//
|
||||
let eStyle = AVAILABLE_STYLES[style];
|
||||
if (eStyle === undefined) {
|
||||
return content;
|
||||
}
|
||||
|
||||
//
|
||||
return `${eStyle}${content}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply specific foreground color on a content ...
|
||||
*
|
||||
* @param {string} content specific content which going to colorified ...
|
||||
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
|
||||
* @returns {string} colorified content ...
|
||||
*/
|
||||
function applyForegroundColor(content, color) {
|
||||
//
|
||||
// Validate Arg ...
|
||||
if (!XValueTools.isValidArg(content)) {
|
||||
return content;
|
||||
}
|
||||
|
||||
//
|
||||
let eColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||
if (eColor === undefined) {
|
||||
return content;
|
||||
}
|
||||
|
||||
//
|
||||
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply specific background color on a content ...
|
||||
*
|
||||
* @param {string} content specific content which going to colorified ...
|
||||
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
|
||||
* @returns {string} colorified content ...
|
||||
*/
|
||||
function applyBackgroundColor(content, color) {
|
||||
//
|
||||
// Validate Arg ...
|
||||
if (!XValueTools.isValidArg(content)) {
|
||||
return content;
|
||||
}
|
||||
|
||||
//
|
||||
let eColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||
if (eColor === undefined) {
|
||||
return content;
|
||||
}
|
||||
|
||||
//
|
||||
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate style and color applier expression ...
|
||||
*
|
||||
* @param {string} color specific color name for using to styling ...
|
||||
* @param {string} style soecufic style name to use ...
|
||||
* @param {boolean} reset close applier string by reset styles ...
|
||||
* @param {boolean} toForeground apply specified color as foreground ...
|
||||
* @param {boolean} toBackground apply specified color as background ...
|
||||
* @returns {string} style and color applier string ...
|
||||
*/
|
||||
function getApplier(
|
||||
style = "",
|
||||
color = "",
|
||||
reset = false,
|
||||
toForeground = true,
|
||||
toBackground = false
|
||||
) {
|
||||
//
|
||||
let result = "";
|
||||
|
||||
//
|
||||
// Detect and Validate Style and Apply it ...
|
||||
let eStyle = AVAILABLE_STYLES[style];
|
||||
if (XValueTools.isValidArg(eStyle)) {
|
||||
result = `${eStyle}`;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Foreground Color and Apply it ...
|
||||
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||
if (
|
||||
!!toForeground
|
||||
&& XValueTools.isValidArg(eFColor)
|
||||
) {
|
||||
result = `${eFColor}`;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Background Color and Apply it ...
|
||||
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||
if (
|
||||
!!toBackground
|
||||
&& XValueTools.isValidArg(eBColor)
|
||||
) {
|
||||
result = `${eBColor}`;
|
||||
}
|
||||
|
||||
//
|
||||
if (
|
||||
!!reset &&
|
||||
result.length > 0
|
||||
) {
|
||||
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate style applier expression ...
|
||||
*
|
||||
* @param {string} style soecufic style name to use ...
|
||||
* @param {boolean} reset close applier string by reset styles ...
|
||||
* @returns {string} style applier string ...
|
||||
*/
|
||||
function getStyleApplier(
|
||||
style = "",
|
||||
reset = false
|
||||
) {
|
||||
//
|
||||
let result = "";
|
||||
|
||||
//
|
||||
// Detect and Validate Style and Apply it ...
|
||||
let eStyle = AVAILABLE_STYLES[style];
|
||||
if (XValueTools.isValidArg(eStyle)) {
|
||||
result = `${eStyle}`;
|
||||
}
|
||||
|
||||
//
|
||||
if (
|
||||
!!reset &&
|
||||
result.length > 0
|
||||
) {
|
||||
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate color applier expression ...
|
||||
*
|
||||
* @param {string} color specific color name for using to styling ...
|
||||
* @param {boolean} reset close applier string by reset styles ...
|
||||
* @param {boolean} toForeground apply specified color as foreground ...
|
||||
* @param {boolean} toBackground apply specified color as background ...
|
||||
* @returns {string} color applier string ...
|
||||
*/
|
||||
function getColorApplier(
|
||||
color = "",
|
||||
reset = false,
|
||||
toForeground = true,
|
||||
toBackground = false
|
||||
) {
|
||||
//
|
||||
let result = "";
|
||||
|
||||
//
|
||||
// Detect and Validate Foreground Color and Apply it ...
|
||||
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||
if (
|
||||
!!toForeground
|
||||
&& XValueTools.isValidArg(eFColor)
|
||||
) {
|
||||
result = `${eFColor}`;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Background Color and Apply it ...
|
||||
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||
if (
|
||||
!!toBackground
|
||||
&& XValueTools.isValidArg(eBColor)
|
||||
) {
|
||||
result = `${eBColor}`;
|
||||
}
|
||||
|
||||
//
|
||||
if (
|
||||
!!reset &&
|
||||
result.length > 0
|
||||
) {
|
||||
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* colorified specific content ...
|
||||
*
|
||||
* @param {string} content specified content for styling ...
|
||||
* @param {string} color specific color name for using to styling ...
|
||||
* @param {boolean} toForeground apply specified color as foreground ...
|
||||
* @param {boolean} toBackground apply specified color as background ...
|
||||
* @returns {string}
|
||||
*/
|
||||
function colorifyContent(
|
||||
content = "",
|
||||
color = "",
|
||||
toForeground = true,
|
||||
toBackground = false
|
||||
) {
|
||||
//
|
||||
let result = content;
|
||||
|
||||
//
|
||||
if (!XValueTools.isValidArg(content)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Finde Colors ...
|
||||
|
||||
//
|
||||
// Detect and Validate Foreground Color and Apply it ...
|
||||
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||
if (
|
||||
!!toForeground
|
||||
&& XValueTools.isValidArg(eFColor)
|
||||
) {
|
||||
result = `${eFColor}${result}`;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Background Color and Apply it ...
|
||||
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||
if (
|
||||
!!toBackground
|
||||
&& XValueTools.isValidArg(eBColor)
|
||||
) {
|
||||
result = `${eBColor}${result}`;
|
||||
}
|
||||
|
||||
//
|
||||
if (
|
||||
result.length > 0
|
||||
&& (
|
||||
XValueTools.isValidArg(eFColor) ||
|
||||
XValueTools.isValidArg(eBColor)
|
||||
)
|
||||
) {
|
||||
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply style on specific content ...
|
||||
*
|
||||
* @param {string} content specified content for styling ...
|
||||
* @param {string} style soecufic style name to use ...
|
||||
* @returns {string}
|
||||
*/
|
||||
function stylifiyContent(
|
||||
content = "",
|
||||
style = "",
|
||||
) {
|
||||
//
|
||||
let result = content;
|
||||
|
||||
//
|
||||
if (!XValueTools.isValidArg(content)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect and Validate Style and Apply it ...
|
||||
let eStyle = AVAILABLE_STYLES[style];
|
||||
if (XValueTools.isValidArg(eStyle)) {
|
||||
result = `${eStyle}${result}`;
|
||||
}
|
||||
|
||||
//
|
||||
if (
|
||||
result.length > 0
|
||||
&& XValueTools.isValidArg(eStyle)
|
||||
) {
|
||||
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Module Exports ...
|
||||
module.exports = {
|
||||
//
|
||||
STYLE_NAMES,
|
||||
COLOR_NAMES,
|
||||
//
|
||||
apply,
|
||||
applyStyle,
|
||||
getApplier,
|
||||
getColorApplier,
|
||||
getStyleApplier,
|
||||
colorifyContent,
|
||||
stylifiyContent,
|
||||
applyForegroundColor,
|
||||
applyBackgroundColor,
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,830 @@
|
||||
/**
|
||||
* XFile Tools Module ...
|
||||
* a module for handle all file/folder manipulating task in node js ...
|
||||
*
|
||||
* Maintainer
|
||||
*
|
||||
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||
*/
|
||||
|
||||
//
|
||||
//#region Module Imports ...
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const Path = require('path');
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const XValueTools = require('./x-value.tools');
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constants ...
|
||||
/**
|
||||
* current os path separators ...
|
||||
*/
|
||||
const PathSeparator = Path.sep;
|
||||
|
||||
/**
|
||||
* current directory ...
|
||||
*/
|
||||
const CurrentDir = __dirname;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
//
|
||||
//#region Global ...
|
||||
/**
|
||||
* retrieve a path status ...
|
||||
*
|
||||
* @param {string} path a path value to check ...
|
||||
* @returns an stat object ...
|
||||
*/
|
||||
function getStatus(path = '') {
|
||||
//
|
||||
if (!XValueTools.isValidArg(path)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
//
|
||||
return fs.statSync(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve user's Home path ...
|
||||
*
|
||||
* @returns {string} a path ...
|
||||
*/
|
||||
function getHomePath() {
|
||||
return os.homedir();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Path ...
|
||||
/**
|
||||
* retrieve the base name of specific address path ...
|
||||
*
|
||||
* @param {string} path address of file or folder ...
|
||||
* @returns string ...
|
||||
*/
|
||||
function basename(path = '') {
|
||||
//
|
||||
if (!XValueTools.isValidArg(path)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//
|
||||
const result = Path.basename(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* join several path segments together ...
|
||||
*
|
||||
* @param {...string} path path params ...
|
||||
* @returns a joined paths ...
|
||||
*/
|
||||
function joinPath(...path) {
|
||||
return Path.join(...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* resolve a relative path to absolute ...
|
||||
*
|
||||
* @param {string[]} path a path value to check ...
|
||||
* @returns {string}
|
||||
*/
|
||||
function resolvePath(...path) {
|
||||
return Path.resolve(...path);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region File ...
|
||||
/**
|
||||
* determines a path destination is a file or not ...
|
||||
*
|
||||
* @param {string} path a path value to check ...
|
||||
* @returns a boolean value ...
|
||||
*/
|
||||
function isFileExists(path = '') {
|
||||
//
|
||||
if (!XValueTools.isValidArg(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
const stat = getStatus(path);
|
||||
if (!stat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
return stat.isFile();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a file ...
|
||||
*
|
||||
* @param {string} path a file path ...
|
||||
* @returns {Promise<boolean>} action done or not ...
|
||||
*/
|
||||
function removeFile(path = '') {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (!isFileExists(path)) {
|
||||
resolve(false);
|
||||
}
|
||||
|
||||
//
|
||||
fs.unlink(path, (err) => {
|
||||
//
|
||||
if (err) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* copy a file to destination path ...
|
||||
*
|
||||
* @param {string} source source file path ...
|
||||
* @param {string} dest dest folder path ...
|
||||
* @returns {Promise<boolean>} action done or not ...
|
||||
*/
|
||||
function copyFile(
|
||||
source = '',
|
||||
dest = ''
|
||||
) {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (
|
||||
!isFileExists(source) ||
|
||||
!isDirectoryExists(dest)
|
||||
) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const destFilePath = Path.join(dest, Path.basename(source));
|
||||
fs.copyFile(source, destFilePath, (err) => {
|
||||
//
|
||||
if (err) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* reading specified file content ...
|
||||
*
|
||||
* @param {string} path a file path ...
|
||||
* @returns {Promise<string>} file content ...
|
||||
*/
|
||||
function readFile(path = '') {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (!isFileExists(path)) {
|
||||
resolve('');
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
fs.readFile(path, 'utf8', (err, content) => {
|
||||
//
|
||||
if (err) {
|
||||
resolve(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(content);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* write content to a file ...
|
||||
*
|
||||
* @param {string} path a file path ...
|
||||
* @param {string} content the content which going to write to the file ...
|
||||
* @param {bool} overwrite determines file overwrite if exists ...
|
||||
* @returns {Promise<boolean>} action done or not ...
|
||||
*/
|
||||
function writeFile(
|
||||
path = '',
|
||||
content = '',
|
||||
overwrite = true
|
||||
) {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (isFileExists(path) && !overwrite) {
|
||||
//
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Normalize Content ...
|
||||
content = XValueTools.isValidArg(content) ?
|
||||
content :
|
||||
'';
|
||||
|
||||
//
|
||||
fs.writeFile(path, content, (err) => {
|
||||
//
|
||||
if (err) {
|
||||
//
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* create a file ...
|
||||
*
|
||||
* @param {string} path file path ...
|
||||
* @param {string} fileName file name ...
|
||||
* @returns {Promise<boolean>} action done or not ...
|
||||
*/
|
||||
function createFile(
|
||||
path = '',
|
||||
fileName = ''
|
||||
) {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
const filePath = Path.join(path, fileName);
|
||||
if (
|
||||
isFileExists(filePath) ||
|
||||
!XValueTools.isValidArg(path) ||
|
||||
!XValueTools.isValidArg(fileName)
|
||||
) {
|
||||
//
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
fs.writeFile(filePath, '', (err) => {
|
||||
//
|
||||
if (err) {
|
||||
//
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a file name extension ...
|
||||
*
|
||||
* @param {string} name
|
||||
* @returns {string} name without extension ...
|
||||
*/
|
||||
function removeFileExtension(name = '') {
|
||||
return name.substring(0, name.lastIndexOf('.')) || name;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve a file extension ...
|
||||
*
|
||||
* @param {string} path a path which locate a file ...
|
||||
* @returns {string}
|
||||
*/
|
||||
function getFileExtension(path = '') {
|
||||
//
|
||||
let result = "";
|
||||
|
||||
//
|
||||
// Validate Arg ...
|
||||
if (
|
||||
!XValueTools.isValidArg(path)
|
||||
|| !isFileExists(path)
|
||||
) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve just file name ...
|
||||
const fileName = basename(path);
|
||||
result = fileName.replace(
|
||||
removeFileExtension(fileName),
|
||||
""
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve all files list recursively from specific path ...
|
||||
*
|
||||
* @param {string} path a source folder path ...
|
||||
* @param {string[]} extensions which file extensions need to be listed, live empty for all files ...
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
async function getRecursiveFilesList(
|
||||
path = "",
|
||||
extensions = []
|
||||
) {
|
||||
//
|
||||
let result = [];
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
!XValueTools.isValidArg(path)
|
||||
|| !isDirectoryExists(path)
|
||||
) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
const contents = await getDirectoryContents(path);
|
||||
for(const item of contents) {
|
||||
//
|
||||
const itemPath = joinPath(
|
||||
path,
|
||||
item
|
||||
);
|
||||
|
||||
//
|
||||
const isItemFile = isFileExists(itemPath);
|
||||
if (isItemFile) {
|
||||
//
|
||||
const itemFileExtension = getFileExtension(itemPath);
|
||||
const isFileInSupportedExtensions =
|
||||
extensions === undefined || extensions.length === 0
|
||||
? true
|
||||
: extensions.includes(itemFileExtension)
|
||||
;
|
||||
if (isFileInSupportedExtensions) {
|
||||
result.push(itemPath);
|
||||
}
|
||||
} else if (isDirectoryExists(itemPath)) {
|
||||
//
|
||||
const itemPathFiles = await getRecursiveFilesList(itemPath, extensions);
|
||||
result.push(...itemPathFiles);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Directory ...
|
||||
/**
|
||||
* create a directory ...
|
||||
*
|
||||
* @param {string} path destination path including dir name ...
|
||||
* @param {boolean} recursive create directories recursively ...
|
||||
* @returns action done or not ...
|
||||
*/
|
||||
function createDirectory(
|
||||
path = '',
|
||||
recursive = true
|
||||
) {
|
||||
//
|
||||
let result = false;
|
||||
|
||||
//
|
||||
if (
|
||||
isDirectoryExists(path) ||
|
||||
!XValueTools.isValidArg(path)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
//
|
||||
fs.mkdirSync(path, { recursive: recursive });
|
||||
result = true;
|
||||
return result;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a directory ...
|
||||
*
|
||||
* @param {string} path destination path including dir name ...
|
||||
* @param {boolean} recursive removes directories recursively ...
|
||||
* @returns {Promise<boolean>} action done or not ...
|
||||
*/
|
||||
function removeDirectory(
|
||||
path = '',
|
||||
recursive = false
|
||||
) {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (!isDirectoryExists(path)) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
fs.rm(path, {
|
||||
recursive
|
||||
}, (err) => {
|
||||
//
|
||||
if (err) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* determines a path destination is a directory or not ...
|
||||
*
|
||||
* @param {string} path a folder path ...
|
||||
* @returns represent destnation path is Directory or not ...
|
||||
*/
|
||||
function isDirectoryExists(path = '') {
|
||||
//
|
||||
if (!XValueTools.isValidArg(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
try {
|
||||
//
|
||||
const isExists = fs.existsSync(path);
|
||||
if (!isExists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
const stat = getStatus(path);
|
||||
if (!stat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
const result = stat.isDirectory();
|
||||
return result;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve a directory content ...
|
||||
*
|
||||
* @param {string} path a folder path ...
|
||||
* @returns {Promise<string[]>} a collection of folder files ...
|
||||
*/
|
||||
function getDirectoryContents(path = '') {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (!isDirectoryExists(path)) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
fs.readdir(path, (err, content) => {
|
||||
//
|
||||
if (err) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(content);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve a directory files ...
|
||||
*
|
||||
* @param {string} path a folder path ...
|
||||
* @returns {Promise<string[]>} a collection of folder files ...
|
||||
*/
|
||||
function getDirectoryFiles(
|
||||
path = '',
|
||||
containsHiddenFiles = false
|
||||
) {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (!isDirectoryExists(path)) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
fs.readdir(path, (err, content) => {
|
||||
//
|
||||
if (err) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (!containsHiddenFiles) {
|
||||
content = content.filter(c => !c.startsWith('.'));
|
||||
}
|
||||
|
||||
//
|
||||
const result = [];
|
||||
content
|
||||
.forEach(c => {
|
||||
//
|
||||
const cPath = Path.join(path, c);
|
||||
if (isFileExists(cPath)) {
|
||||
result.push(c);
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve a directory folders ...
|
||||
*
|
||||
* @param {string} path a folder path ...
|
||||
* @returns {Promise<string[]>} a collection of folder names ...
|
||||
*/
|
||||
function getDirectoryFolders(path = '') {
|
||||
return new Promise((resolve) => {
|
||||
//
|
||||
if (!isDirectoryExists(path)) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
fs.readdir(path, (err, content) => {
|
||||
//
|
||||
if (err) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const result = [];
|
||||
content.forEach(c => {
|
||||
//
|
||||
const cPath = Path.join(path, c);
|
||||
if (isDirectoryExists(cPath)) {
|
||||
result.push(c);
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* copy a folder with all of it's content to dest ...
|
||||
*
|
||||
* @param {string} source source folder path ...
|
||||
* @param {string} dest dest folder path ...
|
||||
* @returns {Promise<boolean>} action done or not ...
|
||||
*/
|
||||
async function copyFolder(
|
||||
source = '',
|
||||
dest = ''
|
||||
) {
|
||||
//
|
||||
if (
|
||||
!isDirectoryExists(source) ||
|
||||
!XValueTools.isValidArg(dest) ||
|
||||
!XValueTools.isValidArg(source)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
const folderName = Path.basename(source);
|
||||
const destPath = Path.join(dest, folderName);
|
||||
|
||||
//
|
||||
// Create Dest Path folder if not exists ...
|
||||
if (!isDirectoryExists(destPath)) {
|
||||
//
|
||||
let result = createDirectory(destPath, true);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Files ...
|
||||
const files = await getDirectoryFiles(source);
|
||||
if (files && files.constructor === Array && files.length > 0) {
|
||||
//
|
||||
const filesPromises = files.map(file => copyFile(Path.join(source, file), destPath));
|
||||
const filesResult = (await Promise.all(filesPromises)).every(r => !!r);
|
||||
if (!filesResult) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Folders ...
|
||||
const folders = await getDirectoryFolders(source);
|
||||
if (folders && folders.constructor === Array && folders.length > 0) {
|
||||
//
|
||||
const folderPromises = folders.map(folder => copyFolder(Path.join(source, folder), destPath));
|
||||
const filesResult = (await Promise.all(folderPromises)).every(r => !!r);
|
||||
if (!filesResult) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return true;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Downloader ...
|
||||
/**
|
||||
* download a file from specific url and store it ...
|
||||
*
|
||||
* @param {string} filepath the file name and path which required to put download file on it ...
|
||||
* @param {string} url the web url for downloading ...
|
||||
*/
|
||||
function download(filepath, url) {
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
!XValueTools.isValidArg(url)
|
||||
|| !XValueTools.isValidURL(url)
|
||||
|| !XValueTools.isValidArg(filepath)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
var file = fs.createWriteStream(filepath);
|
||||
|
||||
//
|
||||
if (url.startsWith('https:')) {
|
||||
https.get(url, function (response) {
|
||||
response.pipe(file);
|
||||
});
|
||||
} else if (url.startsWith('http:')) {
|
||||
http.get(url, function (response) {
|
||||
response.pipe(file);
|
||||
});
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region JSON ...
|
||||
/**
|
||||
* read and parse a JSON content from a file ...
|
||||
*
|
||||
* @param {string} path source file path ...
|
||||
* @returns {any}
|
||||
*/
|
||||
function readJSON(path = "") {
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!isFileExists(path)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
//
|
||||
let result = undefined;
|
||||
try {
|
||||
result = require(path);
|
||||
} catch {
|
||||
result = undefined;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* write a JSON Object content into a file ...
|
||||
*
|
||||
* @param {string} path dest file path ...
|
||||
* @param {any} content an object which required to write to file ...
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function writeJSON(
|
||||
path = "",
|
||||
content = undefined
|
||||
) {
|
||||
//
|
||||
let result = false;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (!XValueTools.isValidArg(path)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Normallize Content ...
|
||||
if (content === undefined) {
|
||||
content = {};
|
||||
}
|
||||
|
||||
//
|
||||
const contentString = XValueTools.beautifyJSON(content);
|
||||
|
||||
//
|
||||
result = await writeFile(
|
||||
path,
|
||||
contentString,
|
||||
true
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Module Exports ...
|
||||
module.exports = {
|
||||
//
|
||||
CurrentDir,
|
||||
PathSeparator,
|
||||
|
||||
//
|
||||
getStatus,
|
||||
getHomePath,
|
||||
|
||||
//
|
||||
basename,
|
||||
joinPath,
|
||||
resolvePath,
|
||||
|
||||
//
|
||||
download,
|
||||
|
||||
//
|
||||
readJSON,
|
||||
writeJSON,
|
||||
|
||||
//
|
||||
copyFile,
|
||||
readFile,
|
||||
writeFile,
|
||||
createFile,
|
||||
removeFile,
|
||||
isFileExists,
|
||||
getFileExtension,
|
||||
removeFileExtension,
|
||||
getRecursiveFilesList,
|
||||
|
||||
//
|
||||
copyFolder,
|
||||
createDirectory,
|
||||
removeDirectory,
|
||||
createDirectory,
|
||||
removeDirectory,
|
||||
isDirectoryExists,
|
||||
isDirectoryExists,
|
||||
getDirectoryFiles,
|
||||
getDirectoryFolders,
|
||||
getDirectoryContents,
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* XShell Tools Module ...
|
||||
* a module for handling shell actions and retrieve OS Info in node js ...
|
||||
*
|
||||
* Maintainer
|
||||
*
|
||||
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||
*/
|
||||
|
||||
//
|
||||
//#region Imports ...
|
||||
const os = require('os');
|
||||
const process = require('process');
|
||||
const { exec } = require("child_process");
|
||||
const XFileTools = require('./x-file.tools');
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constants ...
|
||||
//
|
||||
const OS = {
|
||||
Aix: 'aix',
|
||||
Darwin: 'darwin',
|
||||
FreeBSD: 'freebsd',
|
||||
Linux: 'linux',
|
||||
OpenBSD: 'openbsd',
|
||||
SnOS: 'sunos',
|
||||
Windows: 'win32'
|
||||
};
|
||||
|
||||
//
|
||||
const isWindows = process.platform === OS.Windows;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
//
|
||||
//#region Pure shell commands ...
|
||||
/**
|
||||
* execute a command using NodeJS on shell ...
|
||||
*
|
||||
* @param {string} cmd command to execute ...
|
||||
* @param {string} cwd working directory ...
|
||||
*
|
||||
* @returns Promise<any, errr> instance ...
|
||||
*/
|
||||
function execute(cmd, cwd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
//
|
||||
if (!cmd || cmd.toString().length === 0 || (cwd && !XFileTools.isDirectoryExists(cwd))) {
|
||||
reject('invalid args ...');
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
exec(cmd, { cwd }, (err, result, stdError) => {
|
||||
//
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
if (stdError) {
|
||||
//
|
||||
// reject(stdError);
|
||||
// return;
|
||||
}
|
||||
|
||||
//
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* determines a command exists on host or not ...
|
||||
*
|
||||
* @param {string} name specific command name ...
|
||||
*
|
||||
* @returns boolean Promise ...
|
||||
*/
|
||||
function checkCommandExists(name) {
|
||||
return new Promise(resolve => {
|
||||
//
|
||||
if (!name) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const cmd = isWindows ? `${name} >nul 2>&1` : `type ${name} >/dev/null 2>&1`;
|
||||
execute(cmd).then(result => {
|
||||
resolve(true);
|
||||
})
|
||||
.catch(err => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region required commands state ...
|
||||
/**
|
||||
* check al required commands exists or not ...
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
async function isRequiredCommandsExists() {
|
||||
//
|
||||
let result = false;
|
||||
|
||||
//
|
||||
// const isTarExists = await isTarCommandExists();
|
||||
// const isCatExists = await isCatCommandExists();
|
||||
// const isGrepExists = await isGrepCommandExists();
|
||||
// const isSedExists = await isSedCommandExists();
|
||||
const isNpmExists = await isNpmCommandExists();
|
||||
const isNgExists = await isNgCommandExists();
|
||||
const isIonicExists = await isIonicCommandExists();
|
||||
const isCordovaExists = await isCordovaCommandExists();
|
||||
|
||||
//
|
||||
result = isNpmExists
|
||||
&& isNgExists
|
||||
&& isIonicExists
|
||||
&& isCordovaExists
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve required commands state object ...
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
async function getRequiredCommandsStates() {
|
||||
//
|
||||
const result = {};
|
||||
|
||||
//
|
||||
// const isTarExists = await isTarCommandExists();
|
||||
// const isCatExists = await isCatCommandExists();
|
||||
// const isGrepExists = await isGrepCommandExists();
|
||||
// const isSedExists = await isSedCommandExists();
|
||||
const isNpmExists = await isNpmCommandExists();
|
||||
const isNgExists = await isNgCommandExists();
|
||||
const isIonicExists = await isIonicCommandExists();
|
||||
const isCordovaExists = await isCordovaCommandExists();
|
||||
|
||||
//
|
||||
result['npm'] = isNpmExists;
|
||||
result['ng'] = isNgExists;
|
||||
result['ionic'] = isIonicExists;
|
||||
result['cordova'] = isCordovaExists;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Commonly used Command Checkers ...
|
||||
/**
|
||||
* determines npm command exists or not ...
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
function isNpmCommandExists() {
|
||||
return checkCommandExists('npm');
|
||||
}
|
||||
|
||||
/**
|
||||
* determines ng command exists or not ...
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
function isNgCommandExists() {
|
||||
return checkCommandExists('ng');
|
||||
}
|
||||
|
||||
/**
|
||||
* determines ionic command exists or not ...
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
function isIonicCommandExists() {
|
||||
return checkCommandExists('ionic');
|
||||
}
|
||||
|
||||
/**
|
||||
* determines cordova command exists or not ...
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
function isCordovaCommandExists() {
|
||||
return checkCommandExists('cordova');
|
||||
}
|
||||
//#endregion
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Module Exports ...
|
||||
module.exports = {
|
||||
//
|
||||
execute,
|
||||
checkCommandExists,
|
||||
isRequiredCommandsExists,
|
||||
getRequiredCommandsStates,
|
||||
|
||||
//
|
||||
isNgCommandExists,
|
||||
isIonicCommandExists,
|
||||
isCordovaCommandExists,
|
||||
}
|
||||
//#endregion
|
||||
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* DataType Tools Module ...
|
||||
* a module for manipulate and detect supported data types in node js ...
|
||||
*
|
||||
* Maintainer
|
||||
*
|
||||
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||
*/
|
||||
|
||||
//
|
||||
//#region Constants ...
|
||||
/**
|
||||
* all supported data types ...
|
||||
*/
|
||||
const DataTypes = {
|
||||
Null: 'null',
|
||||
Date: 'date',
|
||||
Array: 'array',
|
||||
Object: 'object',
|
||||
String: 'string',
|
||||
Number: 'number',
|
||||
Unknown: 'unknown',
|
||||
Boolean: 'boolean',
|
||||
Function: 'function',
|
||||
Undefined: 'undefined',
|
||||
};
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Actions ...
|
||||
/**
|
||||
* detect type of a content ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function getType(value) {
|
||||
//
|
||||
const type = typeof value;
|
||||
|
||||
//
|
||||
let result = DataTypes.Unknown;
|
||||
let dateIdentifier = '[object Date]';
|
||||
let constructor = value && value.constructor ?
|
||||
value.constructor.toString() :
|
||||
'';
|
||||
|
||||
//
|
||||
switch (type) {
|
||||
//
|
||||
case 'undefined':
|
||||
result = DataTypes.Undefined;
|
||||
break;
|
||||
|
||||
//
|
||||
case 'boolean':
|
||||
result = DataTypes.Boolean;
|
||||
break;
|
||||
|
||||
//
|
||||
case 'string':
|
||||
result = DataTypes.String;
|
||||
break;
|
||||
|
||||
//
|
||||
case 'number':
|
||||
result = DataTypes.Number;
|
||||
break;
|
||||
|
||||
//
|
||||
case 'function':
|
||||
result = DataTypes.Function;
|
||||
break;
|
||||
|
||||
//
|
||||
case 'object':
|
||||
//
|
||||
// Null ...
|
||||
if (value === null) {
|
||||
result = DataTypes.Null;
|
||||
} else
|
||||
//
|
||||
// Array ...
|
||||
if (Array.isArray(value)) {
|
||||
result = DataTypes.Array;
|
||||
} else
|
||||
//
|
||||
// Data ...
|
||||
if (
|
||||
value instanceof Date ||
|
||||
isFunction(value.getMonth) ||
|
||||
constructor.includes(dateIdentifier) ||
|
||||
Object.prototype.toString.call(value) === dateIdentifier
|
||||
) {
|
||||
result = DataTypes.Date;
|
||||
} else
|
||||
//
|
||||
// Object ...
|
||||
{
|
||||
result = DataTypes.Object;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
default:
|
||||
result = DataTypes.Unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve an object constructor ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function getConstructor(value) {
|
||||
//
|
||||
const result = value && value.constructor ?
|
||||
value.constructor.toString() :
|
||||
'';
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve an object prototype ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function getPrototype(value) {
|
||||
//
|
||||
const result = value ?
|
||||
Object.prototype.toString.call(value) :
|
||||
'';
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is null or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isNull(value) {
|
||||
return getType(value) === DataTypes.Null;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is undefined or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isUndefined(value) {
|
||||
return getType(value) === DataTypes.Undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is null or undefined or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isNullOrUndefined(value) {
|
||||
return isNull(value) || isUndefined(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is a date or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isDate(value) {
|
||||
return getType(value) === DataTypes.Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is number or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isNumber(value) {
|
||||
return getType(value) === DataTypes.Number;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is string or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isString(value) {
|
||||
return getType(value) === DataTypes.String;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is boolean or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isBoolean(value) {
|
||||
return getType(value) === DataTypes.Boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is an Array or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isArray(value) {
|
||||
return getType(value) === DataTypes.Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is and Object or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isObject(value) {
|
||||
return getType(value) === DataTypes.Object;
|
||||
}
|
||||
|
||||
/**
|
||||
* check an object is a Function or not ...
|
||||
*
|
||||
* @param {any} value the content which going to check ...
|
||||
* @returns
|
||||
*/
|
||||
function isFunction(value) {
|
||||
return getType(value) === DataTypes.Function;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Module Exports ...
|
||||
module.exports = {
|
||||
//
|
||||
DataTypes,
|
||||
|
||||
//
|
||||
getType,
|
||||
getConstructor,
|
||||
getPrototype,
|
||||
isNull,
|
||||
isUndefined,
|
||||
isNullOrUndefined,
|
||||
isDate,
|
||||
isNumber,
|
||||
isString,
|
||||
isBoolean,
|
||||
isArray,
|
||||
isObject,
|
||||
isFunction,
|
||||
}
|
||||
//#endregion
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true
|
||||
@@ -0,0 +1,22 @@
|
||||
const int rates_total, // total calculated Candles on charts ...
|
||||
const int prev_calculated, // total calculated Candles on charts ...
|
||||
const datetime &time[], // history of Candles Open Time ...
|
||||
const double &open[], // history of Candles Open Price ...
|
||||
const double &high[], // history of Candles High Price ...
|
||||
const double &low[], // history of Candles Low Price ...
|
||||
const double &close[], // history of Candles Close Price ...
|
||||
const long &tick_volume[], // history of Tick Volumes on Candle ...
|
||||
const long &volume[], // history of Trade Volumes ...
|
||||
const int &spread[] // history of Candles Spread Price ...
|
||||
|
||||
|
||||
// //
|
||||
// // XICH ...
|
||||
// string ich =
|
||||
// //
|
||||
// "" + "\n" +
|
||||
// "-------------" + "\n" +
|
||||
// (( || !ignoreFalseConditions) ? ": " + ToString() + "\n" : "") +
|
||||
// "\n"
|
||||
// //
|
||||
// ;
|
||||
Reference in New Issue
Block a user