bkp dosuments ...

This commit is contained in:
2024-12-19 01:33:40 +03:30
parent 6557f4f1ce
commit b9ab1c234a
35 changed files with 62797 additions and 0 deletions
@@ -0,0 +1,394 @@
///////////////////////////////////////////////////////
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------
// Name: X3MA
// Description: X3MA Trend Detector ...
//
// 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 X3MA Indicator"
#property strict
//
#define ShortName "X3MA"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int fastLength = 50; // Fast Length
input int midLength = 100; // Mid Length
input int slowLength = 200; // Slow Length
input int shiftLength = 0; // Shift
input ENUM_MA_METHOD method = MODE_SMA; // Mode
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
//
// Presentation ...
input group "Presentation";
//
// Parts ...
input bool showFast = true; // Show Fast
input bool showMid = true; // Show Mid
input bool showSlow = true; // Show Slow
//
// Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 3
#property indicator_plots 3
//
// Current ...
//
// Fast ...
#define fastBufferIndex 0
double fastBuffer[];
//
#property indicator_label1 "X3MA F"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrAqua
#property indicator_style1 STYLE_DOT
#property indicator_width1 1
//
// Mid ...
#define midBufferIndex 1
double midBuffer[];
//
#property indicator_label2 "X3MA M"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrOrange
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
// Slow ...
#define slowBufferIndex 2
double slowBuffer[];
//
#property indicator_label3 "X3MA S"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrMagenta
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// Variables ...
//
int maxLength;
//
// Handlers ...
int fastHandler = INVALID_HANDLE;
int midHandler = INVALID_HANDLE;
int slowHandler = INVALID_HANDLE;
//
// EVENT Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
if (!InitHandlers())
{
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
//
// Release Handlers ...
IndicatorRelease(fastHandler);
IndicatorRelease(midHandler);
IndicatorRelease(slowHandler);
}
//
// Calculating what we want ...
int OnCalculate(
const int rates_total, // Total Bars on Chart ...
const int prev_calculated, // Total Calculated Bars on Charts ...
const datetime &time[], // History of Open Time ...
const double &open[], // History of Open Price ...
const double &high[], // History of High Price ...
const double &low[], // History of Low Price ...
const double &close[], // History of Close Price ...
const long &tick_volume[], // History of Tick Volumes on Bar ...
const long &volume[], // History of Trade Volumes ...
const int &spread[] // History of Spread Price ...
)
{
//
ArraySetAsSeries(low, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(close, true);
//
// this counts Available Bars ...
int limit;
//
// Validate Calculated Bars ...
bool isPassedRequiredCalculatedBars =
//
BarsCalculated(fastHandler) >= maxLength &&
BarsCalculated(midHandler) >= maxLength &&
BarsCalculated(slowHandler) >= maxLength
//
;
if (!isPassedRequiredCalculatedBars)
{
return prev_calculated;
}
//
limit =
(prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
int copiedFasts = CopyBuffer(fastHandler, 0, 0, limit, fastBuffer);
int copiedMids = CopyBuffer(midHandler, 0, 0, limit, midBuffer);
int copiedSlows = CopyBuffer(slowHandler, 0, 0, limit, slowBuffer);
//
// Validate Copied Items ...
bool isPassedRequiredCopiedItems =
//
copiedFasts > 0 &&
copiedMids > 0 &&
copiedSlows > 0
//
;
if (!isPassedRequiredCopiedItems)
{
return prev_calculated;
}
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
}
//
return rates_total;
}
//
// CUSTOM Functions ...
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result =
//
fastLength > 2 &&
midLength > fastLength &&
slowLength > midLength &&
//
shiftLength >= 0
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
// Current ...
result = MathMax(fastLength, midLength);
result = MathMax(result, slowLength);
//
return result;
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
//
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// Fast ...
bool canShowFast = showFast;
ENUM_DRAW_TYPE fastDrawType = canShowFast ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(fastBuffer, true);
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
PlotIndexSetDouble(fastBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(fastBufferIndex, PLOT_SHOW_DATA, canShowFast);
PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_TYPE, fastDrawType);
//
// Mid ...
bool canShowMid = showMid;
ENUM_DRAW_TYPE midDrawType = canShowMid ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(midBuffer, true);
SetIndexBuffer(midBufferIndex, midBuffer, INDICATOR_DATA);
PlotIndexSetDouble(midBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(midBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(midBufferIndex, PLOT_SHOW_DATA, canShowMid);
PlotIndexSetInteger(midBufferIndex, PLOT_DRAW_TYPE, midDrawType);
//
// Slow ...
bool canShowSlow = showSlow;
ENUM_DRAW_TYPE slowDrawType = canShowSlow ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(slowBuffer, true);
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
PlotIndexSetDouble(slowBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(slowBufferIndex, PLOT_SHOW_DATA, canShowSlow);
PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_TYPE, slowDrawType);
}
//
// Initial Indicator Handlers ...
bool InitHandlers()
{
//
bool result = false;
//
// Initialize Handlers ...
//
// Fast ...
fastHandler = iMA(
_Symbol,
_Period,
fastLength,
shiftLength,
method,
appliedTo //
);
//
// Mid ...
midHandler = iMA(
_Symbol,
_Period,
midLength,
shiftLength,
method,
appliedTo //
);
//
// Slow ...
slowHandler = iMA(
_Symbol,
_Period,
slowLength,
shiftLength,
method,
appliedTo //
);
//
result =
//
fastHandler != INVALID_HANDLE &&
midHandler != INVALID_HANDLE &&
slowHandler != INVALID_HANDLE
//
;
//
return result;
}
//
@@ -0,0 +1,564 @@
///////////////////////////////////////////////////////
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------
// Name: X3VWAP
// Description: X3VWAP Trend Detector ...
//
// 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 X3VWAP Indicator"
#property strict
//
#define ShortName "X3VWAP"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int fastLength = 50; // Fast Length
input int midLength = 100; // Mid Length
input int slowLength = 200; // Slow Length
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To
//
// Presentation ...
input group "Presentation";
input bool showFast = true; // Show Fast
input bool showMid = true; // Show Mid
input bool showSlow = true; // Show Slow
//
// Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 11
#property indicator_plots 3
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
// Current ...
//
// Fast ...
#define fastBufferIndex 0
double fastBuffer[];
#define fastColorBufferIndex 1
double fastColorBuffer[];
//
#define fastPlotBufferIndex 0
#property indicator_label1 "X3VWAP F"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 CLR_NONE, clrAqua, clrMagenta, clrGray
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//
// Mid ...
#define midBufferIndex 2
double midBuffer[];
#define midColorBufferIndex 3
double midColorBuffer[];
//
#define midPlotBufferIndex 1
#property indicator_label2 "X3VWAP M"
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_color2 CLR_NONE, clrGreen, clrRed, clrGray
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//
// Slow ...
#define slowBufferIndex 4
double slowBuffer[];
#define slowColorBufferIndex 5
double slowColorBuffer[];
//
#define slowPlotBufferIndex 2
#property indicator_label3 "X3VWAP S"
#property indicator_type3 DRAW_COLOR_LINE
#property indicator_color3 CLR_NONE, clrSteelBlue, clrDarkRed, clrGray
#property indicator_style3 STYLE_SOLID
#property indicator_width3 2
//
// Data Buffers ...
//
// Volumes ...
#define volumeBufferIndex 6
double volumeBuffer[];
//
// Price ...
#define priceBufferIndex 7
double priceBuffer[];
//
// Fast State ...
#define fastStateBufferIndex 8
double fastStateBuffer[];
//
// Mid State ...
#define midStateBufferIndex 9
double midStateBuffer[];
//
// Slow State ...
#define slowStateBufferIndex 10
double slowStateBuffer[];
//
// Variables ...
//
int maxLength;
//
// 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
}
//
// Calculating what we want ...
int OnCalculate(
const int rates_total, // Total Bars on Chart ...
const int prev_calculated, // Total Calculated Bars on Charts ...
const datetime &time[], // History of Open Time ...
const double &open[], // History of Open Price ...
const double &high[], // History of High Price ...
const double &low[], // History of Low Price ...
const double &close[], // History of Close Price ...
const long &tick_volume[], // History of Tick Volumes on Bar ...
const long &volume[], // History of Trade Volumes ...
const int &spread[] // History of Spread Price ...
)
{
//
ArraySetAsSeries(low, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
//
// this counts Available Bars ...
int limit;
//
limit =
(prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// CUSTOM Functions ...
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result =
//
fastLength > 2 &&
midLength > fastLength &&
slowLength > midLength
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
// Current ...
result = MathMax(fastLength, midLength);
result = MathMax(result, slowLength);
//
return result;
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
//
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// Fast ...
ArraySetAsSeries(fastBuffer, true);
ArraySetAsSeries(fastColorBuffer, true);
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
SetIndexBuffer(fastColorBufferIndex, fastColorBuffer, INDICATOR_COLOR_INDEX);
//
// Mid ...
ArraySetAsSeries(midBuffer, true);
ArraySetAsSeries(midColorBuffer, true);
SetIndexBuffer(midBufferIndex, midBuffer, INDICATOR_DATA);
SetIndexBuffer(midColorBufferIndex, midColorBuffer, INDICATOR_COLOR_INDEX);
//
// Slow ...
ArraySetAsSeries(slowBuffer, true);
ArraySetAsSeries(slowColorBuffer, true);
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
SetIndexBuffer(slowColorBufferIndex, slowColorBuffer, INDICATOR_COLOR_INDEX);
//
// Data Buffers ...
//
// Volumes ...
ArraySetAsSeries(volumeBuffer, true);
SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS);
//
// Price ...
ArraySetAsSeries(priceBuffer, true);
SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS);
//
// Fast State ...
ArraySetAsSeries(fastStateBuffer, true);
SetIndexBuffer(fastStateBufferIndex, fastStateBuffer, INDICATOR_CALCULATIONS);
//
// Mid State ...
ArraySetAsSeries(midStateBuffer, true);
SetIndexBuffer(midStateBufferIndex, midStateBuffer, INDICATOR_CALCULATIONS);
//
// Slow State ...
ArraySetAsSeries(slowStateBuffer, true);
SetIndexBuffer(slowStateBufferIndex, slowStateBuffer, INDICATOR_CALCULATIONS);
}
//
// Calculate Buffers ...
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Calculate Volumes and Price ...
//
if (ratesTotal - bar_index <= maxLength)
{
//
CalculateDataBuffers(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
return;
}
//
CalculateDataBuffers(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
//
CalculateVWAPS(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
//
// Calculate Required Data Buffers ...
void CalculateDataBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
double price = GetAppliedPrice(
appliedTo,
open,
high,
low,
close,
bar_index //
);
priceBuffer[bar_index] = price;
volumeBuffer[bar_index] = (double)tickVolume[bar_index];
}
//
// Calculate Different VWaps ...
void CalculateVWAPS(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Fast ...
CalculateVWAP(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume,
//
fastLength,
showFast,
fastBuffer,
fastColorBuffer,
fastStateBuffer //
);
//
// Mid ...
CalculateVWAP(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume,
//
midLength,
showMid,
midBuffer,
midColorBuffer,
midStateBuffer //
);
//
// Fast ...
CalculateVWAP(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume,
//
slowLength,
showSlow,
slowBuffer,
slowColorBuffer,
slowStateBuffer //
);
}
//
// Calculate VWAP ...
void CalculateVWAP(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[],
//
int _length, // Calculation Length
bool _show,
double &_buffer[],
double &_colorBuffer[],
double &_stateBuffer[] //
)
{
//
double vSum = 0;
double pSum = 0;
double mSum = 0;
for (int x = 0; x < _length; x++)
{
//
pSum += priceBuffer[x + bar_index];
vSum += volumeBuffer[x + bar_index];
mSum += priceBuffer[x + bar_index] * volumeBuffer[x + bar_index];
}
//
double iValue = mSum / vSum;
iValue = NormalizeDouble(iValue, _Digits);
//
_buffer[bar_index] = iValue;
//
bool isBullish = low[bar_index] > iValue;
bool isBearish = high[bar_index] < iValue;
//
double iColor =
isBullish
? bullishColorIDX
: isBearish
? bearishColorIDX
: neuturalColorIDX;
//
_colorBuffer[bar_index] = hideColorIDX;
_stateBuffer[bar_index] = iColor;
if (_show)
{
_colorBuffer[bar_index] = iColor;
}
}
//
@@ -0,0 +1,691 @@
///////////////////////////////////////////////////////
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------
// Name: XCHM
// Description: XCHMrend Detector ...
//
// 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 XCHM Indicator"
#property strict
//
#define ShortName "XCHSAR"
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input double sarStep = 0.02; // Step
input double sarMax = 0.2; // Maximum
//
input group "Cycles";
//
input group "Short";
input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period
input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period
//
input group "Medium";
input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period
input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period
//
input group "Long";
input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period
input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period
//
input group "Hind";
input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period
input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period
//
// Presentation ...
input group "Presentation";
//
input int cArrowCode = 225; // Current Cycle Arrow Code
input int sArrowCode = 225; // Short Cycle Arrow Code
input int mArrowCode = 225; // Medium Cycle Arrow Code
input int lArrowCode = 225; // Long Cycle Arrow Code
input int hArrowCode = 225; // Hind Cycle Arrow Code
//
input bool showCurrent = true; // Show Current Cycle
input bool showShort = false; // Show Short Cycle
input bool showMedium = false; // Show Medium Cycle
input bool showLong = false; // Show Long Cycle
input bool showHind = false; // Show Hind Cycle
//
// Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 5
#property indicator_plots 5
//
// Current ...
#define cBufferIndex 0
double cBuffer[];
//
#property indicator_label1 "XCHSAR C"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrYellow
#property indicator_width1 2
//
// Short ...
#define sBufferIndex 1
double sBuffer[];
//
#property indicator_label2 "XCHSAR S"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrMagenta
#property indicator_width2 2
//
// Medium ...
#define mBufferIndex 2
double mBuffer[];
//
#property indicator_label3 "XCHSAR M"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrDodgerBlue
#property indicator_width3 2
//
// Long ...
#define lBufferIndex 3
double lBuffer[];
//
#property indicator_label4 "XCHSAR L"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrLime
#property indicator_width4 2
//
// Hind ...
#define hBufferIndex 4
double hBuffer[];
//
#property indicator_label5 "XCHSAR H"
#property indicator_type5 DRAW_ARROW
#property indicator_color5 clrRed
#property indicator_width5 2
//
// Variables ...
//
int maxLength;
//
// Current ...
int cHandler = INVALID_HANDLE;
//
// Short ...
ENUM_TIMEFRAMES mSCPeriod = NULL;
int sHandler = INVALID_HANDLE;
//
// Medium ...
ENUM_TIMEFRAMES mMCPeriod = NULL;
int mHandler = INVALID_HANDLE;
//
// Long ...
ENUM_TIMEFRAMES mLCPeriod = NULL;
int lHandler = INVALID_HANDLE;
//
// Hind ...
ENUM_TIMEFRAMES mHCPeriod = NULL;
int hHandler = INVALID_HANDLE;
//
// EVENT Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
if (!InitMarketCycles())
{
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
//
// Current ...
IndicatorRelease(cHandler);
//
// Short ...
IndicatorRelease(sHandler);
//
// Medium ...
IndicatorRelease(mHandler);
//
// Long ...
IndicatorRelease(lHandler);
//
// Hind ...
IndicatorRelease(hHandler);
}
//
// Calculating what we want ...
int OnCalculate(
const int rates_total, // Total Bars on Chart ...
const int prev_calculated, // Total Calculated Bars on Charts ...
const datetime &time[], // History of Open Time ...
const double &open[], // History of Open Price ...
const double &high[], // History of High Price ...
const double &low[], // History of Low Price ...
const double &close[], // History of Close Price ...
const long &tick_volume[], // History of Tick Volumes on Bar ...
const long &volume[], // History of Trade Volumes ...
const int &spread[] // History of Spread Price ...
)
{
//
ArraySetAsSeries(low, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(close, true);
//
// this counts Available Bars ...
int limit;
//
// Validate Calculated Bars ...
bool isPassedRequiredCalculatedBars =
//
// Current ...
BarsCalculated(cHandler) >= maxLength &&
//
// Short ...
BarsCalculated(sHandler) >= maxLength &&
//
// Medium ...
BarsCalculated(mHandler) >= maxLength &&
//
// Long ...
BarsCalculated(lHandler) >= maxLength &&
//
// Hind ...
BarsCalculated(hHandler) >= maxLength
//
;
if (!isPassedRequiredCalculatedBars)
{
return prev_calculated;
}
//
limit =
(prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// Current ...
int copiedCs = CopyBuffer(cHandler, 0, 0, limit, cBuffer);
//
// Short ...
int copiedSs = CopyBuffer(sHandler, 0, 0, limit, sBuffer);
//
// Medium ...
int copiedMs = CopyBuffer(mHandler, 0, 0, limit, mBuffer);
//
// Long ...
int copiedLs = CopyBuffer(lHandler, 0, 0, limit, lBuffer);
//
// Hind ...
int copiedHs = CopyBuffer(hHandler, 0, 0, limit, hBuffer);
//
// Validate Copied Items ...
bool isPassedRequiredCopiedItems =
//
//
// Current ...
copiedCs > 0 &&
//
// Short ...
copiedSs > 0 &&
//
// Medium ...
copiedMs > 0 &&
//
// Long ...
copiedLs > 0 &&
//
// Hind ...
copiedHs > 0
//
;
if (!isPassedRequiredCopiedItems)
{
return prev_calculated;
}
//
// Main Loop ...
// for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
// {
// CalculateBuffers(i);
// }
//
return rates_total;
}
//
// CUSTOM Functions ...
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result =
//
sarStep > 0 &&
sarMax > sarStep &&
//
(IsValid(scMethod, scPeriod) &&
IsValid(mcMethod, mcPeriod) &&
IsValid(lcMethod, lcPeriod) &&
IsValid(hcMethod, hcPeriod))
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
return result;
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
//
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// CURRENT ...
//
ENUM_DRAW_TYPE cDrawType = showCurrent ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(cBuffer, true);
SetIndexBuffer(cBufferIndex, cBuffer, INDICATOR_DATA);
PlotIndexSetInteger(cBufferIndex, PLOT_ARROW, cArrowCode);
PlotIndexSetDouble(cBufferIndex, PLOT_EMPTY_VALUE, 0);
//
PlotIndexSetInteger(cBufferIndex, PLOT_SHOW_DATA, showCurrent);
PlotIndexSetInteger(cBufferIndex, PLOT_DRAW_TYPE, cDrawType);
//
// SHORT ...
//
ENUM_DRAW_TYPE sDrawType = showShort ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(sBuffer, true);
SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA);
PlotIndexSetInteger(mBufferIndex, PLOT_ARROW, sArrowCode);
PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0);
//
PlotIndexSetInteger(sBufferIndex, PLOT_SHOW_DATA, showShort);
PlotIndexSetInteger(sBufferIndex, PLOT_DRAW_TYPE, sDrawType);
//
// MEDIUM ...
//
ENUM_DRAW_TYPE mDrawType = showMedium ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(mBuffer, true);
SetIndexBuffer(mBufferIndex, mBuffer, INDICATOR_DATA);
PlotIndexSetInteger(mBufferIndex, PLOT_ARROW, mArrowCode);
PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0);
//
PlotIndexSetInteger(mBufferIndex, PLOT_SHOW_DATA, showMedium);
PlotIndexSetInteger(mBufferIndex, PLOT_DRAW_TYPE, mDrawType);
//
// LONG ...
//
ENUM_DRAW_TYPE lDrawType = showLong ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(lBuffer, true);
SetIndexBuffer(lBufferIndex, lBuffer, INDICATOR_DATA);
PlotIndexSetInteger(lBufferIndex, PLOT_ARROW, lArrowCode);
PlotIndexSetDouble(lBufferIndex, PLOT_EMPTY_VALUE, 0);
//
PlotIndexSetInteger(lBufferIndex, PLOT_SHOW_DATA, showLong);
PlotIndexSetInteger(lBufferIndex, PLOT_DRAW_TYPE, lDrawType);
//
// HIND ...
//
ENUM_DRAW_TYPE hDrawType = showHind ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(hBuffer, true);
SetIndexBuffer(hBufferIndex, hBuffer, INDICATOR_DATA);
PlotIndexSetInteger(hBufferIndex, PLOT_ARROW, hArrowCode);
PlotIndexSetDouble(hBufferIndex, PLOT_EMPTY_VALUE, 0);
//
PlotIndexSetInteger(hBufferIndex, PLOT_SHOW_DATA, showHind);
PlotIndexSetInteger(hBufferIndex, PLOT_DRAW_TYPE, hDrawType);
}
//
// Initial Market Cycles ...
bool InitMarketCycles()
{
//
bool result = false;
//
// Current Cycle Initialization ...
//
int cPeriodSeconds = PeriodSeconds(_Period);
//
// Initialize Handlers ...
//
// Current ...
cHandler = iSAR(
_Symbol,
_Period,
sarStep,
sarMax //
);
result = cHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
// Short Cycle Initialization ...
//
// Find Cycle Period ...
if (scMethod == X_PERIOD_AUTO)
{
//
// Select Period ...
mSCPeriod = GetCyclePeriod(
X_MARKET_CYCLE_SHORT,
_Period //
);
}
else
{
mSCPeriod = scPeriod;
}
//
result = IsValid(mSCPeriod);
if (!result)
{
return result;
}
//
sHandler = iSAR(
_Symbol,
mSCPeriod,
sarStep,
sarMax //
);
result = sHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
// Medium Cycle Initialization ...
//
// Find Cycle Period ...
if (mcMethod == X_PERIOD_AUTO)
{
//
// Select Period ...
mMCPeriod = GetCyclePeriod(
X_MARKET_CYCLE_MEDIUM,
_Period //
);
}
else
{
mMCPeriod = mcPeriod;
}
//
result = IsValid(mMCPeriod);
if (!result)
{
return result;
}
//
mHandler = iSAR(
_Symbol,
mMCPeriod,
sarStep,
sarMax //
);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
// Long Cycle Initialization ...
//
// Find Cycle Period ...
if (lcMethod == X_PERIOD_AUTO)
{
//
// Select Period ...
mLCPeriod = GetCyclePeriod(
X_MARKET_CYCLE_LONG,
_Period //
);
}
else
{
mLCPeriod = lcPeriod;
}
//
result = IsValid(mLCPeriod);
if (!result)
{
return result;
}
//
lHandler = iSAR(
_Symbol,
mLCPeriod,
sarStep,
sarMax //
);
result = lHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
// Hind Cycle Initialization ...
//
// Find Cycle Period ...
if (hcMethod == X_PERIOD_AUTO)
{
//
// Select Period ...
mHCPeriod = GetCyclePeriod(
X_MARKET_CYCLE_HIND,
_Period //
);
}
else
{
mHCPeriod = hcPeriod;
}
//
result = IsValid(mHCPeriod);
if (!result)
{
return result;
}
//
hHandler = iSAR(
_Symbol,
mHCPeriod,
sarStep,
sarMax //
);
result = hHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
return result;
}
//
// Do all Custom Calculations ...
void CalculateBuffers(int barIndex)
{
}
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,643 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XTick Oscillator
// Description: Tick Charts ...
//
//
// 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 XTick Oscillator"
#property strict
//
// Definitions ...
//
#define ShortName "XTick"
//
// Declaration of the enumeration
enum ENUM_X_PRICE_TYPES
{
X_Bid, // Bid
X_Ask // Ask
};
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
input group "Makret";
//
input group "Chart Config";
input int ticksCount = 3; // Ticks Count
input ENUM_X_PRICE_TYPES appliedPrice = 0; // Price
//
input group "Moving Average";
input int maLength = 10; // Length
input int maShift = 0; // Shift
input ENUM_MA_METHOD maMethod = MODE_SMA; // Mode
input ENUM_X_PRICE maAppliedTo = X_PRICE_CLOSE; // Applied To
//
input group "Presentation";
input bool showBars = true; // Show Bars
input bool showMa = true; // Show Moving Average
//
// Buffers ...
//
#property indicator_separate_window
//
#property indicator_buffers 8
#property indicator_plots 2
//
double openBuffer[];
#define openBufferIndex 0
//
double highBuffer[];
#define highBufferIndex 1
//
double lowBuffer[];
#define lowBufferIndex 2
//
double closeBuffer[];
#define closeBufferIndex 3
//
double colorBuffer[];
#define colorBufferIndex 4
//
#define barBufferIndex 0
#property indicator_label1 "Open;High;Low;Close"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 CLR_NONE, clrGray, clrAqua, clrMagenta
//
double maBuffer[];
#define maBufferIndex 5
#define maPlotBufferIndex 1
//
#property indicator_label2 "MA"
#property indicator_type2 DRAW_LINE // DRAW_COLOR_LINE
#property indicator_color2 clrRoyalBlue // CLR_NONE, clrGreen, clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
double ticksBuffer[];
#define ticksBufferIndex 6
//
double maPriceBuffer[];
#define maPriceBufferIndex 7
//
#define hideColorIDX 0;
#define neuturalColorIDX 1;
#define bullishColorIDX 2;
#define bearishColorIDX 3;
//
// The variable contains the number of stored quotes ...
int ticks_stored;
//
// The variable specifies the path and prefix to the file name ...
string path_prefix = ""; // FileName Prefix
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
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
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
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[] //
)
{
//
// 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);
//
int file_handle; // is a file handle
int bidPosition; // are positions of Bid prices in the string
int askPosition; // are positions of Ask prices in the string
int line_string_len; // is a length of a string, read from the file
int barNumber; // number of candle, for which the prices OHLC are determined
int i; // loop counter
//
// the recent received Bid price ...
double last_price_bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
//
// the recent received Ask price ...
double last_price_ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
//
string filename; // name of a file, the file_buffer is a string
string file_buffer; // a buffer for reading and writing of string data
//
// Setting the size of ticksBuffer array ...
ArrayResize(ticksBuffer, ArraySize(closeBuffer));
//
// File name formation from the path_prefix variable, name
// of financial instrument and ".Txt" symbols
StringConcatenate(filename, path_prefix, Symbol(), ".txt");
//
// Opening a file for reading and writing, codepage ANSI, shared reading mode
file_handle = FileOpen(filename, FILE_READ | FILE_WRITE | FILE_ANSI | FILE_SHARE_READ);
if (prev_calculated == 0)
{
//
// Reading the first line from the file and determine the length of a string ...
line_string_len = StringLen(FileReadString(file_handle)) + 2;
//
// if file is large (contains more quotes than rates_total/2) ...
if (FileSize(file_handle) > (ulong)line_string_len * rates_total / 2)
{
//
// Setting file pointer to read the latest rates_total/2 quotes
FileSeek(file_handle, -line_string_len * rates_total / 2, SEEK_END);
//
// Moving file pointer to the beginning of the next line
FileReadString(file_handle);
}
//
// if file size is small
else
{
//
// Moving file pointer at the beginning of a file
FileSeek(file_handle, 0, SEEK_SET);
}
//
// Reset the counter of stored quotes
ticks_stored = 0;
//
// Reading until the end of the file
while (FileIsEnding(file_handle) == false)
{
//
// Reading a string from thefile
file_buffer = FileReadString(file_handle);
//
// Processing of string if its length is larger than 6 characters
if (StringLen(file_buffer) > 6)
{
//
// Finding the start position of Bid price in the line
bidPosition = StringFind(file_buffer, " ", StringFind(file_buffer, " ") + 1) + 1;
//
// Finding the start position of Ask price in the line
askPosition = StringFind(file_buffer, " ", bidPosition) + 1;
//
// If the Bid prices are used, adding the Bid price to ticksBuffer[] array
if (appliedPrice == 0)
{
ticksBuffer[ticks_stored] = StringToDouble(StringSubstr(file_buffer, bidPosition, askPosition - bidPosition - 1));
}
//
// If the Ask prices are used, adding the Ask price to ticksBuffer[] array
if (appliedPrice == 1)
{
ticksBuffer[ticks_stored] = StringToDouble(StringSubstr(file_buffer, askPosition));
}
//
// Increasing the counter of stored quotes
ticks_stored++;
}
}
}
//
// If the data have been read before
else
{
//
// Moving file pointer at the end of the file
FileSeek(file_handle, 0, SEEK_END);
//
// Forming a string, that should be written to the file
StringConcatenate(file_buffer, TimeCurrent(), " ", DoubleToString(last_price_bid, _Digits), " ", DoubleToString(last_price_ask, _Digits));
//
// Writing a string to the file
FileWrite(file_handle, file_buffer);
//
// If the Bid prices are used, adding the last Bid price to ticksBuffer[] array
if (appliedPrice == 0)
{
ticksBuffer[ticks_stored] = last_price_bid;
}
//
// If the Ask prices are used, adding the last Ask price to ticksBuffer[] array
if (appliedPrice == 1)
{
ticksBuffer[ticks_stored] = last_price_ask;
}
//
// Increasing the quotes counter
ticks_stored++;
}
//
// Closing the file
FileClose(file_handle);
//
// If number of quotes is more or equal than number of bars in the chart
if (ticks_stored >= rates_total)
{
//
// Removing the first tick_stored/2 quotes and shifting remaining quotes
for (i = ticks_stored / 2; i < ticks_stored; i++)
{
//
// Shifting the data to the beginning in the ticksBuffer[] array on tick_stored/2
ticksBuffer[i - ticks_stored / 2] = ticksBuffer[i];
}
//
// Changing the quotes counter
ticks_stored -= ticks_stored / 2;
}
//
// We assign the barNumber with a number of invalid candle
barNumber = -1;
//
// Search for all the price data available for candle formation
for (i = 0; i < ticks_stored; i++)
{
//
// If this candle is forming already
if (barNumber == (int)(MathFloor((ticks_stored - 1) / ticksCount) - MathFloor(i / ticksCount)))
{
//
// The current quote is still closing price of the current candle
closeBuffer[barNumber] = ticksBuffer[i];
//
// If the current price is greater than the highest price of the current candle, it will be a new highest price of the candle
if (ticksBuffer[i] > highBuffer[barNumber])
{
highBuffer[barNumber] = ticksBuffer[i];
}
//
// If the current price is lower than the lowest price of the current candle, it will be a new lowest price of the candle
if (ticksBuffer[i] < lowBuffer[barNumber])
{
lowBuffer[barNumber] = ticksBuffer[i];
}
//
// If the candle is bullish ...
if (closeBuffer[barNumber] > openBuffer[barNumber])
{
colorBuffer[barNumber] = bullishColorIDX;
}
//
// If the candle is bearish ...
if (closeBuffer[barNumber] < openBuffer[barNumber])
{
colorBuffer[barNumber] = bearishColorIDX;
}
//
// If the opening and closing prices are equal, then the candle will have a color with index 0 (grey)
if (closeBuffer[barNumber] == openBuffer[barNumber])
{
colorBuffer[barNumber] = neuturalColorIDX;
}
}
//
// If this candle hasn't benn calculated yet
else
{
//
// Let's determine the index of a candle
barNumber = (int)(MathFloor((ticks_stored - 1) / ticksCount) - MathFloor(i / ticksCount));
//
// The current quote will be the opening price of a candle
openBuffer[barNumber] = ticksBuffer[i];
//
// The current quote will be the highest price of a candle
highBuffer[barNumber] = ticksBuffer[i];
//
// The current quote will be the lowest price of a candle
lowBuffer[barNumber] = ticksBuffer[i];
//
// The current quote will be the closing price of a candle
closeBuffer[barNumber] = ticksBuffer[i];
//
// The candle will have a color with index 0 (gray)
colorBuffer[barNumber] = 0;
}
}
//
// Custom Calculations ...
//
int limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total //
);
}
//
// Return from OnCalculate(), return a value, different from zero
return (rates_total);
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result =
//
ticksCount > 0
//
;
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Color ...
ArraySetAsSeries(colorBuffer, true);
SetIndexBuffer(colorBufferIndex, colorBuffer, INDICATOR_COLOR_INDEX);
//
// Set EMPTY_VALUE on Bar Buffer ...
PlotIndexSetDouble(barBufferIndex, PLOT_EMPTY_VALUE, 0.0);
//
PlotIndexSetInteger(barBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(colorBufferIndex, PLOT_SHOW_DATA, false);
//
// Open ...
ArraySetAsSeries(openBuffer, true);
PlotIndexSetInteger(openBufferIndex, PLOT_SHOW_DATA, true);
SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA);
//
// High ...
ArraySetAsSeries(highBuffer, true);
PlotIndexSetInteger(highBufferIndex, PLOT_SHOW_DATA, true);
SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA);
//
// Close ...
ArraySetAsSeries(closeBuffer, true);
PlotIndexSetInteger(closeBufferIndex, PLOT_SHOW_DATA, true);
SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA);
//
// Low ...
ArraySetAsSeries(lowBuffer, true);
PlotIndexSetInteger(lowBufferIndex, PLOT_SHOW_DATA, true);
SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA);
//
bool canShowMa = showMa;
ArraySetAsSeries(maBuffer, true);
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA);
PlotIndexSetDouble(maPlotBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(maPlotBufferIndex, PLOT_DRAW_BEGIN, maLength);
PlotIndexSetInteger(maPlotBufferIndex, PLOT_SHOW_DATA, showMa);
//
// Data Buffers ...
//
// The TicksBuffer[] array is used for intermediate calculations
SetIndexBuffer(ticksBufferIndex, ticksBuffer, INDICATOR_CALCULATIONS);
//
ArraySetAsSeries(maPriceBuffer, true);
SetIndexBuffer(maPriceBufferIndex, maPriceBuffer, INDICATOR_CALCULATIONS);
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Calculate Custom Buffers ...
*
* @param barIndex: Integer ...
*/
void CalculateBuffers(
int barIndex,
int prevCalculated,
int ratesTotal //
)
{
//
bool canDoMovingAverage =
maLength > 0 &&
maAppliedTo != X_PRICE_UP &&
maAppliedTo != X_PRICE_DOWN;
if (canDoMovingAverage)
{
//
// Do Moving Average Calculations ...
//
// Select Ma Price ...
double iPrice = 0;
switch (maAppliedTo)
{
//
case X_PRICE_HIGH:
iPrice = highBuffer[barIndex];
break;
//
case X_PRICE_OPEN:
iPrice = openBuffer[barIndex];
break;
//
case X_PRICE_CLOSE:
iPrice = closeBuffer[barIndex];
break;
//
case X_PRICE_LOW:
iPrice = lowBuffer[barIndex];
break;
}
//
maPriceBuffer[barIndex] = iPrice;
int total = ArraySize(closeBuffer);
//
int calculatedMas = iMAOnBuffer(
total,
prevCalculated,
barIndex,
maLength,
maPriceBuffer,
maBuffer,
maMethod //
);
}
}
//
@@ -0,0 +1,214 @@
//
// Draw Last Sar Change ...
string iVLineName = sarChangeBar.GetTag("XSAR");
CChartObjectVLine *iVLineObj;
iVLineObj = new CChartObjectVLine();
result = iVLineObj.Create(
ChartID(),
iVLineName,
0,
sarChangeBar.time //
);
if (result)
{
iVLineObj.Color(clrYellow);
}
//
// Draw Last Decision Bar ...
string iVLineNameDecision = decisionBar.GetTag("XDECISION");
CChartObjectVLine *iVLineDecisionObj;
iVLineDecisionObj = new CChartObjectVLine();
result = iVLineDecisionObj.Create(
ChartID(),
iVLineNameDecision,
0,
decisionBar.time //
);
if (result)
{
iVLineDecisionObj.Color(clrYellow);
}
//
// Draw Breaker Bar ...
string iVLineNameBreaker = breakerBar.GetTag("XBREAKER");
CChartObjectVLine *iVLineBreakerObj;
iVLineBreakerObj = new CChartObjectVLine();
result = iVLineBreakerObj.Create(
ChartID(),
iVLineNameBreaker,
0,
breakerBar.time //
);
if (result)
{
iVLineBreakerObj.Color(clrMagenta);
}
//
// TODO: Remove This ...
bool ignoreSwingHighs = true;
bool ignoreSwingLows = true;
bool ignoreSupportZones = true;
bool ignoreResistanceZones = true;
bool ignoreSupplyZones = true;
bool ignoreDemandZones = true;
bool ignoreBullishOrderBlocks = true;
bool ignoreBearishOrderBlocks = true;
bool ignoreBullishFairValueGaps = true;
bool ignoreBearishFairValueGaps = true;
bool ignoreBullishRejectionBars = true;
bool ignoreBearishRejectionBars = true;
bool ignoreBullishMomentumBars = true;
bool ignoreBearishMomentumBars = true;
//
if (IsBullish(marketStructureDir))
{
//
ignoreSwingLows = true;
ignoreSupportZones = true;
ignoreDemandZones = true;
ignoreBullishOrderBlocks = true;
ignoreBullishFairValueGaps = false;
ignoreBullishRejectionBars = false;
ignoreBullishMomentumBars = false;
//
ignoreSwingHighs = true;
ignoreResistanceZones = true;
ignoreSupplyZones = true;
ignoreBearishOrderBlocks = true;
ignoreBearishFairValueGaps = true;
ignoreBearishRejectionBars = true;
ignoreBearishMomentumBars = true;
}
else
{
//
ignoreSwingLows = true;
ignoreSupportZones = true;
ignoreDemandZones = true;
ignoreBullishOrderBlocks = true;
ignoreBullishFairValueGaps = true;
ignoreBullishRejectionBars = true;
ignoreBullishMomentumBars = true;
//
ignoreSwingHighs = true;
ignoreResistanceZones = true;
ignoreSupplyZones = true;
ignoreBearishOrderBlocks = true;
ignoreBearishFairValueGaps = false;
ignoreBearishRejectionBars = false;
ignoreBearishMomentumBars = false;
}
//
RedrawOrderFlow(
true, // Force Clean ...
false, // Same Period ...
true, // Order Flow ...
true, // Order Flow State ...
false, // Only Last Order Flow ...
true, // Only Last Order Flow State ...
//
marketStructureDir, // Direction Force ...
ignoreSwingHighs,
ignoreSwingLows,
ignoreSupportZones,
ignoreResistanceZones,
ignoreSupplyZones,
ignoreDemandZones,
ignoreBullishOrderBlocks,
ignoreBearishOrderBlocks,
ignoreBullishFairValueGaps,
ignoreBearishFairValueGaps,
ignoreBullishRejectionBars,
ignoreBearishRejectionBars,
ignoreBullishMomentumBars,
ignoreBearishMomentumBars //
);
/////////////////////////////////////////////////////
/**
* Validate an Order Block is Not Touched ...
*
* @param bar: XOHCL instance, start bar ...
*
* @return ( bool )
*/
bool ValidateOrderBlock(
XCOrderBlock *ob,
XOHCL &bar //
)
{
//
bool result = false;
//
result =
bar.IsValid() &&
ob.IsValid();
if (!result)
{
return result;
}
//
bool isBullish = ob.IsBullish();
//
XOHCL mBar;
result = bar.BarIn(ob.GetPeriod(), mBar);
if (!result) {
return result;
}
//
int start = mBar.Index();
int end = mBar.Index(ob.From());
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
for (int i = start; i < end; i++)
{
//
XOHCL iBar;
result = mBar.BarAt(
i,
iBar //
);
if (!result)
{
break;
}
//
result =
isBullish
? iBar.low > ob.Upper()
: iBar.high < ob.Lower();
if (!result)
{
break;
}
}
//
return result;
}
@@ -0,0 +1,153 @@
/**
* Check Ticks is Bullish or not ...
*
* @return ( bool )
*/
bool IsTicksBullish()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredBullishTicks = 5;
CalculateTicksParams(
start,
end,
requiredBullishTicks //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
bool isBullish = iTick.bid >= prevTick.bid;
result = result && isBullish;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check Ticks is Bearish or not ...
*
* @return ( bool )
*/
bool IsTicksBearish()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredBearishTicks = 5;
CalculateTicksParams(
start,
end,
requiredBearishTicks //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
bool isBearish = iTick.bid <= prevTick.bid;
result = result && isBearish;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check Ticks Has Momentum or not ...
*
* @return ( bool )
*/
bool IsTicksHasMomentum()
{
//
bool result = false;
//
int start = -1;
int end = -1;
int requiredTicksForMomentum = 5;
CalculateTicksParams(
start,
end,
requiredTicksForMomentum //
);
result = IsValidIndex(start) &&
IsValidIndex(end);
if (!result)
{
return result;
}
//
result = true;
int lastDiff = 0;
for (int i = start + 1; i < end; i++)
{
//
XTick iTick = mTicks[i];
XTick prevTick = mTicks[i - 1];
//
int timeDiff = MathAbs((int)iTick.time - (int)prevTick.bid);
if (lastDiff <= 0)
{
lastDiff = timeDiff;
}
result = result && timeDiff >= lastDiff;
if (!result)
{
break;
}
//
lastDiff = timeDiff;
}
//
return result;
}
///////////////////////////////////////////////////////////////////////
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,830 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XC121SMCExpert
// Description: provides all based classes for use ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-expert.class.mq5"
#include "../../Classes/x-saherelm.x-poi.class.mq5"
// #include "../Classes/x-121.smc.xtradehandler.class.mq5"
//
// Definitions ...
string XC121SMCExpertToken = "XC121SMCEA";
//
// Implementation ...
class XC121SMCExpert : public XCBaseExpert
{
//
public:
//
//
// Signal Event Listener ...
TOnStopLoss OnPositionSLEventListener;
TOnTakeProfit OnPositionTPEventListener;
TOnPartialClose OnPositionPartialCloseEventListener;
TOnModify OnPositionModifiedEventListener;
TOnForceClose OnPositionForceCloseEventListener;
//
// Getter(s) / Setter(s) ...
/**
* Get Use Dynamic Volume State ...
*
* @return ( bool )
*/
bool UseDynamicVolume()
{
return mUseDynamicVolume;
}
/**
* Set Use Dynamic Volume State ...
*
* @param value: Boolean ...
*/
void UseDynamicVolume(bool value)
{
mUseDynamicVolume = value;
}
/**
* Get Increase Volume Step ...
*
* @return ( double )
*/
double DynamicVolumeStep()
{
return mDynamicVolumeStep;
}
/**
* Set Increase Volume Step ...
*
* @param value: Double ...
*/
void DynamicVolumeStep(double value)
{
//
if (value < 0.01)
{
value = 0.01;
}
//
mDynamicVolumeStep = value;
}
/**
* Get Balance Factor for Generate Dynamic Volume ...
*
* @return ( double )
*/
double DynamicVolumeBalanceFactor()
{
return mDynamicVolumeBalanceFactor;
}
/**
* Set Balance Factor for Generate Dynamic Volume ...
*
* @param value: Double ...
*/
void DynamicVolumeBalanceFactor(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mDynamicVolumeBalanceFactor = value;
}
/**
* Get Static Volume ...
*
* @return ( double )
*/
double Volume()
{
return mVolume;
}
/**
* Set Static Volume ...
*
* @param value: Double ...
*/
void Volume(double value)
{
//
if (value < 0.01)
{
value = 0.01;
}
//
mVolume = value;
}
//
// Actions ...
//
// Override Actions ...
/**
* Apply Default Configurations ...
*/
void DefaultConfigure() override
{
//
// Commons ...
Slippage(10);
TagPrefix("");
MagicNumber(1694056);
//
// Symbol ...
SetSymbol(_Symbol);
SetPeriod(_Period);
MultiSymbol(false);
Symbols("EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb");
//
// Signalling ...
Disabled(false);
AllowLong(true);
AllowShort(true);
//
string tag = GetTag();
//
// Alert ...
SetAlertPrefix(tag);
SetAlertLogAlerts(true);
SetAlertPushAlerts(true);
SetAlertMailAlerts(false);
SetAlertEnableAlerts(true);
SetAlertTerminalAlerts(false);
//
// Reports ...
ReportNewDays(true);
ReportNewWeeks(false);
ReportNewHours(false);
ReportNewMonths(false);
//
// Volume Default Configurations ...
Volume(0.01);
UseDynamicVolume(false);
DynamicVolumeStep(0.01);
DynamicVolumeBalanceFactor(200);
}
/**
* Vaslidate Inputs ...
*
* @return ( bool )
*/
bool ValidateInputs() override
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
Slippage() > 0 &&
MagicNumber() > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
// Checking Volume ...
bool isVolumeValid = true;
if (UseDynamicVolume())
{
//
isVolumeValid =
DynamicVolumeStep() > 0 &&
DynamicVolumeBalanceFactor() > 0;
if (!isVolumeValid)
{
errMessage += "Dynamic Volume configurations error;" + "\n";
}
}
isVolumeValid = isVolumeValid &&
Volume() > 0;
if (!isVolumeValid)
{
errMessage += "Static Volume configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Volume Coniguration ...
isVolumeValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
errMessage = " Errors: \n" + errMessage;
Alert(errMessage);
}
//
return result;
}
//
// Initializers and DeInitializers ...
/**
* Initial EA Requirements ...
*
* @return ( bool )
*/
bool InitEA() override
{
//
bool result = false;
//
// Initialize Indicator Helpers ...
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
mPOIDetector = new XCPOIDetector(
symbol,
period //
);
mPOIDetector.Init();
//
// Bar Timer ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
mCTHelper = new XCXCTHelper();
result = mCTHelper.Init(
GetSymbol(),
GetPeriod(),
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
mCCHelper = new XCXCCHelper();
result = mCCHelper.Init(
GetSymbol(),
GetPeriod(),
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Trader Instance and Configure it ...
mTrader = new XCTrade(
Slippage(),
MagicNumber() //
);
mTrader.AddOnStopLossEventHandler(OnPositionSLEventListener);
mTrader.AddOnTakeProfitEventHandler(OnPositionTPEventListener);
mTrader.AddOnModifyPositionEventHandler(OnPositionModifiedEventListener);
mTrader.AddOnForceClosePositionEventHandler(OnPositionForceCloseEventListener);
mTrader.AddOnPartialClosePositionEventHandler(OnPositionPartialCloseEventListener);
// //
// // Initialize Trade Handler ...
// mTradeHandler = new XC121SMCTradeHandler(mTrader);
// mTradeHandler.SaveTrades(true);
// mTradeHandler.SaveSignals(true);
// mTradeHandler.SaveConditions(true);
// //
// // Configure Alerts ...
// mTradeHandler.SetAlertPrefix(GetTag());
// mTradeHandler.SetAlertEnableAlerts(GetAlertEnableAlerts());
// mTradeHandler.SetAlertLogAlerts(GetAlertLogAlerts());
// mTradeHandler.SetAlertMailAlerts(GetAlertMailAlerts());
// mTradeHandler.SetAlertPushAlerts(GetAlertPushAlerts());
// mTradeHandler.SetAlertTerminalAlerts(GetAlertTerminalAlerts());
// //
// // TODO: Make This Configurable Later ...
// //
// mTradeHandler.DelayBarBetweenTwoSignal(3);
// mTradeHandler.MaxAllowedSLToPause(0);
// mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24));
// //
// // Configure Trade Management ...
// mTradeHandler.AllowLong(AllowLong());
// mTradeHandler.AllowShort(AllowShort());
// mTradeHandler.MaxAllowedLongs(0);
// mTradeHandler.MaxAllowedShorts(0);
// mTradeHandler.UseMaxAllowedTradesPerSymbol(true);
// mTradeHandler.MaxDrawdownPercentForOpenTrades(5);
// //
// // Configure Position Protector ...
// //
// mTradeHandler.UseForceMomentumsInProtection(true);
// mTradeHandler.DelayBarBetweenTwoSignal(2);
// //
// // Configure Hedging ...
// mTradeHandler.AllowHedge(false);
// mTradeHandler.HedgeMinVolumeStep(0.01);
// mTradeHandler.MinimumOpenPositionsForHEHedge(2);
// mTradeHandler.HedgeHEMinProfitPerVolumeStep(0.2);
// mTradeHandler.HedgeBEMinProfitPerVolumeStep(0.06);
// //
// // In Profit Position Protecting ...
// //
// // Trail ...
// mTradeHandler.AllowTrail(false);
// mTradeHandler.TrailStep(15);
// mTradeHandler.TrailStartDistance(30);
// mTradeHandler.OnlyTrailUnprotected(true);
// mTradeHandler.RemoveTPAfterTrailedLevel(4);
// //
// // Partial Close (In Profit) ...
// mTradeHandler.PartialCloseInProfitDistance(0);
// mTradeHandler.PartialCloseInProfitVolume(0);
// //
// // In Drawdown Positions Protecting ...
// //
// // Protect ...
// mTradeHandler.AllowProtect(false);
// mTradeHandler.ProtectionDelay(20);
// mTradeHandler.MaxAllowedProtection(0);
// mTradeHandler.UseEntryAsProtectionSL(true);
// mTradeHandler.ProtectOnConditions(true);
// mTradeHandler.AllowDirectionProtct(false);
// mTradeHandler.ProtectionStartDistance(50);
// mTradeHandler.ProtectionVolumeMultiplier(2);
// //
// // Partial Close (In Profit) ...
// mTradeHandler.PartialCloseInDrawdownDistance(0);
// mTradeHandler.PartialCloseInDrawdownVolume(0);
//
// Parsers ...
XSymbolParser _symbolParser;
//
// Single Symbol ...
if (!MultiSymbol())
{
//
// Register Strategy ...
//
// Create Class Instance ...
// XCX121SMCBaseStrategy *iX121SMCStrategy;
// iX121SMCStrategy = new XCX121SMCTestStrategy(
// _Symbol,
// _Period //
// );
// //
// iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener);
// //
// ConfigureStrategy(iX121SMCStrategy);
// RegisterStrategy(iX121SMCStrategy);
}
//
// Multi Symbol ...
else
{
//
// Parse Symbols ...
string symbols[];
int symbolsCount = SplitContent(
symbols,
Symbols() //
);
result = IsValidSize(symbolsCount);
if (!result)
{
return result;
}
//
for (int i = 0; i < symbolsCount; i++)
{
//
// Select Symbol ...
string iSymbol = symbols[i];
//
// Register Strategy Based On Symbol ...
//
// Parse Symbol ...
bool isEURUSD = _symbolParser.IsEURUSD(_Symbol);
bool isGBPUSD = _symbolParser.IsGBPUSD(_Symbol);
bool isEURGBP = _symbolParser.IsEURGBP(_Symbol);
bool isUSDCHF = _symbolParser.IsUSDCHF(_Symbol);
bool isEURCHF = _symbolParser.IsEURCHF(_Symbol);
bool isUSDJPY = _symbolParser.IsUSDJPY(_Symbol);
bool isEURJPY = _symbolParser.IsEURJPY(_Symbol);
bool isUSDCAD = _symbolParser.IsUSDCAD(_Symbol);
bool isEURCAD = _symbolParser.IsEURCAD(_Symbol);
bool isAUDUSD = _symbolParser.IsAUDUSD(_Symbol);
bool isEURAUD = _symbolParser.IsEURAUD(_Symbol);
bool isNZDUSD = _symbolParser.IsNZDUSD(_Symbol);
bool isEURNZD = _symbolParser.IsEURNZD(_Symbol);
//
// Check Symbol Can Register or not ...
bool canRegisterStrategy = true;
//
if (canRegisterStrategy)
{
// //
// // Create Class Instance ...
// XCX121SMCBaseStrategy *iX121SMCStrategy;
// iX121SMCStrategy = new XCX121SMCTestStrategy(
// iSymbol,
// _Period //
// );
// //
// iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener);
// //
// // Register Strategy ...
// ConfigureStrategy(iX121SMCStrategy);
// RegisterStrategy(iX121SMCStrategy);
}
}
}
//
return result;
}
/**
* Destroy all Initialized EA Requirements ...
*/
void DestroyEA() override
{
//
delete mCTHelper;
delete mCCHelper;
// delete mTradeHandler;
//
// Clean(mStrategies);
}
/**
* Call all Registered Strategies On Tick ...
*/
void HandleStrategiesOnTick() override
{
//
ENUM_XPOI_EVENTS events[];
mPOIDetector.Update(events);
//
// int count = ArraySize(mStrategies);
// if (!IsValidSize(count))
// {
// return;
// }
// //
// for (int i = 0; i < count; i++)
// {
// //
// // Call Tick Handler Function ...
// mStrategies[i].HandleTick();
// }
}
//
// Event Handlers ...
/**
* Calls When a Position's SL Triggered ...
*
* @param deal: XDeal instance ...
*/
void HandleOnStopLossTriggered(const XDeal &deal) override
{
//
// Finish ...
// mTradeHandler.Finish(deal);
//
HandleReportBalance();
}
/**
* Calls When a Position's TP Triggered ...
*
* @param deal: XDeal instance ...
*/
void HandleOnTakeProfitTriggered(const XDeal &deal) override
{
//
// Finish ...
// mTradeHandler.Finish(deal);
//
HandleReportBalance();
}
/**
* Handle Force Close a Position ...
*
* @param ticket: Position Ticket ...
* @param position: XPosition ...
* @param comment: Closing Comment ...
*/
void HandleOnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
) override
{
//
// Finish ...
// mTradeHandler.Finish(
// ticket,
// position,
// comment //
// );
//
HandleReportBalance();
}
/**
* Reset All Paused Symbols on Each New Days ...
*/
void HandleOnNewDay() override
{
// mTradeHandler.ResumePausedSymbols();
}
/**
* Generate Identifier Tag ...
*
* @return ( string )
*/
string GetTag() override
{
//
string result = NULL;
//
string tagPrefix = TagPrefix();
if (IsValid(tagPrefix))
{
result = tagPrefix;
}
else
{
result = "";
}
//
result =
XCBaseExpertToken + result;
//
return result;
}
//
protected:
//
//
// Props ...
//
datetime mLastSignalOn;
//
XCPOIDetector *mPOIDetector;
//
// XC121SMCTradeHandler *mTradeHandler; // Trade Handler ...
// XCX121SMCBaseStrategy *mStrategies[]; // Registere Strategies in EA ...
//
// Actions ...
/**
* Apply Volume Based On Configurations on Signal ...
*
* @param signal: XSignal instance
*/
void ApplyVolumeOnSignal(XSignal &signal)
{
//
// Prepare Signal Dynamic Volume
// if Provided ...
if (UseDynamicVolume() &&
DynamicVolumeStep() > 0 &&
DynamicVolumeBalanceFactor() > 0)
{
//
double dVolume = mTrader.GetDynamicVolume(
signal.symbol,
DynamicVolumeBalanceFactor(),
DynamicVolumeStep() //
);
//
if (dVolume > 0)
{
signal.volume = dVolume;
}
else
{
signal.volume = Volume();
}
}
else
{
signal.volume = Volume();
}
//
// mTradeHandler.UpdateSignal(signal);
}
/**
* Configure Startegy ...
*/
// void ConfigureStrategy(XCX121SMCBaseStrategy *&strategy)
// {
// //
// if (strategy == NULL)
// {
// return;
// }
// //
// // Configure Alerts ...
// strategy.SetAlertPrefix(GetTag());
// strategy.SetAlertLogAlerts(GetAlertLogAlerts());
// strategy.SetAlertMailAlerts(GetAlertMailAlerts());
// strategy.SetAlertPushAlerts(GetAlertPushAlerts());
// strategy.SetAlertEnableAlerts(GetAlertEnableAlerts());
// strategy.SetAlertTerminalAlerts(GetAlertTerminalAlerts());
// //
// // Confiugre Signalling ...
// //
// strategy.R2R(2);
// strategy.AllowLong(AllowLong());
// strategy.AllowShort(AllowShort());
// //
// if (Disabled())
// {
// strategy.Disable();
// }
// else
// {
// strategy.Enable();
// }
// //
// }
/**
* Register an Strategy in EA ...
*
* @param strategy: XCX121SMCBaseStrategy instance ...
*/
// void RegisterStrategy(XCX121SMCBaseStrategy *strategy)
// {
// //
// if (strategy == NULL)
// {
// return;
// }
// //
// ArrayResize(
// mStrategies,
// ArraySize(mStrategies) + 1 //
// );
// //
// mStrategies[ArraySize(mStrategies) - 1] = strategy;
// }
/**
* Re Configure All Registered Strategies ...
*/
// void ReConfigureAllStrategies()
// {
// //
// int count = ArraySize(mStrategies);
// if (!IsValidSize(count))
// {
// return;
// }
// //
// for (int i = 0; i < count; i++)
// {
// //
// ConfigureStrategy(mStrategies[i]);
// }
// }
//
private:
//
//
// Props ...
//
// Volume Management ...
bool mUseDynamicVolume; // Use Dynamic Volume ...
double mDynamicVolumeStep; // Increase Volume Step ...
double mDynamicVolumeBalanceFactor; // Balance Factor for Generate Dynamic Volume ...
double mVolume; // Static Volume ...
//
};
//
@@ -0,0 +1,830 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XC121SMCExpert
// Description: provides all based classes for use ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-expert.class.mq5"
#include "../../Classes/x-saherelm.x-poi.class.mq5"
// #include "../Classes/x-121.smc.xtradehandler.class.mq5"
//
// Definitions ...
string XC121SMCExpertToken = "XC121SMCEA";
//
// Implementation ...
class XC121SMCExpert : public XCBaseExpert
{
//
public:
//
//
// Signal Event Listener ...
TOnStopLoss OnPositionSLEventListener;
TOnTakeProfit OnPositionTPEventListener;
TOnPartialClose OnPositionPartialCloseEventListener;
TOnModify OnPositionModifiedEventListener;
TOnForceClose OnPositionForceCloseEventListener;
//
// Getter(s) / Setter(s) ...
/**
* Get Use Dynamic Volume State ...
*
* @return ( bool )
*/
bool UseDynamicVolume()
{
return mUseDynamicVolume;
}
/**
* Set Use Dynamic Volume State ...
*
* @param value: Boolean ...
*/
void UseDynamicVolume(bool value)
{
mUseDynamicVolume = value;
}
/**
* Get Increase Volume Step ...
*
* @return ( double )
*/
double DynamicVolumeStep()
{
return mDynamicVolumeStep;
}
/**
* Set Increase Volume Step ...
*
* @param value: Double ...
*/
void DynamicVolumeStep(double value)
{
//
if (value < 0.01)
{
value = 0.01;
}
//
mDynamicVolumeStep = value;
}
/**
* Get Balance Factor for Generate Dynamic Volume ...
*
* @return ( double )
*/
double DynamicVolumeBalanceFactor()
{
return mDynamicVolumeBalanceFactor;
}
/**
* Set Balance Factor for Generate Dynamic Volume ...
*
* @param value: Double ...
*/
void DynamicVolumeBalanceFactor(double value)
{
//
if (value < 0)
{
value = 0;
}
//
mDynamicVolumeBalanceFactor = value;
}
/**
* Get Static Volume ...
*
* @return ( double )
*/
double Volume()
{
return mVolume;
}
/**
* Set Static Volume ...
*
* @param value: Double ...
*/
void Volume(double value)
{
//
if (value < 0.01)
{
value = 0.01;
}
//
mVolume = value;
}
//
// Actions ...
//
// Override Actions ...
/**
* Apply Default Configurations ...
*/
void DefaultConfigure() override
{
//
// Commons ...
Slippage(10);
TagPrefix("");
MagicNumber(1694056);
//
// Symbol ...
SetSymbol(_Symbol);
SetPeriod(_Period);
MultiSymbol(false);
Symbols("EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb");
//
// Signalling ...
Disabled(false);
AllowLong(true);
AllowShort(true);
//
string tag = GetTag();
//
// Alert ...
SetAlertPrefix(tag);
SetAlertLogAlerts(true);
SetAlertPushAlerts(true);
SetAlertMailAlerts(false);
SetAlertEnableAlerts(true);
SetAlertTerminalAlerts(false);
//
// Reports ...
ReportNewDays(true);
ReportNewWeeks(false);
ReportNewHours(false);
ReportNewMonths(false);
//
// Volume Default Configurations ...
Volume(0.01);
UseDynamicVolume(false);
DynamicVolumeStep(0.01);
DynamicVolumeBalanceFactor(200);
}
/**
* Vaslidate Inputs ...
*
* @return ( bool )
*/
bool ValidateInputs() override
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
Slippage() > 0 &&
MagicNumber() > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
// Checking Volume ...
bool isVolumeValid = true;
if (UseDynamicVolume())
{
//
isVolumeValid =
DynamicVolumeStep() > 0 &&
DynamicVolumeBalanceFactor() > 0;
if (!isVolumeValid)
{
errMessage += "Dynamic Volume configurations error;" + "\n";
}
}
isVolumeValid = isVolumeValid &&
Volume() > 0;
if (!isVolumeValid)
{
errMessage += "Static Volume configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Volume Coniguration ...
isVolumeValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
errMessage = " Errors: \n" + errMessage;
Alert(errMessage);
}
//
return result;
}
//
// Initializers and DeInitializers ...
/**
* Initial EA Requirements ...
*
* @return ( bool )
*/
bool InitEA() override
{
//
bool result = false;
//
// Initialize Indicator Helpers ...
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
mPOIDetector = new XCPOIDetector(
symbol,
period //
);
mPOIDetector.Init();
//
// Bar Timer ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
mCTHelper = new XCXCTHelper();
result = mCTHelper.Init(
GetSymbol(),
GetPeriod(),
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
mCCHelper = new XCXCCHelper();
result = mCCHelper.Init(
GetSymbol(),
GetPeriod(),
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Trader Instance and Configure it ...
mTrader = new XCTrade(
Slippage(),
MagicNumber() //
);
mTrader.AddOnStopLossEventHandler(OnPositionSLEventListener);
mTrader.AddOnTakeProfitEventHandler(OnPositionTPEventListener);
mTrader.AddOnModifyPositionEventHandler(OnPositionModifiedEventListener);
mTrader.AddOnForceClosePositionEventHandler(OnPositionForceCloseEventListener);
mTrader.AddOnPartialClosePositionEventHandler(OnPositionPartialCloseEventListener);
// //
// // Initialize Trade Handler ...
// mTradeHandler = new XC121SMCTradeHandler(mTrader);
// mTradeHandler.SaveTrades(true);
// mTradeHandler.SaveSignals(true);
// mTradeHandler.SaveConditions(true);
// //
// // Configure Alerts ...
// mTradeHandler.SetAlertPrefix(GetTag());
// mTradeHandler.SetAlertEnableAlerts(GetAlertEnableAlerts());
// mTradeHandler.SetAlertLogAlerts(GetAlertLogAlerts());
// mTradeHandler.SetAlertMailAlerts(GetAlertMailAlerts());
// mTradeHandler.SetAlertPushAlerts(GetAlertPushAlerts());
// mTradeHandler.SetAlertTerminalAlerts(GetAlertTerminalAlerts());
// //
// // TODO: Make This Configurable Later ...
// //
// mTradeHandler.DelayBarBetweenTwoSignal(3);
// mTradeHandler.MaxAllowedSLToPause(0);
// mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24));
// //
// // Configure Trade Management ...
// mTradeHandler.AllowLong(AllowLong());
// mTradeHandler.AllowShort(AllowShort());
// mTradeHandler.MaxAllowedLongs(0);
// mTradeHandler.MaxAllowedShorts(0);
// mTradeHandler.UseMaxAllowedTradesPerSymbol(true);
// mTradeHandler.MaxDrawdownPercentForOpenTrades(5);
// //
// // Configure Position Protector ...
// //
// mTradeHandler.UseForceMomentumsInProtection(true);
// mTradeHandler.DelayBarBetweenTwoSignal(2);
// //
// // Configure Hedging ...
// mTradeHandler.AllowHedge(false);
// mTradeHandler.HedgeMinVolumeStep(0.01);
// mTradeHandler.MinimumOpenPositionsForHEHedge(2);
// mTradeHandler.HedgeHEMinProfitPerVolumeStep(0.2);
// mTradeHandler.HedgeBEMinProfitPerVolumeStep(0.06);
// //
// // In Profit Position Protecting ...
// //
// // Trail ...
// mTradeHandler.AllowTrail(false);
// mTradeHandler.TrailStep(15);
// mTradeHandler.TrailStartDistance(30);
// mTradeHandler.OnlyTrailUnprotected(true);
// mTradeHandler.RemoveTPAfterTrailedLevel(4);
// //
// // Partial Close (In Profit) ...
// mTradeHandler.PartialCloseInProfitDistance(0);
// mTradeHandler.PartialCloseInProfitVolume(0);
// //
// // In Drawdown Positions Protecting ...
// //
// // Protect ...
// mTradeHandler.AllowProtect(false);
// mTradeHandler.ProtectionDelay(20);
// mTradeHandler.MaxAllowedProtection(0);
// mTradeHandler.UseEntryAsProtectionSL(true);
// mTradeHandler.ProtectOnConditions(true);
// mTradeHandler.AllowDirectionProtct(false);
// mTradeHandler.ProtectionStartDistance(50);
// mTradeHandler.ProtectionVolumeMultiplier(2);
// //
// // Partial Close (In Profit) ...
// mTradeHandler.PartialCloseInDrawdownDistance(0);
// mTradeHandler.PartialCloseInDrawdownVolume(0);
//
// Parsers ...
XSymbolParser _symbolParser;
//
// Single Symbol ...
if (!MultiSymbol())
{
//
// Register Strategy ...
//
// Create Class Instance ...
// XCX121SMCBaseStrategy *iX121SMCStrategy;
// iX121SMCStrategy = new XCX121SMCTestStrategy(
// _Symbol,
// _Period //
// );
// //
// iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener);
// //
// ConfigureStrategy(iX121SMCStrategy);
// RegisterStrategy(iX121SMCStrategy);
}
//
// Multi Symbol ...
else
{
//
// Parse Symbols ...
string symbols[];
int symbolsCount = SplitContent(
symbols,
Symbols() //
);
result = IsValidSize(symbolsCount);
if (!result)
{
return result;
}
//
for (int i = 0; i < symbolsCount; i++)
{
//
// Select Symbol ...
string iSymbol = symbols[i];
//
// Register Strategy Based On Symbol ...
//
// Parse Symbol ...
bool isEURUSD = _symbolParser.IsEURUSD(_Symbol);
bool isGBPUSD = _symbolParser.IsGBPUSD(_Symbol);
bool isEURGBP = _symbolParser.IsEURGBP(_Symbol);
bool isUSDCHF = _symbolParser.IsUSDCHF(_Symbol);
bool isEURCHF = _symbolParser.IsEURCHF(_Symbol);
bool isUSDJPY = _symbolParser.IsUSDJPY(_Symbol);
bool isEURJPY = _symbolParser.IsEURJPY(_Symbol);
bool isUSDCAD = _symbolParser.IsUSDCAD(_Symbol);
bool isEURCAD = _symbolParser.IsEURCAD(_Symbol);
bool isAUDUSD = _symbolParser.IsAUDUSD(_Symbol);
bool isEURAUD = _symbolParser.IsEURAUD(_Symbol);
bool isNZDUSD = _symbolParser.IsNZDUSD(_Symbol);
bool isEURNZD = _symbolParser.IsEURNZD(_Symbol);
//
// Check Symbol Can Register or not ...
bool canRegisterStrategy = true;
//
if (canRegisterStrategy)
{
// //
// // Create Class Instance ...
// XCX121SMCBaseStrategy *iX121SMCStrategy;
// iX121SMCStrategy = new XCX121SMCTestStrategy(
// iSymbol,
// _Period //
// );
// //
// iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener);
// //
// // Register Strategy ...
// ConfigureStrategy(iX121SMCStrategy);
// RegisterStrategy(iX121SMCStrategy);
}
}
}
//
return result;
}
/**
* Destroy all Initialized EA Requirements ...
*/
void DestroyEA() override
{
//
delete mCTHelper;
delete mCCHelper;
// delete mTradeHandler;
//
// Clean(mStrategies);
}
/**
* Call all Registered Strategies On Tick ...
*/
void HandleStrategiesOnTick() override
{
//
ENUM_XPOI_EVENTS events[];
mPOIDetector.Update(events);
//
// int count = ArraySize(mStrategies);
// if (!IsValidSize(count))
// {
// return;
// }
// //
// for (int i = 0; i < count; i++)
// {
// //
// // Call Tick Handler Function ...
// mStrategies[i].HandleTick();
// }
}
//
// Event Handlers ...
/**
* Calls When a Position's SL Triggered ...
*
* @param deal: XDeal instance ...
*/
void HandleOnStopLossTriggered(const XDeal &deal) override
{
//
// Finish ...
// mTradeHandler.Finish(deal);
//
HandleReportBalance();
}
/**
* Calls When a Position's TP Triggered ...
*
* @param deal: XDeal instance ...
*/
void HandleOnTakeProfitTriggered(const XDeal &deal) override
{
//
// Finish ...
// mTradeHandler.Finish(deal);
//
HandleReportBalance();
}
/**
* Handle Force Close a Position ...
*
* @param ticket: Position Ticket ...
* @param position: XPosition ...
* @param comment: Closing Comment ...
*/
void HandleOnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
) override
{
//
// Finish ...
// mTradeHandler.Finish(
// ticket,
// position,
// comment //
// );
//
HandleReportBalance();
}
/**
* Reset All Paused Symbols on Each New Days ...
*/
void HandleOnNewDay() override
{
// mTradeHandler.ResumePausedSymbols();
}
/**
* Generate Identifier Tag ...
*
* @return ( string )
*/
string GetTag() override
{
//
string result = NULL;
//
string tagPrefix = TagPrefix();
if (IsValid(tagPrefix))
{
result = tagPrefix;
}
else
{
result = "";
}
//
result =
XCBaseExpertToken + result;
//
return result;
}
//
protected:
//
//
// Props ...
//
datetime mLastSignalOn;
//
XCPOIDetector *mPOIDetector;
//
// XC121SMCTradeHandler *mTradeHandler; // Trade Handler ...
// XCX121SMCBaseStrategy *mStrategies[]; // Registere Strategies in EA ...
//
// Actions ...
/**
* Apply Volume Based On Configurations on Signal ...
*
* @param signal: XSignal instance
*/
void ApplyVolumeOnSignal(XSignal &signal)
{
//
// Prepare Signal Dynamic Volume
// if Provided ...
if (UseDynamicVolume() &&
DynamicVolumeStep() > 0 &&
DynamicVolumeBalanceFactor() > 0)
{
//
double dVolume = mTrader.GetDynamicVolume(
signal.symbol,
DynamicVolumeBalanceFactor(),
DynamicVolumeStep() //
);
//
if (dVolume > 0)
{
signal.volume = dVolume;
}
else
{
signal.volume = Volume();
}
}
else
{
signal.volume = Volume();
}
//
// mTradeHandler.UpdateSignal(signal);
}
/**
* Configure Startegy ...
*/
// void ConfigureStrategy(XCX121SMCBaseStrategy *&strategy)
// {
// //
// if (strategy == NULL)
// {
// return;
// }
// //
// // Configure Alerts ...
// strategy.SetAlertPrefix(GetTag());
// strategy.SetAlertLogAlerts(GetAlertLogAlerts());
// strategy.SetAlertMailAlerts(GetAlertMailAlerts());
// strategy.SetAlertPushAlerts(GetAlertPushAlerts());
// strategy.SetAlertEnableAlerts(GetAlertEnableAlerts());
// strategy.SetAlertTerminalAlerts(GetAlertTerminalAlerts());
// //
// // Confiugre Signalling ...
// //
// strategy.R2R(2);
// strategy.AllowLong(AllowLong());
// strategy.AllowShort(AllowShort());
// //
// if (Disabled())
// {
// strategy.Disable();
// }
// else
// {
// strategy.Enable();
// }
// //
// }
/**
* Register an Strategy in EA ...
*
* @param strategy: XCX121SMCBaseStrategy instance ...
*/
// void RegisterStrategy(XCX121SMCBaseStrategy *strategy)
// {
// //
// if (strategy == NULL)
// {
// return;
// }
// //
// ArrayResize(
// mStrategies,
// ArraySize(mStrategies) + 1 //
// );
// //
// mStrategies[ArraySize(mStrategies) - 1] = strategy;
// }
/**
* Re Configure All Registered Strategies ...
*/
// void ReConfigureAllStrategies()
// {
// //
// int count = ArraySize(mStrategies);
// if (!IsValidSize(count))
// {
// return;
// }
// //
// for (int i = 0; i < count; i++)
// {
// //
// ConfigureStrategy(mStrategies[i]);
// }
// }
//
private:
//
//
// Props ...
//
// Volume Management ...
bool mUseDynamicVolume; // Use Dynamic Volume ...
double mDynamicVolumeStep; // Increase Volume Step ...
double mDynamicVolumeBalanceFactor; // Balance Factor for Generate Dynamic Volume ...
double mVolume; // Static Volume ...
//
};
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,991 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XChartObjects
// Description: provides all require Chart Objects ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
#include "../../Classes/x-saherelm.x-chart-objects.class.mq5"
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
#include "../Libraries/x-121.smc.lib.mq5"
//
#include <Arrays/ArrayObj.mqh>
//
// Definitions ...
enum ENUM_X121SMC_CHARTOBJECTS
{
//
// Global ...
X_121SMC_CONDITIONS_OBJ = 110121,
X_121SMC_MARKET_STRUCTURE_OBJ = 110122,
};
//
// Implementations ...
//
// Market Conditions ...
class XC121SMCConditionsObject : public XCBaseObject
{
//
public:
//
//
// Constructor ...
void XC121SMCConditionsObject(XCPOIDrawer *_poiDrawer)
{
mPOIDrawer = _poiDrawer;
}
//
// Deconstructor ...
void ~XC121SMCConditionsObject()
{
}
/**
* Create a Conditions Object on Chart ...
*
* @param chart_id: Long ...
* @param name: String ...
* @param window: Integer ...
* @param conditions: X121SMCStrategyConditions instance ...
*
* @return ( bool )
*/
bool CreateByConditions(
long chart_id,
const string name,
const int window,
X121SMCStrategyConditions &conditions //
)
{
//
bool result = false;
//
result = IsValid(name);
if (!result)
{
return result;
}
//
string nameMD5 = ToMD5(name);
string suffix = "_" + nameMD5;
//
// Supply Zone ...
bool isCreated = mPOIDrawer.CreateSupplyZone(
conditions.supplyZone,
mSupplyZoneObj //
);
//
// Demnd Zone ...
isCreated = mPOIDrawer.CreateDemandZone(
conditions.demandZone,
mDemandZoneObj //
);
//
// Bullish Order Block ...
isCreated = mPOIDrawer.CreateBullishOrderBlock(
conditions.bullishOrderBlock,
mBullishOBObj //
);
//
// Bearish Order Block ...
isCreated = mPOIDrawer.CreateBearishOrderBlock(
conditions.bearishOrderBlock,
mBearishOBObj //
);
//
// Collections ...
//
// Order Blocks ...
//
// Bullish ...
int count = ArraySize(conditions.bullishOrderBlocks);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = conditions.bullishOrderBlocks[i];
//
XCBullishOrderBlockObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishOrderBlock(
iZone,
iObj //
);
//
if (isCreated)
{
mBullishOBObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(conditions.bearishOrderBlocks);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = conditions.bearishOrderBlocks[i];
//
XCBearishOrderBlockObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishOrderBlock(
iZone,
iObj //
);
//
if (isCreated)
{
mBearishOBObjs.Add(iObj);
}
}
}
//
// Fair Value Gaps ...
//
// Bullish ...
count = ArraySize(conditions.bullishFVGs);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = conditions.bullishFVGs[i];
//
XCBullishFVGObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishFVG(
iZone,
iObj //
);
//
if (isCreated)
{
mBullishFVGObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(conditions.bearishFVGs);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = conditions.bearishFVGs[i];
//
XCBearishFVGObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishFVG(
iZone,
iObj //
);
//
if (isCreated)
{
mBearishFVGObjs.Add(iObj);
}
}
}
//
// Support and Resistance Zones ...
//
// Supports ...
count = ArraySize(conditions.supports);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.supports[i];
//
XCSupportZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateSupportZone(
iBar,
iObj //
);
//
if (isCreated)
{
mSupportZoneObjs.Add(iObj);
}
}
}
//
// Resistances ...
count = ArraySize(conditions.resistances);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.resistances[i];
//
XCResistanceZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateResistanceZone(
iBar,
iObj //
);
//
if (isCreated)
{
mResistanceZoneObjs.Add(iObj);
}
}
}
//
// Swings ...
//
// High ...
count = ArraySize(conditions.swingHighs);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.swingHighs[i];
//
XCSwingHighObject *iObj;
bool isCreated = mPOIDrawer.CreateSwingHigh(
iBar,
iObj //
);
//
if (isCreated)
{
mSwingHighObjs.Add(iObj);
}
}
}
//
// Low ...
count = ArraySize(conditions.swingLows);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.swingLows[i];
//
XCSwingLowObject *iObj;
bool isCreated = mPOIDrawer.CreateSwingLow(
iBar,
iObj //
);
//
if (isCreated)
{
mSwingLowObjs.Add(iObj);
}
}
}
//
// Momentum Bars ...
//
// Bullish ...
count = ArraySize(conditions.bullishMomentumBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.bullishMomentumBars[i];
//
XCBullishMomentumBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishMomentumBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBullishMomentumBarObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(conditions.bearishMomentumBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.bearishMomentumBars[i];
//
XCBearishMomentumBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishMomentumBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBearishMomentumBarObjs.Add(iObj);
}
}
}
//
// Rejection Bars ...
//
// Bullish ...
count = ArraySize(conditions.bullishRejectionBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.bullishRejectionBars[i];
//
XCBullishRejectionBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishRejectionBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBullishRejectionBarObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(conditions.bearishRejectionBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = conditions.bearishRejectionBars[i];
//
XCBearishRejectionBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishRejectionBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBearishRejectionBarObjs.Add(iObj);
}
}
}
//
if (result)
{
ObjName(name);
}
//
return result;
}
/**
* Retrieve Object Type ...
*
* @return ( ENUM_X121SMC_CHARTOBJECTS )
*/
virtual ENUM_X121SMC_CHARTOBJECTS Type()
{
return X_121SMC_CONDITIONS_OBJ;
}
//
private:
//
XCPOIDrawer *mPOIDrawer;
//
XCSupplyZoneObject *mSupplyZoneObj;
XCDemandZoneObject *mDemandZoneObj;
//
XCBullishOrderBlockObject *mBullishOBObj;
XCBearishOrderBlockObject *mBearishOBObj;
//
CArrayObj mBullishOBObjs;
CArrayObj mBearishOBObjs;
//
CArrayObj mBullishFVGObjs;
CArrayObj mBearishFVGObjs;
//
CArrayObj mSupportZoneObjs;
CArrayObj mResistanceZoneObjs;
//
CArrayObj mSwingHighObjs;
CArrayObj mSwingLowObjs;
//
CArrayObj mBullishMomentumBarObjs;
CArrayObj mBearishMomentumBarObjs;
//
CArrayObj mBullishRejectionBarObjs;
CArrayObj mBearishRejectionBarObjs;
//
};
//
// Market Structure ...
class XC121SMCMarketStructureObject : public XCBaseObject
{
//
public:
//
//
// Constructor ...
void XC121SMCMarketStructureObject(XCPOIDrawer *_poiDrawer)
{
mPOIDrawer = _poiDrawer;
}
//
// Deconstructor ...
void ~XC121SMCMarketStructureObject()
{
}
/**
* Create a Conditions Object on Chart ...
*
* @param chart_id: Long ...
* @param name: String ...
* @param window: Integer ...
* @param conditions: X121SMCStrategyConditions instance ...
*
* @return ( bool )
*/
bool CreateByStructure(
long chart_id,
const string name,
const int window,
X121SMCMarketStructure &structure //
)
{
//
bool result = false;
//
result = IsValid(name);
if (!result)
{
return result;
}
//
string nameMD5 = ToMD5(name);
string suffix = "_" + nameMD5;
//
// Supply Zone ...
bool isCreated = mPOIDrawer.CreateSupplyZone(
structure.supplyZone,
mSupplyZoneObj //
);
//
// Demnd Zone ...
isCreated = mPOIDrawer.CreateDemandZone(
structure.demandZone,
mDemandZoneObj //
);
//
// Bullish Order Block ...
isCreated = mPOIDrawer.CreateBullishOrderBlock(
structure.bullishOrderBlock,
mBullishOBObj //
);
//
// Bearish Order Block ...
isCreated = mPOIDrawer.CreateBearishOrderBlock(
structure.bearishOrderBlock,
mBearishOBObj //
);
//
// Collections ...
//
// Order Blocks ...
//
// Bullish ...
int count = ArraySize(structure.bullishOrderBlocks);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = structure.bullishOrderBlocks[i];
//
XCBullishOrderBlockObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishOrderBlock(
iZone,
iObj //
);
//
if (isCreated)
{
mBullishOBObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(structure.bearishOrderBlocks);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = structure.bearishOrderBlocks[i];
//
XCBearishOrderBlockObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishOrderBlock(
iZone,
iObj //
);
//
if (isCreated)
{
mBearishOBObjs.Add(iObj);
}
}
}
//
// Fair Value Gaps ...
//
// Bullish ...
count = ArraySize(structure.bullishFVGs);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = structure.bullishFVGs[i];
//
XCBullishFVGObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishFVG(
iZone,
iObj //
);
//
if (isCreated)
{
mBullishFVGObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(structure.bearishFVGs);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = structure.bearishFVGs[i];
//
XCBearishFVGObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishFVG(
iZone,
iObj //
);
//
if (isCreated)
{
mBearishFVGObjs.Add(iObj);
}
}
}
//
// Support and Resistance Zones ...
//
// Supports ...
count = ArraySize(structure.supports);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.supports[i];
//
XCSupportZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateSupportZone(
iBar,
iObj //
);
//
if (isCreated)
{
mSupportZoneObjs.Add(iObj);
}
}
}
//
// Resistances ...
count = ArraySize(structure.resistances);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.resistances[i];
//
XCResistanceZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateResistanceZone(
iBar,
iObj //
);
//
if (isCreated)
{
mResistanceZoneObjs.Add(iObj);
}
}
}
//
// Swings ...
//
// High ...
count = ArraySize(structure.swingHighs);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.swingHighs[i];
//
XCSwingHighObject *iObj;
bool isCreated = mPOIDrawer.CreateSwingHigh(
iBar,
iObj //
);
//
if (isCreated)
{
mSwingHighObjs.Add(iObj);
}
}
}
//
// Low ...
count = ArraySize(structure.swingLows);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.swingLows[i];
//
XCSwingLowObject *iObj;
bool isCreated = mPOIDrawer.CreateSwingLow(
iBar,
iObj //
);
//
if (isCreated)
{
mSwingLowObjs.Add(iObj);
}
}
}
//
// Momentum Bars ...
//
// Bullish ...
count = ArraySize(structure.bullishMomentumBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.bullishMomentumBars[i];
//
XCBullishMomentumBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishMomentumBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBullishMomentumBarObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(structure.bearishMomentumBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.bearishMomentumBars[i];
//
XCBearishMomentumBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishMomentumBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBearishMomentumBarObjs.Add(iObj);
}
}
}
//
// Rejection Bars ...
//
// Bullish ...
count = ArraySize(structure.bullishRejectionBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.bullishRejectionBars[i];
//
XCBullishRejectionBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishRejectionBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBullishRejectionBarObjs.Add(iObj);
}
}
}
//
// Bearish ...
count = ArraySize(structure.bearishRejectionBars);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = structure.bearishRejectionBars[i];
//
XCBearishRejectionBarObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishRejectionBar(
iBar,
iObj //
);
//
if (isCreated)
{
mBearishRejectionBarObjs.Add(iObj);
}
}
}
//
if (result)
{
ObjName(name);
}
//
return result;
}
/**
* Retrieve Object Type ...
*
* @return ( ENUM_X121SMC_CHARTOBJECTS )
*/
virtual ENUM_X121SMC_CHARTOBJECTS Type()
{
return X_121SMC_MARKET_STRUCTURE_OBJ;
}
//
private:
//
XCPOIDrawer *mPOIDrawer;
//
XCSupplyZoneObject *mSupplyZoneObj;
XCDemandZoneObject *mDemandZoneObj;
//
XCBullishOrderBlockObject *mBullishOBObj;
XCBearishOrderBlockObject *mBearishOBObj;
//
CArrayObj mBullishOBObjs;
CArrayObj mBearishOBObjs;
//
CArrayObj mBullishFVGObjs;
CArrayObj mBearishFVGObjs;
//
CArrayObj mSupportZoneObjs;
CArrayObj mResistanceZoneObjs;
//
CArrayObj mSwingHighObjs;
CArrayObj mSwingLowObjs;
//
CArrayObj mBullishMomentumBarObjs;
CArrayObj mBearishMomentumBarObjs;
//
CArrayObj mBullishRejectionBarObjs;
CArrayObj mBearishRejectionBarObjs;
//
};
//
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
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,934 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 X121 SMC Signal Class
// -------------------------------------------------
// Name:
// Description: provide all Signalling functions ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
#include "../Libraries/x-121.smc.lib.mq5"
//
// Definitions ...
struct X121SMCStrategyTestSignalConditions
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
double sl;
ENUM_X_DIRECTION dir;
ENUM_X_POSITION_TYPES type;
//
// Setup Props ...
//
datetime setupTime;
datetime triggerTime;
//
// Bullish Order Blocks ...
datetime bullishOrderBlockTime;
XCOrderBlock *bullishOrderBlock;
//
// Bearish Order Blocks ...
XCOrderBlock *bearishOrderBlock;
datetime bearishOrderBlockTime;
//
// Trigger Props ...
//
// Constructor ...
X121SMCStrategyTestSignalConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleaning Up ...
*/
void Clean()
{
//
sl = 0;
//
dir = X_DIRECTION_NONE;
type = X_POSITION_TYPE_NONE;
//
symbol = NULL;
period = NULL;
setupTime = NULL;
triggerTime = NULL;
//
// Additional ...
//
bullishOrderBlock = NULL;
bearishOrderBlock = NULL;
bullishOrderBlockTime = NULL;
bearishOrderBlockTime = NULL;
}
/**
* Check Condition is Setting Up ...
*
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
*
* @return ( bool )
*/
bool IsSetuped()
{
//
bool result = false;
//
result = IsValid(setupTime) &&
HasDirection(dir);
if (!result)
{
return result;
}
//
return result;
}
/**
* Detect How we Can Trigger Signal ...
*
* @return ( bool )
*/
bool CanTrigger()
{
//
bool result = false;
//
result =
//
sl > 0 &&
IsValid(symbol) &&
IsValid(period) &&
IsValid(triggerTime) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE
//
;
//
return result;
}
//
// Extensions ...
bool HasBullishOrderBlock()
{
//
bool result =
bullishOrderBlock != NULL &&
bullishOrderBlock.IsValid() &&
bullishOrderBlock.IsBullish() &&
IsValid(bullishOrderBlockTime);
//
return result;
}
bool HasBearishOrderBlock()
{
//
bool result =
bearishOrderBlock != NULL &&
bearishOrderBlock.IsValid() &&
bearishOrderBlock.IsBullish() &&
IsValid(bearishOrderBlockTime);
//
return result;
}
bool HasOrderBlock()
{
//
bool result = HasBullishOrderBlock() &&
HasBearishOrderBlock();
//
return result;
}
//
};
//
// Extension Functions ...
//
// Detect Setup Conditions ...
bool DetectX121SMCTestSiganlSetup(
string _symbol,
ENUM_TIMEFRAMES _period,
//
X121SMCStrategyTestSignalConditions &conditions,
//
XC121SMCCycleHelper *triggerCycleHelper,
XC121SMCCycleHelper *decisionCycleHelper,
XC121SMCCycleHelper *analyseCycleHelper,
XC121SMCCycleHelper *verificationCycleHelper,
XC121SMCCycleHelper *consolidationCycleHelper,
XC121SMCCycleHelper *visionCycleHelper
//
)
{
//
bool result = false;
//
bool isBullish = false;
bool isBearish = false;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
string symbol = _symbol;
ENUM_TIMEFRAMES period = _period;
//
conditions.symbol = symbol;
conditions.period = period;
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
//
double ll = cBar.FindLowest(9, MODE_LOW);
double hh = cBar.FindHighest(9, MODE_HIGH);
//
int zoneValidationDivider = 10;
int validPivotRepetition = triggerCycleHelper.mX121Helper
.GetDonChainLength();
//
double selectedSL = 0;
//
// Cycles Conditions ...
//
// Trigger ...
ENUM_XPOI_EVENTS triggerPoiEvents[];
ENUM_X_CYCLE_EVENTS triggerCycleEvents[];
X121SMCCycleConditions triggerConditions;
result = triggerCycleHelper.GetConditions(
triggerCycleEvents,
triggerPoiEvents,
triggerConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Decision ...
ENUM_XPOI_EVENTS decisionPoiEvents[];
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
X121SMCCycleConditions decisionConditions;
result = decisionCycleHelper.GetConditions(
decisionCycleEvents,
decisionPoiEvents,
decisionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Analyse ...
ENUM_XPOI_EVENTS analysePoiEvents[];
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
X121SMCCycleConditions analyseConditions;
result = analyseCycleHelper.GetConditions(
analyseCycleEvents,
analysePoiEvents,
analyseConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Verification ...
ENUM_XPOI_EVENTS verificationPoiEvents[];
ENUM_X_CYCLE_EVENTS verificationCycleEvents[];
X121SMCCycleConditions verificationConditions;
result = verificationCycleHelper.GetConditions(
verificationCycleEvents,
verificationPoiEvents,
verificationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Consolidation ...
ENUM_XPOI_EVENTS consolidationPoiEvents[];
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
X121SMCCycleConditions consolidationConditions;
result = consolidationCycleHelper.GetConditions(
consolidationCycleEvents,
consolidationPoiEvents,
consolidationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Vision ...
ENUM_XPOI_EVENTS visionPoiEvents[];
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
X121SMCCycleConditions visionConditions;
result = visionCycleHelper.GetConditions(
visionCycleEvents,
visionPoiEvents,
visionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Cycles POI States ...
XPOIState triggerState = triggerConditions.state;
XPOIState decisionState = decisionConditions.state;
XPOIState analyseState = analyseConditions.state;
XPOIState verificationState = verificationConditions.state;
XPOIState consolidationState = consolidationConditions.state;
XPOIState visionState = visionConditions.state;
//
// Check Order Block ...
// TODO: Later ...
// bool hasOrderBlock = conditions.HasOrderBlock();
// if (hasOrderBlock)
// {
// //
// DetectX121SMCTestSiganlOrderBlock(
// zBar,
// consolidationState,
// conditions //
// );
// }
//
bool isMarketBullish =
//
// VWap State ...
decisionConditions.x121Conditions.isVWapBullishState &&
analyseConditions.x121Conditions.isVWapBullishState &&
verificationConditions.x121Conditions.isVWapBullishState
//
&&
//
// VWap Order ...
decisionConditions.x121Conditions.isVWapBullishOrdered &&
analyseConditions.x121Conditions.isVWapBullishOrdered &&
verificationConditions.x121Conditions.isVWapBullishOrdered
//
&&
//
// Sar ...
decisionConditions.x121Conditions.isSarBullish &&
analyseConditions.x121Conditions.isSarBullish &&
verificationConditions.x121Conditions.isSarBullish
//
;
//
bool isMarketBearish =
//
// VWap State ...
decisionConditions.x121Conditions.isVWapBearishState &&
analyseConditions.x121Conditions.isVWapBearishState &&
verificationConditions.x121Conditions.isVWapBearishState
//
&&
//
// VWap Order ...
decisionConditions.x121Conditions.isVWapBearishOrdered &&
analyseConditions.x121Conditions.isVWapBearishOrdered &&
verificationConditions.x121Conditions.isVWapBearishOrdered
//
&&
//
// Sar ...
decisionConditions.x121Conditions.isSarBearish &&
analyseConditions.x121Conditions.isSarBearish &&
verificationConditions.x121Conditions.isSarBearish
//
;
//
// Step 1
// Detect Market Direction ...
isBullish = isMarketBullish;
isBearish = isMarketBearish;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
// Step 2
// VWap Switches or Sar Switches ...
//
bool isSarBullish = triggerConditions.x121Conditions.isSarBullish;
bool isSarBearish = triggerConditions.x121Conditions.isSarBearish;
//
bool isSarSwitchedToBullish = triggerConditions.x121Conditions.isSarSwitchedToBullish;
bool isSarSwitchedToBearish = triggerConditions.x121Conditions.isSarSwitchedToBearish;
//
bool isVWapBullishState = triggerConditions.x121Conditions.isVWapBullishState;
bool isVWapBearishState = triggerConditions.x121Conditions.isVWapBearishState;
//
bool isVWapSwitchedToBullishState = triggerConditions.x121Conditions.isVWapSwitchedToBullishState;
bool isVWapSwitchedToBearishState = triggerConditions.x121Conditions.isVWapSwitchedToBearishState;
//
bool isVWapBullishOrdered = triggerConditions.x121Conditions.isVWapBullishOrdered;
bool isVWapBearishOrdered = triggerConditions.x121Conditions.isVWapBearishOrdered;
//
bool isVWapSwitchedToBullishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBullishOrdered;
bool isVWapSwitchedToBearishOrdered = triggerConditions.x121Conditions.isVWapSwitchedToBearishOrdered;
//
//
//
//
bool isSarStartedBullishStructure =
//
isSarSwitchedToBullish &&
isVWapBullishState &&
isVWapBullishOrdered
//
;
//
bool isSarStartedBearishStructure =
//
isSarSwitchedToBearish &&
isVWapBearishState &&
isVWapBearishOrdered
//
;
//
//
//
//
bool isVWapStateStartedBullishStructure =
//
isVWapSwitchedToBullishState &&
isSarBullish &&
isVWapBullishOrdered
//
;
//
bool isVWapStateStartedBearishStructure =
//
isVWapSwitchedToBearishState &&
isSarBearish &&
isVWapBearishOrdered
//
;
//
//
//
//
bool isVWapOrderStartedBullishStructure =
//
isVWapSwitchedToBullishOrdered &&
isSarBullish &&
isVWapBullishState
//
;
//
bool isVWapOrderStartedBearishStructure =
//
isVWapSwitchedToBearishOrdered &&
isSarBearish &&
isVWapBearishState
//
;
//
//
//
//
isBullish =
//
isBullish
//
&&
//
(
//
isSarStartedBullishStructure ||
isVWapStateStartedBullishStructure ||
isVWapOrderStartedBullishStructure
//
)
//
;
//
isBearish =
//
isBearish
//
&&
//
(
//
isSarStartedBearishStructure ||
isVWapStateStartedBearishStructure ||
isVWapOrderStartedBearishStructure
//
)
//
;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
conditions.setupTime = cTime;
conditions.dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
//
// Detect Trigger Conditions ...
bool DetectX121SMCTestSiganlTrigger(
//
X121SMCStrategyTestSignalConditions &conditions,
//
string _symbol,
ENUM_TIMEFRAMES _period,
//
XC121SMCCycleHelper *triggerCycleHelper,
XC121SMCCycleHelper *decisionCycleHelper,
XC121SMCCycleHelper *analyseCycleHelper,
XC121SMCCycleHelper *verificationCycleHelper,
XC121SMCCycleHelper *consolidationCycleHelper,
XC121SMCCycleHelper *visionCycleHelper
//
)
{
//
bool result = false;
//
result = conditions.IsSetuped();
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION setupDir = conditions.dir;
//
bool isBullish = false;
bool isBearish = false;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_SMPV;
string providerStr = ToString(provider);
//
string symbol = _symbol;
ENUM_TIMEFRAMES period = _period;
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
//
double ll = cBar.FindLowest(9, MODE_LOW);
double hh = cBar.FindHighest(9, MODE_HIGH);
//
int zoneValidationDivider = 10;
int validPivotRepetition = triggerCycleHelper.mX121Helper
.GetDonChainLength();
//
double selectedSL = 0;
//
// Cycles Conditions ...
//
// Trigger ...
ENUM_XPOI_EVENTS triggerPoiEvents[];
ENUM_X_CYCLE_EVENTS triggerCycleEvents[];
X121SMCCycleConditions triggerConditions;
result = triggerCycleHelper.GetConditions(
triggerCycleEvents,
triggerPoiEvents,
triggerConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Decision ...
ENUM_XPOI_EVENTS decisionPoiEvents[];
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
X121SMCCycleConditions decisionConditions;
result = decisionCycleHelper.GetConditions(
decisionCycleEvents,
decisionPoiEvents,
decisionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Analyse ...
ENUM_XPOI_EVENTS analysePoiEvents[];
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
X121SMCCycleConditions analyseConditions;
result = analyseCycleHelper.GetConditions(
analyseCycleEvents,
analysePoiEvents,
analyseConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Verification ...
ENUM_XPOI_EVENTS verificationPoiEvents[];
ENUM_X_CYCLE_EVENTS verificationCycleEvents[];
X121SMCCycleConditions verificationConditions;
result = verificationCycleHelper.GetConditions(
verificationCycleEvents,
verificationPoiEvents,
verificationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Consolidation ...
ENUM_XPOI_EVENTS consolidationPoiEvents[];
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
X121SMCCycleConditions consolidationConditions;
result = consolidationCycleHelper.GetConditions(
consolidationCycleEvents,
consolidationPoiEvents,
consolidationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Vision ...
ENUM_XPOI_EVENTS visionPoiEvents[];
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
X121SMCCycleConditions visionConditions;
result = visionCycleHelper.GetConditions(
visionCycleEvents,
visionPoiEvents,
visionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Cycles POI States ...
XPOIState triggerState = triggerConditions.state;
XPOIState decisionState = decisionConditions.state;
XPOIState analyseState = analyseConditions.state;
XPOIState verificationState = verificationConditions.state;
XPOIState consolidationState = consolidationConditions.state;
XPOIState visionState = visionConditions.state;
//
result = false;
//
return result;
}
//
// Tools Functions ...
//
// We Have to Find Valid Order Blocks ...
// - Order Block Must Not Touched;
bool DetectX121SMCTestSiganlOrderBlock(
XOHCL &bar,
XPOIState &state,
X121SMCStrategyTestSignalConditions &conditions //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
state.IsValid() &&
state.HasChild();
if (!result)
{
return result;
}
//
int start = bar.Index();
//
// Bullish Order Block Check ...
bool hasBullishOB = conditions.HasBullishOrderBlock();
if (!hasBullishOB)
{
//
int count = state.CountBullishOrderBlocks();
result = IsValidSize(count);
if (!result)
{
return result;
}
//
XCOrderBlock *tmpOB[];
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = state.bullishOrderBlocks[i];
//
bool isOBTouched = DetectOrderBlockTouch(iOB);
}
//
hasBullishOB = conditions.HasBullishOrderBlock();
result = hasBullishOB;
if (!result)
{
return result;
}
}
//
// Bearish Order Block Check ...
bool hasBearishOB = conditions.HasBearishOrderBlock();
if (!hasBearishOB)
{
//
//
hasBearishOB = conditions.HasBearishOrderBlock();
result = hasBearishOB;
if (!result)
{
return result;
}
}
//
return result;
}
//
// TODO: Complete this ...
bool DetectOrderBlockTouch(
XCOrderBlock *ob //
)
{
//
bool result = false;
//
result = ob != NULL &&
ob.IsValid();
if (!result)
{
return result;
}
//
return result;
}
//
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
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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,883 @@
//////////////////////////////////////////////////////////////////////////////////////////
//
// Temp Test Strategy:
//
//////////////////////////////////////////////////////////////////////////////////////////
//
// TODO: Remove this ...
XSMCStrategySetupConditions mTestConditions;
bool DetectTestSignal(
X121SMCStrategyConditions &conditions //
)
{
//
bool result = false;
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_SMPV;
string providerStr = ToString(provider);
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
bool isBullish = false;
bool isBearish = false;
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
//
double ll = cBar.FindLowest(9, MODE_LOW);
double hh = cBar.FindHighest(9, MODE_HIGH);
//
double selectedSL = 0;
//
X121SMCCycleConditions triggerConditions = conditions.triggerConditions;
X121SMCCycleConditions decisionConditions = conditions.decisionConditions;
X121SMCCycleConditions analyseConditions = conditions.analyseConditions;
X121SMCCycleConditions verificationConditions = conditions.verificationConditions;
X121SMCCycleConditions consolidationConditions = conditions.consolidationConditions;
X121SMCCycleConditions visionConditions = conditions.visionConditions;
//
XPOIState triggerState = triggerConditions.state;
XPOIState decisionState = decisionConditions.state;
XPOIState analyseState = analyseConditions.state;
XPOIState verificationState = verificationConditions.state;
XPOIState consolidationState = consolidationConditions.state;
XPOIState visionState = visionConditions.state;
//
// Retrieve Peak and Vale ...
double triggerPeak = triggerConditions.x121Conditions.peaksBuffer[0];
double triggerVale = triggerConditions.x121Conditions.valesBuffer[0];
//
int zoneValidationDivider = 10;
int validPivotRepetition = mTriggerCycleHelper.mX121Helper
.GetDonChainLength();
//
datetime setupTime = mTestConditions.setupTime;
bool isSetuped = mTestConditions.IsSetuped();
ENUM_X_DIRECTION setupDir = mTestConditions.dir;
if (!isSetuped)
{
//
// Detect Signal Setup ...
//
if (!result)
{
return result;
}
}
//
// Detect Trigger Conditions ...
bool canTrigger = mTestConditions.CanTrigger();
datetime triggerTime = mTestConditions.triggerTime;
result = canTrigger;
if (!canTrigger)
{
//
if (!result)
{
return result;
}
//
isBullish = IsBullish(setupDir);
isBearish = IsBearish(setupDir);
result = isBullish ||
isBearish;
if (!result)
{
//
// Check Trigger Consitions ...
if (cTime - setupTime > 2400)
{
//
ClearDraws();
//
mTestConditions.Clean();
}
return result;
}
//
mTestConditions.symbol = symbol;
mTestConditions.period = period;
mTestConditions.triggerTime = cTime;
mTestConditions.sl = isBullish
? 0
: 0;
mTestConditions.type = isBullish
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
//
canTrigger = mTestConditions.CanTrigger();
triggerTime = mTestConditions.triggerTime;
result = canTrigger;
if (!result)
{
//
// Check Trigger Consitions ...
if (cTime - setupTime > 2400)
{
//
ClearDraws();
//
mTestConditions.Clean();
}
//
return result;
}
}
//
// Check Signal Direction ...
//
isBullish = IsBullish(setupDir);
isBearish = IsBearish(setupDir);
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
if (cTime - setupTime > 2400)
{
//
ClearDraws();
//
mTestConditions.Clean();
}
//
// Issues Signal on Conditions ...
conditions.signalDir = mTestConditions.dir;
conditions.provider = providerStr;
conditions.sl = mTestConditions.sl;
//
mTestConditions.Clean();
//
return result;
}
//
// Custom Providers Conditions ...
struct XSMCStrategySetupConditions
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
double sl;
ENUM_X_DIRECTION dir;
ENUM_X_POSITION_TYPES type;
//
// Setup Props ...
//
datetime setupTime;
datetime triggerTime;
//
// Trigger Props ...
//
// Constructor ...
XSMCStrategySetupConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleaning Up ...
*/
void Clean()
{
//
sl = 0;
//
dir = X_DIRECTION_NONE;
type = X_POSITION_TYPE_NONE;
//
symbol = NULL;
period = NULL;
setupTime = NULL;
triggerTime = NULL;
}
/**
* Check Condition is Setting Up ...
*
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
*
* @return ( bool )
*/
bool IsSetuped()
{
//
bool result = false;
//
result = IsValid(setupTime) &&
HasDirection(dir);
if (!result)
{
return result;
}
//
return result;
}
/**
* Detect How we Can Trigger Signal ...
*
* @return ( bool )
*/
bool CanTrigger()
{
//
bool result = false;
//
result =
//
sl > 0 &&
IsValid(symbol) &&
IsValid(period) &&
IsValid(triggerTime) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE
//
;
//
return result;
}
//
};
//////////////////////////////////////////////////////////////////////////////////////////
//
// Consolidation Based Strategy:
//
//////////////////////////////////////////////////////////////////////////////////////////
//
// TODO: Remove this ...
XSMCStrategySetupConditions mTestConditions;
bool DetectTestSignal(
X121SMCStrategyConditions &conditions //
)
{
//
bool result = false;
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_SMPV;
string providerStr = ToString(provider);
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
XOHCL zBar;
result = zBar.Init(
symbol,
period,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
cIndex //
);
if (!result)
{
return result;
}
//
bool isBullish = false;
bool isBearish = false;
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
//
double ll = cBar.FindLowest(9, MODE_LOW);
double hh = cBar.FindHighest(9, MODE_HIGH);
//
double selectedSL = 0;
//
X121SMCCycleConditions triggerConditions = conditions.triggerConditions;
X121SMCCycleConditions decisionConditions = conditions.decisionConditions;
X121SMCCycleConditions analyseConditions = conditions.analyseConditions;
X121SMCCycleConditions verificationConditions = conditions.verificationConditions;
X121SMCCycleConditions consolidationConditions = conditions.consolidationConditions;
X121SMCCycleConditions visionConditions = conditions.visionConditions;
//
XPOIState triggerState = triggerConditions.state;
XPOIState decisionState = decisionConditions.state;
XPOIState analyseState = analyseConditions.state;
XPOIState verificationState = verificationConditions.state;
XPOIState consolidationState = consolidationConditions.state;
XPOIState visionState = visionConditions.state;
//
// Retrieve Peak and Vale ...
double triggerPeak = triggerConditions.x121Conditions.peaksBuffer[0];
double triggerVale = triggerConditions.x121Conditions.valesBuffer[0];
//
int zoneValidationDivider = 10;
int validPivotRepetition = mTriggerCycleHelper.mX121Helper
.GetDonChainLength();
//
XOHCL breakerBar;
bool hasZone = false;
XPVPivotPoint validPeak;
XPVPivotPoint validVale;
bool canTrigger = false;
bool hasValidPeak = false;
bool hasValidVale = false;
datetime setupTime = NULL;
bool isZoneBreaked = false;
bool hasConsolidation = false;
XConsolidationZone consolidation;
//
setupTime = mTestConditions.setupTime;
bool isSetuped = mTestConditions.IsSetuped();
ENUM_X_DIRECTION setupDir = mTestConditions.dir;
if (!isSetuped)
{
//
bool isNewPeak = triggerConditions.x121Conditions.isNewPeak;
bool isNewVale = triggerConditions.x121Conditions.isNewVale;
bool isNewPivot = isNewPeak ||
isNewVale;
result = isNewPivot;
if (!result)
{
return result;
}
//
mTestConditions.peak = triggerPeak;
mTestConditions.vale = triggerVale;
hasConsolidation = Contains(
CONSOLIDATION_BREAKED_DETECTED,
mTriggerCycleEvents //
);
//
result = hasConsolidation;
if (!result)
{
return result;
}
//
result = mTriggerCycleHelper
.GetLastConsolidationZone(consolidation);
if (!result)
{
return result;
}
//
// Validate Breaker Bar ...
result = consolidation.breakerBar
.GetPreviousBar(breakerBar);
//
// Find Momentum, Engulf Bar ...
//
// Engulfing ...
ENUM_X_DIRECTION engulfDir;
bool isEngulf = mTriggerCycleHelper.mBarAnalyser.IsEngulfBar(
breakerBar,
engulfDir //
);
//
// Momentum ...
ENUM_X_DIRECTION momentumDir;
bool isMomentum = mTriggerCycleHelper.mBarAnalyser.IsMomentumBar(
breakerBar,
momentumDir //
);
//
// Rejection ...
ENUM_X_DIRECTION rejectionDir;
bool isRejection = mTriggerCycleHelper.mBarAnalyser.IsRejectionBar(
breakerBar,
rejectionDir //
);
//
// Fibo Pressure ...
ENUM_X_DIRECTION fiboPresureDir;
bool hasFiboPressure = mTriggerCycleHelper.mBarAnalyser.HasFiboPressure(
breakerBar,
fiboPresureDir //
);
//
// Check Bar is Bullished ...
bool isBarBullish =
//
// Fibo Pressure ...
(hasFiboPressure &&
IsBullish(fiboPresureDir))
//
||
//
(
//
// Engulfing ...
(isEngulf &&
IsBullish(engulfDir))
//
||
//
// Momentum ...
(isMomentum &&
IsBullish(momentumDir))
//
||
//
// Rejection ...
(isRejection &&
IsBullish(rejectionDir))
//
)
//
;
//
// Check Bar is Bearish ...
bool isBarBearish =
//
// Fibo Pressure ...
(hasFiboPressure &&
IsBearish(fiboPresureDir))
//
||
//
(
//
// Engulfing ...
(isEngulf &&
IsBearish(engulfDir))
//
||
//
// Momentum ...
(isMomentum &&
IsBearish(momentumDir))
//
||
//
// Rejection ...
(isRejection &&
IsBearish(rejectionDir))
//
)
//
;
//
bool isBarPassed = isBarBullish ||
isBarBearish;
result = isBarPassed;
if (!result)
{
return result;
}
//
isBullish =
//
isBarBullish &&
IsBullish(consolidation.breakDirection)
//
;
//
isBearish =
//
isBarBearish &&
IsBearish(consolidation.breakDirection)
//
;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
XCConsolidationZoneObject *iConsolidationObj;
iConsolidationObj = new XCConsolidationZoneObject();
bool isCreated = iConsolidationObj.Create(
mPOIDrawer.ChartIdentification(),
mPOIDrawer.SubWindowIdentification(),
consolidation //
);
if (isCreated)
{
//
iConsolidationObj.ZoneWidth(2);
iConsolidationObj.ZoneColor(clrLightBlue);
//
AddObjectIfNotExists(iConsolidationObj);
}
//
isSetuped = true;
setupTime = cTime;
mTestConditions.setupTime = setupTime;
setupDir = consolidation.breakDirection;
mTestConditions.dir = setupDir;
}
//
// Detect Trigger Conditions ...
canTrigger = mTestConditions.CanTrigger();
datetime triggerTime = mTestConditions.triggerTime;
if (!canTrigger)
{
//
isBullish = IsBullish(setupDir);
isBearish = IsBearish(setupDir);
result = isBullish ||
isBearish;
if (!result)
{
//
// Check Trigger Consitions ...
if (cTime - setupTime > 2400)
{
//
ClearDraws();
//
mTestConditions.Clean();
}
return result;
}
//
mTestConditions.symbol = symbol;
mTestConditions.period = period;
mTestConditions.triggerTime = cTime;
mTestConditions.sl = isBullish
? consolidation.lower
: consolidation.upper;
mTestConditions.type = isBullish
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
//
canTrigger = mTestConditions.CanTrigger();
triggerTime = mTestConditions.triggerTime;
result = canTrigger;
if (!result)
{
//
// Check Trigger Consitions ...
if (cTime - setupTime > 2400)
{
//
ClearDraws();
//
mTestConditions.Clean();
}
//
return result;
}
}
//
if (cTime - setupTime > 2400)
{
//
ClearDraws();
//
mTestConditions.Clean();
}
//
// Issues Signal on Conditions ...
conditions.signalDir = mTestConditions.dir;
conditions.provider = providerStr;
conditions.sl = mTestConditions.sl;
//
mTestConditions.Clean();
//
return result;
}
//
// Custom Providers Conditions ...
struct XSMCStrategySetupConditions
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
double sl;
ENUM_X_DIRECTION dir;
ENUM_X_POSITION_TYPES type;
//
// Setup Props ...
//
datetime setupTime;
datetime triggerTime;
XConsolidationZone zone;
XConsolidationZone consolidation;
//
double peak;
double vale;
XPVPivotPoint validPeak;
XPVPivotPoint validVale;
//
// Trigger Props ...
//
// Constructor ...
XSMCStrategySetupConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleaning Up ...
*/
void Clean()
{
//
sl = 0;
//
zone.Clean();
consolidation.Clean();
dir = X_DIRECTION_NONE;
type = X_POSITION_TYPE_NONE;
//
symbol = NULL;
period = NULL;
setupTime = NULL;
triggerTime = NULL;
//
peak = 0;
vale = 0;
validPeak.Clean();
validVale.Clean();
}
/**
* Check Condition is Setting Up ...
*
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
*
* @return ( bool )
*/
bool IsSetuped()
{
//
bool result = false;
//
result = IsValid(setupTime) &&
HasDirection(dir);
if (!result)
{
return result;
}
//
return result;
}
/**
* Detect How we Can Trigger Signal ...
*
* @return ( bool )
*/
bool CanTrigger()
{
//
bool result = false;
//
result =
//
sl > 0 &&
IsValid(symbol) &&
IsValid(period) &&
IsValid(triggerTime) &&
type != X_POSITION_TYPE_ALL &&
type != X_POSITION_TYPE_NONE
//
;
//
return result;
}
//
// Helpers ...
void UpdateZone()
{
//
if (!zone.IsValid() ||
!validPeak.IsValid() ||
!validVale.IsValid())
{
return;
}
//
zone.upper = validPeak.value;
zone.lower = validVale.value;
//
zone.Update();
//
if (consolidation.IsValid())
{
consolidation.Update();
}
}
//
};
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//
// Consolidation Based Strategy:
//
//////////////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,279 @@
<mxfile host="65bd71144e">
<diagram id="QReEEfusIJtThQdlE9lK" name="Page-1">
<mxGraphModel dx="1382" dy="987" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="15" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="100" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="16" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="420" y="100"/>
<mxPoint x="780" y="100"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="2" value="Position" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="360" y="40" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="17" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="4">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="340"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="18" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="100" y="620"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="3" value="States" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="40" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="27" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="420"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="28" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="500"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4" value="InDrawdown" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="320" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="29" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="700"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="30" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="180" y="780"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="5" value="InProfit" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="600" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="19" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="8">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="20" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="9">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="21" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="11">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="22" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="780" y="460"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6" value="Events" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="720" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="31" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="38" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="220"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="39" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="43" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="220"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8" value="Bullish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="200" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="32" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="37" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="300"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="40" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="44" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="300"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9" value="Bearish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="280" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="34" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="400" as="targetPoint"/>
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="35" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="460"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="42" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="680" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="46" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="810" as="targetPoint"/>
<Array as="points">
<mxPoint x="560" y="460"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="10" value="Bearish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="440" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="33" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="25">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="360"/>
<mxPoint x="260" y="360"/>
<mxPoint x="260" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="36" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="26">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="380"/>
<mxPoint x="520" y="560"/>
<mxPoint x="260" y="560"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="41" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="23">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="640"/>
<mxPoint x="260" y="640"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="45" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="24">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="380"/>
<mxPoint x="560" y="840"/>
<mxPoint x="260" y="840"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="11" value="Bullish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="640" y="360" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="23" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="680" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="24" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="760" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="25" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="400" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="26" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="200" y="480" width="120" height="40" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@@ -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,887 @@
/**
* 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;
}
/**
* Extract Specific files from a folder and it's content ...
*
* @param {string} path Folder Path ...
* @returns
*/
async function extractFiles(path = "", ext = [], excludeWorkspaceFolders = []) {
//
const result = [];
//
if (!ext || ext.length == 0) {
return result;
}
//
const pathContent = await getDirectoryContents(path);
if (!pathContent || pathContent.length == 0) {
return result;
}
//
// Loop through Content ...
for (const c of pathContent) {
//
// Prepare full path ...
const cPath = joinPath(path, c);
//
// check content path is file or not ...
const isCFile = isFileExists(cPath);
const isCDirectory = isDirectoryExists(cPath);
if (isCFile) {
//
// Check it is MQL file or not ...
const cExt = getFileExtension(cPath);
if (ext.includes(cExt)) {
result.push(cPath);
}
} else if (isCDirectory) {
//
const destFolderName = basename(cPath);
const isExcluded = excludeWorkspaceFolders.includes(destFolderName);
if (isExcluded) {
continue;
}
//
const cFiles = await extractFiles(cPath, ext);
if (cFiles && cFiles.length > 0) {
result.push(...cFiles);
}
}
}
//
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,
extractFiles,
//
copyFolder,
createDirectory,
removeDirectory,
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,542 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XTest MQL5 Expert Advisor
// -------------------------------------------------
// Name: XEATemplate
// Description: a Template For Exper Advisors
//
// 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 XEATemplate"
#property strict
//
#define ShortName "XEATemplate"
//
// Imports ...
#include "../Classes/x-saherelm.xalert.class.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
#include "../Helpers/x-saherelm.xcc.helper.mq5"
#include "../Helpers/x-saherelm.xct.helper.mq5"
//
// Inputs ...
//
// Common ...
input group "Common";
input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Alert ...
// Here we Provider All Requirements for
// Configuring Alert Provider ...
input group "Alert";
input bool eAEnableAlerts = true; // Enable Alerts
input bool eALogAlerts = true; // Log Alerts
input bool eAMailAlerts = false; // Mail Alerts
input bool eAPushAlerts = false; // Push Alerts
input bool eATerminalAlerts = false; // Terminal Alerts
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = false; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
//
// Define Local Variables ...
//
string eaLogTag; // EA Log Prefix ...
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
XSCTrade *eaTrader; // Trader of Expert Adviser ...
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
XSCXCTHelper *eaCHelper; // Bar Timer Indicator Helper class ...
XSCXCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs and Required Parameters
// for EA to Works fine ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Timer ...
if (!InitTimer()) {
return INIT_FAILED;
}
//
// Initialize all Requirements ...
if (!InitEA())
{
return INIT_FAILED;
}
//
// Initialize all GUI Objects and Classes ...
if (!InitGUI())
{
return INIT_FAILED;
}
//
// Alert Initialization ...
string msg = "Initialized Successfully ...";
eaAlert.Alert(msg);
//
// 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
//
// Destroy Timer ...
DestroyTimer();
//
// Destroy all GUI Requirements ...
DestroyGUI();
//
// Alert De Initialization Succeeded ...
string msg = "De Initialized Successfully ...";
eaAlert.Alert(msg);
//
// Destroy all EA Requirements ...
DestroyEA();
}
//
// On Tick Handler ...
void OnTick()
{
//
UpdateGUI();
HandleReportTime();
UpdatePositionsState();
//
// TODO: Implemetn Tick Processors Algorithm ...
}
//
// Handle On Trade Event ...
void OnTrade()
{
eaTrader.HandleOnTrade();
}
//
// On Timer ...
void OnTimer()
{
//
// TODO: Implement Time Based Functionalities ...
}
//
// Chart Event Handler ...
void OnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
//
// Handle OnClick Event ...
if (id == CHARTEVENT_OBJECT_CLICK)
{
HandleOnClickEvent(sparam);
}
}
//
// Custom Event Handlers ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Force Close a Position ...
*
* @param ticket: Position Ticket ...
* @param position: XPosition ...
* @param comment: Closing Comment ...
*/
void OnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
//
HandleReportBalance();
}
//
// Custom Functions ...
/**
* Validate all Inputs of Expert Adviser ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
eaSlippage > 0 &&
eaMagicNumber > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
Print(ShortName + " Errors: \n", errMessage);
}
//
return result;
}
/**
* Initialize Timer ...
*
* @return ( bool )
*/
bool InitTimer() {
//
bool result = false;
//
// TODO: Initialize Timer if necessary ...
// result = EventSetTimer(1);
// result = EventSetMillisecondTimer(100);
result = true;
//
return result;
}
/**
* Destroy Timer ...
*/
void DestroyTimer() {
//
// TODO: Use This ...
// EventKillTimer();
}
/**
* Initialize all Requirements for Working Fine ...
*
* @return ( bool )
*/
bool InitEA()
{
//
bool result = false;
//
// Locally Apply Changes on Prefix ...
eaLogTag = ShortName + ">" + eaLogSuffix;
//
// Bar Timer ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
eaCHelper = new XSCXCTHelper();
result = eaCHelper.Init(
_Symbol,
_Period,
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
eaCCHelper = new XSCXCCHelper();
result = eaCCHelper.Init(
_Symbol,
_Period,
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Instance of Alert Class and Configure it ...
eaAlert = new XSCAlert();
eaAlert.SetPrefix(eaLogTag);
eaAlert.SetLogAlerts(eALogAlerts);
eaAlert.SetMailAlerts(eAMailAlerts);
eaAlert.SetPushAlerts(eAPushAlerts);
eaAlert.SetEnableAlerts(eAEnableAlerts);
eaAlert.SetTerminalAlerts(eATerminalAlerts);
//
// Create Trader Instance and Configure it ...
eaTrader = new XSCTrade(
eaSlippage,
eaMagicNumber //
);
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
//
return result;
}
/**
* Destroy all Initialized EA Requirements ...
*/
void DestroyEA()
{
//
delete eaCHelper;
delete eaCCHelper;
//
delete eaAlert;
}
/**
* Initialize all GUI Requirements for EA ...
*
* @return ( bool )
*/
bool InitGUI()
{
//
bool result = false;
//
// TODO: Fix This ...
result = true;
//
return result;
}
/**
* Update GUI based on Each Ticks ...
*/
void UpdateGUI()
{
//
// TODO: Implement this ...
}
/**
* Destroy all Initialized GUi Requirements ...
*/
void DestroyGUI()
{
//
// TODO: Complete this ...
}
//
// Others ...
/**
* Update Positions States ...
*/
void UpdatePositionsState()
{
//
// TODO: Implement this ...
}
/**
* Handle On Click Event for GUI Components ...
*
* @param name: Object Name ...
*/
void HandleOnClickEvent(string name)
{
//
if (!IsValid(name))
{
return;
}
//
bool isClicked = false;
//
// TODO: Implement Chart Objects On Click ...
//
if (isClicked)
{
UpdateGUI();
}
}
/**
* Report Account Balance ...
*/
void HandleReportBalance()
{
//
if (!IsRunningOnTestMode())
{
return;
}
//
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
eaAlert.Log(msg);
}
/**
* Time Reporting based on Inputs ...
*/
void HandleReportTime()
{
//
// Monthly Report ....
if (eaReportNewMonths &&
eaTimeTracker.IsNewMonth())
{
//
string msg = "New Month ...";
//
eaAlert.Alert(msg);
}
//
// Weekly Report ....
if (eaReportNewWeeks &&
eaTimeTracker.IsNewWeek())
{
//
string msg = "New Week ...";
//
eaAlert.Alert(msg);
}
//
// Daily Report ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.Alert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.Alert(msg);
}
}
//
@@ -0,0 +1,575 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XTest MQL5 Expert Advisor
// -------------------------------------------------
// Name: XPanelEA
// Description: an Exper Advisor which used Panels
//
// 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 XPanelEA"
#property strict
//
#define ShortName "XPANELEA"
//
// Imports ...
#include "../Classes/x-saherelm.x-app-dialog.class.mq5"
#include "../Classes/x-saherelm.xalert.class.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
#include "../Helpers/x-saherelm.xcc.helper.mq5"
#include "../Helpers/x-saherelm.xct.helper.mq5"
//
// Inputs ...
//
// Common ...
input group "Common";
input long eaMagicNumber = 78692110; // Magic Number
input int eaSlippage = 10; // Slippgae
input string eaLogSuffix = ""; // Log Suffix
//
// Alert ...
// Here we Provider All Requirements for
// Configuring Alert Provider ...
input group "Alert";
input bool eAEnableAlerts = true; // Enable Alerts
input bool eALogAlerts = true; // Log Alerts
input bool eAMailAlerts = false; // Mail Alerts
input bool eAPushAlerts = false; // Push Alerts
input bool eATerminalAlerts = false; // Terminal Alerts
//
// Time Report ...
input group "Reports";
input bool eaReportNewMonths = false; // Report New Month
input bool eaReportNewWeeks = false; // Report New Weeks
input bool eaReportNewDays = false; // Report New Days
input bool eaReportNewHours = false; // Report New Hours
//
// Define Local Variables ...
//
string eaLogTag; // EA Log Prefix ...
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
XSCTrade *eaTrader; // Trader of Expert Adviser ...
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
XSCXCTHelper *eaCTHelper; // Bar Timer Indicator Helper class ...
XSCXCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
//
XCAppDialog eaMainWindow; // EA Main Dialog ...
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs and Required Parameters
// for EA to Works fine ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Timer ...
if (!InitTimer())
{
return INIT_FAILED;
}
//
// Initialize all Requirements ...
if (!InitEA())
{
return INIT_FAILED;
}
//
// Initialize all GUI Objects and Classes ...
if (!InitGUI())
{
return INIT_FAILED;
}
//
// Alert Initialization ...
string msg = "Initialized Successfully ...";
eaAlert.Alert(msg);
//
// 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
//
// Destroy Timer ...
DestroyTimer();
//
// Destroy all GUI Requirements ...
DestroyGUI();
//
// Alert De Initialization Succeeded ...
string msg = "De Initialized Successfully ...";
eaAlert.Alert(msg);
//
// Destroy all EA Requirements ...
DestroyEA();
}
//
// On Tick Handler ...
void OnTick()
{
//
UpdateGUI();
HandleReportTime();
UpdatePositionsState();
//
// TODO: Implemetn Tick Processors Algorithm ...
}
//
// Handle On Trade Event ...
void OnTrade()
{
eaTrader.HandleOnTrade();
}
//
// On Timer ...
void OnTimer()
{
//
// TODO: Implement Time Based Functionalities ...
}
//
// Chart Event Handler ...
void OnChartEvent(
const int id,
const long &lparam,
const double &dparam,
const string &sparam //
)
{
//
// Apply Chart Event on Main Window ...
eaMainWindow.ChartEvent(id, lparam, dparam, sparam);
//
// Handle OnClick Event ...
if (id == CHARTEVENT_OBJECT_CLICK)
{
HandleOnClickEvent(sparam);
}
}
//
// Custom Event Handlers ...
/**
* Handle StopLoss Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnStopLossTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Take Profit Triggered Positions ...
*
* @param deal: XDeal ...
*/
void OnTakeProfitTriggered(const XDeal &deal)
{
//
HandleReportBalance();
}
/**
* Handle Force Close a Position ...
*
* @param ticket: Position Ticket ...
* @param position: XPosition ...
* @param comment: Closing Comment ...
*/
void OnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
//
HandleReportBalance();
}
//
// Custom Functions ...
/**
* Validate all Inputs of Expert Adviser ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
string errMessage = "";
//
bool isCommonValid = (
//
eaSlippage > 0 &&
eaMagicNumber > 0
//
);
if (!isCommonValid)
{
//
errMessage += "common configurations error;" + "\n";
}
//
result =
//
// Common ...
isCommonValid &&
//
// Otere ...
true
//
;
//
if (!result)
{
//
// Since here Logger not Initiallized, we Use Raw Print Command ...
Print(ShortName + " Errors: \n", errMessage);
}
//
return result;
}
/**
* Initialize Timer ...
*
* @return ( bool )
*/
bool InitTimer()
{
//
bool result = false;
//
// TODO: Initialize Timer if necessary ...
// result = EventSetTimer(1);
// result = EventSetMillisecondTimer(100);
result = true;
//
return result;
}
/**
* Destroy Timer ...
*/
void DestroyTimer()
{
//
// TODO: Use This ...
// EventKillTimer();
}
/**
* Initialize all Requirements for Working Fine ...
*
* @return ( bool )
*/
bool InitEA()
{
//
bool result = false;
//
// Locally Apply Changes on Prefix ...
eaLogTag = ShortName + ">" + eaLogSuffix;
//
// Bar Timer ...
XCTInputs ctInputs;
ctInputs.Default(); // Default Configurations ...
eaCTHelper = new XSCXCTHelper();
result = eaCTHelper.Init(
_Symbol,
_Period,
ctInputs //
);
if (!result)
{
return result;
}
//
// Bar Styles ...
XCCInputs ccInputs;
ccInputs.Default(); // Default Configurations ...
eaCCHelper = new XSCXCCHelper();
result = eaCCHelper.Init(
_Symbol,
_Period,
ccInputs //
);
if (!result)
{
return result;
}
//
// Create Instance of Alert Class and Configure it ...
eaAlert = new XSCAlert();
eaAlert.SetPrefix(eaLogTag);
eaAlert.SetLogAlerts(eALogAlerts);
eaAlert.SetMailAlerts(eAMailAlerts);
eaAlert.SetPushAlerts(eAPushAlerts);
eaAlert.SetEnableAlerts(eAEnableAlerts);
eaAlert.SetTerminalAlerts(eATerminalAlerts);
//
// Create Trader Instance and Configure it ...
eaTrader = new XSCTrade(
eaSlippage,
eaMagicNumber //
);
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
//
return result;
}
/**
* Destroy all Initialized EA Requirements ...
*/
void DestroyEA()
{
//
delete eaCTHelper;
delete eaCCHelper;
//
delete eaAlert;
}
/**
* Initialize all GUI Requirements for EA ...
*
* @return ( bool )
*/
bool InitGUI()
{
//
bool result = false;
//
// Initialize Application Main Window ...
result = eaMainWindow.Create(
ChartID(),
ShortName, // Dialog Name ...
0, // SubWindow ...
10, // X1 ...
35, // Y1 ...
300, // X2 ...
200 // Y2 ...
);
//
// Configuring Dialog ...
// eaMainWindow.MinimizeButton(false); // Hide Minimize Button ...
// eaMainWindow.CloseButton(false); // Hide Close Button ...
eaMainWindow.BackgroundColor(clrBlack);
// result = true;
//
// Try To Run Main Window ...
if (result)
{
eaMainWindow.Run();
}
//
return result;
}
/**
* Update GUI based on Each Ticks ...
*/
void UpdateGUI()
{
//
// TODO: Implement this ...
}
/**
* Destroy all Initialized GUi Requirements ...
*/
void DestroyGUI()
{
//
eaMainWindow.Destroy();
}
//
// Others ...
/**
* Update Positions States ...
*/
void UpdatePositionsState()
{
//
// TODO: Implement this ...
}
/**
* Handle On Click Event for GUI Components ...
*
* @param name: Object Name ...
*/
void HandleOnClickEvent(string name)
{
//
if (!IsValid(name))
{
return;
}
//
bool isClicked = false;
//
// TODO: Implement Chart Objects On Click ...
//
if (isClicked)
{
UpdateGUI();
}
}
/**
* Report Account Balance ...
*/
void HandleReportBalance()
{
//
if (!IsRunningOnTestMode())
{
return;
}
//
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
eaAlert.Log(msg);
}
/**
* Time Reporting based on Inputs ...
*/
void HandleReportTime()
{
//
// Monthly Report ....
if (eaReportNewMonths &&
eaTimeTracker.IsNewMonth())
{
//
string msg = "New Month ...";
//
eaAlert.Alert(msg);
}
//
// Weekly Report ....
if (eaReportNewWeeks &&
eaTimeTracker.IsNewWeek())
{
//
string msg = "New Week ...";
//
eaAlert.Alert(msg);
}
//
// Daily Report ....
if (eaReportNewDays &&
eaTimeTracker.IsNewDay())
{
//
string msg = "New Day ...";
//
eaAlert.Alert(msg);
}
//
// Hourly Report ....
if (eaReportNewHours &&
eaTimeTracker.IsNewHour())
{
//
string msg = "New Hour ...";
//
eaAlert.Alert(msg);
}
}
//