commit efa8818dbba4491d52d02270aca79cfb4982df60 Author: Hadi Khazaee Asl Date: Thu Jan 25 04:08:38 2024 +0330 Initial Commit ... diff --git a/.gitkeep b/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/EURUSD-5M-V0.1/EX5/Experts/x-saherelm.test.ea.ex5 b/EURUSD-5M-V0.1/EX5/Experts/x-saherelm.test.ea.ex5 new file mode 100644 index 0000000..107055b Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Experts/x-saherelm.test.ea.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xchlh.oscillator.ex5 b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xchlh.oscillator.ex5 new file mode 100644 index 0000000..619de77 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xchlh.oscillator.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xchma.oscillator.ex5 b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xchma.oscillator.ex5 new file mode 100644 index 0000000..abeb89c Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xchma.oscillator.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xobd.oscillator.ex5 b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xobd.oscillator.ex5 new file mode 100644 index 0000000..175eb86 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xobd.oscillator.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xrsi.oscillator.ex5 b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xrsi.oscillator.ex5 new file mode 100644 index 0000000..a206d3f Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xrsi.oscillator.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xtd.oscillator.ex5 b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xtd.oscillator.ex5 new file mode 100644 index 0000000..1cfaee5 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xtd.oscillator.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xtm.indicator.ex5 b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xtm.indicator.ex5 new file mode 100644 index 0000000..37e7c11 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Indicators/x-saherelm.xtm.indicator.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.alert.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.alert.lib.ex5 new file mode 100644 index 0000000..66cdadc Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.alert.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.class.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.class.lib.ex5 new file mode 100644 index 0000000..5bb64c6 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.class.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.common.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.common.lib.ex5 new file mode 100644 index 0000000..98efc35 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.common.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.draw.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.draw.lib.ex5 new file mode 100644 index 0000000..60eb07c Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.draw.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.http.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.http.lib.ex5 new file mode 100644 index 0000000..3d13e4f Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.http.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.log.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.log.lib.ex5 new file mode 100644 index 0000000..7569a3f Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.log.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.models.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.models.lib.ex5 new file mode 100644 index 0000000..7489921 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.models.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.nn.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.nn.lib.ex5 new file mode 100644 index 0000000..2977459 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.nn.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xchlh.oscillator.helper.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xchlh.oscillator.helper.lib.ex5 new file mode 100644 index 0000000..94b7af1 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xchlh.oscillator.helper.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xchma.oscillator.helper.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xchma.oscillator.helper.lib.ex5 new file mode 100644 index 0000000..e40f6e6 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xchma.oscillator.helper.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xobd.oscillator.helper.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xobd.oscillator.helper.lib.ex5 new file mode 100644 index 0000000..3a03aa3 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xobd.oscillator.helper.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xrsi.oscillator.helper.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xrsi.oscillator.helper.lib.ex5 new file mode 100644 index 0000000..a2ea18d Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xrsi.oscillator.helper.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtd.oscillator.helper.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtd.oscillator.helper.lib.ex5 new file mode 100644 index 0000000..5852346 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtd.oscillator.helper.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.indicators.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.indicators.lib.ex5 new file mode 100644 index 0000000..66bba4e Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.indicators.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.inputs.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.inputs.lib.ex5 new file mode 100644 index 0000000..ed12827 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.inputs.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.lib.ex5 new file mode 100644 index 0000000..1e5fed5 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtest.provider.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtm.indicator.helper.lib.ex5 b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtm.indicator.helper.lib.ex5 new file mode 100644 index 0000000..23fbab8 Binary files /dev/null and b/EURUSD-5M-V0.1/EX5/Libraries/x-saherelm.xtm.indicator.helper.lib.ex5 differ diff --git a/EURUSD-5M-V0.1/MQ5/Experts/x-saherelm.test.ea.mq5 b/EURUSD-5M-V0.1/MQ5/Experts/x-saherelm.test.ea.mq5 new file mode 100644 index 0000000..4f71b0b --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Experts/x-saherelm.test.ea.mq5 @@ -0,0 +1,192 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: XEA +// Description: this is an expert controller +// advisors which provides a mechanism for use them ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XEA" +#property strict + +// +// START Inputs ... +// + +input group "Commons"; + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "..\Libraries\x-saherelm.log.lib.mq5"; + +// +// Common Library ... +#include "..\Libraries\x-saherelm.common.lib.mq5"; + +// +// Alert Library ... +#include "..\Libraries\x-saherelm.alert.lib.mq5"; + +// +// Draw Library ... +#include "..\Libraries\x-saherelm.draw.lib.mq5"; + +// +// XTEST Signal Provider ... +#include "..\Libraries\x-saherelm.xtest.provider.lib.mq5"; + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = "XEA"; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize XTEST Provider ... + if (!XTESTInitSignalProviderLibrary()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Apply default Chart Style for EA ... + ApplyChartStyle(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Initialize XTEST Provider ... + XTESTDeinitSignalProviderLibrary(reason); + + // + // De Init XDraw Library ... + // OnDeinitDrawLibrary(); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Prevent Going Forward if user Disable it ... + if (!xTESTEnableProvider) { + return; + } + + // + if (!IsNewCandle()) + { + return; + } + + // + // Handle Processing on XTEST Signal Provider ... + XTESTSignalProviderHandleTick(); +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + + // + // Validate XTEST Provider Inputs ... + result = XTESTValidateInputs(); + if (!result) + { + return false; + } + + // + // Logging State ... + string message = "Validation of (" + "XEA" + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// END Functions ... +// + \ No newline at end of file diff --git a/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xchlh.oscillator.mq5 b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xchlh.oscillator.mq5 new file mode 100644 index 0000000..0e057b8 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xchlh.oscillator.mq5 @@ -0,0 +1,838 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel LH Oscillator +// --------------------------------------------------- +// Name: XCHLH +// Description: detecting HH and LL based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHLH Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHLH" + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// XCHLH Signal Calculation Types ... +enum ENUM_X_XCHLH_SIGNAL_TYPES +{ + X_XCHLH_AVG_SIGNAL, + X_XCHLH_DELTA_SIGNAL, +}; + +// +// Including Models Library ... +#include "..\Libraries\x-saherelm.models.lib.mq5"; +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// Signal Calculations ... +input group "Signal Calculations"; +input ENUM_X_XCHLH_SIGNAL_TYPES signalType = X_XCHLH_AVG_SIGNAL; // Signal Method + +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotHHArrowCode = 234; // Hot HH Arrow Code +input color hotHHArrowColor = clrAqua; // Hot HH Arrow Color +input uchar hotLLArrowCode = 233; // Hot LL Arrow Code +input color hotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcLength = 28; // Length +input double lcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE lcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE lcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcHHColor = clrAqua; // Highest High Color +input color lcLLColor = clrFuchsia; // Lowest Low Color +input group "LC Drawings"; +input bool lcDrawHH = true; // Draw Highest High +input bool lcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcLength = 14; // Length +input double mcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE mcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE mcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcHHColor = clrLime; // Highest High Color +input color mcLLColor = clrRed; // Lowest Low Color +input group "MC Drawings"; +input bool mcDrawHH = true; // Draw Highest High +input bool mcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scLength = 7; // Length +input double scThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE scHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE scLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_DOT; // Draw Style +input color scHHColor = clrLightBlue; // Highest High Color +input color scLLColor = clrLightSalmon; // Lowest Low Color +input group "SC Drawings"; +input bool scDrawHH = true; // Draw Highest High +input bool scDrawLL = true; // Draw Lowest Low +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 9 +#property indicator_plots 8 + +// +// LC ... +#define lcHHBufferIndex 0 +#define lcLLBufferIndex 1 + +// +double lcHHBuffer[]; +double lcLLBuffer[]; + +// +// MC ... +#define mcHHBufferIndex 2 +#define mcLLBufferIndex 3 + +// +double mcHHBuffer[]; +double mcLLBuffer[]; + +// +// SC ... +#define scHHBufferIndex 4 +#define scLLBufferIndex 5 + +// +double scHHBuffer[]; +double scLLBuffer[]; + +// +// SIGNAL ... +#define signalTBufferIndex 6 +#define signalBBufferIndex 7 + +// +double signalTBuffer[]; +double signalBBuffer[]; + +// +#property indicator_label7 "XSignal T" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrGold +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +#property indicator_label8 "XSignal B" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrBlueViolet +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +// Hot State ... +// +#define hotStateBufferIndex 8 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcLength, mcLength); + maxLength = MathMax(maxLength, scLength); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = + lcLength >= 4 && + lcLength > mcLength && + lcLength > scLength; + bool isMCInputsValid = + mcLength >= 4 && + mcLength > scLength && + mcLength < lcLength; + bool isSCInputsValid = + scLength >= 4 && + scLength < mcLength && + scLength < lcLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // SIGNAL ... + SignalDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + LCCalculateBuffers(bar_index); + + // + // MC ... + MCCalculateBuffers(bar_index); + + // + // SC ... + SCCalculateBuffers(bar_index); + + // + // SIGNAL ... + SignalCalculateBuffers(bar_index); + + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC HH Buffer ... + string lcHHBufferLabel = ShortName + " LC HH (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcHHDrawType = lcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcHHBufferIndex, PLOT_LABEL, lcHHBufferLabel); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_COLOR, lcHHColor); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_TYPE, lcHHDrawType); + + // + // LC LL Buffer ... + string lcLLBufferLabel = ShortName + " LC LL (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcLLDrawType = lcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcLLBufferIndex, PLOT_LABEL, lcLLBufferLabel); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_COLOR, lcLLColor); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_TYPE, lcLLDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC HH Buffer ... + string mcHHBufferLabel = ShortName + " MC HH (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcHHDrawType = mcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcHHBufferIndex, PLOT_LABEL, mcHHBufferLabel); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_COLOR, mcHHColor); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_TYPE, mcHHDrawType); + + // + // MC LL Buffer ... + string mcLLBufferLabel = ShortName + " MC LL (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcLLDrawType = mcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcLLBufferIndex, PLOT_LABEL, mcLLBufferLabel); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_COLOR, mcLLColor); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_TYPE, mcLLDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC HH Buffer ... + string scHHBufferLabel = ShortName + " SC HH (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scHHDrawType = scDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scHHBufferIndex, PLOT_LABEL, scHHBufferLabel); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_COLOR, scHHColor); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_TYPE, scHHDrawType); + + // + // SC LL Buffer ... + string scLLBufferLabel = ShortName + " SC LL (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scLLDrawType = scDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scLLBufferIndex, PLOT_LABEL, scLLBufferLabel); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_COLOR, scLLColor); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_TYPE, scLLDrawType); +} + +// +// SIGNAL Buffers Definitions ... +void SignalDefineBuffers() +{ + // + // SIGNAL T Buffer ... + string signalTBufferLabel = ShortName + " Signal T"; + ArraySetAsSeries(signalTBuffer, true); + SetIndexBuffer(signalTBufferIndex, signalTBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalTBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(signalTBufferIndex, PLOT_LABEL, signalTBufferLabel); + + // + // SIGNAL B Buffer ... + string signalBBufferLabel = ShortName + " Signal B"; + ArraySetAsSeries(signalBBuffer, true); + SetIndexBuffer(signalBBufferIndex, signalBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(signalBBufferIndex, PLOT_LABEL, signalBBufferLabel); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Calculations ... +void LCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = lcLength; + ENUM_SERIESMODE hhMode = lcHHMode; + ENUM_SERIESMODE llMode = lcLLMode; + double threshold = PipsToPrice(lcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + lcHHBuffer[bar_index] = hhValue; + lcLLBuffer[bar_index] = llValue; +} + +// +// MC Calculations ... +void MCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = mcLength; + ENUM_SERIESMODE hhMode = mcHHMode; + ENUM_SERIESMODE llMode = mcLLMode; + double threshold = PipsToPrice(mcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + mcHHBuffer[bar_index] = hhValue; + mcLLBuffer[bar_index] = llValue; +} + +// +// SC Calculations ... +void SCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = scLength; + ENUM_SERIESMODE hhMode = scHHMode; + ENUM_SERIESMODE llMode = scLLMode; + double threshold = PipsToPrice(scThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + scHHBuffer[bar_index] = hhValue; + scLLBuffer[bar_index] = llValue; +} + +// +// SIGNAL Calculations ... +void SignalCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC Values ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + double lcDelta = lcHH - lcLL; + double lcAvg = lcDelta / 2; + + // + // MC Values ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + double mcDelta = mcHH - mcLL; + double mcAvg = mcDelta / 2; + + // + // SC Values ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + double scDelta = scHH - scLL; + double scAvg = scDelta / 2; + + // + // Min Value ... + double minValue = MathMin( + scLL, mcLL); + minValue = MathMin( + lcLL, minValue); + + // + // Max Value ... + double maxValue = MathMin( + scHH, mcHH); + maxValue = MathMin( + lcHH, maxValue); + + // + double operationalValue = 0; + switch(signalType) { + // + case X_XCHLH_DELTA_SIGNAL: + operationalValue = ((lcDelta + mcDelta + scDelta) / 3); + break; + + // + case X_XCHLH_AVG_SIGNAL: + default: + operationalValue = ((lcAvg + mcAvg + scAvg) / 3); + break; + } + + // + double signalTValue = minValue + operationalValue; + double signalBValue = maxValue - operationalValue; + + // + signalTBuffer[bar_index] = signalTValue; + signalBBuffer[bar_index] = signalBValue; +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + // + double lcHH1 = lcHHBuffer[bar_index + 1]; + double lcLL1 = lcLLBuffer[bar_index + 1]; + + // + // MC ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + // + double mcHH1 = mcHHBuffer[bar_index + 1]; + double mcLL1 = mcLLBuffer[bar_index + 1]; + + // + // SC ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + // + double scHH1 = scHHBuffer[bar_index + 1]; + double scLL1 = scLLBuffer[bar_index + 1]; + + // + bool isHotLLState = scLL == mcLL && mcLL == lcLL; + bool isHotLLState1 = scLL1 == mcLL1 && mcLL1 == lcLL1; + // + bool isHotHHState = scHH == mcHH && mcHH == lcHH; + bool isHotHHState1 = scHH1 == mcHH1 && mcHH1 == lcHH1; + + // + bool isHotLL = isHotLLState && !isHotLLState1; + bool isHotHH = isHotHHState && !isHotHHState1; + + // + double hotStateValue = X_XCHLH_NEUTURAL; + if (isHotHH) + { + hotStateValue = X_XCHLH_HOT_HH; + } + else if (isHotLL) + { + hotStateValue = X_XCHLH_HOT_LL; + } + + // + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotHHArea = hotStateValue == 1; + bool isHotLLArea = hotStateValue == -1; + if (isHotHHArea || isHotLLArea) + { + // + bool isHH = isHotHHArea; + + // + double price = isHH ? candle.high : candle.low; + ENUM_ARROW_ANCHOR anchor = isHH ? ANCHOR_BOTTOM : ANCHOR_TOP; + color clr = isHH ? hotHHArrowColor : hotLLArrowColor; + uchar arrowCode = isHH ? hotHHArrowCode : hotLLArrowCode; + string name = "HOT " + (isHH ? "HH" : "LL") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr, + STYLE_SOLID, + 1); + } + } +} +// +// END Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xchma.oscillator.mq5 b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xchma.oscillator.mq5 new file mode 100644 index 0000000..8f64a40 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xchma.oscillator.mq5 @@ -0,0 +1,1153 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel Moving Averages Oscillator +// ---------------------------------------------------------------- +// Name: XCHMA +// Description: trend detecting based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHMA Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHMA" + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotBullishArrowCode = 228; // Hot Bullish Arrow Code +input color hotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color +input uchar hotBearishArrowCode = 230; // Hot Bearish Arrow Code +input color hotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcFastLength = 20; // Fast Length +input int lcSlowLength = 50; // Slow Length +input ENUM_MA_METHOD lcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE lcAppliedTo = PRICE_CLOSE; // Applied To +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcFastColor = clrAqua; // Fast Color +input color lcSlowColor = clrFuchsia; // Slow Color +input group "LC Drawings"; +input bool lcDrawFast = true; // Draw Fast +input bool lcDrawSlow = true; // Draw Slow +input bool lcDrawCrosses = true; // Draw Cross Lines + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcFastLength = 10; // Fast Length +input int mcSlowLength = 30; // Slow Length +input ENUM_MA_METHOD mcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE mcAppliedTo = PRICE_CLOSE; // Applied To +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcFastColor = clrLime; // Fast Color +input color mcSlowColor = clrRed; // Slow Color +input group "MC Drawings"; +input bool mcDrawFast = true; // Draw Fast +input bool mcDrawSlow = true; // Draw Slow +input bool mcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scFastLength = 7; // Fast Length +input int scSlowLength = 14; // Slow Length +input ENUM_MA_METHOD scMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE scAppliedTo = PRICE_CLOSE; // Applied To +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_SOLID; // Draw Style +input color scFastColor = clrLightBlue; // Fast Color +input color scSlowColor = clrLightSalmon; // Slow Color +input group "SC Drawings"; +input bool scDrawFast = true; // Draw Fast +input bool scDrawSlow = true; // Draw Slow +input bool scDrawCrosses = false; // Draw Cross Lines +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 7 +#property indicator_plots 6 + +// +// LC ... +#define lcFastBufferIndex 0 +#define lcSlowBufferIndex 1 + +// +double lcFastBuffer[]; +double lcSlowBuffer[]; + +// +// MC ... +#define mcFastBufferIndex 2 +#define mcSlowBufferIndex 3 + +// +double mcFastBuffer[]; +double mcSlowBuffer[]; + +// +// SC ... +#define scFastBufferIndex 4 +#define scSlowBufferIndex 5 + +// +double scFastBuffer[]; +double scSlowBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// LC ... +int lcFastHandler = INVALID_HANDLE; +int lcSlowHandler = INVALID_HANDLE; + +// +// MC ... +int mcFastHandler = INVALID_HANDLE; +int mcSlowHandler = INVALID_HANDLE; + +// +// SC ... +int scFastHandler = INVALID_HANDLE; +int scSlowHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init All Required Handlers ... + if (!InitHandlers()) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcFastLength, lcSlowLength); + + // + // Get Retrieved Values from indicators ... + // + // LC ... + int lcFastCalculatedBars = BarsCalculated(lcFastHandler); + int lcSlowCalculatedBars = BarsCalculated(lcSlowHandler); + + // + // MC ... + int mcFastCalculatedBars = BarsCalculated(mcFastHandler); + int mcSlowCalculatedBars = BarsCalculated(mcSlowHandler); + + // + // SC ... + int scFastCalculatedBars = BarsCalculated(scFastHandler); + int scSlowCalculatedBars = BarsCalculated(scSlowHandler); + + // + // Check Calculated Bars ... + if ( + // + // LC ... + lcFastCalculatedBars < maxLength || + lcSlowCalculatedBars < maxLength || + // + // MC ... + mcFastCalculatedBars < maxLength || + mcSlowCalculatedBars < maxLength || + // + // SC ... + scFastCalculatedBars < maxLength || + scSlowCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Copy Buffers from indicators ... + // + // LC ... + int lcFastCopiedItems = CopyBuffer(lcFastHandler, 0, 0, limit + 1, lcFastBuffer); + int lcSlowCopiedItems = CopyBuffer(lcSlowHandler, 0, 0, limit + 1, lcSlowBuffer); + + // + // MC ... + int mcFastCopiedItems = CopyBuffer(mcFastHandler, 0, 0, limit + 1, mcFastBuffer); + int mcSlowCopiedItems = CopyBuffer(mcSlowHandler, 0, 0, limit + 1, mcSlowBuffer); + + // + // SC ... + int scFastCopiedItems = CopyBuffer(scFastHandler, 0, 0, limit + 1, scFastBuffer); + int scSlowCopiedItems = CopyBuffer(scSlowHandler, 0, 0, limit + 1, scSlowBuffer); + + // + // Check Copied Items Number ... + if ( + // + // LC ... + lcFastCopiedItems <= 0 || + lcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = lcFastLength >= 4 && lcSlowLength > lcFastLength; + bool isMCInputsValid = mcFastLength >= 4 && mcSlowLength > mcFastLength; + bool isSCInputsValid = scFastLength >= 4 && scSlowLength > scFastLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid && + lcFastLength > mcFastLength && + mcFastLength > scFastLength) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Init Handlers ... +bool InitHandlers() +{ + // + bool result = false; + + // + // LC ... + result = LCInitHandlers(); + if (!result) + { + return result; + } + + // + // MC ... + result = MCInitHandlers(); + if (!result) + { + return result; + } + + // + // SC ... + result = SCInitHandlers(); + if (!result) + { + return result; + } + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC Fast Buffer ... + string lcFastBufferLabel = ShortName + " LC Fast (" + (string)lcFastLength + ")"; + ENUM_DRAW_TYPE lcFastDrawType = lcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcFastBuffer, true); + SetIndexBuffer(lcFastBufferIndex, lcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(lcFastBufferIndex, PLOT_LABEL, lcFastBufferLabel); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_COLOR, lcFastColor); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_BEGIN, lcFastLength); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_TYPE, lcFastDrawType); + + // + // LC Slow Buffer ... + string lcSlowBufferLabel = ShortName + " LC Slow (" + (string)lcSlowLength + ")"; + ENUM_DRAW_TYPE lcSlowDrawType = lcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcSlowBuffer, true); + SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(lcSlowBufferIndex, PLOT_LABEL, lcSlowBufferLabel); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_COLOR, lcSlowColor); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_BEGIN, lcSlowLength); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_TYPE, lcSlowDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC Fast Buffer ... + string mcFastBufferLabel = ShortName + " MC Fast (" + (string)mcFastLength + ")"; + ENUM_DRAW_TYPE mcFastDrawType = mcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcFastBuffer, true); + SetIndexBuffer(mcFastBufferIndex, mcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(mcFastBufferIndex, PLOT_LABEL, mcFastBufferLabel); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_COLOR, mcFastColor); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_BEGIN, mcFastLength); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_TYPE, mcFastDrawType); + + // + // MC Slow Buffer ... + string mcSlowBufferLabel = ShortName + " MC Slow (" + (string)mcSlowLength + ")"; + ENUM_DRAW_TYPE mcSlowDrawType = mcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcSlowBuffer, true); + SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(mcSlowBufferIndex, PLOT_LABEL, mcSlowBufferLabel); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_COLOR, mcSlowColor); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_BEGIN, mcSlowLength); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_TYPE, mcSlowDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC Fast Buffer ... + string scFastBufferLabel = ShortName + " SC Fast (" + (string)scFastLength + ")"; + ENUM_DRAW_TYPE scFastDrawType = scDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scFastBuffer, true); + SetIndexBuffer(scFastBufferIndex, scFastBuffer, INDICATOR_DATA); + PlotIndexSetString(scFastBufferIndex, PLOT_LABEL, scFastBufferLabel); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_COLOR, scFastColor); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_BEGIN, scFastLength); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_TYPE, scFastDrawType); + + // + // SC Slow Buffer ... + string scSlowBufferLabel = ShortName + " SC Slow (" + (string)scSlowLength + ")"; + ENUM_DRAW_TYPE scSlowDrawType = scDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scSlowBuffer, true); + SetIndexBuffer(scSlowBufferIndex, scSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(scSlowBufferIndex, PLOT_LABEL, scSlowBufferLabel); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_COLOR, scSlowColor); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_BEGIN, scSlowLength); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_TYPE, scSlowDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Init Handlers ... +bool LCInitHandlers() +{ + // + ResetLastError(); + + // + // LC Fast Handler ... + lcFastHandler = iMA( + _Symbol, + _Period, + lcFastLength, + 0, + lcMethod, + lcAppliedTo); + if (lcFastHandler == INVALID_HANDLE) + { + // + LogMessage("LC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // LC Slow Handler ... + lcSlowHandler = iMA( + _Symbol, + _Period, + lcSlowLength, + 0, + lcMethod, + lcAppliedTo); + if (lcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("LC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// MC Init Handlers ... +bool MCInitHandlers() +{ + // + ResetLastError(); + + // + // MC Fast Handler ... + mcFastHandler = iMA( + _Symbol, + _Period, + mcFastLength, + 0, + mcMethod, + mcAppliedTo); + if (mcFastHandler == INVALID_HANDLE) + { + // + LogMessage("MC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // MC Slow Handler ... + mcSlowHandler = iMA( + _Symbol, + _Period, + mcSlowLength, + 0, + mcMethod, + mcAppliedTo); + if (mcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("MC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// SC Init Handlers ... +bool SCInitHandlers() +{ + // + ResetLastError(); + + // + // SC Fast Handler ... + scFastHandler = iMA( + _Symbol, + _Period, + scFastLength, + 0, + scMethod, + scAppliedTo); + if (scFastHandler == INVALID_HANDLE) + { + // + LogMessage("SC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // SC Slow Handler ... + scSlowHandler = iMA( + _Symbol, + _Period, + scSlowLength, + 0, + scMethod, + scAppliedTo); + if (scSlowHandler == INVALID_HANDLE) + { + // + LogMessage("SC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// LC State ... +double GetLCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// MC State ... +double GetMCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// SC State ... +double GetSCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcFast = lcFastBuffer[bar_index]; + double lcSlow = lcSlowBuffer[bar_index]; + // + double lcFastPrev = lcFastBuffer[bar_index + 1]; + double lcSlowPrev = lcSlowBuffer[bar_index + 1]; + // + double lcState = GetLCState(bar_index); + + // + // MC ... + double mcFast = mcFastBuffer[bar_index]; + double mcSlow = mcSlowBuffer[bar_index]; + // + double mcFastPrev = mcFastBuffer[bar_index + 1]; + double mcSlowPrev = mcSlowBuffer[bar_index + 1]; + // + double mcState = GetMCState(bar_index); + + // + // SC ... + double scFast = scFastBuffer[bar_index]; + double scSlow = scSlowBuffer[bar_index]; + // + double scFastPrev = scFastBuffer[bar_index + 1]; + double scSlowPrev = scSlowBuffer[bar_index + 1]; + // + double scState = GetSCState(bar_index); + + // + // Detect HOT Bearish Area ... + bool isHotBearishArea = + lcFast < lcSlow && + mcFast < mcSlow && + scFast < scSlow; + // + bool isPrevHotBearishArea = + lcFastPrev < lcSlowPrev && + mcFastPrev < mcSlowPrev && + scFastPrev < scSlowPrev; + + // + // Detect HOT Bearish Area ... + bool isHotBullishArea = + lcFast > lcSlow && + mcFast > mcSlow && + scFast > scSlow; + // + bool isPrevHotBullishArea = + lcFastPrev > lcSlowPrev && + mcFastPrev > mcSlowPrev && + scFastPrev > scSlowPrev; + + // + // Generate HotState Value ... + double hotStateValue = + isHotBullishArea && !isPrevHotBullishArea + ? 1 + : isHotBearishArea && !isPrevHotBearishArea + ? -1 + : 0; + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotBullishArea = hotStateValue == 1; + bool isHotBearishArea = hotStateValue == -1; + if (isHotBullishArea || isHotBearishArea) + { + // + bool isBull = isHotBullishArea; + + // + double price = isBull ? candle.low : candle.high; + ENUM_ARROW_ANCHOR anchor = isBull ? ANCHOR_TOP : ANCHOR_BOTTOM; + color clr = isBull ? hotBullishArrowColor : hotBearishArrowColor; + uchar arrowCode = isBull ? hotBullishArrowCode : hotBearishArrowCode; + string name = "HOT " + (isBull ? "Bullish" : "Bearish") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); + } + } + + // + // Draw LC Crosses ... + if (lcDrawCrosses) + { + // + double lcStateValue = GetLCState(bar_index); + bool isLcFastCrossedOverSlow = lcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isLcFastCrossedUnderSlow = lcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isLcFastCrossedOverSlow || isLcFastCrossedUnderSlow) + { + // + bool isBull = isLcFastCrossedOverSlow; + + // + color clr = isBull ? lcFastColor : lcSlowColor; + string name = "LC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw MC Crosses ... + if (mcDrawCrosses) + { + // + double mcStateValue = GetMCState(bar_index); + bool isMcFastCrossedOverSlow = mcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isMcFastCrossedUnderSlow = mcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isMcFastCrossedOverSlow || isMcFastCrossedUnderSlow) + { + // + bool isBull = isMcFastCrossedOverSlow; + + // + color clr = isBull ? mcFastColor : mcSlowColor; + string name = "MC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw SC Crosses ... + if (scDrawCrosses) + { + // + double scStateValue = GetSCState(bar_index); + bool isScFastCrossedOverSlow = scStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isScFastCrossedUnderSlow = scStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isScFastCrossedOverSlow || isScFastCrossedUnderSlow) + { + // + bool isBull = isScFastCrossedOverSlow; + + // + color clr = isBull ? scFastColor : scSlowColor; + string name = "SC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } +} +// +// END Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xobd.oscillator.mq5 b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xobd.oscillator.mq5 new file mode 100644 index 0000000..c7907ce --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xobd.oscillator.mq5 @@ -0,0 +1,328 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Oscillator +// ------------------------------------------------------ +// Name: XOBD +// Description: detect Order Blocks based on Swings ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XOBD Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XOBD" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input int length = 288; // Market Length + +// +// START Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// START Buffers ... +// + +// +#property indicator_separate_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +#define swingHighBufferIndex 0 +#define swingLowBufferIndex 1 +#define signalBufferIndex 2 + +// +double swingHighBuffer[]; +double swingLowBuffer[]; +double signalBuffer[]; + +// +#property indicator_label1 "XSwing High" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#property indicator_label2 "XSwing Low" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrFuchsia +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#property indicator_label3 "XSignal" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Swing High ... + string swingHighBufferLabel = ShortName + " Swing H (" + (string) length + ")"; + ArraySetAsSeries(swingHighBuffer, true); + SetIndexBuffer(swingHighBufferIndex, swingHighBuffer, INDICATOR_DATA); + PlotIndexSetInteger(swingHighBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(swingHighBufferIndex, PLOT_LABEL, swingHighBufferLabel); + + // + // Swing Low ... + string swingLowBufferLabel = ShortName + " Swing L (" + (string) length + ")"; + ArraySetAsSeries(swingLowBuffer, true); + SetIndexBuffer(swingLowBufferIndex, swingLowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(swingLowBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(swingLowBufferIndex, PLOT_LABEL, swingLowBufferLabel); + + // + // Signal ... + string signalBufferLabel = ShortName + " Signal (" + (string) length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + int inCycleSwingHighCount = 0; + int inCycleSwingLowCount = 0; + + // + // Loop Back Through Cycle ... + for (int i = bar_index; i < bar_index + length; i++) { + // + ENUM_X_SWING_TYPE iSwingType = GetCandleSwing(i); + if (iSwingType == X_NO_SWING) { + continue; + } + + // + if (iSwingType == X_SWING_HIGH) { + inCycleSwingHighCount++; + } else if (iSwingType == X_SWING_LOW) { + inCycleSwingLowCount++; + } + } + + // + swingHighBuffer[bar_index] = inCycleSwingHighCount; + swingLowBuffer[bar_index] = inCycleSwingLowCount; + + // + signalBuffer[bar_index] = inCycleSwingLowCount - inCycleSwingHighCount; +} + +// +// END Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xrsi.oscillator.mq5 b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xrsi.oscillator.mq5 new file mode 100644 index 0000000..dda4f63 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xrsi.oscillator.mq5 @@ -0,0 +1,358 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Oscillator +// ------------------------------------------------------ +// Name: XRSI +// Description: detect market conditions based on RSI ... +// +// +// 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 XRSI Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XRSI" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 14; // Market Length +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +input group "Short Entry"; +input double shortEntryValue = 70; // Short Entry Level +input color shortEntryColor = clrRed; // Short Entry Level Color +input ENUM_LINE_STYLE shortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// +input group "Short Exit"; +input double shortExitValue = 40; // Short Exit Level +input color shortExitColor = clrFuchsia; // Short Exit Level Color +input ENUM_LINE_STYLE shortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +input group "Long Entry"; +input double longEntryValue = 30; // Long Entry Level +input color longEntryColor = clrGreen; // Long Entry Level Color +input ENUM_LINE_STYLE longEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// +input group "Long Exit"; +input double longExitValue = 60; // Long Exit Level +input color longExitColor = clrAqua; // Long Exit Level Color +input ENUM_LINE_STYLE longExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// START Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// START Buffers ... +// + +// +#property indicator_separate_window +#property indicator_buffers 1 +#property indicator_plots 1 + +// +#define rsiBufferIndex 0 + +double rsiBuffer[]; + +#property indicator_label1 "XRSI" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int rsiHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + rsiHandler = iRSI( + _Symbol, + _Period, + length, + appliedTo); + if (rsiHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(rsiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + int rsiCalculatedBars = BarsCalculated(rsiHandler); + if (rsiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + if (rsiCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RSI ... + string rsiBufferLabel = ShortName + " (" + (string)length + ")"; + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rsiBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(rsiBufferIndex, PLOT_LABEL, rsiBufferLabel); + + // + // Set Indicator Levels here ... + // OB, ExitLong, ExitShort, OS ... + IndicatorSetInteger(INDICATOR_LEVELS, 4); + + // + // SHORTENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, shortEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, shortEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, shortEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 0, "Short Entry"); + + // + // LONGEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, longExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, longExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, shortExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Long Exit"); + + // + // SHORTEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 2, shortExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 2, shortExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 2, longEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 2, "Short Exit"); + + // + // LONGENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 3, longEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 3, longEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 3, longExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 3, "Long Entry"); + + // + // Set Maximum and Minimum for subwindow + IndicatorSetInteger(INDICATOR_DIGITS, 2); + IndicatorSetDouble(INDICATOR_MINIMUM, 0); + IndicatorSetDouble(INDICATOR_MAXIMUM, 100); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ +} + +// +// END Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xtd.oscillator.mq5 b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xtd.oscillator.mq5 new file mode 100644 index 0000000..675c149 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xtd.oscillator.mq5 @@ -0,0 +1,465 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Trend Detector Oscillator +// -------------------------------------------------- +// Name: XTD +// Description: trend detecting in both sides ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTD Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTD" + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; +// +// END Constants ... +// + +// +// Include Models Library ... +#include "../Libraries/x-saherelm.models.lib.mq5"; + +// +// START Inputs ... +// +input int length = 14; // Market Length +input bool drawCrosses = true; // Draw Cross Arrows + +// +// Bullish ... +input uchar bullishArrowCode = 228; // Cross Over Arrow Code +input color bullishArrowColor = clrAqua; // Cross Over Arrow Color + +// +// Bearish ... +input uchar bearishArrowCode = 230; // Cross Under Arrow Code +input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +#define bullishBufferIndex 0 +#define bearishBufferIndex 1 +#define signalBufferIndex 2 + +// +double bullishBuffer[]; +double bearishBuffer[]; +double signalBuffer[]; + +// +#property indicator_label1 "XBullPower" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#property indicator_label2 "XBearPower" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#property indicator_label3 "XSignal" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +int xtdBullishCandleCount = 0; +int xtdBearishCandleCount = 0; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i, close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 5) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Bullish Buffer ... + string bullishBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishBuffer, true); + SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel); + + // + // Bearish Buffer ... + string bearishBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishBuffer, true); + SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + "Signal " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, + const double &close[]) +{ + // + // Reset Global Counters ... + xtdBullishCandleCount = 0; + xtdBearishCandleCount = 0; + + // + // Loop through Closes ... + for (int i = bar_index; i <= bar_index + length; i++) + { + for (int j = i + 1; j <= bar_index + length; j++) + { + // + if (close[i] > close[j]) + { + xtdBullishCandleCount++; + } + + // + if (close[i] < close[j]) + { + xtdBearishCandleCount++; + } + } + } + + // + // Bullish Power Buffer ... + bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount); + + // + // Bearish Power Buffer ... + bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount); + + // + // Signal Buffer ... + signalBuffer[bar_index] = bullishBuffer[bar_index] - bearishBuffer[bar_index]; + + // + // Check and Draw Crosses if it's Specified ... + if (drawCrosses) + { + DrawCrosses(bar_index); + } +} + +// +// +double GetState( + int bar_index // Specified Bar Index +) +{ + // + // Check Cross Points ... + // bullishCrossedOverBearish = 2; + // bullishOverBearish = 1; + // bullishCrossedUnderBearish = -2; + // bullishUnderBearish = -1; + // OtherWise = 0; + bool isBullishCrossedOverBearish = IsCrossOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishCrossedUnderBearish = IsCrossUnder( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishOverBearish = IsOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishUnderBearish = IsUnder( + bullishBuffer, + bearishBuffer, + bar_index); + + // + double result = X_XTD_NEUTURAL; + if (isBullishCrossedOverBearish) + { + result = X_XTD_BULLISH_CROSSED_OVER_BEARISH; + } + else if (isBullishCrossedUnderBearish) + { + result = X_XTD_BULLISH_CROSSED_UNDER_BEARISH; + } + else if (isBullishOverBearish) + { + result = X_XTD_BULLISH_OVER_BEARISH; + } + else if (isBullishUnderBearish) + { + result = X_XTD_BULLISH_UNDER_BEARISH; + } + else + { + result = X_XTD_NEUTURAL; + } + + // + return result; +} + +// +// Draw Crosses ... +void DrawCrosses( + int bar_index // the bars which required to draw cross arrow on it ... +) +{ + // + double stateValue = GetState(bar_index); + + // + bool isOver = stateValue == 2; + double low = iLow(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + + // + double price = isOver ? low : high; + datetime time = iTime(_Symbol, _Period, bar_index); + ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM; + uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode; + color arrowColor = isOver ? bullishArrowColor : bearishArrowColor; + string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price; + + // + DrawArrow( + 0, + crossName, + 0, + time, + price, + arrowCode, + anchor, + arrowColor); +} +// +// END Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xtm.indicator.mq5 b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xtm.indicator.mq5 new file mode 100644 index 0000000..fac9877 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Indicators/x-saherelm.xtm.indicator.mq5 @@ -0,0 +1,349 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Indicator +// --------------------------------------------- +// Name: XTM +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int maPeriod = 14; // Period +input int maShift = 0; // Shift +input ENUM_MA_METHOD maMethod = MODE_SMA; // Method +input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XTM" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + maPeriod, + maShift, + maMethod, + maAppliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, maPeriod); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (maPeriod >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XTM " + "(" + (string)maPeriod + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XTM_BULLISH : lineColorIndex == 2 ? X_XTM_BEARISH + : X_XTM_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.alert.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.alert.lib.mq5 new file mode 100644 index 0000000..9ccf667 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.alert.lib.mq5 @@ -0,0 +1,197 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Alert Library +// -------------------------------------- +// Name: XAlert +// Description: provides Alerts abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Alerts"; +input bool enableAlerts = true; // Enable Alerts +input bool logAlerts = true; // Log Alerts +input bool terminalAlerts = true; // Terminal Alerts +input bool mailAlerts = true; // Mail Alerts +input bool pushAlerts = true; // Push Alerts +// +// END Inputs ... +// + +// +#include "x-saherelm.log.lib.mq5"; + +// +// START Global Definitions: Variables, Properties and etc ... +// +string alertPrefix = "X-Alert"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitAlertLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitAlertLibrary() +{ +} + +// +// Attach Alert Prefix to Message ... +string PrepareAlertMessage(string message) +{ + // + StringConcatenate(message, alertPrefix, " > ", message); + + // + return message; +} + +// +// Logging an Alert ... +void LogAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !logAlerts) + { + return; + } + + // + LogMessage(alertPrefix, message); +} + +// +// Terminal Alert ... +void TerminalAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !terminalAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // Send Terminal Alert ... + Alert(message); +} + +// +// Mail Alert ... +void MailAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !mailAlerts) + { + return; + } + + // + // Send Mail Alert ... + SendMail(alertPrefix, message); +} + +// +// Send Push Notification ... +void PushAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !pushAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); +} + +// +// Alert Sending ... +void SendAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts) + { + return; + } + + // + // Log ... + if (logAlerts) + { + LogAlert(message); + } + + // + // Terminal ... + if (terminalAlerts) + { + TerminalAlert(message); + } + + // + // Mail ... + if (mailAlerts) + { + MailAlert(message); + } + + // + // Push ... + if (pushAlerts) + { + PushAlert(message); + } +} +void SendAlert( + XSignal &signal, // the Signal Object which requred to Alert + bool asExecuted = true // determines Alert Signal as Executed Signal or not +) +{ + // + // Prepare Message ... + string message = asExecuted ? ExecutedSignalToString(signal) : SignalToString(signal); + + // + // Do Alerting ... + SendAlert(message); +} +// +// END Provided Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.class.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.class.lib.mq5 new file mode 100644 index 0000000..4ede425 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.class.lib.mq5 @@ -0,0 +1,3991 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XClass +// Description: provides all classes for use ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include +#include +#include +#include +#include "x-saherelm.draw.lib.mq5" +#include "x-saherelm.models.lib.mq5" +#include "x-saherelm.common.lib.mq5" +#include + +// +// START Model Definitions ... +// +// +// END Model Definitions ... +// + +// +// START Overrides ... +// +class XSCTrade : public CTrade +{ +public: + // + // Specific Position Close ... + bool PositionClose( + const ulong ticket, // Position Ticket + const ulong deviation, // Deviation + const string comment // Comment For Close + ) + { + // + bool result = false; + + // + // check stopped ... + if (IsStopped(__FUNCTION__)) + { + return result; + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return result; + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // Clean ... + ClearStructures(); + + // + // Check Position Type ... + // BUY / LONG ... + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // Prepare Request for Close BUY Position ... + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + // + // SELL / Short ... + else + { + // + // Prepare Request for Close SELL Position ... + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // Setting Request Fields ... + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.position = ticket; + m_request.action = TRADE_ACTION_DEAL; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specify Comment ... + m_request.comment = comment; // PositionGetString(POSITION_COMMENT); // "Comment anything"; + + // + // Log Info on Screen ... + PrintFormat("PositionClose #%I64d %s %.2f", ticket, EnumToString((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)), m_request.volume); + + // + // Close Position ... + result = (OrderSend(m_request, m_result)); + + // + return result; + } + + // + // Specific Position Close ... + bool PositionClose( + const ulong ticket, // Position Ticket + const string comment = "" // Comment For Close + ) + { + // + bool result = false; + + // + // check stopped ... + if (IsStopped(__FUNCTION__)) + { + return result; + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return result; + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // Clean ... + ClearStructures(); + + // + // Check Position Type ... + // BUY / LONG ... + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // Prepare Request for Close BUY Position ... + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + // + // SELL / Short ... + else + { + // + // Prepare Request for Close SELL Position ... + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // Setting Request Fields ... + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.position = ticket; + m_request.deviation = m_deviation; + m_request.action = TRADE_ACTION_DEAL; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + + // + // Specify Comment ... + m_request.comment = comment; // PositionGetString(POSITION_COMMENT); // "Comment anything"; + + // + // Log Info on Screen ... + PrintFormat("PositionClose #%I64d %s %.2f", ticket, EnumToString((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)), m_request.volume); + + // + // Close Position ... + result = (OrderSend(m_request, m_result)); + + // + return result; + } +}; +// +// END Overrides ... +// + +// +// XSaherElm Account Info Class ... +class XCAccountInfo +{ + // + // Public properties ... +public: + // + // Constructro ... + void XCAccountInfo() + { + // + mAccountInfo = new CAccountInfo(); + + // + mInitialBalance = mAccountInfo.Balance(); + } + + // + // Deconstructor ... + void ~XCAccountInfo() + { + // + mInitialBalance = 0; + } + + // + // User Account ... + long GetUserAccount() + { + return mAccountInfo.Login(); + } + + // + // Account Leverage ... + long GetLeverage() + { + return mAccountInfo.Leverage(); + } + + // + // Get Trade Expert State ... + bool CanExpertTrade() + { + return mAccountInfo.TradeExpert(); + } + + // + // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... + ENUM_ACCOUNT_TRADE_MODE GetTradeMode() + { + return mAccountInfo.TradeMode(); + } + + // + // Get Account Balance ... + double GetBalance() + { + return mAccountInfo.Balance(); + } + + // + // Get Initial Deposit Balance ... + double GetInitialBalance() + { + return mInitialBalance; + } + + // + // Get the amount of give Credit ... + double GetCredit() + { + return mAccountInfo.Credit(); + } + + // + // Get the amount of current Profit on account ... + double GetProfit() + { + return mAccountInfo.Profit(); + } + + // + // Get the amount of current Equity on account ... + double GetEquity() + { + return mAccountInfo.Equity(); + } + + // + // Get the amount of reserved Margin ... + double GetMargin() + { + return mAccountInfo.Margin(); + } + + // + // Get the amount of free Margin ... + double GetFreeMargin() + { + return mAccountInfo.FreeMargin(); + } + + // + // Get the Level of Margin ... + double GetMarginLevel() + { + return mAccountInfo.MarginLevel(); + } + + // + // Get the Level Of Margin for a Deposit ... + double GetMarginCall() + { + return mAccountInfo.MarginCall(); + } + + // + // Get the Level of Margin for Stop out ... + double GetMarginStopOut() + { + return mAccountInfo.MarginStopOut(); + } + + // + // Get the Client Name ... + string GetName() + { + return mAccountInfo.Name(); + } + + // + // Get the Trade Server Name ... + string GetServerName() + { + return mAccountInfo.Server(); + } + + // + // Get deposit Currency Name ... + string GetCurrency() + { + return mAccountInfo.Currency(); + } + + // + // Get the Company Name that serves an Account ... + string GetCompany() + { + return mAccountInfo.Company(); + } + + // + // Calculate Profits for the current account based on passed parameters ... + double CalculateTradeProfit( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry, // open price + double exit // close price + ) + { + // + double result = mAccountInfo.OrderProfitCheck( + symbol, + type, + volume, + entry, + exit); + + // + return result; + } + + // + // Calculate amount of margin which required for trade operation ... + double CalculateMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.MarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate amount of free margin left after trade operation ... + double CalculateFreeMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.FreeMarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate the Maximum possible volume of trade operation ... + double CalculateMaxVolume( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double entry, // open price + double percent = 100 // percent of available margin + ) + { + // + double result = mAccountInfo.MaxLotCheck( + symbol, + type, + entry, + percent); + + // + return result; + } + + // + // Protected properties ... +protected: + // + // Private properties ... +private: + // + // Initial Account Balance ... + double mInitialBalance; + + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// XSaherElm Trade Class ... +class XCTrade +{ + // + // all public features ... +public: + // + // Constructor ... + void XCTrade( + string tag, // Specify a Tag for Trader instance + string symbol, // Specify Trader Symbol + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + int maxAllowedTrades, // Specify Max Allowed Trades + int maxAllowedSupportTrades, // Specify Max Allowed Support Trades for each Trade + double minTradeProfitsInPips, // Minimum Profit of each Trade in Pips + double supportTradesPriceDistanceInPips, // Support Trades Price Distance in Pips + double minAllowedFreeMarginForOpenTrades, // Minimum Free Marging for Open Trades + double minBallanceForOpenTrades // Minimum Balance for Open Trades + ) + { + // + mTag = tag; + mSymbol = symbol; + mSlippage = slippage; + mMagicNumber = magicNumber; + mMaxAllowedTrades = maxAllowedTrades; + mMinTradeProfitsInPips = minTradeProfitsInPips; + mMaxAllowedSupportTrades = maxAllowedSupportTrades; + mMinBallanceForOpenTrades = minBallanceForOpenTrades; + mSupportTradesPriceDistanceInPips = supportTradesPriceDistanceInPips; + mMinAllowedFreeMarginForOpenTrades = minAllowedFreeMarginForOpenTrades; + + // + mTrader = new XSCTrade(); + + // + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + } + + // + // Deconstructor ... + void ~XCTrade() + { + } + + // + // Count Open Positions ... + int Count() + { + // + int result = 0; + + // + int total = PositionsTotal(); + for (int i = 0; i < total; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + result++; + } + + // + return result; + } + + // + // Count Longs ... + int CountLongs() + { + int result = CountByType(X_SIGNAL_LONG); + return result; + } + + // + // Count Shorts ... + int CountShorts() + { + int result = CountByType(X_SIGNAL_SHORT); + return result; + } + + // + // Count By Type ... + int CountByType(ENUM_X_SIGNAL_TYPE type) + { + // + // Validate Args ... + ENUM_POSITION_TYPE mType = POSITION_TYPE_BUY; + if (type == X_SIGNAL_LONG) + { + mType = POSITION_TYPE_BUY; + } + else if (type == X_SIGNAL_SHORT) + { + mType = POSITION_TYPE_SELL; + } + + // + int result = CountByType(mType); + return result; + } + + // + // Count By Type and Kind ... + int CountByKind( + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind // Specify Kind of Positions + ) + { + // + int result = 0; + + // + XSignal trades[]; + GetPositionsByKind( + type, + kind, + trades); + + // + result = ArraySize(trades); + + // + return result; + } + int CountByKind( + ENUM_X_SIGNAL_KIND kind // Specify Kind of Positions + ) + { + // + int result = 0; + + // + // Count Longs ... + result = CountByKind( + X_SIGNAL_UNKNOWN, + kind); + + // + return result; + } + + // + // Count Supported Positions belongs to Specified Parent Signal ... + int CountSupportedPositions( + XSignal &parent // Specified Parent Signal + ) + { + // + int result = 0; + + // + XSignal supports[]; + GetSupportedPositions(parent, supports); + result = ArraySize(supports); + + // + return result; + } + + // + // Retrieve Specified Position by it's Ticket ... + XSignal GetPosition( + ulong ticket // Specified Ticket + ) + { + // + XSignal result = {}; + + // + result = PositionToSignal(ticket); + + // + return result; + } + + // + // Retrieve all Positions ... + void GetAllPositions( + XSignal &result[] // Holds Result ... + ) + { + // + CleanBuffer(result); + + // + int totalPositions = PositionsTotal(); + for (int i = 0; i < totalPositions; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + // Position to Signal ... + XSignal signal = PositionToSignal(i); + Add( + signal, + result); + } + } + + // + // Retrieve all Long Positions ... + void GetLongPositions( + XSignal &result[] // Holds Result ... + ) + { + GetAllPositionsByType(POSITION_TYPE_BUY, result); + } + + // + // Retrieve all Short Positions ... + void GetShortPositions( + XSignal &result[] // Holds Result ... + ) + { + GetAllPositionsByType(POSITION_TYPE_SELL, result); + } + + // + // Get Positions by Specified Type ... + void GetPositionsByType( + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + XSignal &result[] // Holds Result ... + ) + { + // + CleanBuffer(result); + + // + switch (type) + { + // + case X_SIGNAL_LONG: + GetLongPositions(result); + break; + + // + case X_SIGNAL_SHORT: + GetShortPositions(result); + break; + + // + case X_SIGNAL_UNKNOWN: + default: + GetAllPositions(result); + break; + } + } + + // + // Get Positions by Specified Type and Kind ... + void GetPositionsByKind( + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &result[] // Holds Result ... + ) + { + // + CleanBuffer(result); + + // + XSignal trades[]; + switch (type) + { + // + case X_SIGNAL_LONG: + GetLongPositions(trades); + break; + + // + case X_SIGNAL_SHORT: + GetShortPositions(trades); + break; + + // + case X_SIGNAL_UNKNOWN: + default: + GetAllPositions(trades); + break; + } + + // + int count = ArraySize(trades); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + XSignal trade = trades[i]; + if (trade.kind != kind) + { + continue; + } + + // + Add( + trade, + result); + } + } + + // + // Retrieve List Of Supported Positions belongs to Specified Parent Signal ... + void GetSupportedPositions( + XSignal &parent, // Specified Parent Signal + XSignal &result[] // Holds Result ... + ) + { + // + CleanBuffer(result); + + // + // Validate Signal ... + bool isValidSignal = IsValid(parent, mMagicNumber); + if (!isValidSignal) + { + return; + } + + // + // Validate Signal is Parent Signal ... + bool isParentSignal = parent.kind == X_KIND_TRADE; + if (!isParentSignal) + { + return; + } + + // + // Retrieve All Support Signals ... + XSignal supports[]; + GetPositionsByKind( + X_SIGNAL_UNKNOWN, + X_KIND_SUPPORT, + supports); + int supportsCount = ArraySize(supports); + if (supportsCount <= 0) + { + return; + } + + // + // Loop Through Supports ... + for (int i = 0; i < supportsCount; i++) + { + // + XSignal support = supports[i]; + + // + bool isBelongsToParent = support.parent == parent.ticket; + if (isBelongsToParent) + { + // + Add( + support, + result); + } + } + } + + // + // Get All Trades Which Candle Passed after Open ... + void GetLongTimeTrades( + int life, // Max Candle Passed after Trades Open + ENUM_TIMEFRAMES period, // Calculate Candles based on time frame + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &result[] // Holds Result + ) + { + // + CleanBuffer(result); + + // + // Normalize Period ... + if (period == EMPTY_VALUE) + { + period = _Period; + } + + // + XSignal positions[]; + GetPositionsByKind( + type, + kind, + positions); + int count = ArraySize(positions); + if (count <= 0) + { + return; + } + + // + // Current Time Frame Candle Index ... + int currentBarIndex = 0; + + // + // Loop through Positions ... + for (int i = 0; i < count; i++) + { + // + XSignal trade = positions[i]; + + // + // Retrieve Trade Open Bar Index based on Current Period ... + int tradeOpenBarIndex = iBarShift( + mSymbol, + period, + trade.time); + + // + // Calculate Trade Life ... + int diff = MathAbs(currentBarIndex - tradeOpenBarIndex); + if (diff >= life) + { + // + Add( + trade, + result); + } + } + } + + // + // Get In DrawDown Trades ... + void GetInDrawDownTrades( + double maxDrawDown, // Maximum DrawDown of Trades + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &result[] // Holds Result + ) + { + // + CleanBuffer(result); + + // + // Validate Args ... + if (maxDrawDown <= 0) + { + maxDrawDown = 0; + } + + // + XSignal trades[]; + + // + // Retrieve Signals ... + GetPositionsByKind( + type, + kind, + trades); + + // + // Check Trades Count ... + int count = ArraySize(trades); + if (count <= 0) + { + return; + } + + // + // Loop through all retrieved trades ... + for (int i = 0; i < count; i++) + { + // + XSignal trade = trades[i]; + if (trade.profit > 0) + { + continue; + } + + // + bool isPassed = maxDrawDown == 0 ? true : (-1 * trade.profit) >= maxDrawDown; + if (isPassed) + { + // + Add( + trade, + result); + } + } + } + + // + // Get In Profit Trades ... + void GetInProfitTrades( + double minProfit, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &result[] // Holds Result + ) + { + // + CleanBuffer(result); + + // + XSignal trades[]; + GetPositionsByKind( + type, + kind, + result); + + // + // Check Trades Count ... + int count = ArraySize(trades); + if (count <= 0) + { + return; + } + + // + // Loop through all retrieved trades ... + for (int i = 0; i < count; i++) + { + // + XSignal trade = trades[i]; + if (trade.profit < 0) + { + continue; + } + + // + bool isPassed = minProfit <= 0 ? true : trade.profit >= minProfit; + if (isPassed) + { + // + Add( + trade, + result); + } + } + } + + // + // Filter Trades by Searching Comments ... + void FilterTrades( + string query, // Search String + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &result[] // Holds Result + ) + { + // + // Free Buffer ... + CleanBuffer(result); + + // + XSignal source[]; + GetPositionsByKind( + type, + kind, + source); + int sourceCount = ArraySize(source); + + // + if (sourceCount <= 0) + { + return; + } + + // + // Do Filtering Signals ... + FilterSignals( + query, + source, + result); + } + + // + // Filter In DrawDown Trades by Searching Comments ... + void FilterInDrawDowntTrades( + string query, // Search String + double maxDrawDown, // Maximum DrawDown of Trades + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &result[] // Holds Result + ) + { + // + // Free Buffer ... + CleanBuffer(result); + + // + XSignal source[]; + GetInDrawDownTrades( + maxDrawDown, + type, + kind, + source); + int sourceCount = ArraySize(source); + + // + if (sourceCount <= 0) + { + return; + } + + // + // Do Filtering Signals ... + FilterSignals( + query, + source, + result); + } + + // + // Filter In DrawDown Trades by Searching Comments ... + void FilterInProfitTrades( + string query, // Search String + double minProfit, // Minimum Profit of Trades + ENUM_X_SIGNAL_TYPE type, // Specify trades type to act + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &result[] // Holds Result + ) + { + // + // Free Buffer ... + CleanBuffer(result); + + // + XSignal source[]; + GetInProfitTrades( + minProfit, + type, + kind, + source); + int sourceCount = ArraySize(source); + + // + if (sourceCount <= 0) + { + return; + } + + // + // Do Filtering Signals ... + FilterSignals( + query, + source, + result); + } + + // + // Filter Trades by Searching Comments ... + void FilterTrades( + string query, // Search String + XSignal &source[], // Source Buffer to Filter + XSignal &result[] // Holds Result + ) + { + // + // Free Buffer ... + CleanBuffer(result); + + // + // Do Filtering Signals ... + FilterSignals( + query, + source, + result); + } + + // + // Force Open a Buy/Long Position ... + bool Buy( + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + const string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.Buy( + volume, + mSymbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Force Open a Sell/Short Position ... + bool Sell( + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + const string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.Sell( + volume, + mSymbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Validate Signal ... + bool ValidateSignal( + XSignal &signal // Specify Signal for Execution + ) + { + // + bool result = false; + + // + // Validate Signal Type ... + result = signal.type != X_SIGNAL_UNKNOWN; + if (!result) + { + return result; + } + + // + // Check Symbol ... + result = StringLen(signal.symbol) == 0 ? true : signal.symbol == mSymbol; + if (!result) + { + return result; + } + + // + // Check magic number ... + result = signal.magicNumber <= 0 ? true : signal.magicNumber == mMagicNumber; + if (!result) + { + return result; + } + + // + // Check Entry ... + result = signal.entry > 0; + if (!result) + { + return result; + } + + // + // Check SL ... + result = signal.sl == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.sl < signal.entry + : signal.sl > signal.entry; + if (!result) + { + return result; + } + + // + // Check TP ... + result = signal.tp == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.tp > signal.entry + : signal.tp < signal.entry; + if (!result) + { + return result; + } + + // + // Check Volume ... + result = signal.volume > 0; + if (!result) + { + return result; + } + + // + // Check Time ... + result = signal.time > 0; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Execute an Specific XSignal instance ... + bool ExecuteSignal( + XSignal &signal, // Specify Signal for Execution + int &error // Error code if Happens + ) + { + // + bool result = false; + + // + // Validate Signal ... + result = ValidateSignal(signal); + if (!result) + { + // + error = X_INVALID_SIGNAL_ERROR; + return result; + } + + // + signal.symbol = mSymbol; + + // + bool isTrade = signal.kind == X_KIND_TRADE; + + // + // Check Account Balance ... + result = IsAccountBalanceReadyForTrade(); + if (!result) + { + // + error = X_XTRADER_NOT_ENOUGH_BALANCE_ERROR; + return result; + } + + // + // Check Account Free Margin ... + result = IsFreeMarginReadyForTrade(); + if (!result) + { + // + error = X_XTRADER_NOT_ENOUGH_MARIGIN_ERROR; + return result; + } + + // + // Check Can Open Trades ... + result = CanOpenNewTrade( + signal.type, + signal.kind); + if (!result) + { + error = isTrade ? + // + X_XTRADER_MAX_ALLOWED_TRADE_KIND_REACHED_ERROR + : + // + X_XTRADER_MAX_ALLOWED_SUPPORT_KIND_REACHED_ERROR + // + ; + } + + // + ResetLastError(); + + // + // Execute Signal Trade ... + result = + // + signal.type == X_SIGNAL_LONG + // + ? + // + Buy( + signal.volume, + signal.entry, + signal.sl, + signal.tp, + signal.comment) + // + : + // + signal.type == X_SIGNAL_SHORT + // + ? + // + Sell( + signal.volume, + signal.entry, + signal.sl, + signal.tp, + signal.comment) + // + : + // + false + // + ; + + // + // if (!result) + // { + // // + // int errorCode = GetLastError(); + + // // + // // Not Enough Money, since Volume is High ... + // if (errorCode == 4756) + // { + // // + // signal.volume = NormalizeVolume(signal.volume / 3); + // result = ExecuteSignal( + // signal, + // error); + // } + // } + + // + if (result) + { + // + error = X_SUCCEED_EXECUTION; + + // + ulong positionTicket = 0; + if (mPositionInfo.SelectByIndex(PositionsTotal() - 1)) + { + positionTicket = mPositionInfo.Ticket(); + } + + // + signal.id = positionTicket; + signal.ticket = positionTicket; + + // + // Draw Signal On Chart ... + DrawSignalEvent(signal); + } + else + { + error = X_UNKNOWN_ERROR; + } + + // + return result; + } + + // + // Execute Support Signal ... + bool ExecuteSupportSignal( + XSignal &signal, // Specify Signal for Execution + int &error // Error code if Happens + ) + { + // + bool result = false; + error = X_UNKNOWN_ERROR; + + // + // Validate Signal ... + result = ValidateSignal(signal); + if (!result) + { + // + error = X_INVALID_SIGNAL_ERROR; + return result; + } + + // + // Determines Signal is Long or Short ... + bool isLong = signal.type == X_SIGNAL_LONG; + + // + // Check Signal Kind ... + result = signal.kind == X_KIND_SUPPORT; + if (!result) + { + // + error = X_INVALID_SIGNAL_ERROR; + return result; + } + + // + // Check Signal Kind Based Properties ... + result = signal.parent > 0; + if (!result) + { + // + error = X_INVALID_SIGNAL_ERROR; + return result; + } + + // + // Check Support Trade Parent Position Existance ... + XSignal parent = GetPosition(signal.parent); + result = IsValid(parent, mMagicNumber); + if (!result) + { + // + error = X_INVALID_SIGNAL_ERROR; + return result; + } + + // + // Check Max Number Of Support Trades which belongs to Parent ... + int supportsCount = CountSupportedPositions(parent); + result = supportsCount < mMaxAllowedSupportTrades; + if (!result) + { + // + error = X_XTRADER_MAX_ALLOWED_SUPPORT_KIND_REACHED_ERROR; + return result; + } + + // + // Check Support Trade Price Distance Passed ... + double supportTradesPriceDistance = PipsToPrice(mSupportTradesPriceDistanceInPips); + double supportPriceDistance = MathAbs(parent.entry - signal.entry); + result = supportPriceDistance >= supportTradesPriceDistance; + if (!result) + { + // + error = X_TRADER_SUPPORT_DISTANCE_NOT_HAPPENS_ERROR; + return result; + } + + // + // Check Account Balance ... + result = IsAccountBalanceReadyForTrade(); + if (!result) + { + // + error = X_XTRADER_NOT_ENOUGH_BALANCE_ERROR; + return result; + } + + // + ResetLastError(); + + // + // Execute Signal Trade ... + result = + // + signal.type == X_SIGNAL_LONG + // + ? + // + Buy( + signal.volume, + signal.entry, + signal.sl, + signal.tp, + signal.comment) + // + : + // + signal.type == X_SIGNAL_SHORT + // + ? + // + Sell( + signal.volume, + signal.entry, + signal.sl, + signal.tp, + signal.comment) + // + : + // + false + // + ; + + // + // if (!result) + // { + // // + // int errorCode = GetLastError(); + + // // + // // Not Enough Money, since Volume is High ... + // if (errorCode == 4756) + // { + // // + // signal.volume = NormalizeVolume(signal.volume / 3); + // result = ExecuteSupportSignal( + // signal, + // error); + // } + // } + + // + if (result) + { + // + error = X_SUCCEED_EXECUTION; + + // + ulong positionTicket = 0; + if (mPositionInfo.SelectByIndex(PositionsTotal() - 1)) + { + positionTicket = mPositionInfo.Ticket(); + } + + // + signal.id = positionTicket; + signal.ticket = positionTicket; + + // + // Draw Signal On Chart ... + DrawSignalEvent(signal); + } + else + { + error = X_UNKNOWN_ERROR; + } + + // + return result; + } + + // + // Modify Position ... + bool Modify( + const ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0 // take profit + ) + { + // + bool result = false; + + // + // Validate Args ... + if (tp <= 0 && sl <= 0) + { + result = false; + return result; + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp); + + // + return result; + } + + // + // Close Position By Ticket ... + bool Close( + ulong ticket, // Position Ticket + string comment // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + // Try to Select Position ... + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + // Close Position By Specific Comment ... + result = mTrader.PositionClose( + ticket, + comment); + if (result) + { + RemoveSignal(ticket); + } + + // + return result; + } + + // + // Close Partial By Ticket ... + bool ClosePartial(ulong ticket, double volume) + { + // + bool result = false; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + result = mTrader.PositionClosePartial( + ticket, + volume); + + // + return result; + } + + // + // Partial Close all Reached Signals ... + void RiskFreeSignals( + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &riskFrees[] // Holds all Executed Signals + ) + { + // + CleanBuffer(riskFrees); + + // + XSignal trades[]; + GetPositionsByKind( + type, + kind, + trades); + int count = ArraySize(trades); + if (count <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < count; i++) + { + // + XSignal trade = trades[i]; + + // + // Ignore Not Risk Free Signal ... + if ( + trade.riskFree <= 0 || + (trade.riskFree > 0 && trade.riskFreeRate <= 0)) + { + continue; + } + + // + bool isLong = trade.type == X_SIGNAL_LONG; + + // + // Check Exit Price reached Risk Free ... + double exitPrice = GetExit(trade.type); + double isPriceReachedRiskFree = isLong ? exitPrice >= trade.riskFree : exitPrice <= trade.riskFree; + if (!isPriceReachedRiskFree) + { + continue; + } + + // + double volume = trade.volume; + double riskFreeRate = trade.riskFreeRate; + double riskFreeVolume = riskFreeRate * volume; + riskFreeVolume = NormalizeVolume(riskFreeVolume); + + // + // Check Trade Doesnt Closed Partial Before ... + // Check Volume is Enough for Partial Closing ... + if ( + trade.sl > 0 || + riskFreeVolume == volume) + { + continue; + } + + // + bool isPartialClosed = ClosePartial(trade.ticket, riskFreeVolume); + if (isPartialClosed) + { + // + bool isLong = trade.type == X_SIGNAL_LONG; + double entry = GetEntry(trade.symbol, trade.type); + + // + double tpValue = trade.tp; + double slDistance = 0; // PipsToPrice(2); + double slValue = isLong ? trade.entry - slDistance : trade.entry + slDistance; + + // + ResetLastError(); + bool isModified = Modify(trade.ticket, slValue, tpValue); + if (isModified) + { + // + Add( + trade, + riskFrees); + + // + LogMessage("Order: " + (string)trade.ticket + " Modification Succeed ..."); + } + else + { + LogMessage("Order: " + (string)trade.ticket + " Modification Failed: " + (string)GetLastError() + ", Desc: " + GetErrorDescription(GetLastError())); + } + } + } + } + void RiskFreeSignals( + XSignal &riskFrees[] // Holds all Executed Signals + ) + { + // + CleanBuffer(riskFrees); + + // + XSignal trades[]; + RiskFreeSignals( + X_SIGNAL_UNKNOWN, + X_KIND_TRADE, + trades); + int tradesCount = ArraySize(trades); + if (tradesCount > 0) + { + // + // Loop ... + for (int i = 0; i < tradesCount; i++) + { + // + XSignal fTrade = trades[i]; + + // + Add( + fTrade, + riskFrees); + } + } + + // + XSignal supports[]; + RiskFreeSignals( + X_SIGNAL_UNKNOWN, + X_KIND_SUPPORT, + supports); + int supportsCount = ArraySize(supports); + if (supportsCount > 0) + { + // + // Loop ... + for (int i = 0; i < supportsCount; i++) + { + // + XSignal fTrade = supports[i]; + + // + Add( + fTrade, + riskFrees); + } + } + } + + // + // Close All Open Positions ... + void CloseAllPositions( + XSignal &closed[] // Holds Closed Positions + ) + { + // + CleanBuffer(closed); + + // + XSignal allPositions[]; + GetAllPositions(allPositions); + + // + // Count all Specified Positions ... + int total = ArraySize(allPositions); + if (total <= 0) + { + return; + } + + // + for (int i = 0; i < total; i++) + { + // + XSignal signal = allPositions[i]; + string comment = GetSignalForceClosedComment(signal); + bool isClosed = Close( + signal.ticket, + comment); + if (isClosed) + { + // + Add( + signal, + closed); + } + } + } + + // + // Close Positions By Type ... + void ClosePositionsByType( + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + XSignal &closed[] // Holds Closed Positions + ) + { + // + CleanBuffer(closed); + + // + XSignal allPositions[]; + GetPositionsByType( + type, + allPositions); + + // + // Count all Specified Positions ... + int total = ArraySize(allPositions); + if (total <= 0) + { + return; + } + + // + for (int i = 0; i < total; i++) + { + // + XSignal signal = allPositions[i]; + string comment = GetSignalForceClosedComment(signal); + bool isClosed = Close( + signal.ticket, + comment); + if (isClosed) + { + // + Add( + signal, + closed); + } + } + } + + // + // Close Positions By Kind ... + void ClosePositionsByKind( + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &closed[] // Holds Closed Positions + ) + { + // + CleanBuffer(closed); + + // + XSignal allPositions[]; + GetPositionsByKind( + type, + kind, + allPositions); + + // + // Count all Specified Positions ... + int total = ArraySize(allPositions); + if (total <= 0) + { + return; + } + + // + for (int i = 0; i < total; i++) + { + // + XSignal signal = allPositions[i]; + string comment = GetSignalForceClosedComment(signal); + bool isClosed = Close( + signal.ticket, + comment); + if (isClosed) + { + // + Add( + signal, + closed); + } + } + } + + // + // Close All Trades Which Candle Passed after Open ... + void CloseLongTimeTrades( + int life, // Max Candle Passed after Trades Open + ENUM_TIMEFRAMES period, // Calculate Candles based on time frame + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &closed[] // Holds Closed Trades + ) + { + // + CleanBuffer(closed); + + // + // Normalize Period ... + if (period == EMPTY_VALUE) + { + period = _Period; + } + + // + XSignal positions[]; + GetLongTimeTrades( + life, + period, + type, + kind, + positions); + int count = ArraySize(positions); + if (count <= 0) + { + return; + } + + // + // Loop through Positions ... + for (int i = 0; i < count; i++) + { + // + XSignal trade = positions[i]; + string comment = GetSignalForceClosedComment(trade); + bool isClosed = Close( + trade.ticket, + comment); + if (isClosed) + { + // + Add( + trade, + closed); + } + } + } + void CloseLongTimeTrades( + int life, // Max Candle Passed after Trades Open + ENUM_TIMEFRAMES period, // Calculate Candles based on time frame + XSignal &closed[] // Holds Closed Trades + ) + { + // + CleanBuffer(closed); + + // + XSignal trades[]; + CloseLongTimeTrades( + life, + period, + X_SIGNAL_UNKNOWN, + X_KIND_TRADE, + trades); + int tradesCount = ArraySize(trades); + if (tradesCount > 0) + { + // + // Loop ... + for (int i = 0; i < tradesCount; i++) + { + // + XSignal fTrade = trades[i]; + + // + Add( + fTrade, + closed); + } + } + + // + XSignal supports[]; + CloseLongTimeTrades( + life, + period, + X_SIGNAL_UNKNOWN, + X_KIND_SUPPORT, + supports); + int supportsCount = ArraySize(supports); + if (supportsCount > 0) + { + // + // Loop ... + for (int i = 0; i < supportsCount; i++) + { + // + XSignal fTrade = supports[i]; + + // + Add( + fTrade, + closed); + } + } + } + + // + // Close In DrawDown Trades ... + void CloseInDrawDownTrades( + double maxDrawDown, // Maximum DrawDown of Trades + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &closed[] // Holds Closed Trades + ) + { + // + CleanBuffer(closed); + + // + // Validate Args ... + if (maxDrawDown <= 0) + { + return; + } + + // + XSignal trades[]; + GetInDrawDownTrades( + maxDrawDown, + type, + kind, + trades); + + // + // Check Trades Count ... + int count = ArraySize(trades); + if (count <= 0) + { + return; + } + + // + // Loop through all retrieved trades ... + for (int i = 0; i < count; i++) + { + // + XSignal trade = trades[i]; + string comment = GetSignalInDistanceClosedComment(trade); + bool isClosed = Close( + trade.ticket, + comment); + if (isClosed) + { + Add( + trade, + closed); + } + } + } + void CloseInDrawDownTrades( + double maxDrawDown, // Maximum DrawDown of Trades + XSignal &closed[] // Holds Closed Trades + ) + { + // + CleanBuffer(closed); + + // + XSignal trades[]; + CloseInDrawDownTrades( + maxDrawDown, + X_SIGNAL_UNKNOWN, + X_KIND_TRADE, + trades); + int tradesCount = ArraySize(trades); + if (tradesCount > 0) + { + // + // Loop ... + for (int i = 0; i < tradesCount; i++) + { + // + XSignal fTrade = trades[i]; + + // + Add( + fTrade, + closed); + } + } + + // + XSignal supports[]; + CloseInDrawDownTrades( + maxDrawDown, + X_SIGNAL_UNKNOWN, + X_KIND_SUPPORT, + supports); + int supportsCount = ArraySize(supports); + if (supportsCount > 0) + { + // + // Loop ... + for (int i = 0; i < supportsCount; i++) + { + // + XSignal fTrade = supports[i]; + + // + Add( + fTrade, + closed); + } + } + } + + // + // Close All In Profit Trades ... + void CloseInProfitTrades( + double minProfit, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type, // Specify trades type to act + ENUM_X_SIGNAL_KIND kind, // Specify Kind of Positions + XSignal &closed[] // Holds Closed Trades + ) + { + // + CleanBuffer(closed); + + // + XSignal trades[]; + GetInProfitTrades( + minProfit, + type, + kind, + trades); + + // + // Check Trades Count ... + int count = ArraySize(trades); + if (count <= 0) + { + return; + } + + // + // Loop through all retrieved trades ... + for (int i = 0; i < count; i++) + { + // + XSignal trade = trades[i]; + string comment = GetSignalInDistanceClosedComment(trade); + bool isClosed = Close( + trade.ticket, + comment); + if (isClosed) + { + Add( + trade, + closed); + } + } + } + void CloseInProfitTrades( + double minProfit, // Minimum Profit To Close Trades + XSignal &closed[] // Holds Closed Trades + ) + { + // + CleanBuffer(closed); + + // + XSignal trades[]; + CloseInProfitTrades( + minProfit, + X_SIGNAL_UNKNOWN, + X_KIND_TRADE, + trades); + int tradesCount = ArraySize(trades); + if (tradesCount > 0) + { + // + // Loop ... + for (int i = 0; i < tradesCount; i++) + { + // + XSignal fTrade = trades[i]; + + // + Add( + fTrade, + closed); + } + } + + // + XSignal supports[]; + CloseInProfitTrades( + minProfit, + X_SIGNAL_UNKNOWN, + X_KIND_SUPPORT, + supports); + int supportsCount = ArraySize(supports); + if (supportsCount > 0) + { + // + // Loop ... + for (int i = 0; i < supportsCount; i++) + { + // + XSignal fTrade = supports[i]; + + // + Add( + fTrade, + closed); + } + } + } + + // + // Pyramid Open Trades ... + void PyramidTrades( + XSignal &closed[] // Holds Closed Trades + ) + { + // + CleanBuffer(closed); + + // + // Check Open Positions In DrawDown Values ... + + // + // Trades ... + XSignal inDDTrades[]; + GetInDrawDownTrades( + 0, + X_SIGNAL_UNKNOWN, + X_KIND_TRADE, + inDDTrades); + int inDDTradesCount = ArraySize(inDDTrades); + + // + // Supports ... + XSignal inDDSupports[]; + GetInDrawDownTrades( + 0, + X_SIGNAL_UNKNOWN, + X_KIND_SUPPORT, + inDDSupports); + int inDDSupportsCount = ArraySize(inDDSupports); + + // + // Prevent Going Forward ... + if (inDDTradesCount == 0 && inDDSupportsCount == 0) + { + return; + } + + // + // Number Of In DD Trades ... + int count = inDDTradesCount + inDDSupportsCount; + if (count <= 1) + { + return; + } + + // + // Select Longest inDD ... + XSignal longestDD = {}; + + // + // Trades ... + if (inDDTradesCount > 0) + { + // + for (int i = 0; i < inDDTradesCount; i++) + { + // + XSignal iSignal = inDDTrades[i]; + + // + longestDD = longestDD.profit == 0 || longestDD.profit > iSignal.profit ? iSignal : longestDD; + } + } + + // + // Supports ... + if (inDDSupportsCount > 0) + { + // + for (int i = 0; i < inDDSupportsCount; i++) + { + // + XSignal iSignal = inDDSupports[i]; + + // + longestDD = longestDD.profit == 0 || longestDD.profit > iSignal.profit ? iSignal : longestDD; + } + } + + // + // Check Longest In DD ... + LogMessage("Longest (" + (string)count + ") inDD: " + (string)longestDD.ticket + ", Profit: " + (string)longestDD.profit); + + // + // Close Longest In DD ... + Close(longestDD.ticket, "Longets In Drawdown Position"); + + // + Add( + longestDD, + closed); + } + + // + // START Signal Related ... + // + + // + // Prepare a Signall ... + XSignal GenerateSignal( + ENUM_X_SIGNAL_TYPE type, // Signal Type + double tp = 0, // Take Profit + double sl = 0, // Stop Loss + double volume = 0, // Volume + double riskFree = 0, // Risk Free Price + double riskFreeRate = 0, // Risk Free Rate + ENUM_X_SIGNAL_KIND kind = X_KIND_TRADE, // Signal Kind + ulong parent = 0 // Support Kind Signal Parent + ) + { + // + XSignal result = {}; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + // Check Signal Type ... + bool isLong = type == X_SIGNAL_LONG; + + // + // Retrieve entry Price ... + double entry = GetEntry(mSymbol, type); + double spread = GetSpread(mSymbol); + + // + double tpPrice = 0; + double slPrice = 0; + double riskFreePrice = 0; + + // + // Normalize TP Value ... + if (tp <= 0) + { + // + double minReward = PipsToPrice(mMinTradeProfitsInPips); + tp = minReward; + } + + // + if (riskFree > 0 && riskFreeRate > 0) + { + // + riskFreePrice = type == X_SIGNAL_LONG ? entry + riskFree : entry - riskFree; + riskFreePrice = NormalizePrice(riskFreePrice, mSymbol); + } + + // + if (tp > 0) + { + // + tp += spread; + + // + tpPrice = isLong ? entry + tp : entry - tp; + tpPrice = NormalizePrice(tpPrice, mSymbol); + } + + // + if (sl > 0) + { + // + sl += spread; + + // + slPrice = isLong ? entry - sl : entry + sl; + slPrice = NormalizePrice(slPrice, mSymbol); + } + + // + result.type = type; + result.kind = kind; + result.tp = tpPrice; + result.sl = slPrice; + result.entry = entry; + result.parent = parent; + result.symbol = mSymbol; + result.riskFree = riskFreePrice; + result.magicNumber = mMagicNumber; + result.riskFreeRate = riskFreeRate; + result.time = iTime(mSymbol, _Period, 0); + result.volume = NormalizeVolume(volume, mSymbol); + + // + // Since we Use signal instance to Generate Comment, this must be at the end ... + result.comment = GetSignalComment(result); + + // + return result; + } + XSignal GenerateTradeSignal( + ENUM_X_SIGNAL_TYPE type, // Signal Type + double tp, // Take Profit + double sl, // Stop Loss + double volume, // Volume + double riskFree = 0, // Risk Free Price + double riskFreeRate = 0 // Risk Free Rate + ) + { + // + XSignal result = GenerateSignal( + type, + tp, + sl, + volume, + riskFree, + riskFreeRate, + X_KIND_TRADE, + 0 + // + ); + + // + return result; + } + XSignal GenerateSupportSignal( + ENUM_X_SIGNAL_TYPE type, // Signal Type + double tp, // Take Profit + double sl, // Stop Loss + double volume, // Volume + double riskFree, // Risk Free Price + double riskFreeRate, // Risk Free Rate + ulong parent // Support Kind Signal Parent + ) + { + // + XSignal result = GenerateSignal( + type, + tp, + sl, + volume, + riskFree, + riskFreeRate, + X_KIND_SUPPORT, + parent + // + ); + + // + return result; + } + + // + // Calculate SignalAge ... + int GetSignalAge( + datetime time // Signal Execution Time + ) + { + // + int result = 0; + + // + // Validate Arg ... + if (time <= 0) + { + return result; + } + + // + int sIndex = iBarShift( + mSymbol, + _Period, + time); + + // + datetime cTime = iTime( + mSymbol, + _Period, + 0); + int cIndex = iBarShift( + mSymbol, + _Period, + cTime); + + // + result = MathAbs(cIndex - sIndex); + + // + return result; + } + int GetSignalAge( + datetime time, // Signal Execution Time + ENUM_TIMEFRAMES period // Specify Time Frame + ) + { + // + int result = 0; + + // + // Validate Arg ... + if (time <= 0) + { + return result; + } + + // + int sIndex = iBarShift( + mSymbol, + period, + time); + + // + datetime cTime = iTime( + mSymbol, + period, + 0); + int cIndex = iBarShift( + mSymbol, + _Period, + cTime); + + // + result = MathAbs(cIndex - sIndex); + + // + return result; + } + int GetSignalAge( + XSignal &signal // Specify Signal + ) + { + // + int result = 0; + + // + // Validate Arg ... + if ( + signal.time <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GetSignalAge(signal.time); + + // + return result; + } + int GetSignalAge( + XSignal &signal, // Specify Signal + ENUM_TIMEFRAMES period // Specify Time Frame + ) + { + // + int result = 0; + + // + // Validate Arg ... + if ( + signal.time <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GetSignalAge( + signal.time, + period); + + // + return result; + } + + // + // Generate a Signal Object name for Draw Events On Chart ... + string GetSignalObjectName( + ulong ticket // Specify Ticket + ) + { + // + string result = ""; + + // + // Validate Arg ... + if (ticket <= 0) + { + return result; + } + + // + // TICKET ... + // it is very importants since they hold position info ... + result += "T(" + (string)ticket + ")"; + + // + return result; + } + string GetSignalObjectName( + XSignal &signal // Specify Signal + ) + { + // + string result = ""; + + // + // Validate Arg ... + if (!IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GetSignalObjectName(signal.ticket); + + // + return result; + } + + // + // Convert a Signal to String Representation ... + string ToString( + XSignal &signal // Specify Signal + ) + { + // + string result = ""; + + // + if (!IsValid(signal, mMagicNumber) || signal.ticket <= 0) + { + return result; + } + + // + // TICKET ... + // it is very importants since they hold position info ... + result += "T(" + (string)signal.ticket + ")"; + + // + // TYPE ... + string typeStr = GetSignalType(signal.type); + result += "_TY(" + typeStr + ")"; + + // + // KIND ... + string kindStr = GetSignalKind(signal.kind); + result += "_K(" + kindStr + ")"; + + // + // PARENT ... + result += "_PR(" + (string)signal.parent + ")"; + + // + // ENTRY ... + result += "_E(" + (string)signal.entry + ")"; + + // + // RISKFREE ... + result += "_RF(" + (string)signal.riskFree + ")"; + + // + // RISKFREERATE ... + result += "_RR(" + (string)signal.riskFreeRate + ")"; + + // + // VOLUME ... + result += "_V(" + (string)signal.volume + ")"; + + // + // TYPE ... + // KIND ... + // ENTRY ... + // TICKET ... + // PARENT ... + // VOLUME ... + // RISKFREE ... + // VIRTUALTP ... + // VIRTUALSL ... + // RISKFREERATE ... + // an String Representation of a Signal Carry above fields ... + + // + // ID ... + // TP ... + // SL ... + // TIME ... + // SYMBOL ... + // PROFIT ... + // COMMENT ... + // MAGICNUMBER ... + // these above items can read using PositionInfo instance ... + // so they are not necessary ... + + // + return result; + } + + // + // Convert an string to signal ... + XSignal FromString( + string represent // String Represenation of a Signal + ) + { + // + XSignal result = {}; + + // + // Validate Arg ... + if (StringLen(represent) == 0) + { + return result; + } + + // + // TICKET ... + string ticketStr = ExtractString( + represent, + "T(", + ")"); + if (StringLen(ticketStr) > 0) + { + result.ticket = (ulong)ticketStr; + } + + // + // TYPE ... + string typeStr = ExtractString( + represent, + "_TY(", + ")"); + if (StringLen(typeStr) > 0) + { + // + ENUM_X_SIGNAL_TYPE type = GetSignalType(typeStr); + result.type = type; + } + + // + // KIND ... + string kindStr = ExtractString( + represent, + "_K(", + ")"); + if (StringLen(kindStr) > 0) + { + // + ENUM_X_SIGNAL_KIND kind = GetSignalKind(kindStr); + result.kind = kind; + } + + // + // PARENT ... + string parentStr = ExtractString( + represent, + "_PR(", + ")"); + if (StringLen(parentStr) > 0) + { + result.parent = (ulong)parentStr; + } + + // + // ENTRY ... + string entryStr = ExtractString( + represent, + "_E(", + ")"); + if (StringLen(entryStr) > 0) + { + result.entry = (double)entryStr; + } + + // + // RISKFREE ... + string riskFreeStr = ExtractString( + represent, + "_RF(", + ")"); + if (StringLen(riskFreeStr) > 0) + { + result.riskFree = (double)riskFreeStr; + } + + // + // RISKFREERATE ... + string riskFreeRateStr = ExtractString( + represent, + "_RR(", + ")"); + if (StringLen(riskFreeRateStr) > 0) + { + result.riskFreeRate = (double)riskFreeRateStr; + } + + // + // VOLUME ... + string volumeStr = ExtractString( + represent, + "_V(", + ")"); + if (StringLen(volumeStr) > 0) + { + result.volume = (double)volumeStr; + } + + // + return result; + } + void FromString( + XSignal &result, // Holds Result + string represent // String Represenation of a Signal + ) + { + // + // Validate Arg ... + if (StringLen(represent) == 0) + { + return; + } + + // + // TICKET ... + string ticketStr = ExtractString( + represent, + "T(", + ")"); + if (StringLen(ticketStr) > 0) + { + result.ticket = (ulong)ticketStr; + } + + // + // TYPE ... + string typeStr = ExtractString( + represent, + "_TY(", + ")"); + if (StringLen(typeStr) > 0) + { + // + ENUM_X_SIGNAL_TYPE type = GetSignalType(typeStr); + result.type = type; + } + + // + // KIND ... + string kindStr = ExtractString( + represent, + "_K(", + ")"); + if (StringLen(kindStr) > 0) + { + // + ENUM_X_SIGNAL_KIND kind = GetSignalKind(kindStr); + result.kind = kind; + } + + // + // PARENT ... + string parentStr = ExtractString( + represent, + "_PR(", + ")"); + if (StringLen(parentStr) > 0) + { + result.parent = (ulong)parentStr; + } + + // + // ENTRY ... + string entryStr = ExtractString( + represent, + "_E(", + ")"); + if (StringLen(entryStr) > 0) + { + result.entry = (double)entryStr; + } + + // + // RISKFREE ... + string riskFreeStr = ExtractString( + represent, + "_RF(", + ")"); + if (StringLen(riskFreeStr) > 0) + { + result.riskFree = (double)riskFreeStr; + } + + // + // RISKFREERATE ... + string riskFreeRateStr = ExtractString( + represent, + "_RR(", + ")"); + if (StringLen(riskFreeRateStr) > 0) + { + result.riskFreeRate = (double)riskFreeRateStr; + } + + // + // VOLUME ... + string volumeStr = ExtractString( + represent, + "_V(", + ")"); + if (StringLen(volumeStr) > 0) + { + result.volume = (double)volumeStr; + } + } + + // + // END Signal Related ... + // + + // + // all protected features ... +protected: + // + // all private features ... +private: + // + // Specified Unique Tag ... + string mTag; + + // + // which Symbol ... + string mSymbol; + + // + // using deviation, it must be in Point ... + int mSlippage; + + // + // using magic number ... + ulong mMagicNumber; + + // + // Specify Max Allowed Trades + int mMaxAllowedTrades; + + // + // Specify Max Allowed Support Trades for each Trade + int mMaxAllowedSupportTrades; + + // + // Minimum Profit of each Trade in Pips + double mMinTradeProfitsInPips; + + // + // Support Trades Price Distance in Pips + double mSupportTradesPriceDistanceInPips; + + // + // Minimum Free Marging for Open Trades + double mMinAllowedFreeMarginForOpenTrades; + + // + // Minimum Balance for Open Trades + double mMinBallanceForOpenTrades; + + // + // using CTrade instance ... + XSCTrade mTrader; + + // + // An Instance Of XCAccount Info for Handling Account Related Actions ... + XCAccountInfo mAccountInfo; + + // + // using PositionInfo instance ... + CPositionInfo mPositionInfo; + + // + // For Manage Deals ... + CDealInfo mDealInfo; + + // + // using OrderInfo instance ... + COrderInfo mPendingInfo; + + // + // using HistoryOrderInfo instance ... + CHistoryOrderInfo mHistoryInfo; + + // + // Count Specific Type Of Positions ... + int CountByType(ENUM_POSITION_TYPE type) + { + // + int result = 0; + + // + int total = PositionsTotal(); + for (int i = 0; i < total; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + if (mPositionInfo.PositionType() != type) + { + continue; + } + + // + result++; + } + + // + return result; + } + + // + // Convert Position to Signal by Index ... + XSignal PositionToSignal(int index) + { + // + XSignal result = {}; + + // + if (!mPositionInfo.SelectByIndex(index)) + { + return result; + } + + // + ulong ticket = mPositionInfo.Ticket(); + string signalContent = RetrieveSignalContent(ticket); + if (StringLen(signalContent) > 0) + { + // + // Fill Additional Contents ... + FromString( + result, + signalContent); + } + + // + // Ticket ... + result.ticket = mPositionInfo.Ticket(); + + // + // ID ... + result.id = mPositionInfo.Identifier(); + + // + // Symbol ... + result.symbol = mPositionInfo.Symbol(); + + // + // Type ... + ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType(); + ENUM_X_SIGNAL_TYPE type = pType == POSITION_TYPE_BUY ? X_SIGNAL_LONG : X_SIGNAL_SHORT; + result.type = type; + + // + // MagicNumber ... + result.magicNumber = mPositionInfo.Magic(); + + // + // Entry/Open Price ... + result.entry = mPositionInfo.PriceOpen(); + + // + // Take Profit ... + result.tp = mPositionInfo.TakeProfit(); + + // + // Stop Loss ... + result.sl = mPositionInfo.StopLoss(); + + // + // Profit ... + result.profit = mPositionInfo.Profit(); + + // + // Time ... + result.time = mPositionInfo.Time(); + + // + // Volume ... + result.volume = mPositionInfo.Volume(); + + // + // Comment ... + result.comment = mPositionInfo.Comment(); + + // + return result; + } + + // + // Position To Signal by Ticket ... + XSignal PositionToSignal(ulong ticket) + { + // + XSignal result = {}; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + string signalContent = RetrieveSignalContent(ticket); + if (StringLen(signalContent) > 0) + { + // + // Fill Additional Contents ... + FromString( + result, + signalContent); + } + + // + // Ticket ... + result.ticket = mPositionInfo.Ticket(); + + // + // ID ... + result.id = mPositionInfo.Identifier(); + + // + // Symbol ... + result.symbol = mPositionInfo.Symbol(); + + // + // Type ... + ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType(); + ENUM_X_SIGNAL_TYPE type = pType == POSITION_TYPE_BUY ? X_SIGNAL_LONG : X_SIGNAL_SHORT; + result.type = type; + + // + // MagicNumber ... + result.magicNumber = mPositionInfo.Magic(); + + // + // Entry/Open Price ... + result.entry = mPositionInfo.PriceOpen(); + + // + // Take Profit ... + result.tp = mPositionInfo.TakeProfit(); + + // + // Stop Loss ... + result.sl = mPositionInfo.StopLoss(); + + // + // Profit ... + result.profit = mPositionInfo.Profit(); + + // + // Time ... + result.time = mPositionInfo.Time(); + + // + // Volume ... + result.volume = mPositionInfo.Volume(); + + // + // Comment ... + result.comment = mPositionInfo.Comment(); + + // + return result; + } + + // + // Convert Position to Signal by Index ... + XSignal OrderToSignal(int index) + { + // + XSignal result = {}; + + // + if (!mHistoryInfo.SelectByIndex(index)) + { + return result; + } + + // + // ID ... + result.id = mHistoryInfo.PositionId(); + + // + // Symbol ... + result.symbol = mHistoryInfo.Symbol(); + + // + // Type ... + ENUM_ORDER_TYPE pType = (ENUM_ORDER_TYPE)mHistoryInfo.OrderType(); + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN; + switch (pType) + { + // + case ORDER_TYPE_BUY: + case ORDER_TYPE_BUY_LIMIT: + case ORDER_TYPE_BUY_STOP: + case ORDER_TYPE_BUY_STOP_LIMIT: + type = X_SIGNAL_LONG; + break; + + // + case ORDER_TYPE_SELL: + case ORDER_TYPE_SELL_LIMIT: + case ORDER_TYPE_SELL_STOP: + case ORDER_TYPE_SELL_STOP_LIMIT: + type = X_SIGNAL_SHORT; + break; + + // + // Default ... + default: + type = X_SIGNAL_UNKNOWN; + break; + } + result.type = type; + + // + // MagicNumber ... + result.magicNumber = mHistoryInfo.Magic(); + + // + // Ticket ... + result.ticket = mHistoryInfo.Ticket(); + + // + // Entry/Open Price ... + result.entry = mHistoryInfo.PriceOpen(); + + // + // Take Profit ... + result.tp = mHistoryInfo.TakeProfit(); + + // + // Stop Loss ... + result.sl = mHistoryInfo.StopLoss(); + + // + // Profit ... + // TODO Calculate it ... + // result.profit = mHistoryInfo.Profit(); + + // // + // // Time ... + // result.time = mHistoryInfo.Time(); + + // // + // // Volume ... + // result.volume = mHistoryInfo.Volume(); + + // + // Comment ... + result.comment = mHistoryInfo.Comment(); + + // + return result; + } + + // + // Draw a Signal on Screen ... + void DrawSignalEvent( + XSignal &signal, // Specify Draw which Signal on Screen + color longColor = clrAqua, // Long Signal Object Color + color shortColor = clrFuchsia, // Short Signal Object Color + int chartId = -1, // Specify Chart ID + int subWindow = -1 // Specify SubWindow ID + ) + { + // + // Validate Args ... + if ( + signal.ticket <= 0 || + !IsValid(signal, mMagicNumber) || + signal.type == X_SIGNAL_UNKNOWN) + { + return; + } + + // + // Normalize Chart and SubWindow ID ... + if (chartId == -1) + { + chartId = 0; + } + if (subWindow == -1) + { + subWindow = 0; + } + + // + bool isLong = signal.type == X_SIGNAL_LONG; + + // + // Simply Draw an Arrow on Chart for Representing Signal Info ... + string name = GetSignalObjectName(signal); + string content = ToString(signal); + if (StringLen(content) == 0) + { + return; + } + + // + color signalColor = isLong ? longColor : shortColor; + + // + // Create an Event On Chart ... + bool isCreated = EventCreate( + chartId, + name, + subWindow, + content, + signal.time, + signalColor); + if (isCreated) + { + // + DrawSignalShape( + signal, + longColor, + shortColor); + } + } + + // + // Filter Trades Buffer ... + void FilterSignals( + string query, // Search String + XSignal &source[], // Source Buffer to Filter + XSignal &result[] // Holds Result + ) + { + // + // Free Buffer ... + CleanBuffer(result); + + // + int sourceCount = ArraySize(source); + + // + // Check Conditions and Validate Args ... + if ( + sourceCount == 0 || + StringLen(query) == 0) + { + return; + } + + // + // Loop Through Source ... + for (int i = 0; i < sourceCount; i++) + { + // + // Retrieve Indexed Item ... + XSignal trade = source[i]; + + // + // Check Query Exists or not ... + int pos = StringFind( + trade.comment, + query); + + // + // Continue if nothing found ... + if (pos <= -1) + { + continue; + } + + // + // Resize the result array ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = trade; + } + } + + // + // Get all Positions based on Position Type ... + void GetAllPositionsByType(ENUM_POSITION_TYPE type, XSignal &result[]) + { + // + int existsTotal = CountByType(type); + + // + CleanBuffer(result); + ArrayResize(result, existsTotal); + + // + int filledIndex = 0; + int total = PositionsTotal(); + for (int i = 0; i < total; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + if (mPositionInfo.PositionType() != type) + { + continue; + } + + // + result[filledIndex] = PositionToSignal(i); + filledIndex++; + } + } + + // + // Retrieve Signal Specified Object Text ... + string RetrieveSignalContent( + ulong ticket, // Specify Position Ticket + int chartId = -1, // Specify Chart ID + int subWindow = -1 // Specify SubWindow ID + ) + { + // + string result = ""; + + // + // Validate Arg ... + if (ticket <= 0) + { + return result; + } + + // + string signalObjectName = GetSignalObjectName(ticket); + if (StringLen(signalObjectName) == 0) + { + return result; + } + + // + // Normalize Chart and SubWindow ID ... + if (chartId == -1) + { + chartId = 0; + } + if (subWindow == -1) + { + subWindow = 0; + } + + // + // Search For Signal Object Name ... + int objectIndex = ObjectFind( + chartId, + signalObjectName); + if (objectIndex < 0) + { + return result; + } + + // + // Loop Through Objects ... + int count = ObjectsTotal( + chartId, + subWindow); + for (int i = count - 1; i >= 0; i--) + { + // + // Retrieve Object Name ... + string objectName = ObjectName(chartId, i, subWindow); + + // + // Find Signal Ticket Position in Object Name ... + int stPos = StringFind( + objectName, + signalObjectName); + if (stPos < 0) + { + continue; + } + + // + // Retrieve Object Type and Check it Event ... + int oType = (int)ObjectGetInteger(chartId, objectName, OBJPROP_TYPE); + if (oType != OBJ_EVENT) { + continue; + } + + // + // Retrieve Object Text as String Representation OF Signal ... + result = ObjectGetString(chartId, objectName, OBJPROP_TEXT); + break; + } + + // + return result; + } + string RetrieveSignalContent( + XSignal &signal, // Specify Signal + int chartId = -1, // Specify Chart ID + int subWindow = -1 // Specify SubWindow ID + ) + { + // + string result = ""; + + // + result = RetrieveSignalContent( + signal.ticket, + chartId, + subWindow); + + // + return result; + } + + // + // Remove Signal Object from Chart ... + bool RemoveSignal( + ulong ticket, // Specify Position Ticket + int chartId = -1 // Specify Chart ID + ) + { + // + bool result = false; + + // + // Validate Arg ... + if (ticket <= 0) + { + return result; + } + + // + // Normalize Chart Id ... + if (chartId <= 0) + { + chartId = 0; + } + + // + // Generate Signal Object Name ... + string signalObjectName = GetSignalObjectName(ticket); + + // + // Remove Object from Chart ... + result = ObjectDelete(chartId, signalObjectName); + + // + return result; + } + bool RemoveSignal( + XSignal &signal, // Specify Signal + int chartId = -1 // Specify Chart ID + ) + { + // + bool result = false; + + // + result = RemoveSignal( + signal.ticket, + chartId); + + // + return result; + } + + // + // Generate Comments for Specific Signal ... + string GetSignalComment( + ENUM_X_SIGNAL_KIND kind, // Specify Kind + ENUM_X_SIGNAL_TYPE type, // Specify Kind Signal Type + ulong parentTicket, // Parent Signal Ticket + double volume, // Signal Volume + double riskFree, // Risk Free Price + double riskFreeRate // Risk Free Volume Multiplier + ) + { + // + string result = ""; + + // + string kindStr = GetSignalKind(kind); + string typeStr = GetSignalType(type); + if ( + volume <= 0 || + StringLen(kindStr) == 0 || + StringLen(typeStr) == 0 || + (parentTicket <= 0 && kind == X_KIND_SUPPORT)) + { + return result; + } + + // + // Normalize Data ... + // + if (riskFreeRate < 0) + { + riskFreeRate = 0; + } + else if (riskFreeRate > 1) + { + riskFreeRate = 0.75; + } + + // + volume = NormalizeVolume(volume, mSymbol); + riskFree = NormalizePrice(riskFree, mSymbol); + + // + if (riskFree > 0 && riskFreeRate == 0) + { + riskFreeRate = 0.75; + } + else if (riskFree <= 0 && riskFreeRate > 0) + { + riskFreeRate = 0; + } + + // + string kindTitle = kind == X_KIND_TRADE ? kindStr : kindStr + "_For_" + (string)parentTicket; + result = mTag + "_" + typeStr + "_" + kindTitle; + + // + return result; + } + string GetSignalComment( + XSignal &signal // Specify Signal + ) + { + // + string result = GetSignalComment( + signal.kind, + signal.type, + signal.parent, + signal.volume, + signal.riskFree, + signal.riskFreeRate + // + ); + + // + return result; + } + + // + // Generate TP Comment For Closing Signal ... + string GetSignalClosedOnTPComment( + XSignal &signal // Model Signal to Use + ) + { + // + string result = ""; + + // + if (signal.ticket <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + double exitPrice = GetExit(signal.type); + string prefix = GetSignalObjectName(signal); + + // + // "_E(" + (string)signal.entry + ")" ... + result = prefix + "_TP(" + (string)exitPrice + ")"; + + // + return result; + } + + // + // Generate SL Comment For Closing Signal ... + string GetSignalClosedOnSLComment( + XSignal &signal // Model Signal to Use + ) + { + // + string result = ""; + + // + if (signal.ticket <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + double exitPrice = GetExit(signal.type); + string prefix = GetSignalObjectName(signal); + + // + // "_E(" + (string)signal.entry + ")" ... + result = prefix + "_SL(" + (string)exitPrice + ")"; + + // + return result; + } + + // + // Generate Comment For Force Closing Signal ... + string GetSignalForceClosedComment( + XSignal &signal // Model Signal to Use + ) + { + // + string result = ""; + + // + if (signal.ticket <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + double exitPrice = GetExit(signal.type); + string prefix = GetSignalObjectName(signal); + + // + // "_E(" + (string)signal.entry + ")" ... + result = "F_" + prefix + "_P(" + (string)exitPrice + ")"; + + // + return result; + } + + // + // Generate Comment For In DrawDown and In Profit Closing Signal ... + string GetSignalInDistanceClosedComment( + XSignal &signal // Model Signal to Use + ) + { + // + string result = ""; + + // + if (signal.ticket <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + double exitPrice = GetExit(signal.type); + string prefix = GetSignalObjectName(signal); + string distanceStr = signal.profit > 0 ? "InP" : "InDD"; + + // + // "_E(" + (string)signal.entry + ") ... + // "_P(" + (string)exitPrice + ")" ... + result = distanceStr + "_" + prefix + "_D(" + (string)signal.profit + ")"; + + // + return result; + } + + // + // Generate Comment For Long Time Closing Signal ... + string GetSignalLongTimeClosedComment( + XSignal &signal // Model Signal to Use + ) + { + // + string result = ""; + + // + if (signal.ticket <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + double exitPrice = GetExit(signal.type); + string prefix = GetSignalObjectName(signal); + + // + int signalAge = GetSignalAge(signal); + + // + // "_E(" + (string)signal.entry + ")" ... + // "_P(" + (string)exitPrice + ")" ... + result = "LT_" + prefix + "_A(" + (string)signalAge + ")" + "_D(" + (string)signal.profit + ")"; + + // + return result; + } + + // + // Check Number Of Trades is Valid ... + bool CanOpenNewTrade( + ENUM_X_SIGNAL_TYPE type, // Specify Type of Positions + ENUM_X_SIGNAL_KIND kind // Specify Kind of Positions + ) + { + // + bool result = false; + + // + int tradesCount = CountByKind( + type, + kind); + + // + result = tradesCount <= 0; + if (!result) + { + return result; + } + + // + bool isTradeKind = kind == X_KIND_TRADE; + + // + // Check based on Trade Kind ... + result = + // + isTradeKind + // + ? + // + tradesCount < mMaxAllowedTrades + // + : + // + tradesCount < mMaxAllowedSupportTrades + // + ; + + // + return result; + } + + // + // Check Account Has Minimum Balance For Trade ... + bool IsAccountBalanceReadyForTrade() + { + // + bool result = false; + + // + result = mAccountInfo.GetBalance() >= mMinBallanceForOpenTrades; + + // + return result; + } + + // + // Check Free Margin Has Enough For Trade ... + bool IsFreeMarginReadyForTrade() + { + // + bool result = false; + + // + double freeMargin = mAccountInfo.GetFreeMargin(); + + // + result = freeMargin >= mMinAllowedFreeMarginForOpenTrades; + + // + return result; + } +}; +// +// END Global Definitions: Variables, Properties and etc ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.common.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..e94b782 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,3584 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommon +// Description: provide all commonly used 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 + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// Include Models Library ... +#include "x-saherelm.models.lib.mq5"; + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Detect is new Candle or not ... +bool IsNewCandle() +{ + // + bool result = false; + + // + static int barsOnChart = 0; + int currentBarsOnChart = Bars(_Symbol, _Period); + result = currentBarsOnChart > barsOnChart; + if (!result) + { + return result; + } + + // + barsOnChart = currentBarsOnChart; + result = true; + + // + return result; +} + +// +// Retrive Ask Price ... +double GetAsk() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_ASK); +} +double GetAsk( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_BID); +} +double GetBid( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_BID); + + // + return result; +} + +// +// Calculate and Retrieve Spread Price ... +double GetSpread() +{ + // + double ask = GetAsk(); + double bid = GetBid(); + double result = MathAbs(ask - bid); + + // + return result; +} +double GetSpread( + string symbol // selected symbol for calculations +) +{ + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Get Points ... +double GetPoints() +{ + return _Point; +} +double GetPoints( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + return result; +} + +// +// Get Digits ... +int GetDigits() +{ + return _Digits; +} +int GetDigits( + string symbol // selected symbol for calculations +) +{ + // + int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Get Signal Entry ... +double GetEntry( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice() +{ + // + double result = _Point; + if (_Digits == 3 || _Digits == 5) + { + result *= 10; + } + + // + return result; +} +double GetPipPrice( + string symbol // selected symbol for calculations +) +{ + // + double symbolPoint = GetPoints(symbol); + int symbolDigits = GetDigits(symbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + int pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + double pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + int pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + double pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(); + double pipPrice = GetPipPrice(); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PriceToPips( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(symbol); + double pipPrice = GetPipPrice(symbol); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Get a Candle Body ... +double GetCandleBody( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.open - candle.close); + + // + return result; +} + +// +// Get a Candle Range ... +double GetCandleRange( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.high - candle.low); + + // + return result; +} + +// +// Get a Candle Shadow ... +double GetCandleShadow( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + double result = MathAbs(range - body); + + // + return result; +} + +// +// Retrieve Applied Price at Specific Candle ... +double GetAppliedPrice( + XOHCL &candle, // specified candle + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + switch (source) + { + // + // Open ... + case PRICE_OPEN: + result = candle.open; + break; + + // + // High ... + case PRICE_HIGH: + result = candle.high; + break; + + // + // Low ... + case PRICE_LOW: + result = candle.low; + break; + + // + // Median ((High + Low) / 2) ... + case PRICE_MEDIAN: + result = (candle.high + candle.low) / 2; + break; + + // + // Typical ((High + Low + Close)/3) ... + case PRICE_TYPICAL: + result = (candle.high + candle.low + candle.close) / 3; + break; + + // + // Weighted ((High + Low + Close + Close)/4) ... + case PRICE_WEIGHTED: + result = (candle.high + candle.low + (candle.close * 2)) / 4; + break; + + // + // Close ... + default: + case PRICE_CLOSE: + result = candle.close; + break; + } + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + XOHCL candle = GetCandle(bar_index); + result = GetAppliedPrice(candle, source); + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + double result = 0; + + // + ENUM_APPLIED_PRICE mAppliedTo = To(mode); + result = GetAppliedPrice( + bar_index, + mAppliedTo); + + // + return result; +} + +// +// Converts ... +ENUM_APPLIED_PRICE To( + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + ENUM_APPLIED_PRICE result = PRICE_CLOSE; + + // + switch (mode) + { + // + // High ... + case MODE_HIGH: + result = PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve a Candel Data ... +XOHCL GetCandle(int bar_index) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + double close = iClose(_Symbol, _Period, bar_index); + double low = iLow(_Symbol, _Period, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, mPeriod, bar_index); + double high = iHigh(_Symbol, mPeriod, bar_index); + double close = iClose(_Symbol, mPeriod, bar_index); + double low = iLow(_Symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(symbol, mPeriod, bar_index); + double high = iHigh(symbol, mPeriod, bar_index); + double close = iClose(symbol, mPeriod, bar_index); + double low = iLow(symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} + +// +// Retrieve a candle index in current timeframe inside another timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(_Symbol, _Period, bar_index); + result = iBarShift(_Symbol, destPeriod, barTime); + + // + return result; +} + +// +// Retrieve a symbol candle index in source time frame inside dest timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + string symbol, // Specify desired Symbol + ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(symbol, sourcePeriod, bar_index); + result = iBarShift(symbol, destPeriod, barTime); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBullishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open < candle.close; + + // + return result; +} +bool IsBullishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} +bool IsBullishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBearishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open > candle.close; + + // + return result; +} +bool IsBearishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} +bool IsBearishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} + +// +// Check Candle Body Bigger Than it's Shadow ... +bool HasStrongBody(XOHCL &candle) +{ + // + double bodySize = MathAbs(candle.open - candle.close); + double shadowSize = MathAbs(candle.high - candle.low) - bodySize; + + // + bool result = bodySize > (shadowSize * 1.5); + + // + return result; +} + +// +// Determines a cnadle is Swing High +// or Swing Low order block ... +ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(bar_index + 1); + candles[1] = GetCandle(bar_index + 2); + candles[2] = GetCandle(bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(mPeriod, bar_index + 1); + candles[1] = GetCandle(mPeriod, bar_index + 2); + candles[2] = GetCandle(mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); + candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); + candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} + +// +// Retrieve Market Highest High ... +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Retrieve Market Lowest Low ... +double GetLowestLow( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} +// +// END Provided Functions ... +// + +// +// Find Farest Time Frame ... +ENUM_TIMEFRAMES GetFarestTimeFrame() +{ + // + ENUM_TIMEFRAMES result = PERIOD_MN1; + + // + switch (_Period) + { + // + // M1-M30 ... + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + case PERIOD_M30: + result = PERIOD_D1; + break; + + // + // H1-H12 ... + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + result = PERIOD_W1; + break; + + // + // D!, W1 ... + case PERIOD_D1: + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + // Otherwise ... + default: + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Find Medium Time Frame ... +ENUM_TIMEFRAMES GetMediumTimeFrame() +{ + // + ENUM_TIMEFRAMES result = PERIOD_D1; + + // + switch (_Period) + { + // + // M1-M30 ... + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + case PERIOD_M30: + result = PERIOD_H4; + break; + + // + // H1-H12 ... + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + // D!, W1 ... + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + // Otherwise ... + default: + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Find Smallest Time Frame ... +ENUM_TIMEFRAMES GetSmallestTimeFrame() +{ + // + ENUM_TIMEFRAMES result = PERIOD_M5; + + // + switch (_Period) + { + // + // M1-M5 ... + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + result = _Period; + break; + + // + // M6-M30 ... + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + case PERIOD_M30: + result = PERIOD_M5; + break; + + // + // H1-H12 ... + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + result = PERIOD_H1; + break; + + // + // D! ... + case PERIOD_D1: + result = PERIOD_H2; + break; + + // + // Otherwise ... + default: + result = PERIOD_H4; + } + + // + return result; +} + +// +// Check first Cross Over second at bar_index ... +bool IsCrossOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + !(first[bar_index + 1] > second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Over second at bar_index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + first[bar_index + 1] > second[bar_index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at bar_index ... +bool IsCrossUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + !(first[bar_index + 1] < second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Under second at bar_index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + first[bar_index + 1] < second[bar_index + 1]; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + int from, // In Past Index ... + int to, // In Past Index ... + double &buffer[]) +{ + // + double result = 0; + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Get Max Value of Specific Loopback of a Buffer ... +double GetMaxValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min Value of Specific Loopback of a Buffer ... +double GetMinValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +bool IsInPeak( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue > lastValue + // + && + // + ( + firstValue > q1Value && + firstValue > halfValue) + // + ; + + // + return result; +} + +// +bool IsInVale( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue < lastValue + // + && + // + ( + firstValue < q1Value && + firstValue < halfValue) + // + ; + + // + return result; +} + +// +// Check Sharp Happens or not ... +bool IsSharpChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check InCreased Sharp Happens or not ... +bool IsSharpIncreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check Decreased Sharp Happens or not ... +bool IsSharpDecreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + !isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Validate Struct ... +bool IsValid(XSignal &model, ulong magicNumber) +{ + // + bool result = false; + + // + // Validate Signal Type ... + result = model.type != X_SIGNAL_UNKNOWN; + if (!result) + { + return result; + } + + // + // Check Symbol ... + result = StringLen(model.symbol) == 0 ? true : model.symbol == _Symbol; + if (!result) + { + return result; + } + + // + // Check magic number ... + result = model.magicNumber <= 0 ? true : model.magicNumber == magicNumber; + if (!result) + { + return result; + } + + // + // Check Entry ... + result = model.entry > 0; + if (!result) + { + return result; + } + + // + // Check SL ... + result = model.sl == 0 ? true : model.type == X_SIGNAL_LONG ? model.sl < model.entry + : model.sl > model.entry; + if (!result) + { + return result; + } + + // + // Check TP ... + result = model.tp == 0 ? true : model.type == X_SIGNAL_LONG ? model.tp > model.entry + : model.tp < model.entry; + if (!result) + { + return result; + } + + // + // Check Volume ... + result = model.volume > 0; + if (!result) + { + return result; + } + + // + // Check Time ... + result = model.time > 0; + if (!result) + { + return result; + } + + // + return result; +} +bool IsValid(XTPSL &model) +{ + // + bool result = false; + + // + result = model.entry > 0 && model.type != X_SIGNAL_UNKNOWN; + + // + return result; +} + +// +void CleanBuffer(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(double &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(XSignal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +void Add( + int item, // item want to add + int &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + double item, // item want to add + double &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOHCL &item, // item want to add + XOHCL &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XSignal &item, // item want to add + XSignal &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Check a Signal is Long or not ... +bool IsLong(ENUM_X_SIGNAL_TYPE type) +{ + return type == X_SIGNAL_LONG; +} +bool IsLong(XSignal &signal) +{ + // + bool result = IsLong(signal.type); + + // + return result; +} + +// +// Check a Signal is Short or not ... +bool IsShort(ENUM_X_SIGNAL_TYPE type) +{ + return type == X_SIGNAL_SHORT; +} +bool IsShort(XSignal &signal) +{ + // + bool result = IsShort(signal.type); + + // + return result; +} + +// +// Retrieve a Signal Type String Value ... +string GetSignalType(ENUM_X_SIGNAL_TYPE type) +{ + // + string result = ""; + + // + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + result = type == X_SIGNAL_LONG ? "Long" : "Short"; + + // + return result; +} +string GetSignalType(XSignal &signal) +{ + // + string result = ""; + + // + result = GetSignalType(signal.type); + + // + return result; +} +ENUM_X_SIGNAL_TYPE GetSignalType(string typeStr) +{ + // + ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; + + // + if (typeStr == GetSignalType(X_SIGNAL_LONG)) + { + result = X_SIGNAL_LONG; + } + else if (typeStr == GetSignalType(X_SIGNAL_SHORT)) + { + result = X_SIGNAL_SHORT; + } + + // + return result; +} + +// +// Retrieve a Signal Kind String Value ... +string GetSignalKind(ENUM_X_SIGNAL_KIND kind) +{ + // + string result = ""; + + // + if (kind != X_KIND_TRADE && kind != X_KIND_SUPPORT) + { + return result; + } + + // + result = kind == X_KIND_TRADE ? "Trade" : "Support"; + + // + return result; +} +string GetSignalKind(XSignal &signal) +{ + // + string result = ""; + + // + result = GetSignalKind(signal.kind); + + // + return result; +} +ENUM_X_SIGNAL_KIND GetSignalKind(string kindStr) +{ + // + ENUM_X_SIGNAL_KIND result = X_KIND_TRADE; + + // + if (kindStr == GetSignalKind(X_KIND_TRADE)) + { + result = X_KIND_TRADE; + } + else if (kindStr == GetSignalKind(X_KIND_SUPPORT)) + { + result = X_KIND_SUPPORT; + } + + // + return result; +} + +// +// Retrieve Signal Execution String ... +string GetSignalExecutionError(int error) +{ + // + string result = ""; + + // + switch (error) + { + // + case X_INVALID_SIGNAL_ERROR: + result = "Invalid Signal ..."; + break; + + // + case X_XTRADER_NOT_ENOUGH_BALANCE_ERROR: + result = "Not Enough Balance for Trade ..."; + break; + + // + case X_XTRADER_NOT_ENOUGH_MARIGIN_ERROR: + result = "Not Enough Marigin For Trade ..."; + break; + + // + case X_XTRADER_MAX_ALLOWED_TRADE_KIND_REACHED_ERROR: + result = "Max Allowed Trade Reached ..."; + break; + + // + case X_XTRADER_MAX_ALLOWED_SUPPORT_KIND_REACHED_ERROR: + result = "Max Allowed Support Trade Reached ..."; + break; + + // + case X_UNKNOWN_ERROR: + default: + result = "Unknown Issue ..."; + break; + } + + // + return result; +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double volume // desired volume to normalization +) +{ + // + double result = volume; + + // + // Normalize Volume ... + result = NormalizeDouble(result, 2); + + // + double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} +double NormalizeVolume( + double volume, // desired volume to normalize + string symbol // Specified Symbol for Normalization +) +{ + // + double result = volume; + + // + // Normalize Volume ... + result = NormalizeDouble(result, 2); + + // + double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double price // desired Price for normalization +) +{ + // + double result = 0; + + // + result = NormalizeDouble(price, _Digits); + + // + return result; +} +double NormalizePrice( + double price, // desired Price for normalization + string symbol // Specified Symbol for Normalization +) +{ + // + double result = 0; + + // + int digits = GetDigits(symbol); + result = NormalizeDouble(price, digits); + + // + return result; +} + +// +// START Error Descriptions ... +// + +// +// Retrieve Specified Error Code Description ... +string GetErrorDescription(int err_code) +{ + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; +} + +// +// Retrieve Specified Error Code Description ... +string GetTradeServerReturnCodeDescription(int return_code) +{ + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; +} diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.draw.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.draw.lib.mq5 new file mode 100644 index 0000000..e904cd6 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.draw.lib.mq5 @@ -0,0 +1,2220 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Draw Library +// -------------------------------------- +// Name: XDraw +// Description: provides Draw abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// Include Logger Library ... +#include "x-saherelm.log.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string drawPrefix = "X-OBJ"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// DeInitial Library if required ... +void OnDeinitDrawLibrary() +{ + RemoveDraws(); +} + +// +void DrawSignalShape( + XSignal &signal, // Specify Signal to Draw + color longColor = clrAqua, // Long Signals Color + color shortColor = clrFuchsia, // Short Signal Color + color entryColor = clrGold // Signal Entry Price Color +) { + // + // Draw Signal Info : + // - Draw Entry Price Line; + // - Draw SL; + // - Draw TP; + // - Risk Free; + + // + bool isLong = signal.type == X_SIGNAL_LONG; + + // + color tpColor = longColor; + color slColor = shortColor; + + // + string name = "T(" + (string) signal.ticket + ")" + "_" + "TY(" + EnumToString(signal.type) + ")" + "_" + "KI(" + EnumToString(signal.kind) + ")"; + string tpName = "TP_" + name; + string slName = "SL_" + name; + string riskFreeName = "RF_" + name; + string entryName = "Entry_" + name; + + // + int signalBarIndex = iBarShift( + signal.symbol, + _Period, + signal.time + ); + + // + datetime time1 = iTime( + signal.symbol, + _Period, + signalBarIndex + 1 + ); + datetime time2 = iTime( + signal.symbol, + _Period, + signalBarIndex - 1 + ); + + // + // Entry ... + bool isTrendLineDrawn = DrawTrendLine( + 0, + entryName, + 0, + time1, + signal.entry, + time2, + signal.entry, + entryColor + ); + + // + // TP ... + bool isTPDrawn = false; + if (signal.tp > 0) { + // + isTPDrawn = DrawTrendLine( + 0, + tpName, + 0, + time1, + signal.tp, + time2, + signal.tp, + tpColor, + STYLE_SOLID, + 1, + false, + true + ); + } + + // + // RISKFREE ... + bool isRFDrawn = false; + if (signal.riskFree > 0) { + // + isRFDrawn = DrawTrendLine( + 0, + riskFreeName, + 0, + time1, + signal.riskFree, + time2, + signal.riskFree, + tpColor, + STYLE_DOT, + 1, + false, + true + ); + } + + // + // SL ... + bool isSLDrawn = false; + if (signal.sl > 0) { + // + isSLDrawn = DrawTrendLine( + 0, + slName, + 0, + time1, + signal.sl, + time2, + signal.sl, + slColor, + STYLE_SOLID, + 1, + false, + true + ); + } +} + +// +// remove drawn objects ... +void RemoveDraws( + string tag = NULL, + int chartId = -1, + int subWindow = -1) +{ + // + // Normalize Args ... + // + if (tag == NULL) + { + tag = drawPrefix; + } + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, tag) == 0) + { + ObjectDelete(chartId, on); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} +// +// END Provided Functions ... +// + +// +// START Regular Draws ... +// + +// +// START Arrow Functions ... +// +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = 252, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create an arrow ... + if (!ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete an arrow ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change the arrow code ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) + { + // + string message = + __FUNCTION__ + + ": failed to change the arrow code! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change anchor type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) + { + // + string message = + __FUNCTION__ + + ": failed to change anchor type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Arrow Functions ... +// + +// +// START Horizontal Line Functions ... +// +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the price is not set, set it at the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a horizontal line ... + if (!ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) +{ + // + // if the line price is not set, move it to the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move a horizontal line ... + if (!ObjectMove(chartID, name, 0, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a horizontal line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} +// +// END Horizontal Line Functions ... +// + +// +// START Vertical Line Functions ... +// +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int sub_window = 0, // subwindow index + datetime time = 0, // line time + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the line time is not set, draw it via the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a vertical line ... + if (!ObjectCreate(chartID, objName, OBJ_VLINE, sub_window, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) +{ + // + // if line time is not set, move the line to the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the vertical line ... + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the vertical line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END Vertical Line Functions ... +// + +// +// START RectangleLabel Functions ... +// +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color back_clr = clrWhiteSmoke, // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + //--- create a rectangle label + if (!ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, back_clr); + + // + // set border type ... + ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the label by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // move the rectangle label ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) + { + // + string message = + __FUNCTION__ + + ": failed to move X coordinate of the label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) + { + // + string message = + __FUNCTION__ + + ": failed to move Y coordinate of the label! Error code = " + + (string)GetLastError(); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the label ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change label size ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's width! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's height! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change border type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) + { + // + string message = + __FUNCTION__ + + ": failed to change the border type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} +// +// END RectangleLabel Functions ... +// + +// +// START TrendLine Funcions ... +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a trend line by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move trend line's anchor point ... + if (!ObjectMove(chartID, name, pointindex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a trend line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) + { + price2 = price1; + } +} +// +// END TrendLine Functions ... +// + +// +// START Text Functions ... +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + //--- create Text object + if (!ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set the text ... + ObjectSetString(chartID, objName, OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, objName, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the object by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + //--- if point position is not set, move it to the current bar having Bid price + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point .. + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change object text ... + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Text Functions ... +// + +// +// START Fibonacchi Functions ... +// +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + bool result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + objName); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // check array sizes ... + if ( + levels != ArraySize(colors) || + levels != ArraySize(styles) || + levels != ArraySize(widths) || + levels != ArraySize(widths)) + { + // + string message = + __FUNCTION__ + + ": array length does not correspond to the number of levels, error!"; + + // + LogMessage(message); + + // + return (false); + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for (int i = 0; i < levels; i++) + { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return (true); +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, pointIndex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) + { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) + { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time2, 10, temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) + { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} +// +// END Fibonacci Functions ... +// + +// +// START Event Functions ... +// + +// +// Create an Event ... +bool EventCreate( + const long chartID = 0, // chart's ID + const string name = "Event", // object name + const int subWindow = 0, // subwindow index + const string text = "Content", // event text + datetime time = 0, // anchor point time + const color clr = clrRed, // color + const int width = 1, // point width when highlighted + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + if (!time) + { + time = TimeCurrent(); + } + + // + ResetLastError(); + + // + if (!ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set event text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set anchor point width if the object is highlighted + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving event by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution + return (true); +} + +// +// Change Event object text +bool EventTextChange( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + const string text = "Content" // text +) +{ + // + // reset the error value + ResetLastError(); + + // + // change object text + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Move Event object +bool EventMove( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + datetime time = 0 // time +) +{ + // + // if time is not set, move event to the last bar + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // move the object + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Delete Event object +bool EventDelete( + const long chartID = 0, // chart's ID + const string name = "Event" // event name +) +{ + // + // reset the error value + ResetLastError(); + + // + // delete the object + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// END Event Functions ... +// + +// +// END Regular Draws ... +// + +// +// START Chart Style Drawers ... +// +// +// Apply Styles On Chart ... +void ApplyChartStyle( + int chartId = -1, // chart's ID + ENUM_CHART_MODE mode = CHART_CANDLES, // chart's mode + bool showBidLine = true, // show bid line + bool showAskLine = true, // show ask line + bool showGrid = false, // show grids on chart + bool showVolumes = false, // show volumes + bool showTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool autoScroll = true, // chart autoscroll + bool quickNavigation = true, // chart quick navigation state + color foreGroundColor = clrWhite, // chart's foreground color + color backGroundColor = clrBlack, // chart's background color + color upColor = clrGreen, // Up Color + color downColor = clrRed, // Down Color + color bullishColor = clrGreen, // Bullish color + color bearishColor = clrRed, // Bearish color + color gridColor = clrGray, // grid color + color bidLineColor = clrGray, // bid line color + color askLineColor = clrRed, // ask line color + color lineColor = clrLime, // line mode and doji candlestick color + color stopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color volumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (chartId == -1) + { + chartId = 0; + } + + // + ChartSetInteger(chartId, CHART_MODE, mode); + ChartSetInteger(chartId, CHART_SHOW_BID_LINE, showBidLine); + ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, showAskLine); + ChartSetInteger(chartId, CHART_SHOW_GRID, showGrid); + ChartSetInteger(chartId, CHART_SHOW_VOLUMES, showVolumes); + ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, showTradeLevels); + ChartSetInteger(chartId, CHART_AUTOSCROLL, autoScroll); + ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, quickNavigation); + ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, foreGroundColor); + ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, backGroundColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_UP, upColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, downColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, bullishColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, bearishColor); + ChartSetInteger(chartId, CHART_COLOR_GRID, gridColor); + ChartSetInteger(chartId, CHART_COLOR_BID, bidLineColor); + ChartSetInteger(chartId, CHART_COLOR_ASK, askLineColor); + ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, stopColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, lineColor); + ChartSetInteger(chartId, CHART_COLOR_VOLUME, volumesColor); +} +// +// END Chart Style Drawers ... +// \ No newline at end of file diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.http.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.http.lib.mq5 new file mode 100644 index 0000000..97f7ac0 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.http.lib.mq5 @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Http Library +// ------------------------------------------ +// Name: XHttp +// Description: provide http communication +// abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Model Definition ... +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; +// +// END Model Definition ... +// + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitHttpLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitHttpLibrary() +{ +} + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// +// Send Global Request ... +int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) +{ + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) { + return result; + } + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders + ); + + // + return result; +} + +// +// Get Request ... +int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} + +// +// Post Request ... +int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} +// +// END Provided Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.log.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.log.lib.mq5 new file mode 100644 index 0000000..e74039e --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.log.lib.mq5 @@ -0,0 +1,161 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Logger Library +// --------------------------------------- +// Name: XLogger +// Description: provides Logging abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Logging"; +input bool enableLogging = true; // Enable Logging +// +// END Inputs ... +// + +// +// Including Models ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string logTag = "X-Logger"; // LogTag +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Logging a Message ... +void LogMessage(string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, " > ", message); +} +void LogMessage(string tag, string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(tag, " > ", message); +} + +// +// Logging an Array ... +void LogArray(int &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(double &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(string &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} + +// +// Convert a Signal to String Message ... +string SignalToString(XSignal &signal) +{ + // + string result = ""; + + // + result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment; + + // + return result; +} + +// +// Convert an Executed Signal to String Message ... +string ExecutedSignalToString(XSignal &signal) +{ + // + string result = ""; + + // + result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal Executed provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment; + + // + return result; +} + +// +// Logging Signal ... +void LogSignal(XSignal &signal) +{ + // + string message = SignalToString(signal); + + // + LogMessage(message); +} + +// +// Log Signal Execution ... +void LogExecutedSignal(XSignal &signal) +{ + // + string message = ExecutedSignalToString(signal); + + // + LogMessage(message); +} +// +// END Provided Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.models.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.models.lib.mq5 new file mode 100644 index 0000000..52e4050 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.models.lib.mq5 @@ -0,0 +1,187 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Models Library +// --------------------------------------- +// Name: XModels +// Description: provides all required models ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// START Model Definitions ... +// +// +// OHCL Candel Model ... +enum ENUM_X_PRICE +{ + X_PRICE_HIGH, + X_PRICE_OPEN, + X_PRICE_CLOSE, + X_PRICE_LOW +}; + +// +// Describe an Specific Candle ... +struct XOHCL +{ + double high; + double open; + double close; + double low; +}; + +// +// Swing Types Enum ... +enum ENUM_X_SWING_TYPE +{ + X_NO_SWING = 0, + X_SWING_HIGH = 1, + X_SWING_LOW = -1, +}; + +// +// XTrader Execution Signal Result ... +enum ENUM_EXECUTION_SIGNAL_RESULT +{ + // + X_INVALID_SIGNAL_ERROR, + X_XTRADER_NOT_ENOUGH_BALANCE_ERROR, + X_XTRADER_NOT_ENOUGH_MARIGIN_ERROR, + X_XTRADER_MAX_ALLOWED_TRADE_KIND_REACHED_ERROR, + X_XTRADER_MAX_ALLOWED_SUPPORT_KIND_REACHED_ERROR, + // + X_TRADER_SUPPORT_DISTANCE_NOT_HAPPENS_ERROR, + // + X_UNKNOWN_ERROR, + X_SUCCEED_EXECUTION +}; + +// +// Signal Types ... +enum ENUM_X_SIGNAL_TYPE +{ + X_SIGNAL_LONG, + X_SIGNAL_SHORT, + X_SIGNAL_UNKNOWN, +}; + +// +// Represent a Signal issued for Trade or Support a Trade ... +enum ENUM_X_SIGNAL_KIND +{ + X_KIND_TRADE, + X_KIND_SUPPORT +}; + +// +// Signal Structure ... +struct XSignal +{ + // + // Identifier ... + ulong id; + + // + // Which Symbol used for Signal ... + string symbol; + + // + // Which Type of operations ... + ENUM_X_SIGNAL_TYPE type; + + // + // Signal Kind ... + ENUM_X_SIGNAL_KIND kind; + + // + // Parent Ticket ... + ulong parent; + + // + // Magic Number ... + ulong magicNumber; + + // + // Ticket ... + ulong ticket; + + // + // Entry/Open Price ... + double entry; + + // + // TP ... + double tp; + + // + // SL ... + double sl; + + // + // Make Risk Free Trade on this Value if provided ... + double riskFree; + + // + // a Multiplier for determines how much trade volume exit on risk free time ... + double riskFreeRate; + + // + // Trade Profit ... + double profit; + + // + // Time of Operation ... + datetime time; + + // + // Volume ... + double volume; + + // + // Comment ... + string comment; +}; + +// +// TP/SL Struct ... +struct XTPSL +{ + ENUM_X_SIGNAL_TYPE type; + double tp; + double sl; + double entry; + double r2r; +}; +// +// END Provided Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.nn.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.nn.lib.mq5 new file mode 100644 index 0000000..8fa40f5 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.nn.lib.mq5 @@ -0,0 +1,258 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 NN Class Library +// ---------------------------------------- +// Name: XNNClass +// Description: provides all classes for implementing +// Neural Network ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Global Definitions: Variables, Properties and etc ... +// +class XCNNBase +{ + // + // Public Definitions ... +public: + // + // Constructor ... + void XCNNBase( + int nodes = 10, // Number of Input Nodes + double starterWeight = 0.5, // start weight for each input + double coEfficient = 0.1, // COEfficient Multiplier + double upperRange = 1, // Upper Normal Range Value + double lowerRange = -1, // Lower Normal Range Value + double learningRates = 0.1 // Back Propagation Learning Rate + ) { + // + mNodes = nodes; + mUpperRange = upperRange; + mLowerRange = lowerRange; + mCoEfficient = coEfficient; + mLearningRates = learningRates; + mStarterWeight = starterWeight; + + // + ReConstructWeights(); + } + + // + // Deconstructor ... + void ~XCNNBase() {} + + // + // Protected Definitions ... + void NormalizeInputs(double &inputs[], double &result[]) + { + // + ArrayFree(result); + ArrayResize(result, 1); + + // + // Validate inputs ... + if (ArraySize(inputs) != mNodes) + { + return; + } + + // + // Prepare Result ... + ArrayResize(result, mNodes); + + // + // Calculating min and max range value ... + double minRangeValue = inputs[ArrayMinimum(inputs)]; + double maxRangeValue = inputs[ArrayMaximum(inputs)]; + + // + // Loop through Inputs nd Normalize them ... + for (int i = 0; i < mNodes; i++) + { + // + double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange; + result[i] = normalValue; + } + } + + // + // Hyperbolic Tangent Activation Function ... + double TanHActivationFunction(double weightedInputs) + { + // + double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs)); + return result; + } + + // + // Calculate Weighted Inputs ... + double CalculateWeightedInputs( + double &inputs[], + bool applyCOEfficient = true) + { + // + double result = 0; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) + { + // + result = -1; + return result; + } + + // + for (int i = 0; i < mNodes; i++) + { + result += inputs[i] * mWeights[i]; + } + + // + // Multiply if required ... + if (applyCOEfficient) + { + result *= mCoEfficient; + } + + // + return result; + } + + // + // Calculate Hidden Layers ... + virtual double CalculateHiddenLayer(double &inputs[]) + { + // + // this is Default Activation Function which used ... + // you can override this by writing your own ... + double totalWeightedInputs = CalculateWeightedInputs(inputs); + double result = TanHActivationFunction(totalWeightedInputs); + + // + return result; + } + + // + // Calculate Output Layers ... + double CalculateOutputLayer(double &inputs[]) + { + // + double result = -1; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return result; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return result; + } + + // + double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs); + + // + result = 1 * hiddenLayerResult; + + // + return result; + } + + // + // Basck Propaggation Learning ... + void BackPropagation( + double &inputs[], + double &outputs, + double targetOutput + ) { + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return; + } + + // + double error = targetOutput - outputs; + double derivative = 1 - MathPow(outputs, 2); + + // + for (int i = 0; i < mNodes; i++) { + // + double gradient = error * derivative * inputs[i]; + mWeights[i] = mLearningRates * gradient; + } + } + +protected: + // + // Private Definitions ... +private: + // + // Number of Input Nodes ... + int mNodes; + + // + // Specify Upper range of Normal Values ... + double mUpperRange; + + // + // Specify Lower range of Normal Values ... + double mLowerRange; + + // + // Starter Weight for each input node ... + double mStarterWeight; + + // + // double Input Node Weights ... + double mWeights[]; + + // + // CoEfficient is a multiplyer for weighted inputs ... + double mCoEfficient; + + // + // Back Propagation Learning Rates ... + double mLearningRates; + + // + // ReConstruct Weights ... + void ReConstructWeights() { + // + ArrayFree(mWeights); + ArrayResize(mWeights, mNodes); + + // + for (int i = 0; i< mNodes; i++) { + mWeights[i] = mStarterWeight; + } + } +} +// +// END Global Definitions: Variables, Properties and etc ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xchlh.oscillator.helper.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xchlh.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..75f8068 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xchlh.oscillator.helper.lib.mq5 @@ -0,0 +1,925 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHLH Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "..\Libraries\x-saherelm.log.lib.mq5" +#include "..\Libraries\x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// XCHLH Signal Calculation Types ... +enum ENUM_X_XCHLH_SIGNAL_TYPES +{ + X_XCHLH_AVG_SIGNAL, + X_XCHLH_DELTA_SIGNAL, +}; + +// +// XCHLH Buffer Lines ... +enum ENUM_X_XCHLH_BUFFER_LINES +{ + X_XCHLH_LC_HH_LINE = 0, + X_XCHLH_LC_LL_LINE = 1, + X_XCHLH_MC_HH_LINE = 2, + X_XCHLH_MC_LL_LINE = 3, + X_XCHLH_SC_HH_LINE = 4, + X_XCHLH_SC_LL_LINE = 5, + X_XCHLH_SIGNAL_T_LINE = 6, + X_XCHLH_SIGNAL_B_LINE = 7, + X_XCHLH_HOT_STATE_LINE = 8, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// +input group "XCHLH Oscillator"; + +// +// Signal Calculations ... +input group "XCHLH Signal Calculations"; +input ENUM_X_XCHLH_SIGNAL_TYPES xCHLHSignalType = X_XCHLH_AVG_SIGNAL; // Signal Method + +// +// Common ... +input group "XCHLH Hot Areas"; +input bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol +input uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code +input color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color +input uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code +input color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +input group "XCHLH Long Cycle"; +input group "XCHLH LC Market"; +input int xCHLHLcLength = 288; // Length +input double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "XCHLH LC Style"; +input int xCHLHLcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style +input color xCHLHLcHHColor = clrAqua; // Highest High Color +input color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color +input group "XCHLH LC Drawings"; +input bool xCHLHLcDrawHH = true; // Draw Highest High +input bool xCHLHLcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +input group "XCHLH Medium Cycle"; +input group "XCHLH MC Market"; +input int xCHLHMcLength = 72; // Length +input double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "XCHLH MC Style"; +input int xCHLHMcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style +input color xCHLHMcHHColor = clrLime; // Highest High Color +input color xCHLHMcLLColor = clrRed; // Lowest Low Color +input group "XCHLH MC Drawings"; +input bool xCHLHMcDrawHH = true; // Draw Highest High +input bool xCHLHMcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +input group "XCHLH Short Cycle"; +input group "XCHLH SC Market"; +input int xCHLHScLength = 7; // Length +input double xCHLHScThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "XCHLH SC Style"; +input int xCHLHScDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style +input color xCHLHScHHColor = clrLightBlue; // Highest High Color +input color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color +input group "XCHLH SC Drawings"; +input bool xCHLHScDrawHH = true; // Draw Highest High +input bool xCHLHScDrawLL = true; // Draw Lowest Low + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHLHHandler = INVALID_HANDLE; +double xCHLHLcHHBuffer[]; +double xCHLHLcLLBuffer[]; +double xCHLHMcHHBuffer[]; +double xCHLHMcLLBuffer[]; +double xCHLHScHHBuffer[]; +double xCHLHScLLBuffer[]; +double xCHLHSignalTBuffer[]; +double xCHLHSignalBBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Init Oscillators ... +bool XCHLHInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHLH Handler ... + ArraySetAsSeries(xCHLHLcHHBuffer, true); + ArraySetAsSeries(xCHLHLcLLBuffer, true); + ArraySetAsSeries(xCHLHMcHHBuffer, true); + ArraySetAsSeries(xCHLHMcLLBuffer, true); + ArraySetAsSeries(xCHLHScHHBuffer, true); + ArraySetAsSeries(xCHLHScLLBuffer, true); + ArraySetAsSeries(xCHLHSignalTBuffer, true); + ArraySetAsSeries(xCHLHSignalBBuffer, true); + xCHLHHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchlh.oscillator", + // + // Inputs ... + // + // Signal Calculations ... + "", + xCHLHSignalType, + // + // Commons ... + "", + xCHLHDrawHotAreas, + xCHLHHotHHArrowCode, + xCHLHHotHHArrowColor, + xCHLHHotLLArrowCode, + xCHLHHotLLArrowColor, + // + // LC ... + "", + "", + xCHLHLcLength, + xCHLHLcThresholdInPips, + xCHLHLcHHMode, + xCHLHLcLLMode, + "", + xCHLHLcDrawWidth, + xCHLHLcDrawType, + xCHLHLcDrawStyle, + xCHLHLcHHColor, + xCHLHLcLLColor, + "", + xCHLHLcDrawHH, + xCHLHLcDrawLL, + // + // MC ... + "", + "", + xCHLHMcLength, + xCHLHMcThresholdInPips, + xCHLHMcHHMode, + xCHLHMcLLMode, + "", + xCHLHMcDrawWidth, + xCHLHMcDrawType, + xCHLHMcDrawStyle, + xCHLHMcHHColor, + xCHLHMcLLColor, + "", + xCHLHMcDrawHH, + xCHLHMcDrawLL, + // + // SC ... + "", + "", + xCHLHScLength, + xCHLHScThresholdInPips, + xCHLHScHHMode, + xCHLHScLLMode, + "", + xCHLHScDrawWidth, + xCHLHScDrawType, + xCHLHScDrawStyle, + xCHLHScHHColor, + xCHLHScLLColor, + "", + xCHLHScDrawHH, + xCHLHScDrawLL); + if (xCHLHHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHLH Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHLHReleaseHandlers() +{ + IndicatorRelease(xCHLHHandler); +} + +// +// Handle Reading Buffers ... +void XCHLHReadBuffers( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHLH LC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcHHBuffer); + + // + // XCHLH LC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcLLBuffer); + + // + // XCHLH MC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcHHBuffer); + + // + // XCHLH MC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcLLBuffer); + + // + // XCHLH SC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScHHBuffer); + + // + // XCHLH SC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScLLBuffer); + + // + // XCHLH Signal T Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SIGNAL_T_LINE, + 0, + xCHLHItemsPerTick, + xCHLHSignalTBuffer); + + // + // XCHLH Signal B Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SIGNAL_B_LINE, + 0, + xCHLHItemsPerTick, + xCHLHSignalBBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START Signal Related Conditions ... +// + +// +// XCHLH Long Conditions ... +bool XCHLHHasLongConditions( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isSignalBCrossedOverLCLL = XCHLHIsSignalBCrossedOverLCLL(1); + + // + result = + // + isSignalBCrossedOverLCLL + // + ; + + // + return result; +} + +// +// XCHLH Close Long Conditions ... +bool XCHLHHasLongCloseConditions( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) { + // + bool result = false; + + // + bool isSignalBCrossedOverSignalT = XCHLHIsSignalBCrossedOverSignalT(1); + + // + result = + // + isSignalBCrossedOverSignalT + // + ; + + // + return result; +} + +// +// XCHLH Short Conditions ... +bool XCHLHHasShortConditions( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isSignalBCrossedUnderSignalT = XCHLHIsSignalBCrossedUnderSignalT(1); + + // + result = + // + isSignalBCrossedUnderSignalT + // + ; + + // + return result; +} + +// +// XCHLH Close Short Conditions ... +bool XCHLHHasShortCloseConditions( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isSignalBCrossedUnderLCLL = XCHLHIsSignalBCrossedUnderLCLL(1); + + // + result = + // + isSignalBCrossedUnderLCLL + // + ; + + // + return result; +} + +// +// END Signal Related Conditions ... +// + +// +// START XCHLH Custom Functions ... +// + +// +// Check Signal B Crossed Over LC LL ... +bool XCHLHIsSignalBCrossedOverLCLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsCrossOver( + xCHLHSignalBBuffer, + xCHLHLcLLBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal B Over LC LL ... +bool XCHLHIsSignalBOverLCLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsOver( + xCHLHSignalBBuffer, + xCHLHLcLLBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal B Crossed Under LC LL ... +bool XCHLHIsSignalBCrossedUnderLCLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsCrossUnder( + xCHLHSignalBBuffer, + xCHLHLcLLBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal B Under LC LL ... +bool XCHLHIsSignalBUnderLCLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsUnder( + xCHLHSignalBBuffer, + xCHLHLcLLBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal B Crossed Over Signal T ... +bool XCHLHIsSignalBCrossedOverSignalT( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsCrossOver( + xCHLHSignalBBuffer, + xCHLHSignalTBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal B Over Signal T ... +bool XCHLHIsSignalBOverSignalT( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsOver( + xCHLHSignalBBuffer, + xCHLHSignalTBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal B Crossed Under Signal T ... +bool XCHLHIsSignalBCrossedUnderSignalT( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsCrossUnder( + xCHLHSignalBBuffer, + xCHLHSignalTBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal B Under Signal T ... +bool XCHLHIsSignalBUnderSignalT( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 2)) + { + return result; + } + + // + result = IsUnder( + xCHLHSignalBBuffer, + xCHLHSignalTBuffer, + bar_index); + + // + return result; +} + +// +// Check LC and MC has Same HH ... +bool XCHLHIsLCMCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and MC has Same LL ... +bool XCHLHIsLCMCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and SC has Same HH ... +bool XCHLHIsLCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check LC and SC has Same LL ... +bool XCHLHIsLCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same HH ... +bool XCHLHIsMCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same LL ... +bool XCHLHIsMCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check Is Same Highest Highs ... +bool XCHLHIsSameHHs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check Is Same Lowest Lows ... +bool XCHLHIsSameLLs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check and Validate Buffer Sizes ... +bool XCHLHIsValidBufferSizes( + int size // Specified Min Size +) +{ + // + bool result = false; + + // + result = + // + ArraySize(xCHLHLcHHBuffer) > size && + ArraySize(xCHLHLcLLBuffer) > size && + // + ArraySize(xCHLHMcHHBuffer) > size && + ArraySize(xCHLHMcLLBuffer) > size && + // + ArraySize(xCHLHScHHBuffer) > size && + ArraySize(xCHLHScLLBuffer) > size; + + // + return result; +} + +// +// END XCHLH Custom Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xchma.oscillator.helper.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xchma.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..b028bb9 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xchma.oscillator.helper.lib.mq5 @@ -0,0 +1,1535 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHMA Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "..\Libraries\x-saherelm.log.lib.mq5" +#include "..\Libraries\x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XCHMA Cycles ... +enum ENUM_XCHMA_CYCLES +{ + X_XCHMA_CYCLE_LONG, + X_XCHMA_CYCLE_MEDIUM, + X_XCHMA_CYCLE_SHORT, +}; + +// +// XCHMA Oscillator Hot State Presentation ... +enum ENUM_XCHMA_HOT_STATES +{ + X_XCHMA_HOT_BULLISH = 1, + X_XCHMA_HOT_NEUTURAL = 0, + X_XCHMA_HOT_BEARISH = -1, +}; + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; + +// +// XCHMA Oscillator Buffer Lines ... +enum ENUM_X_XCHMA_BUFFER_LINES +{ + X_XCHMA_LC_FAST_LINE = 0, + X_XCHMA_LC_SLOW_LINE = 1, + X_XCHMA_LC_STATE_LINE = 6, + X_XCHMA_MC_FAST_LINE = 2, + X_XCHMA_MC_SLOW_LINE = 3, + X_XCHMA_MC_STATE_LINE = 7, + X_XCHMA_SC_FAST_LINE = 4, + X_XCHMA_SC_SLOW_LINE = 5, + X_XCHMA_SC_STATE_LINE = 8, + X_XCHMA_HOT_STATE_LINE = 9, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +input group "XCHMA Oscillator"; + +// +// Commons ... +input group "XCHMA Hot Areas"; +input bool xCHMADrawHotAreas = false; // Draw Hot Areas Symbol; +input uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code; +input color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color; +input uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code; +input color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color; + +// +// LC Inputs ... +input group "XCHMA Long Cycle"; +input group "XCHMA LC Market"; +input int xCHMALcFastLength = 288; // Fast Length +input int xCHMALcSlowLength = 576; // Slow Length +input ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To +input group "XCHMA LC Style"; +input int xCHMALcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style +input color xCHMALcFastColor = clrAqua; // Fast Color +input color xCHMALcSlowColor = clrFuchsia; // Slow Color +input group "XCHMA LC Drawings"; +input bool xCHMALcDrawFast = true; // Draw Fast +input bool xCHMALcDrawSlow = true; // Draw Slow +input bool xCHMALcDrawCrosses = false; // Draw Cross Lines + +// +// MC Inputs ... +input group "XCHMA Medium Cycle"; +input group "XCHMA MC Market"; +input int xCHMAMcFastLength = 72; // Fast Length +input int xCHMAMcSlowLength = 144; // Slow Length +input ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To +input group "XCHMA MC Style"; +input int xCHMAMcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style +input color xCHMAMcFastColor = clrLime; // Fast Color +input color xCHMAMcSlowColor = clrRed; // Slow Color +input group "XCHMA MC Drawings"; +input bool xCHMAMcDrawFast = true; // Draw Fast +input bool xCHMAMcDrawSlow = true; // Draw Slow +input bool xCHMAMcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +input group "XCHMA Short Cycle"; +input group "XCHMA SC Market"; +input int xCHMAScFastLength = 7; // Fast Length +input int xCHMAScSlowLength = 14; // Slow Length +input ENUM_MA_METHOD xCHMAScMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To +input group "XCHMA SC Style"; +input int xCHMAScDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style +input color xCHMAScFastColor = clrLightBlue; // Fast Color +input color xCHMAScSlowColor = clrLightSalmon; // Slow Color +input group "XCHMA SC Drawings"; +input bool xCHMAScDrawFast = true; // Draw Fast +input bool xCHMAScDrawSlow = true; // Draw Slow +input bool xCHMAScDrawCrosses = false; // Draw Cross Lines + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHMAHandler = INVALID_HANDLE; +double xCHMALcFastBuffer[]; +double xCHMALcSlowBuffer[]; +double xCHMAMcFastBuffer[]; +double xCHMAMcSlowBuffer[]; +double xCHMAScFastBuffer[]; +double xCHMAScSlowBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Init Oscillators ... +bool XCHMAInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHMA Handler ... + ArraySetAsSeries(xCHMALcFastBuffer, true); + ArraySetAsSeries(xCHMALcSlowBuffer, true); + ArraySetAsSeries(xCHMAMcFastBuffer, true); + ArraySetAsSeries(xCHMAMcSlowBuffer, true); + ArraySetAsSeries(xCHMAScFastBuffer, true); + ArraySetAsSeries(xCHMAScSlowBuffer, true); + xCHMAHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchma.oscillator", + // + // Inputs ... + "", + xCHMADrawHotAreas, + xCHMAHotBullishArrowCode, + xCHMAHotBullishArrowColor, + xCHMAHotBearishArrowCode, + xCHMAHotBearishArrowColor, + // + // Long Cycle ... + "", + "", + xCHMALcFastLength, + xCHMALcSlowLength, + xCHMALcMethod, + xCHMALcAppliedTo, + "", + xCHMALcDrawWidth, + xCHMALcDrawType, + xCHMALcDrawStyle, + xCHMALcFastColor, + xCHMALcSlowColor, + "", + xCHMALcDrawFast, + xCHMALcDrawSlow, + xCHMALcDrawCrosses, + // + // Medium Cycle ... + "", + "", + xCHMAMcFastLength, + xCHMAMcSlowLength, + xCHMAMcMethod, + xCHMAMcAppliedTo, + "", + xCHMAMcDrawWidth, + xCHMAMcDrawType, + xCHMAMcDrawStyle, + xCHMAMcFastColor, + xCHMAMcSlowColor, + "", + xCHMAMcDrawFast, + xCHMAMcDrawSlow, + xCHMAMcDrawCrosses, + // + // Short Cycle ... + "", + "", + xCHMAScFastLength, + xCHMAScSlowLength, + xCHMAScMethod, + xCHMAScAppliedTo, + "", + xCHMAScDrawWidth, + xCHMAScDrawType, + xCHMAScDrawStyle, + xCHMAScFastColor, + xCHMAScSlowColor, + "", + xCHMAScDrawFast, + xCHMAScDrawSlow, + xCHMAScDrawCrosses); + if (xCHMAHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHMA Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHMAReleaseHandlers() +{ + IndicatorRelease(xCHMAHandler); +} + +// +// Handle Reading Buffers ... +void XCHMAReadBuffers( + int xCHMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHMA Long Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcSlowBuffer); + + // + // XCHMA Medium Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcSlowBuffer); + + // + // XCHMA Short Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScSlowBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START Signal Related Conditions ... +// + +// +// XCHMA Long Conditions ... +bool XCHMAHasLongConditions( + int xCHMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isSCVale = XCHMAIsSCVale(); + bool isSCFastOverSlow = XCHMAIsSCFastOverSlow(1); + bool isScFastCrossedOver = XCHMAIsSCFastCrossedOverSlow(1); + + // + bool isMcVale = XCHMAIsMCVale(); + bool isMCFastOverSlow = XCHMAIsMCFastOverSlow(1); + bool isMcFastCrossedOver = XCHMAIsMCFastCrossedOverSlow(1); + + // + bool isLcVale = XCHMAIsLCVale(); + bool isLCFastOverSlow = XCHMAIsLCFastOverSlow(1); + bool isLcFastCrossedOver = XCHMAIsLCFastCrossedOverSlow(1); + + // + bool scHasSignal = + // isSCVale && + isScFastCrossedOver && + ( + // + isMCFastOverSlow || + isMcFastCrossedOver + // + ) && + ( + // + isLCFastOverSlow || + isLcFastCrossedOver + // + ); + + // + bool mcHasSignal = + // isMcVale && + isMcFastCrossedOver && + ( + // + isSCFastOverSlow || + isScFastCrossedOver + // + ) && + ( + // + isLCFastOverSlow || + isLcFastCrossedOver + // + ); + ; + + // + bool lcHasSignal = + // isLcVale && + isLcFastCrossedOver && + ( + // + isSCFastOverSlow || + isScFastCrossedOver + // + ) && + ( + // + isMCFastOverSlow || + isMcFastCrossedOver + // + ); + + // + // Signal ... + bool hasSignal = + // + scHasSignal + // + || + // + mcHasSignal + // + || + // + lcHasSignal + // + ; + + // + result = + // + hasSignal + // + ; + + // + return result; +} + +// +// XCHMA Short Conditions ... +bool XCHMAHasShortConditions( + int xCHMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool scHasSignal = false; // XCHMAIsSCPeak(); + bool mcHasSignal = false; // XCHMAIsMCPeak(); + bool lcHasSignal = false; // XCHMAIsLCPeak(); + + // + // Signal ... + bool hasSignal = + // + scHasSignal + // + || + // + mcHasSignal + // + || + // + lcHasSignal + // + ; + + // + // Very Strong Signal ... + bool hasVeryStrongSignal = + // + scHasSignal + // + && + // + mcHasSignal + // + && + // + lcHasSignal + // + ; + + // + // Strong Signal ... + bool hasStrongSignal = + // + !hasVeryStrongSignal + // + && + // + ( + // + // SC and MC Provide Signal ... + ( + // + scHasSignal + // + && + // + mcHasSignal + // + ) + // + || + // + // MC and LC Provide Signal ... + ( + // + mcHasSignal + // + && + // + lcHasSignal + // + ) + // + || + // + // SC and LC Provide Signal ... + ( + // + scHasSignal + // + && + // + lcHasSignal + // + ) + // + ) + // + ; + + // + // Has Regular Signal ... + bool hasRegularSignal = + hasSignal && !hasStrongSignal && !hasVeryStrongSignal; + + // + result = + // + lcHasSignal + // + || + // + mcHasSignal + // + || + // + scHasSignal + // + ; + + // + return result; +} + +// +// END Signal Related Conditions ... +// + +// +// START XCHMA Custom Functions ... +// + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMax( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // SC Fast ... + result = MathMax( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMax( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMax( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMax( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMax( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMax( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMin( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = xCHMAScFastBuffer[bar_index]; + + // + // SC Fast ... + result = MathMin( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMin( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMin( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMin( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMin( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMin( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Long Cycle ... +// + +// +// Check LC is Peak ... +bool XCHMAIsLCPeak() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 30, + 9, + xCHMALcFastBuffer); + + // + bool isDecreasing = IsDecreasing( + 9, + 1, + xCHMALcFastBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check LC is Vale ... +bool XCHMAIsLCVale() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 9, + 1, + xCHMALcFastBuffer); + + // + bool isDecreasing = IsDecreasing( + 30, + 9, + xCHMALcFastBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check LC Fast Crossed Over Slow ... +bool XCHMAIsLCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Over Slow ... +bool XCHMAIsLCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Crossed Under Slow ... +bool XCHMAIsLCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Under Slow ... +bool XCHMAIsLCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Medium Cycle ... +// + +// +// Check MC is Peak ... +bool XCHMAIsMCPeak() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 20, + 6, + xCHMAMcFastBuffer); + + // + bool isDecreasing = IsDecreasing( + 6, + 1, + xCHMAMcFastBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check MC is Vale ... +bool XCHMAIsMCVale() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 6, + 1, + xCHMAMcFastBuffer); + + // + bool isDecreasing = IsDecreasing( + 20, + 6, + xCHMAMcFastBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check MC Fast Crossed Over Slow ... +bool XCHMAIsMCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Over Slow ... +bool XCHMAIsMCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Crossed Under Slow ... +bool XCHMAIsMCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Under Slow ... +bool XCHMAIsMCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Short Cycle ... +// + +// +// Check SC is Peak ... +bool XCHMAIsSCPeak() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 10, + 3, + xCHMAScFastBuffer); + + // + bool isDecreasing = IsDecreasing( + 3, + 1, + xCHMAScFastBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check SC is Vale ... +bool XCHMAIsSCVale() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 3, + 1, + xCHMAScFastBuffer); + + // + bool isDecreasing = IsDecreasing( + 10, + 3, + xCHMAScFastBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check SC Fast Crossed Over Slow ... +bool XCHMAIsSCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Over Slow ... +bool XCHMAIsSCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Crossed Under Slow ... +bool XCHMAIsSCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Under Slow ... +bool XCHMAIsSCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Utility Functions ... +// + +// +// Check all Buffers has valid Size ... +bool XCHMAIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xCHMALcFastBuffer) < size || + ArraySize(xCHMALcSlowBuffer) < size || + // + ArraySize(xCHMAMcFastBuffer) < size || + ArraySize(xCHMAMcSlowBuffer) < size || + // + ArraySize(xCHMAScFastBuffer) < size || + ArraySize(xCHMAScSlowBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Get Cycle Fast Length ... +int XCHMAGetCycleFastLength( + ENUM_XCHMA_CYCLES cycle // Specified Cycle +) +{ + // + int result = 0; + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = xCHMALcFastLength; + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = xCHMAMcFastLength; + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = xCHMAScFastLength; + break; + } + + // + return result; +} + +// +// Get Cycle Slow Length ... +int XCHMAGetCycleSlowLength( + ENUM_XCHMA_CYCLES cycle // Specified Cycle +) +{ + // + int result = 0; + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = xCHMALcSlowLength; + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = xCHMAMcSlowLength; + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = xCHMAScSlowLength; + break; + } + + // + return result; +} + +// +// Retrieve Cycle Fast Buffer ... +void XCHMAGetCycleFastBuffer( + ENUM_XCHMA_CYCLES cycle, // Specified Cycle + double &result[] // Specified Result buffer to Hold Values ... +) +{ + // + CleanBuffer(result); + ArraySetAsSeries(result, true); + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + // + ArrayCopy( + result, + xCHMALcFastBuffer); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + // + ArrayCopy( + result, + xCHMAMcFastBuffer); + break; + + // + case X_XCHMA_CYCLE_SHORT: + // + ArrayCopy( + result, + xCHMAScFastBuffer); + break; + } +} + +// +// Retrieve Cycle Fast Buffer ... +void XCHMAGetCycleSlowBuffer( + ENUM_XCHMA_CYCLES cycle, // Specified Cycle + double &result[] // Specified Result buffer to Hold Values ... +) +{ + // + CleanBuffer(result); + ArraySetAsSeries(result, true); + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + // + ArrayCopy( + result, + xCHMALcSlowBuffer); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + // + ArrayCopy( + result, + xCHMAMcSlowBuffer); + break; + + // + case X_XCHMA_CYCLE_SHORT: + // + ArrayCopy( + result, + xCHMAScSlowBuffer); + break; + } +} + +// +// Check a Cycle is vale ... +bool XCHMAIsCycleVale( + ENUM_XCHMA_CYCLES cycle // Specified Cycle +) +{ + // + bool result = false; + + // + // Retrieve Length ... + int length = XCHMAGetCycleFastLength(cycle); + int halfLength = length / 2; + int thirdLength = length / 3; + int qLength = length / 4; + qLength = qLength < 3 ? 3 : qLength > 7 ? 7 + : qLength; + + // + double buffer[]; + XCHMAGetCycleFastBuffer( + cycle, + buffer); + + // + bool isIncreasing = IsIncreasing( + qLength, + 1, + buffer); + + // + bool isDecreasing = IsDecreasing( + thirdLength, + qLength, + buffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check a Cycle is peak ... +bool XCHMAIsCyclePeak( + ENUM_XCHMA_CYCLES cycle // Specified Cycle +) +{ + // + bool result = false; + + // + // Retrieve Length ... + int length = XCHMAGetCycleFastLength(cycle); + int halfLength = length / 2; + int thirdLength = length / 3; + int qLength = length / 4; + qLength = qLength < 3 ? 3 : qLength > 7 ? 7 + : qLength; + + // + double buffer[]; + XCHMAGetCycleFastBuffer( + cycle, + buffer); + + // + bool isIncreasing = IsIncreasing( + thirdLength, + qLength, + buffer); + + // + bool isDecreasing = IsDecreasing( + qLength, + 1, + buffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} +// +// END XCHMA Custom Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xobd.oscillator.helper.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xobd.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..75543de --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xobd.oscillator.helper.lib.mq5 @@ -0,0 +1,417 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XOBD Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "..\Libraries\x-saherelm.log.lib.mq5" +#include "..\Libraries\x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XOBD Oscillator Buffer Lines ... +enum ENUM_X_XOBD_BUFFER_LINES +{ + X_XOBD_SWING_HIGH_LINE = 0, + X_XOBD_SWING_LOW_LINE = 1, + X_XOBD_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +input group "XOBD Oscillator"; +input int xOBDLength = 72; // Market Length + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xOBDHandler = INVALID_HANDLE; +double xOBDSwingHighBuffer[]; +double xOBDSwingLowBuffer[]; +double xOBDSignalBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Init Oscillators ... +bool XOBDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XOBD Handler ... + ArraySetAsSeries(xOBDSwingHighBuffer, true); + ArraySetAsSeries(xOBDSwingLowBuffer, true); + ArraySetAsSeries(xOBDSignalBuffer, true); + xOBDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xobd.oscillator", + // + // Inputs ... + xOBDLength + // + ); + if (xOBDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XOBD Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XOBDReleaseHandlers() +{ + IndicatorRelease(xOBDHandler); +} + +// +// Handle Reading Buffers ... +void XOBDReadBuffers( + int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // XOBD Swing High ... + CopyBuffer( + xOBDHandler, + X_XOBD_SWING_HIGH_LINE, + 0, + xOBDItemsPerTick, + xOBDSwingHighBuffer); + + // + // XOBD Swing Low ... + CopyBuffer( + xOBDHandler, + X_XOBD_SWING_LOW_LINE, + 0, + xOBDItemsPerTick, + xOBDSwingLowBuffer); + + // + // XOBD Signal ... + CopyBuffer( + xOBDHandler, + X_XOBD_SIGNAL_LINE, + 0, + xOBDItemsPerTick, + xOBDSignalBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START Signal Related Conditions ... +// + +// +// XOBD Long Conditions ... +bool XOBDHasLongConditions( + int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isVale = XOBDIsVale(); + bool isInPeak = IsInPeak( + xOBDItemsPerTick, + xOBDSignalBuffer); + + // + result = + // + isVale + // + && + // + !isInPeak + // + ; + + // + return result; +} + +// +// XOBD Short Conditions ... +bool XOBDHasShortConditions( + int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + return result; +} + +// +// END Signal Related Conditions ... +// + +// +// START XOBD Custom Functions ... +// + +// +// Check all Buffers has valid Size ... +bool XOBDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xOBDSignalBuffer) < size || + ArraySize(xOBDSwingLowBuffer) < size || + ArraySize(xOBDSwingHighBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Check SC is Peak ... +bool XOBDIsPeak() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 10, + 3, + xOBDSignalBuffer); + + // + bool isDecreasing = IsDecreasing( + 3, + 1, + xOBDSignalBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check SC is Vale ... +bool XOBDIsVale() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 5, + 1, + xOBDSignalBuffer); + + // + bool isDecreasing = IsDecreasing( + 20, + 5, + xOBDSignalBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check Signal Crossed Over Swing High ... +bool XOBDIsSignalCrossedOverSwingHigh( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = IsCrossOver( + xOBDSignalBuffer, + xOBDSwingHighBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal Over Swing High ... +bool XOBDIsSignalOverSwingHigh( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = IsOver( + xOBDSignalBuffer, + xOBDSwingHighBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal Crossed Under Swing High ... +bool XOBDIsSignalCrossedUnderSwingHigh( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = IsCrossUnder( + xOBDSignalBuffer, + xOBDSwingHighBuffer, + bar_index); + + // + return result; +} + +// +// Check Signal Under Swing High ... +bool XOBDIsSignalUnderSwingHigh( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = IsUnder( + xOBDSignalBuffer, + xOBDSwingHighBuffer, + bar_index); + + // + return result; +} + +// +// END XOBD Custom Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xrsi.oscillator.helper.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xrsi.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..c1eb3f2 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xrsi.oscillator.helper.lib.mq5 @@ -0,0 +1,424 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XRSI Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "..\Libraries\x-saherelm.log.lib.mq5" +#include "..\Libraries\x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XRSI Oscillator Buffer Lines ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +input group "XRSI Oscillator"; + +// +input group "XRSI Market"; +input int xRSILength = 14; // Market Length +input ENUM_APPLIED_PRICE xRSIAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "XRSI Short Entry"; +input double xRSIShortEntryValue = 70; // Short Entry Level +input color xRSIShortEntryColor = clrRed; // Short Entry Level Color +input ENUM_LINE_STYLE xRSIShortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// +input group "XRSI Short Exit"; +input double xRSIShortExitValue = 40; // Short Exit Level +input color xRSIShortExitColor = clrFuchsia; // Short Exit Level Color +input ENUM_LINE_STYLE xRSIShortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +input group "XRSI Long Entry"; +input double xRSILongEntryValue = 30; // Long Entry Level +input color xRSILongEntryColor = clrGreen; // Long Entry Level Color +input ENUM_LINE_STYLE xRSILongEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// +input group "XRSI Long Exit"; +input double xRSILongExitValue = 60; // Long Exit Level +input color xRSILongExitColor = clrAqua; // Long Exit Level Color +input ENUM_LINE_STYLE xRSILongExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xRSIHandler = INVALID_HANDLE; +double xRSIBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Init Oscillators ... +bool XRSIInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XRSI Handler ... + ArraySetAsSeries(xRSIBuffer, true); + xRSIHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xrsi.oscillator", + // + // Inputs ... + // + // Market ... + "", + xRSILength, + xRSIAppliedTo, + // + // Short Entry ... + "", + xRSIShortEntryValue, + xRSIShortEntryColor, + xRSIShortEntryLineStyle, + // + // Short Exit ... + "", + xRSIShortExitValue, + xRSIShortExitColor, + xRSIShortExitLineStyle, + // + // Long Entry ... + "", + xRSILongEntryValue, + xRSILongEntryColor, + xRSILongEntryLineStyle, + // + // Long Exit ... + "", + xRSILongExitValue, + xRSILongExitColor, + xRSILongExitLineStyle + // + ); + if (xRSIHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XRSI Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XRSIReleaseHandlers() +{ + IndicatorRelease(xRSIHandler); +} + +// +// Handle Reading Buffers ... +void XRSIReadBuffers( + int xRSIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XRSI Signal ... + CopyBuffer( + xRSIHandler, + 0, + 0, + xRSIItemsPerTick, + xRSIBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START Signal Related Conditions ... +// + +// +// XRSI Long Conditions ... +bool XRSIHasLongConditions( + int xRSIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + return result; +} + +// +// XRSI Short Conditions ... +bool XRSIHasShortConditions( + int xRSIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + return result; +} + +// +// END Signal Related Conditions ... +// + +// +// START XRSI Custom Functions ... +// + +// +// Check SC is Peak ... +bool XRSIIsPeak() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 11, + 3, + xRSIBuffer); + + // + bool isDecreasing = IsDecreasing( + 3, + 1, + xRSIBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check SC is Vale ... +bool XRSIIsVale() +{ + // + bool result = false; + + // + bool isIncreasing = IsIncreasing( + 3, + 1, + xRSIBuffer); + + // + bool isDecreasing = IsDecreasing( + 11, + 3, + xRSIBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// RSI Value GO Up from Long Entry ... +bool XRSIIsCrossedOverLongEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongEntryValue && + xRSIBuffer[bar_index + 2] <= xRSILongEntryValue; + + // + return result; +} + +// +// RSI Value GO Up from Long Exit ... +bool XRSIIsCrossedOverLongExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongExitValue && + xRSIBuffer[bar_index + 2] <= xRSILongExitValue; + + // + return result; +} + +// +// RSI Value Go Down Short Entry ... +bool XRSIIsCrossedUnderShortEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortEntryValue && + xRSIBuffer[bar_index + 2] >= xRSIShortEntryValue; + + // + return result; +} + +// +// RSI Value Go Down Short Exit ... +bool XRSIIsCrossedUnderShortExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortExitValue && + xRSIBuffer[bar_index + 2] >= xRSIShortExitValue; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XRSIIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xRSIBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XRSI Custom Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtd.oscillator.helper.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtd.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..ba6d60b --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtd.oscillator.helper.lib.mq5 @@ -0,0 +1,917 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTD Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "..\Libraries\x-saherelm.log.lib.mq5" +#include "..\Libraries\x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; + +// +// XTD Oscillator Buffer Lines ... +enum ENUM_X_XTD_BUFFER_LINES +{ + X_XTD_BULLISH_POWER_LINE = 0, + X_XTD_BEARISH_POWER_LINE = 1, + X_XTD_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +input group "XTD Oscillator"; +input int xTDLength = 14; // Market Length +input bool xTDDrawCrosses = false; // Draw Cross Arrows +input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code +input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color +input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code +input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTDHandler = INVALID_HANDLE; +double xTDBullishBuffer[]; +double xTDBearishBuffer[]; +double xTDSignalBuffer[]; +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Init Oscillators ... +bool XTDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTD Handler ... + ArraySetAsSeries(xTDBullishBuffer, true); + ArraySetAsSeries(xTDBearishBuffer, true); + ArraySetAsSeries(xTDSignalBuffer, true); + xTDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtd.oscillator", + // + // Inputs ... + xTDLength, + xTDDrawCrosses, + xTDBullishArrowCode, + xTDBullishArrowColor, + xTDBearishArrowCode, + xTDBearishArrowColor); + if (xTDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTD Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XTDReleaseHandlers() +{ + IndicatorRelease(xTDHandler); +} + +// +// Handle Reading Buffers ... +void XTDReadBuffers( + int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BULLISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBullishBuffer); + + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BEARISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBearishBuffer); + + // + // XTD Signal Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_SIGNAL_LINE, + 0, + xTDItemsPerTick, + xTDSignalBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START Signal Related Conditions ... +// + +// +// XTD Long Conditions ... +bool XTDHasLongConditions( + int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isVale = XTDIsSignalVale(); + + // + bool isInPeak = IsInPeak( + 15, + xTDSignalBuffer); + + // + bool isSharpChanged = IsSharpChanged( + 15, + 1, + xTDSignalBuffer); + + // + double entry = GetEntry(X_SIGNAL_LONG); + double maxPrice = GetHighestHigh( + 7, + 0); + double minPrice = GetLowestLow( + 7, + 0); + double priceDelta = maxPrice - minPrice; + double priceStep = priceDelta / 7; + + // + bool isPricePassed = + entry < maxPrice && + maxPrice - entry < (priceDelta / 4) * 3; + + // + result = + // + isVale + // + && + // + !isInPeak + // + && + // + !isSharpChanged + // + && + // + isPricePassed + // + ; + + // + return result; +} + +// +// XTD Short Conditions ... +bool XTDHasShortConditions( + int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isPeak = XTDIsSignalPeak(); + + // + bool isInVale = IsInVale( + 15, + xTDSignalBuffer); + + // + bool isSharpChanged = IsSharpChanged( + 15, + 1, + xTDSignalBuffer); + + // + double entry = GetEntry(X_SIGNAL_SHORT); + double maxPrice = GetHighestHigh( + 7, + 0); + double minPrice = GetLowestLow( + 7, + 0); + double priceDelta = maxPrice - minPrice; + double priceStep = priceDelta / 7; + + // + bool isPricePassed = + entry > minPrice && + minPrice + entry > (priceDelta / 4); + + // + result = + // + isPeak + // + && + // + !isInVale + // + && + // + !isSharpChanged + // + && + // + isPricePassed + // + ; + + // + return result; +} + +// +// END Signal Related Conditions ... +// + +// +// START XTD Custom Functions ... +// + +// +// Check Signal Vale ... +bool XTDIsSignalVale() +{ + // + bool result = false; + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + 3, + 1, + xTDSignalBuffer); + + // + // Must Increasing ... + bool isDecreasing = IsDecreasing( + 15, + 3, + xTDSignalBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsSignalPeak() +{ + // + bool result = false; + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + 15, + 3, + xTDSignalBuffer); + + // + // Must Increasing ... + bool isDecreasing = IsDecreasing( + 3, + 1, + xTDSignalBuffer); + + // + // Generating Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Check Signal Peak ... + +// +// Check Bullish Crossed Over Bearish ... +bool XTDIsBullCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Over Bearish ... +bool XTDIsBullOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Crossed Under Bearish ... +bool XTDIsBullCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Under Bearish ... +bool XTDIsBullUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Over Bearish ... +bool XTDIsSignalCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Over Bearish ... +bool XTDIsSignalOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Under Bearish ... +bool XTDIsSignalCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Under Bearish ... +bool XTDIsSignalUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDSignalBuffer) < size) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Count Signal Crossed Over Bear ... +int XTDCountSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Signal Crossed Under Bear ... +int XTDCountSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Over Bear ... +int XTDCountBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Under Bear ... +int XTDCountBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Over Bear ... +int XTDFindLastSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Onder Bear ... +int XTDFindLastSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Over Bear ... +int XTDFindLastBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Under Bear ... +int XTDFindLastBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// END XTD Custom Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.indicators.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.indicators.lib.mq5 new file mode 100644 index 0000000..7e3ec99 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.indicators.lib.mq5 @@ -0,0 +1,2316 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTEST Signal Provider Indicators Library +// ---------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Include Provider Inputs ... +#include "x-saherelm.xtest.provider.inputs.lib.mq5"; + +// +// START Define Enums ... +// + +// +// Represent Signals Methods ... +enum ENUM_X_SIGNAL_METHODS +{ + X_SIGNAL_METHOD_1, + X_SIGNAL_METHOD_2, + X_SIGNAL_METHOD_3, +}; + +// +// Represent Market Conditions ... +struct X_TEST_MARKET_CONDITIONS +{ + // + // XTM ... + bool isXTMPeak; + bool isXTMVale; + + // + // XTD ... + bool isXTDSignalPeak; + bool isXTDSignalVale; + bool isXTDSignalOverBear; + bool isXTDSignalUnderBear; + bool isXTDSignalCrossedOverBear; + bool isXTDSignalCrossedUnderBear; + + // + // XRSI ... + bool isXRSIPeak; + bool isXRSIVale; + bool isXRSICrossedOverLongExit; + bool isXRSICrossedOverLongEntry; + bool isXRSICrossedUnderShortExit; + bool isXRSICrossedUnderShortEntry; + + // + // XOBD ... + bool isXOBDPeak; + bool isXOBDVale; + bool isXOBDSignalOverSwingHigh; + bool isXOBDSignalUnderSwingHigh; + bool isXOBDSignalCrossedOverSwingHigh; + bool isXOBDSignalCrossedUnderSwingHigh; + + // + // XCHLH ... + // + bool isXCHLHSignalBOverSignalT; + bool isXCHLHSignalBUnderSignalT; + bool isXCHLHSignalBCrossedOverSignalT; + bool isXCHLHSignalBCrossedUnderSignalT; + // + bool isXCHLHSignalBOverLCLL; + bool isXCHLHSignalBUnderLCLL; + bool isXCHLHSignalBCrossedOverLCLL; + bool isXCHLHSignalBCrossedUnderLCLL; + // + bool isXCHLHSCMCHHSame; + bool isXCHLHSCMCLLSame; + // + bool isXCHLHSCLCHHSame; + bool isXCHLHSCLCLLSame; + // + bool isXCHLHMCLCHHSame; + bool isXCHLHMCLCLLSame; + + // + // XCHMA ... + // + bool isXCHMASCPeak; + bool isXCHMASCVale; + bool isXCHMASCFastOverSlow; + bool isXCHMASCFastUnderSlow; + bool isXCHMASCFastCrossedOverSlow; + bool isXCHMASCFastCrossedUnderSlow; + // + bool isXCHMAMCPeak; + bool isXCHMAMCVale; + bool isXCHMAMCFastOverSlow; + bool isXCHMAMCFastUnderSlow; + bool isXCHMAMCFastCrossedOverSlow; + bool isXCHMAMCFastCrossedUnderSlow; + // + bool isXCHMALCPeak; + bool isXCHMALCVale; + bool isXCHMALCFastOverSlow; + bool isXCHMALCFastUnderSlow; + bool isXCHMALCFastCrossedOverSlow; + bool isXCHMALCFastCrossedUnderSlow; +}; + +// +// END Define Enums ... +// + +// +// Imports all Indicators Helper here ... +input group "XTEST Provider Indicators"; +// +#include "x-saherelm.xtm.indicator.helper.lib.mq5"; +#include "x-saherelm.xtd.oscillator.helper.lib.mq5"; +#include "x-saherelm.xrsi.oscillator.helper.lib.mq5"; +#include "x-saherelm.xobd.oscillator.helper.lib.mq5"; +#include "x-saherelm.xchlh.oscillator.helper.lib.mq5"; +#include "x-saherelm.xchma.oscillator.helper.lib.mq5"; + +// +int xTESTMaxLengthOfInputs = 0; +int xTESTCalculatedBars = 0; + +// +// Here we Define some Global Market Variables to Analyse MArket Conditions +// using them at each time ... +X_TEST_MARKET_CONDITIONS conditions = {}; + +// +// Init Indicators ... +bool XTESTInitIndicators() +{ + // + bool result = false; + + // + // Check and Calculate Max Length in Inputs ... + // + + // + // XTM ... + xTESTMaxLengthOfInputs = MathMax( + xTMMaPeriod, + xTESTNumberOfItemsPerTick); + + // + // XTD ... + xTESTMaxLengthOfInputs = MathMax( + xTDLength, + xTESTMaxLengthOfInputs); + + // + // XRSI ... + xTESTMaxLengthOfInputs = MathMax( + xRSILength, + xTESTMaxLengthOfInputs); + + // + // XOBD ... + xTESTMaxLengthOfInputs = MathMax( + xOBDLength, + xTESTMaxLengthOfInputs); + + // + // XCHLH ... + xTESTMaxLengthOfInputs = MathMax( + xCHLHLcLength, + xTESTMaxLengthOfInputs); + xTESTMaxLengthOfInputs = MathMax( + xCHLHMcLength, + xTESTMaxLengthOfInputs); + xTESTMaxLengthOfInputs = MathMax( + xCHLHScLength, + xTESTMaxLengthOfInputs); + + // + // XCHMA ... + xTESTMaxLengthOfInputs = MathMax( + xCHMAScFastLength, + xTESTMaxLengthOfInputs); + xTESTMaxLengthOfInputs = MathMax( + xCHMAScSlowLength, + xTESTMaxLengthOfInputs); + xTESTMaxLengthOfInputs = MathMax( + xCHMAMcFastLength, + xTESTMaxLengthOfInputs); + xTESTMaxLengthOfInputs = MathMax( + xCHMAMcSlowLength, + xTESTMaxLengthOfInputs); + xTESTMaxLengthOfInputs = MathMax( + xCHMALcFastLength, + xTESTMaxLengthOfInputs); + xTESTMaxLengthOfInputs = MathMax( + xCHMALcSlowLength, + xTESTMaxLengthOfInputs); + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Init ... + result = XTMInitHandlers(); + if (!result) + { + return result; + } + + // + // XTD Init ... + result = XTDInitHandlers(); + if (!result) + { + return result; + } + + // + // XRSI Init ... + result = XRSIInitHandlers(); + if (!result) + { + return result; + } + + // + // XOBD Init ... + result = XOBDInitHandlers(); + if (!result) + { + return result; + } + + // + // XCLH Init ... + result = XCHLHInitHandlers(); + if (!result) + { + return result; + } + + // + // XCHMA Init ... + result = XCHMAInitHandlers(); + if (!result) + { + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XTESTReleaseIndicators() +{ + // + // Release Handlers ... + XTMReleaseHandlers(); + XTDReleaseHandlers(); + XRSIReleaseHandlers(); + XOBDReleaseHandlers(); + XCHMAReleaseHandlers(); + XCHLHReleaseHandlers(); +} + +// +// Handle Reading Buffers ... +void XTESTHandleReadingBuffers() +{ + // + // Reading Calculated Bars for a Simple Handler ... + xTESTCalculatedBars = BarsCalculated(xTMHandler); + + // + // Read Indicators Buffers ... + XTMReadBuffers(xTESTNumberOfItemsPerTick); + XTDReadBuffers(xTESTNumberOfItemsPerTick); + XRSIReadBuffers(xTESTNumberOfItemsPerTick); + XOBDReadBuffers(xTESTNumberOfItemsPerTick); + XCHMAReadBuffers(xTESTNumberOfItemsPerTick); + XCHLHReadBuffers(xTESTNumberOfItemsPerTick); + + // + XTESTReadConditions(); +} + +// +// +// START Combination Functions ... +// +// + +// +// Can Open Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XTESTCanOpenLongTrade( + double &providedSignals // Recieve Which Number of Providers has Conditions here, used for Volume Increasing +) +{ + // + bool result = false; + + // + bool hasSignal = XTESTHasLongSignal(providedSignals); + + // + result = + // + hasSignal + // + ; + + // + // TODO: Remove this On Production ... + if (result) + { + // + string message = XTESTGetConditionsString("\n"); + + // + XTESTClearConditions(); + + // + if (StringFind(message, "true") >= 0) + { + LogMessage(message); + } + } + + // + return result; +} + +// +// Can Close Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XTESTCanCloseLongTrade() +{ + // + bool result = false; + + // + // TODO: Check Market Conditions for Close Long Trades ... + // result = isXCHMASCFastCrossedUnderMax; + + // + return result; +} + +// +// Can Open Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XTESTCanOpenShortTrade( + double &providedSignals // Recieve Which Number of Providers has Conditions here, used for Volume Increasing +) +{ + // + bool result = false; + + // + bool hasSignal = XTESTHasShortSignal(providedSignals); + + // + result = + // + hasSignal + // + ; + + // + // TODO: Remove this On Production ... + if (result) + { + // + string message = XTESTGetConditionsString("\n"); + + // + XTESTClearConditions(); + + // + if (StringFind(message, "true") >= 0) + { + LogMessage(message); + } + } + + // + return result; +} + +// +// Can Close Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XTESTCanCloseShortTrade() +{ + // + bool result = false; + + // + // TODO: Check Market Conditions for Close Short Trades ... + // result = XTESTHasShortCloseConditions(xTESTNumberOfItemsPerTick); + + // + return result; +} + +// +// +// END Combination Functions ... +// +// + +// +// +// START Combination Signaling ... +// +// + +// +// TODO: Works i Had To Do: +// +// - [] Test All Strategies in All Available Brokers; +// - [] Find a Good Age for Closing Long Time Trades; +// - [] Find a Good Value for Closing Max DrawDown Equity Trades; +// - [] For All Strategies, Find Desired Long/Short Exit Points; +// - [] Find a Combination Point for Close All Trades; +// - [x] Try to Increase Trade Volume on Giving Multiple Signals at Same Time; +// - [] Prepare Signal and Event Alerts and Test Them for Production Environment; +// - [] Add SUpport for Daily and Hourly Alerts and also Make Report of Account State in Start Of Each Day; +// - [] Test All Methods for Find other Assets to Trade On them; +// - [] Do R&D about Multi Asset Trading in MT5; +// - [] Test Other Indicators/Oscillators or Exists Examples to Check and Found Market Conditions; +// + +// +// Read All Globally Required Conditions ... +void XTESTReadConditions() +{ + // + XTESTClearConditions(); + + // + // XTM ... + conditions.isXTMPeak = XTMIsPeak(); + conditions.isXTMVale = XTMIsVale(); + + // + // XTD ... + conditions.isXTDSignalPeak = XTDIsSignalPeak(); + conditions.isXTDSignalVale = XTDIsSignalVale(); + conditions.isXTDSignalOverBear = XTDIsSignalOverBear(1); + conditions.isXTDSignalUnderBear = XTDIsSignalUnderBear(1); + conditions.isXTDSignalCrossedOverBear = XTDIsSignalCrossedOverBear(1); + conditions.isXTDSignalCrossedUnderBear = XTDIsSignalCrossedUnderBear(1); + + // + // XRSI ... + conditions.isXRSIPeak = XRSIIsPeak(); + conditions.isXRSIVale = XRSIIsVale(); + conditions.isXRSICrossedOverLongExit = XRSIIsCrossedOverLongExit(1); + conditions.isXRSICrossedOverLongEntry = XRSIIsCrossedOverLongEntry(1); + conditions.isXRSICrossedUnderShortExit = XRSIIsCrossedUnderShortExit(1); + conditions.isXRSICrossedUnderShortEntry = XRSIIsCrossedUnderShortEntry(1); + + // + // XOBD ... + conditions.isXOBDPeak = XOBDIsPeak(); + conditions.isXOBDVale = XOBDIsVale(); + conditions.isXOBDSignalOverSwingHigh = XOBDIsSignalOverSwingHigh(1); + conditions.isXOBDSignalUnderSwingHigh = XOBDIsSignalUnderSwingHigh(1); + conditions.isXOBDSignalCrossedOverSwingHigh = XOBDIsSignalCrossedOverSwingHigh(1); + conditions.isXOBDSignalCrossedUnderSwingHigh = XOBDIsSignalCrossedUnderSwingHigh(1); + + // + // XCHLH ... + // + conditions.isXCHLHSignalBOverSignalT = XCHLHIsSignalBOverSignalT(1); + conditions.isXCHLHSignalBUnderSignalT = XCHLHIsSignalBUnderSignalT(1); + conditions.isXCHLHSignalBCrossedOverSignalT = XCHLHIsSignalBCrossedOverSignalT(1); + conditions.isXCHLHSignalBCrossedUnderSignalT = XCHLHIsSignalBCrossedUnderSignalT(1); + // + conditions.isXCHLHSignalBOverLCLL = XCHLHIsSignalBOverLCLL(1); + conditions.isXCHLHSignalBUnderLCLL = XCHLHIsSignalBUnderLCLL(1); + conditions.isXCHLHSignalBCrossedOverLCLL = XCHLHIsSignalBCrossedOverLCLL(1); + conditions.isXCHLHSignalBCrossedUnderLCLL = XCHLHIsSignalBCrossedUnderLCLL(1); + // + conditions.isXCHLHSCMCHHSame = XCHLHIsMCSCHasSameHH(1); + conditions.isXCHLHSCMCLLSame = XCHLHIsMCSCHasSameLL(1); + // + conditions.isXCHLHSCLCHHSame = XCHLHIsLCSCHasSameHH(1); + conditions.isXCHLHSCLCLLSame = XCHLHIsLCSCHasSameLL(1); + // + conditions.isXCHLHMCLCHHSame = XCHLHIsLCMCHasSameHH(1); + conditions.isXCHLHMCLCLLSame = XCHLHIsLCMCHasSameLL(1); + + // + // XCHMA ... + // + conditions.isXCHMASCPeak = XCHMAIsSCPeak(); + conditions.isXCHMASCVale = XCHMAIsSCVale(); + conditions.isXCHMASCFastOverSlow = XCHMAIsSCFastOverSlow(1); + conditions.isXCHMASCFastUnderSlow = XCHMAIsSCFastUnderSlow(1); + conditions.isXCHMASCFastCrossedOverSlow = XCHMAIsSCFastCrossedOverSlow(1); + conditions.isXCHMASCFastCrossedUnderSlow = XCHMAIsSCFastCrossedUnderSlow(1); + // + conditions.isXCHMAMCPeak = XCHMAIsMCPeak(); + conditions.isXCHMAMCVale = XCHMAIsMCVale(); + conditions.isXCHMAMCFastOverSlow = XCHMAIsMCFastOverSlow(1); + conditions.isXCHMAMCFastUnderSlow = XCHMAIsMCFastUnderSlow(1); + conditions.isXCHMAMCFastCrossedOverSlow = XCHMAIsMCFastCrossedOverSlow(1); + conditions.isXCHMAMCFastCrossedUnderSlow = XCHMAIsMCFastCrossedUnderSlow(1); + // + conditions.isXCHMALCPeak = XCHMAIsLCPeak(); + conditions.isXCHMALCVale = XCHMAIsLCVale(); + conditions.isXCHMALCFastOverSlow = XCHMAIsLCFastOverSlow(1); + conditions.isXCHMALCFastUnderSlow = XCHMAIsLCFastUnderSlow(1); + conditions.isXCHMALCFastCrossedOverSlow = XCHMAIsLCFastCrossedOverSlow(1); + conditions.isXCHMALCFastCrossedUnderSlow = XCHMAIsLCFastCrossedUnderSlow(1); +} + +// +// Cleanup Conditions ... +void XTESTClearConditions() +{ + // + X_TEST_MARKET_CONDITIONS mConditions = {}; + + // + conditions = mConditions; +} + +// +// Converts Market Conditions to Specific String Representation ... +string XTESTGetConditionsString( + string separator = ",", // Specify Separator + bool ignoreFalses = true // Ignore False Conditions +) +{ + // + string result = ""; + + // + // XTM ... + result += + "| XTM |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTMPeak)) + { + result += "isXTMPeak: " + (string)conditions.isXTMPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTMVale)) + { + result += "isXTMVale: " + (string)conditions.isXTMVale + separator; + } + + // + // Separator ... + result += separator; + + // + // XTD ... + result += + "| XTD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTDSignalPeak)) + { + result += "isXTDSignalPeak: " + (string)conditions.isXTDSignalPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTDSignalVale)) + { + result += "isXTDSignalVale: " + (string)conditions.isXTDSignalVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTDSignalOverBear)) + { + result += "isXTDSignalOverBear: " + (string)conditions.isXTDSignalOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTDSignalUnderBear)) + { + result += "isXTDSignalUnderBear: " + (string)conditions.isXTDSignalUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTDSignalCrossedOverBear)) + { + result += "isXTDSignalCrossedOverBear: " + (string)conditions.isXTDSignalCrossedOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXTDSignalCrossedUnderBear)) + { + result += "isXTDSignalCrossedUnderBear: " + (string)conditions.isXTDSignalCrossedUnderBear + separator; + } + + // + // Separator ... + result += separator; + + // + // XRSI ... + result += + "| XRSI |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXRSIPeak)) + { + result += "isXRSIPeak: " + (string)conditions.isXRSIPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXRSIVale)) + { + result += "isXRSIVale: " + (string)conditions.isXRSIVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXRSICrossedOverLongExit)) + { + result += "isXRSICrossedOverLongExit: " + (string)conditions.isXRSICrossedOverLongExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXRSICrossedOverLongEntry)) + { + result += "isXRSICrossedOverLongEntry: " + (string)conditions.isXRSICrossedOverLongEntry + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXRSICrossedUnderShortExit)) + { + result += "isXRSICrossedUnderShortExit: " + (string)conditions.isXRSICrossedUnderShortExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXRSICrossedUnderShortEntry)) + { + result += "isXRSICrossedUnderShortEntry: " + (string)conditions.isXRSICrossedUnderShortEntry + separator; + } + + // + // Separator ... + result += separator; + + // + // XOBD ... + result += + "| XOBD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXOBDPeak)) + { + result += "isXOBDPeak: " + (string)conditions.isXOBDPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXOBDVale)) + { + result += "isXOBDVale: " + (string)conditions.isXOBDVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXOBDSignalOverSwingHigh)) + { + result += "isXOBDSignalOverSwingHigh: " + (string)conditions.isXOBDSignalOverSwingHigh + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXOBDSignalUnderSwingHigh)) + { + result += "isXOBDSignalUnderSwingHigh: " + (string)conditions.isXOBDSignalUnderSwingHigh + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXOBDSignalCrossedOverSwingHigh)) + { + result += "isXOBDSignalCrossedOverSwingHigh: " + (string)conditions.isXOBDSignalCrossedOverSwingHigh + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXOBDSignalCrossedUnderSwingHigh)) + { + result += "isXOBDSignalCrossedUnderSwingHigh: " + (string)conditions.isXOBDSignalCrossedUnderSwingHigh + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHLH ... + result += + "| XCHLH |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBOverSignalT)) + { + result += "isXCHLHSignalBOverSignalT: " + (string)conditions.isXCHLHSignalBOverSignalT + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBUnderSignalT)) + { + result += "isXCHLHSignalBUnderSignalT: " + (string)conditions.isXCHLHSignalBUnderSignalT + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBCrossedOverSignalT)) + { + result += "isXCHLHSignalBCrossedOverSignalT: " + (string)conditions.isXCHLHSignalBCrossedOverSignalT + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBCrossedUnderSignalT)) + { + result += "isXCHLHSignalBCrossedUnderSignalT: " + (string)conditions.isXCHLHSignalBCrossedUnderSignalT + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBOverLCLL)) + { + result += "isXCHLHSignalBOverLCLL: " + (string)conditions.isXCHLHSignalBOverLCLL + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBUnderLCLL)) + { + result += "isXCHLHSignalBUnderLCLL: " + (string)conditions.isXCHLHSignalBUnderLCLL + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBCrossedOverLCLL)) + { + result += "isXCHLHSignalBCrossedOverLCLL: " + (string)conditions.isXCHLHSignalBCrossedOverLCLL + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSignalBCrossedUnderLCLL)) + { + result += "isXCHLHSignalBCrossedUnderLCLL: " + (string)conditions.isXCHLHSignalBCrossedUnderLCLL + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSCMCHHSame)) + { + result += "isXCHLHSCMCHHSame: " + (string)conditions.isXCHLHSCMCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSCMCLLSame)) + { + result += "isXCHLHSCMCLLSame: " + (string)conditions.isXCHLHSCMCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSCLCHHSame)) + { + result += "isXCHLHSCLCHHSame: " + (string)conditions.isXCHLHSCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHSCLCLLSame)) + { + result += "isXCHLHSCLCLLSame: " + (string)conditions.isXCHLHSCLCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHMCLCHHSame)) + { + result += "isXCHLHMCLCHHSame: " + (string)conditions.isXCHLHMCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHLHMCLCLLSame)) + { + result += "isXCHLHMCLCLLSame: " + (string)conditions.isXCHLHMCLCLLSame + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHMA ... + result += + "| XCHMA |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMASCPeak)) + { + result += "isXCHMASCPeak: " + (string)conditions.isXCHMASCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMASCVale)) + { + result += "isXCHMASCVale: " + (string)conditions.isXCHMASCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMASCFastOverSlow)) + { + result += "isXCHMASCFastOverSlow: " + (string)conditions.isXCHMASCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMASCFastUnderSlow)) + { + result += "isXCHMASCFastUnderSlow: " + (string)conditions.isXCHMASCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMASCFastCrossedOverSlow)) + { + result += "isXCHMASCFastCrossedOverSlow: " + (string)conditions.isXCHMASCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMASCFastCrossedUnderSlow)) + { + result += "isXCHMASCFastCrossedUnderSlow: " + (string)conditions.isXCHMASCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMAMCPeak)) + { + result += "isXCHMAMCPeak: " + (string)conditions.isXCHMAMCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMAMCVale)) + { + result += "isXCHMAMCVale: " + (string)conditions.isXCHMAMCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMAMCFastOverSlow)) + { + result += "isXCHMAMCFastOverSlow: " + (string)conditions.isXCHMAMCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMAMCFastUnderSlow)) + { + result += "isXCHMAMCFastUnderSlow: " + (string)conditions.isXCHMAMCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMAMCFastCrossedOverSlow)) + { + result += "isXCHMAMCFastCrossedOverSlow: " + (string)conditions.isXCHMAMCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMAMCFastCrossedUnderSlow)) + { + result += "isXCHMAMCFastCrossedUnderSlow: " + (string)conditions.isXCHMAMCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMALCPeak)) + { + result += "isXCHMALCPeak: " + (string)conditions.isXCHMALCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMALCVale)) + { + result += "isXCHMALCVale: " + (string)conditions.isXCHMALCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMALCFastOverSlow)) + { + result += "isXCHMALCFastOverSlow: " + (string)conditions.isXCHMALCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMALCFastUnderSlow)) + { + result += "isXCHMALCFastUnderSlow: " + (string)conditions.isXCHMALCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMALCFastCrossedOverSlow)) + { + result += "isXCHMALCFastCrossedOverSlow: " + (string)conditions.isXCHMALCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && conditions.isXCHMALCFastCrossedUnderSlow)) + { + result += "isXCHMALCFastCrossedUnderSlow: " + (string)conditions.isXCHMALCFastCrossedUnderSlow + separator; + } + + // + // Separator ... + result += separator; + + // + return result; +} + +// +// Check Market Conditions by Combination of Power of All tools for LONGs ... +bool XTESTHasLongSignal( + double &providedSignals // Recieve Which Number of Providers has Conditions here, used for Volume Increasing +) +{ + // + bool result = false; + ENUM_X_SIGNAL_METHODS methods[]; + + // + // START Custom Mechanism ... + // + + // + // Required Data ... + double entry = GetEntry(X_SIGNAL_LONG); + double nearHH = GetHighestHigh(3, 1); + double nearLL = GetLowestLow(3, 1); + XOHCL candle1 = GetCandle(1); + + // + bool isSharpChanged = IsSharpChanged( + 5, + 1, + xTMMaBuffer); + + // + bool isCandleSharpChanged = IsSharpChanged( + 5, + 1, + PRICE_CLOSE); + + // + // XRSI ... + bool isXRSIOverLongExit = + xRSIBuffer[1] > xRSILongExitValue; + + // + // XTD ... + // bool isXTDSignalIncreasing = + // xTDSignalBuffer[1] > xTDSignalBuffer[2] && + // xTDSignalBuffer[1] > xTDSignalBuffer[3]; + + // + // XCHLH ... + bool isDecreasingMCHH = IsDecreasing( + 12, + 1, + xCHLHMcHHBuffer); + + // + // XCHMA ... + // + double xCHMAMin1 = XCHMAGetMin(1); + double xCHMAMin2 = XCHMAGetMin(2); + + // + double xCHMAMax1 = XCHMAGetMax(1); + double xCHMAMax2 = XCHMAGetMax(2); + + // + // Calculate Non SC Max ... + double xCHMANonSCMax1 = MathMax(xCHMAMcFastBuffer[1], xCHMAMcSlowBuffer[1]); + xCHMANonSCMax1 = MathMax(xCHMANonSCMax1, xCHMALcFastBuffer[1]); + xCHMANonSCMax1 = MathMax(xCHMANonSCMax1, xCHMALcSlowBuffer[1]); + + // + // Calculate Non SC Min ... + double xCHMANonSCMin1 = MathMin(xCHMAMcFastBuffer[1], xCHMAMcSlowBuffer[1]); + xCHMANonSCMin1 = MathMin(xCHMANonSCMin1, xCHMALcFastBuffer[1]); + xCHMANonSCMin1 = MathMin(xCHMANonSCMin1, xCHMALcSlowBuffer[1]); + + // + double xCHMASCMin1 = MathMin(xCHMAScFastBuffer[1], xCHMAScSlowBuffer[1]); + double xCHMASCMin2 = MathMin(xCHMAScFastBuffer[2], xCHMAScSlowBuffer[2]); + + // + double xCHMASCMax1 = MathMax(xCHMAScFastBuffer[1], xCHMAScSlowBuffer[1]); + double xCHMASCMax2 = MathMax(xCHMAScFastBuffer[2], xCHMAScSlowBuffer[2]); + + // + double xCHMAMCTrend1 = MathAbs(xCHMAMcFastBuffer[1] - xCHMAMcSlowBuffer[1]); + double xCHMAMCTrend5 = MathAbs(xCHMAMcFastBuffer[5] - xCHMAMcSlowBuffer[5]); + double xCHMAMCTrend10 = MathAbs(xCHMAMcFastBuffer[10] - xCHMAMcSlowBuffer[10]); + + // + double xCHMALCTrend1 = MathAbs(xCHMALcFastBuffer[1] - xCHMALcSlowBuffer[1]); + double xCHMALCTrend5 = MathAbs(xCHMALcFastBuffer[5] - xCHMALcSlowBuffer[5]); + double xCHMALCTrend10 = MathAbs(xCHMALcFastBuffer[10] - xCHMALcSlowBuffer[10]); + + // + bool isXCHMASCCrossedOverMin = + // + xCHMASCMin2 <= xCHMAMin2 && + xCHMASCMin1 > xCHMAMin1 + // + ; + + // + bool isXCHMASCFastCrossedOverMax = + xCHMASCMax2 < xCHMAMax2 && + xCHMASCMax1 >= xCHMAMax1; + + // + bool isXCHMASCFastCrossedUnderMin = + xCHMASCMin2 > xCHMAMin2 && + xCHMASCMin1 <= xCHMAMin1; + + // + bool isXCHMASCFastCrossedUnderMax = + xCHMASCMax2 >= xCHMAMax2 && + xCHMASCMax1 < xCHMAMax1; + + // + // Condition 1 ... + // this Method waits for XCHMA Short Cycle's Fast to Going down + // of all Cycles Minimum Value, then Check when its Crossed Over + // min value and then start to Open Long Trades based On Conditions, + // and Recieved Verifications from other Indicator/Oscillator(s) ... + bool customMethodCond1 = + // + isXCHMASCCrossedOverMin + // + && + // + entry < nearHH + // + && + // + candle1.high != nearHH + // + && + // + !isCandleSharpChanged + // + && + // + !( + // + ( + // + conditions.isXCHMASCFastUnderSlow || + conditions.isXCHMASCFastCrossedUnderSlow + // + ) + // + && + // + ( + // + conditions.isXCHMAMCFastUnderSlow || + conditions.isXCHMAMCFastCrossedUnderSlow + // + ) + // + && + // + ( + // + conditions.isXCHMALCFastUnderSlow || + conditions.isXCHMALCFastCrossedUnderSlow + // + ) + // + ) + // + && + // + ( + // + conditions.isXCHMAMCFastOverSlow + // + ? + // + xCHMAMCTrend1 >= xCHMAMCTrend5 && + xCHMAMCTrend5 >= xCHMAMCTrend10 + // + : + // + xCHMAMCTrend1 < xCHMAMCTrend5 && + xCHMAMCTrend5 < xCHMAMCTrend10 + // + ) + // + && + // + !( + // + ( + // + conditions.isXCHMAMCFastUnderSlow || + conditions.isXCHMAMCFastCrossedUnderSlow + // + ) + // + && + // + ( + // + conditions.isXCHMALCFastUnderSlow || + conditions.isXCHMALCFastCrossedUnderSlow + // + ) + // + ) + // + && + // + ( + // + conditions.isXCHMAMCFastUnderSlow && + xTDSignalBuffer[1] < xTDSignalBuffer[2] + // + ? + // + xCHMAMcFastBuffer[1] > xCHMANonSCMin1 + // + && + // + !( + // + xCHLHSignalTBuffer[1] > xCHLHScHHBuffer[1] && + xCHLHSignalBBuffer[1] < xCHLHLcLLBuffer[1] + // + ) + // + : + // + true + // + ) + // + && + // + !( + // + conditions.isXCHMASCVale && + conditions.isXCHMASCFastUnderSlow + // + && + // + ( + // + ( + // + conditions.isXCHLHMCLCHHSame + // + && + // + ( + // + conditions.isXCHLHMCLCLLSame || + conditions.isXCHLHSCMCLLSame + // + ) + // + ) + // + ) + // + ) + // + && + // + !( + // + ( + // + xRSIBuffer[1] > xRSILongExitValue || + conditions.isXRSICrossedOverLongExit + // + ) + // + && + // + conditions.isXCHLHSCMCHHSame && + conditions.isXCHLHSCMCLLSame && + // + conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + ( + // + conditions.isXCHLHSignalBOverLCLL || + conditions.isXCHLHSignalBCrossedOverLCLL + // + ) + // + && + conditions.isXCHLHMCLCLLSame && + // + conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + conditions.isXTDSignalOverBear && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBUnderSignalT && + conditions.isXCHLHSignalBOverLCLL && + conditions.isXCHLHMCLCLLSame && + // + conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + conditions.isXTDSignalOverBear && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBUnderSignalT && + conditions.isXCHLHSignalBUnderLCLL && + conditions.isXCHLHMCLCLLSame && + // + conditions.isXCHMASCFastOverSlow && + conditions.isXCHMAMCFastUnderSlow && + conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + conditions.isXTDSignalOverBear && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBOverSignalT && + conditions.isXCHLHSignalBOverLCLL && + conditions.isXCHLHMCLCHHSame && + // + conditions.isXCHMASCFastOverSlow && + conditions.isXCHMAMCFastOverSlow && + conditions.isXCHMALCFastUnderSlow + // + ) + // + ; + + // + // Filling Methods ... + if (customMethodCond1) + { + // + ArrayResize( + methods, + ArraySize(methods) + 1); + + // + methods[ArraySize(methods) - 1] = X_SIGNAL_METHOD_1; + } + + // + // Condition 2 ... + // this Method waits for XCHMA Medium Cycles Fast Line Crossed Over Slow, + // then start to Open Long Trades based On Conditions, and Recieved Verifications from + // other Indicator/Oscillator(s) ... + bool customMethodCond2 = + // + // MCFast Based ... + ( + // + conditions.isXCHMAMCFastCrossedOverSlow && + // + ( + // + conditions.isXCHMASCFastOverSlow + // + && + // + conditions.isXCHMALCFastOverSlow + // + ) + // + ) + // + && + // + !( + // + ( + // + conditions.isXOBDSignalUnderSwingHigh || + conditions.isXOBDSignalCrossedUnderSwingHigh + // + ) + // + && + // + conditions.isXCHLHSignalBOverSignalT && + conditions.isXCHLHSignalBOverLCLL && + conditions.isXCHLHSCMCHHSame + // + ) + // + && + // + !( + // + conditions.isXTDSignalCrossedOverBear && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBUnderSignalT && + conditions.isXCHLHSignalBOverLCLL && + conditions.isXCHLHMCLCLLSame + // + ) + // + && + // + !( + // + xCHLHScHHBuffer[1] > xCHLHSignalTBuffer[1] && + xCHLHScLLBuffer[1] > xCHLHSignalTBuffer[1] && + xCHLHSignalBBuffer[1] < xCHLHSignalTBuffer[1] && + xCHLHSignalBBuffer[1] < xCHLHMcLLBuffer[1] + // + ) + // + && + // + !( + // + conditions.isXTDSignalOverBear && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBCrossedOverSignalT && + conditions.isXCHLHSignalBOverLCLL && + conditions.isXCHLHSCMCHHSame && + conditions.isXCHLHMCLCLLSame + // + ) + // + && + // + !( + // + conditions.isXTDSignalUnderBear && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBUnderSignalT && + conditions.isXCHLHSignalBOverLCLL && + conditions.isXCHLHMCLCHHSame && + conditions.isXCHLHMCLCLLSame + // + ) + // + && + // + !( + // + conditions.isXTDSignalOverBear && + // + conditions.isXRSICrossedOverLongExit && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBOverSignalT && + conditions.isXCHLHSignalBOverLCLL + // + ) + // + && + // + !( + // + conditions.isXTDSignalCrossedUnderBear && + // + conditions.isXOBDSignalUnderSwingHigh && + // + conditions.isXCHLHSignalBOverSignalT && + conditions.isXCHLHSignalBOverLCLL + // + ) + // + // + && + // + entry < nearHH + // + && + // + nearHH != candle1.high + // + && + // + !isXRSIOverLongExit + // + ; + + // + // Filling Methods ... + if (customMethodCond2) + { + // + ArrayResize( + methods, + ArraySize(methods) + 1); + + // + methods[ArraySize(methods) - 1] = X_SIGNAL_METHOD_2; + } + + // + // Condition 3 ... + // this Method waits for XCHMA Short Cycle's Fast to Crossed Over all Cycles max value + // and then start to Open Long Trades based On Conditions, + // and Recieved Verifications from other Indicator/Oscillator(s) ... + bool customMethodCond3 = + // + isXCHMASCFastCrossedOverMax + // + && + // + conditions.isXCHMALCFastOverSlow + // + && + // + !( + // + xCHLHScLLBuffer[1] > xCHLHMcLLBuffer[1] && + xCHLHMcLLBuffer[1] > xCHLHSignalBBuffer[1] && + xCHLHSignalBBuffer[1] > xCHLHSignalTBuffer[1] && + xCHLHSignalTBuffer[1] > xCHLHLcLLBuffer[1] + // + ) + // + && + // + !( + conditions.isXCHLHSignalBUnderSignalT && + conditions.isXCHLHSignalBOverLCLL && + ( + // + conditions.isXCHLHSCMCHHSame || + conditions.isXCHLHMCLCLLSame + // + ) + // + ) + // + && + // + !( + // + conditions.isXCHLHSignalBOverSignalT && + conditions.isXCHLHSignalBOverLCLL && + // + ( + // + conditions.isXCHLHSCMCHHSame || + conditions.isXCHLHMCLCLLSame || + conditions.isXCHLHMCLCHHSame || + conditions.isXCHLHSCMCLLSame + // + ) + // + ) + // + && + // + !isSharpChanged + // + && + // + !isCandleSharpChanged + // + && + // + entry < nearHH + // + && + // + candle1.close > xTMMaBuffer[1]; + // + ; + + // + // Filling Methods ... + if (customMethodCond3) + { + // + ArrayResize( + methods, + ArraySize(methods) + 1); + + // + methods[ArraySize(methods) - 1] = X_SIGNAL_METHOD_3; + } + + // + // Combine Custom Methods together ... + bool isCustomMethodHasSignal = + // + customMethodCond1 + // + || + // + customMethodCond2 + // + || + // + customMethodCond3 + // + ; + + // + // END Custom Mechanism ... + // + + // + result = + // + // isXTMHasSignal + // isXTDHasSignal + // isXCHMAHasSignal + // + // isXTMMethodHasSignal + // + // || + // + // isXTDMethodHasSignal + // + // || + // // + // isXOBDMethodHasSignal + // // + // || + // // + // isXCHMAMethodHasSignal + // // + // || + // // + // isXCHLHMethodHasSignal + // // + // || + // // + // isXRSIMethodHasSignal + // + // || + isCustomMethodHasSignal + // + ; + + // + if (result) + { + // + // Set Number of Occured Conditions for Increasing Volume ... + providedSignals = ArraySize(methods); + } + + // + return result; +} + +// +// Check Market Conditions by Combination of Power of All tools for SHORTs ... +bool XTESTHasShortSignal( + double &providedSignals // Recieve Which Number of Providers has Conditions here, used for Volume Increasing +) +{ + // + bool result = false; + ENUM_X_SIGNAL_METHODS methods[]; + + // + // START Custom Mechanism ... + // + + // + // Required Data ... + double entry = GetEntry(X_SIGNAL_SHORT); + double nearHH = GetHighestHigh(3, 1); + double nearLL = GetLowestLow(3, 1); + XOHCL candle1 = GetCandle(1); + + // + bool isSharpChanged = IsSharpChanged( + 5, + 1, + xTMMaBuffer); + + // + bool isCandleSharpChanged = IsSharpChanged( + 5, + 1, + PRICE_CLOSE); + + // + // XRSI ... + bool isXRSIOverLongExit = + xRSIBuffer[1] > xRSILongExitValue; + + // + // XCHLH ... + bool isIncreasingMCHH = IsIncreasing( + 12, + 1, + xCHLHMcHHBuffer); + + // + double xCHLHLCRange1 = xCHLHLcHHBuffer[1] - xCHLHLcLLBuffer[1]; + double xCHLHMCRange1 = xCHLHMcHHBuffer[1] - xCHLHMcLLBuffer[1]; + double xCHLHSCRange1 = xCHLHScHHBuffer[1] - xCHLHScLLBuffer[1]; + + // + double xCHLHNonLCMax1 = MathMax(xCHLHScHHBuffer[1], xCHLHMcHHBuffer[1]); + double xCHLHNonLCMin1 = MathMin(xCHLHScLLBuffer[1], xCHLHMcLLBuffer[1]); + double xCHLHNonLCRange1 = xCHLHNonLCMax1 - xCHLHNonLCMin1; + + // // + // bool isIncreasingMCLL = IsIncreasing( + // 12, + // 1, + // xCHLHMcLLBuffer); + + // // + // bool isDecreasingSCHH = IsDecreasing( + // 12, + // 1, + // xCHLHScHHBuffer); + + // // + // bool isDecreasingSCLL = IsDecreasing( + // 12, + // 1, + // xCHLHScLLBuffer); + + // + // XCHMA ... + // + double xCHMAMin1 = XCHMAGetMin(1); + double xCHMAMin2 = XCHMAGetMin(2); + + // + double xCHMAMax1 = XCHMAGetMax(1); + double xCHMAMax2 = XCHMAGetMax(2); + + // + // Calculate Non SC Max ... + double xCHMANonSCMax1 = MathMax(xCHMAMcFastBuffer[1], xCHMAMcSlowBuffer[1]); + xCHMANonSCMax1 = MathMax(xCHMANonSCMax1, xCHMALcFastBuffer[1]); + xCHMANonSCMax1 = MathMax(xCHMANonSCMax1, xCHMALcSlowBuffer[1]); + + // + // Calculate Non SC Min ... + double xCHMANonSCMin1 = MathMin(xCHMAMcFastBuffer[1], xCHMAMcSlowBuffer[1]); + xCHMANonSCMin1 = MathMin(xCHMANonSCMin1, xCHMALcFastBuffer[1]); + xCHMANonSCMin1 = MathMin(xCHMANonSCMin1, xCHMALcSlowBuffer[1]); + + // + // Calculate Non LC Max ... + double xCHMANonLCMax1 = MathMax(xCHMAScFastBuffer[1], xCHMAScSlowBuffer[1]); + xCHMANonLCMax1 = MathMax(xCHMANonLCMax1, xCHMAMcFastBuffer[1]); + xCHMANonLCMax1 = MathMax(xCHMANonLCMax1, xCHMAMcSlowBuffer[1]); + + // + // Calculate Non LC Min ... + double xCHMANonLCMin1 = MathMin(xCHMAScFastBuffer[1], xCHMAScSlowBuffer[1]); + xCHMANonLCMin1 = MathMin(xCHMANonLCMin1, xCHMAMcFastBuffer[1]); + xCHMANonLCMin1 = MathMin(xCHMANonLCMin1, xCHMAMcSlowBuffer[1]); + + // + // Check LC On Top Of Others ... + double xCHMALCMin1 = MathMin(xCHMALcFastBuffer[1], xCHMALcSlowBuffer[1]); + + // + double xCHMASCMin1 = MathMin(xCHMAScFastBuffer[1], xCHMAScSlowBuffer[1]); + double xCHMASCMin2 = MathMin(xCHMAScFastBuffer[2], xCHMAScSlowBuffer[2]); + + // + double xCHMASCMax1 = MathMax(xCHMAScFastBuffer[1], xCHMAScSlowBuffer[1]); + double xCHMASCMax2 = MathMax(xCHMAScFastBuffer[2], xCHMAScSlowBuffer[2]); + + // + double xCHMAMCTrend1 = MathAbs(xCHMAMcFastBuffer[1] - xCHMAMcSlowBuffer[1]); + double xCHMAMCTrend5 = MathAbs(xCHMAMcFastBuffer[5] - xCHMAMcSlowBuffer[5]); + double xCHMAMCTrend10 = MathAbs(xCHMAMcFastBuffer[10] - xCHMAMcSlowBuffer[10]); + + // + double xCHMALCTrend1 = MathAbs(xCHMALcFastBuffer[1] - xCHMALcSlowBuffer[1]); + double xCHMALCTrend5 = MathAbs(xCHMALcFastBuffer[5] - xCHMALcSlowBuffer[5]); + double xCHMALCTrend10 = MathAbs(xCHMALcFastBuffer[10] - xCHMALcSlowBuffer[10]); + + // + bool isXCHMASCCrossedOverMin = + // + xCHMASCMin2 <= xCHMAMin2 && + xCHMASCMin1 > xCHMAMin1 + // + ; + + // + bool isXCHMASCFastCrossedOverMax = + xCHMASCMax2 < xCHMAMax2 && + xCHMASCMax1 >= xCHMAMax1; + + // + bool isXCHMASCFastCrossedUnderMin = + xCHMASCMin2 > xCHMAMin2 && + xCHMASCMin1 <= xCHMAMin1; + + // + bool isXCHMASCFastCrossedUnderMax = + xCHMASCMax2 >= xCHMAMax2 && + xCHMASCMax1 < xCHMAMax1; + + // + // Condition 1 ... + // this Method waits for XCHMA Short Cycle's Fast to Going up + // of all Cycles Maximum Value, then Check when its Crossed Under + // max value and then start to Open Short Trades based On Conditions, + // and Recieved Verifications from other Indicator/Oscillator(s) ... + bool customMethodCond1 = + // + isXCHMASCFastCrossedUnderMax + // + && + // + entry > nearLL + // + && + // + !isSharpChanged + // + && + // + !isCandleSharpChanged + // + && + // + candle1.low != nearLL + // + && + // + !conditions.isXCHLHMCLCLLSame + // + && + // + ( + // + xCHLHNonLCRange1 > (xCHLHLCRange1 / 2) + // + ? + // + true + // + : + // + xCHLHMcHHBuffer[1] > (xCHLHLcHHBuffer[1] - (xCHLHLCRange1 / 2)) && + MathAbs(xCHLHMcLLBuffer[1] - xCHLHLcLLBuffer[1]) > (MathAbs(xCHLHMcHHBuffer[1] - xCHLHLcHHBuffer[1]) / 2) + // + ) + // + && + // + !( + // + xCHLHMcLLBuffer[1] > (xCHLHLcHHBuffer[1] - (xCHLHLCRange1 / 2)) && + xCHLHSignalTBuffer[1] < xCHLHSignalBBuffer[1] && + MathAbs(xCHLHScLLBuffer[1] - xCHLHMcLLBuffer[1]) > MathAbs(xCHLHScHHBuffer[1] - xCHLHMcHHBuffer[1]) + // + ) + // + && + // + !( + // + xTDSignalBuffer[1] > xTDSignalBuffer[2] && + xTDSignalBuffer[2] > xTDSignalBuffer[3] && + xTDSignalBuffer[1] > xTDSignalBuffer[3] + // + ) + // + && + // + !( + // + ( + // + conditions.isXCHMASCFastOverSlow || + conditions.isXCHMASCFastCrossedOverSlow + // + ) + // + && + // + ( + // + conditions.isXCHMAMCFastOverSlow || + conditions.isXCHMAMCFastCrossedOverSlow + // + ) + // + && + // + ( + // + conditions.isXCHMALCFastOverSlow || + conditions.isXCHMALCFastCrossedOverSlow + // + ) + // + ) + // + && + // + !( + // + ( + // + conditions.isXCHMAMCFastOverSlow || + conditions.isXCHMAMCFastCrossedOverSlow + // + ) + // + && + // + ( + // + conditions.isXCHMALCFastOverSlow || + conditions.isXCHMALCFastCrossedOverSlow + // + ) + // + ) + // + && + // + ( + // + conditions.isXCHMAMCFastOverSlow + // + ? + // + xCHMAMCTrend1 < xCHMAMCTrend5 + // + && + // + ( + // + xCHMAMCTrend1 < xCHMAMCTrend10 || + xCHMAMCTrend5 < xCHMAMCTrend10 + // + ) + // + : + // + true + // + ) + // + && + // + ( + // + conditions.isXCHMALCFastOverSlow + // + ? + // + xCHMALCTrend1 <= xCHMALCTrend5 + // + && + // + ( + // + xCHMALCTrend1 <= xCHMALCTrend10 || + xCHMALCTrend5 <= xCHMALCTrend10 + // + ) + // + : + // + true + // + ) + // + && + // + !( + // + conditions.isXCHMASCVale || + conditions.isXCHMAMCVale || + conditions.isXCHMASCPeak || + conditions.isXCHMAMCPeak + // + ) + // + && + // + ( + conditions.isXCHMASCFastOverSlow || + conditions.isXCHMAMCFastOverSlow + // + ? + // + xOBDSwingHighBuffer[1] < xOBDSwingLowBuffer[1] + // + : + // + true) + // + ; + + // + // Filling Methods ... + if (customMethodCond1) + { + // + ArrayResize( + methods, + ArraySize(methods) + 1); + + // + methods[ArraySize(methods) - 1] = X_SIGNAL_METHOD_1; + } + + // + // Condition 2 ... + // this Method waits for XCHMA Medium Cycle Fast Line Crossed Under Slow, + // then start to Open Short Trades based On Conditions, and Recieved Verifications from + // other Indicator/Oscillator(s) ... + bool customMethodCond2 = + // + conditions.isXCHMAMCFastCrossedUnderSlow + // + && + // + entry > nearLL + // + && + // + candle1.low != nearLL + // + && + // + xCHMALCMin1 < xCHMANonLCMax1 + // + && + // + conditions.isXTDSignalUnderBear + // + && + // + ( + // + conditions.isXCHLHMCLCHHSame + // + ? + // + xOBDSwingHighBuffer[1] < xOBDSwingLowBuffer[1] + // + : + // + true + // + ) + // + && + // + !( + conditions.isXCHLHSCMCLLSame || + conditions.isXCHLHSCLCLLSame + // + ) + // + && + // + !( + // + xCHLHMcHHBuffer[1] < xCHLHLcHHBuffer[1] && + // + xCHLHScHHBuffer[1] < xCHLHMcHHBuffer[1] && + xCHLHScLLBuffer[1] > xCHLHMcLLBuffer[1] && + // + xCHLHMcLLBuffer[1] > xCHLHSignalBBuffer[1] && + xCHLHMcLLBuffer[1] > xCHLHSignalTBuffer[1] && + // + xCHLHSignalBBuffer[1] > xCHLHLcLLBuffer[1] && + xCHLHSignalTBuffer[1] > xCHLHLcLLBuffer[1] && + // + MathAbs(xCHLHScLLBuffer[1] - xCHLHMcLLBuffer[1]) < MathAbs(xCHLHScHHBuffer[1] - xCHLHMcHHBuffer[1]) + // + ) + // + ; + + // + // Filling Methods ... + if (customMethodCond2) + { + // + ArrayResize( + methods, + ArraySize(methods) + 1); + + // + methods[ArraySize(methods) - 1] = X_SIGNAL_METHOD_2; + } + + // + // Condition 3 ... + // this Method waits for XCHMA Short Cycle's Fast to Crossed Under all Cycles min value + // and then start to Open Short Trades based On Conditions, + // and Recieved Verifications from other Indicator/Oscillator(s) ... + bool customMethodCond3 = + // + isXCHMASCFastCrossedUnderMin + // + && + // + xCHMAScSlowBuffer[1] < xCHMANonSCMin1 + // + && + // + ( + // + conditions.isXCHMASCFastCrossedUnderSlow || + conditions.isXCHMASCFastUnderSlow + // + ) + // + && + // + ( + // + ( + // + conditions.isXCHMAMCFastCrossedUnderSlow || + conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + ( + // + conditions.isXCHMALCFastCrossedUnderSlow || + conditions.isXCHMALCFastUnderSlow + // + ) + // + ) + // + && + // + ( + // + ( + // + conditions.isXTDSignalCrossedUnderBear || + conditions.isXTDSignalUnderBear + // + ) + // + && + // + xTDBullishBuffer[1] < xTDBearishBuffer[1] + // + ) + // + && + // + !( + // + xCHLHMCRange1 < (xCHLHLCRange1 / 2) + // + && + // + xCHLHMcHHBuffer[1] < (xCHLHLcHHBuffer[1] - (xCHLHLCRange1 / 2)) + // + ) + // + && + // + !( + // + conditions.isXCHMAMCFastUnderSlow + // + && + // + ( + // + xCHMAMcFastBuffer[1] > xCHMAMcFastBuffer[5] && + xCHMAMcFastBuffer[1] > xCHMAMcFastBuffer[10] + // + ) + // + && + // + ( + // + xCHMAMCTrend1 < xCHMAMCTrend5 && + xCHMAMCTrend1 < xCHMAMCTrend10 + // + ) + // + ) + // + ; + + // + // Filling Methods ... + if (customMethodCond3) + { + // + ArrayResize( + methods, + ArraySize(methods) + 1); + + // + methods[ArraySize(methods) - 1] = X_SIGNAL_METHOD_3; + } + + // + // Combine Custom Methods together ... + bool isCustomMethodHasSignal = + // + customMethodCond1 + // + || + // + customMethodCond2 + // + || + // + customMethodCond3 + // + ; + + // + // END Custom Mechanism ... + // + + // + // Fill Result ... + result = + // + isCustomMethodHasSignal + // + ; + + // + if (result) + { + // + // Set Number of Occured Conditions for Increasing Volume ... + providedSignals = ArraySize(methods); + } + + // + return result; +} + +// +// +// END Combination Signaling ... +// +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.inputs.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.inputs.lib.mq5 new file mode 100644 index 0000000..3aba747 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.inputs.lib.mq5 @@ -0,0 +1,82 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTEST Signal Provider Library Inputs +// ----------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +input group "XTEST Provider"; + +// +input group "XTEST Common"; +input bool xTESTEnableProvider = true; // Enable Provider +input bool xTESTEnableAlerts = false; // Enable Events Alert +input int xTESTNumberOfItemsPerTick = 110; // Number Of items Readed In Each Tick + +// +input group "XTEST Trader"; +input int xTESTMagicNumber = 16940567; // Trader MagicNumber +input int xTESTSlippage = 10; // Trader Slippage + +// +input group "XTEST Trade Management"; +input bool xTESTAllowLongTrades = true; // Allow Long Trades +input bool xTESTAllowShortTrades = true; // Allow Short Trades + +// +input group "XTEST Risk Management"; +// +// Trade Count ... +input int xTESTMaxAllowedTrades = 5; // Max Allowed Trades at Same Time +input int xTESTMaxAllowedSupportTrades = 3; // Max Allowed Support Trades for Single Position +// +// Trades Age ... +// 1 Day = 288 +// 14 Day = 4320 +input int xTESTMaxInDrawDownTradeAge = 0; // Max In DrawDown Trades Age +// +// Trade Volume ... +input double xTESTStaticVolume = 0.3; // Static Volume +input double xTESTVolumeMultiplier = 2; // Volume Multiplier +input double xTESTMaxSupportedVolumePerTradeInLots = 2.4; // Max Supported Volume Per Trade in Lot +// +// Trade Profits ... +input double xTESTMinRewardPerTradeInPips = 8; // Min Reward Per Trade In Pips +input double xTESTRiskFreeTradesInPips = 3; // Make Trades Risk Free in Pips +input int xTESTMinRewardPerSupportTradesInPips = 2; // Min Reward for Support Trade +input int xTESTSupportTradesPriceDistanceInPips = 5; // Distance Price to Open Support Trade In Pips +// +// 1000000 Pips = 100$ in EURUSD ... +input double xTESTMaxAllowedDrawDownPerTradesInPips = 0; // Max Allowed Drawdown Per Trade In Pips +input double xTESTRiskFreeRate = 0.5; // Volume Multiplier for Risk Free +// +// Account ... +input double xTESTFreeMarginFactorForOpenTrades = 0.8; // Minimum Free Marging for Open Trades +input double xTESTBalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades + +// +// Validate Inputs before Initialization ... +bool XTESTValidateInputs() +{ + // + bool result = false; + + // + // TODO: Fix this ... + result = true; + + // + return result; +} \ No newline at end of file diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.lib.mq5 new file mode 100644 index 0000000..e2ba2a0 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtest.provider.lib.mq5 @@ -0,0 +1,1073 @@ +//////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTEST Signal Provider Library +// -------------------------------------------------------- +// Name: XTESTSignalProvider +// Description: XTEST based signal provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +#define XTESTProviderName "XTEST" + +// +// START Inputs ... +// + +#include "x-saherelm.xtest.provider.inputs.lib.mq5"; + +// +// END Inputs ... +// + +// +// Include Common Library ... +#include "x-saherelm.common.lib.mq5" + +// +// Include Logger Library ... +#include "x-saherelm.log.lib.mq5" + +// +// Include Alert Library ... +#include "x-saherelm.alert.lib.mq5" + +// +// Include Draw Library ... +#include "x-saherelm.draw.lib.mq5" + +// +// Include Class Libraries ... +#include "x-saherelm.class.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XCTrade *xTESTTrader; +XCAccountInfo xTESTAccountInfo; + +// +#include "x-saherelm.xtest.provider.indicators.lib.mq5" + +// +double xTESTDeposit = 0; +double xTESTBalance = 0; +double xTESTFreeMargin = 0; +double xTESTRiskFreeTrades = 0; +double xTESTMinRewardPerTrade = 0; +double xTESTBalanceForOpenTrades = 0; +double xTESTFreeMarginForOpenTrades = 0; +double xTESTMinRewardPerSupportTrades = 0; +double xTESTSupportTradesPriceDistance = 0; +double xTESTMaxAllowedDrawDownPerTrades = 0; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Initial Library if required ... +bool XTESTInitSignalProviderLibrary() +{ + // + bool result = false; + + // + // Validate Inputs ... + result = XTESTValidateInputs(); + if (!result) + { + return result; + } + + // + // Init Indicators ... + result = XTESTInitIndicators(); + if (!result) + { + return result; + } + + // + // Calculate Account Deposit ... + xTESTDeposit = xTESTAccountInfo.GetInitialBalance(); + + // + // Calculate RiskFree Price Distance ... + if (xTESTRiskFreeTradesInPips > 0 && xTESTRiskFreeRate > 0) + { + xTESTRiskFreeTrades = PipsToPrice(xTESTRiskFreeTradesInPips); + } + + // + // Calculate xTESTMinRewardPerTrade ... + if (xTESTMinRewardPerTradeInPips > 0) + { + xTESTMinRewardPerTrade = PipsToPrice(xTESTMinRewardPerTradeInPips); + } + + // + // Calculate Min Balance for Trades ... + if (xTESTBalanceFactorForOpenTrades > 0) + { + xTESTBalanceForOpenTrades = xTESTBalanceFactorForOpenTrades * xTESTDeposit; + } + + // + // Claculate Min Free Marging for Trades ... + if (xTESTFreeMarginFactorForOpenTrades > 0) + { + xTESTFreeMarginForOpenTrades = xTESTFreeMarginFactorForOpenTrades * xTESTDeposit; + } + + // + // Calculate xTESTSupportTradesPriceDistance ... + if (xTESTMaxAllowedSupportTrades > 0 && xTESTSupportTradesPriceDistanceInPips > 0 && xTESTMinRewardPerSupportTradesInPips > 0) + { + xTESTMinRewardPerSupportTrades = PipsToPrice(xTESTMinRewardPerSupportTradesInPips); + xTESTSupportTradesPriceDistance = PipsToPrice(xTESTSupportTradesPriceDistanceInPips); + } + + // + // Calculate xTESTMaxAllowedDrawDownPerTrade ... + if (xTESTMaxAllowedDrawDownPerTradesInPips > 0) + { + // + xTESTMaxAllowedDrawDownPerTrades = PipsToPrice(xTESTMaxAllowedDrawDownPerTradesInPips); + + // + LogMessage("Max Allowed DrawDown per Trade: " + (string)xTESTMaxAllowedDrawDownPerTrades); + } + + // + // Make XCTrader instance ... + xTESTTrader = new XCTrade( + XTESTProviderName, + _Symbol, + xTESTSlippage, + xTESTMagicNumber, + xTESTMaxAllowedTrades, + xTESTMaxAllowedSupportTrades, + xTESTMinRewardPerTradeInPips, + xTESTSupportTradesPriceDistanceInPips, + xTESTFreeMarginForOpenTrades, + xTESTBalanceForOpenTrades); + + // + result = true; + + // + // Logging State ... + XTESTIssueInitializationSucceedAlert(); + + // + return result; +} + +// +// DeInitial Library if required ... +void XTESTDeinitSignalProviderLibrary( + const int reason) +{ + // + // Release Handlers ... + XTESTReleaseIndicators(); + + // + // Logging State ... + XTESTIssueDeinitializationSucceedAlert(); +} + +// +// this is a Globally Function which do all of +// checkings and positions handling ... +void XTESTSignalProviderHandleTick() +{ + // + // Update account Balance ... + xTESTBalance = xTESTAccountInfo.GetBalance(); + xTESTFreeMargin = xTESTAccountInfo.GetFreeMargin(); + + // + // Check Provider is Enable or Not ... + if (!xTESTEnableProvider) + { + return; + } + + // + // Reading Indicator Buffers ... + XTESTHandleReadingBuffers(); + if (xTESTCalculatedBars < xTESTMaxLengthOfInputs) + { + return; + } + + // + // Handle Open Trades ... + XTESTHandleOpenTrades(); + + // + // Handle Close Trades ... + XTESTHandleCloseTrades(); + + // + // Handle Support Trades ... + XTESTHandleSupportTrades(); +} + +// +// Handle Open Trades ... +void XTESTHandleOpenTrades() +{ + // + // Check Can Trade ... + bool canTrade = xTESTAllowLongTrades || xTESTAllowShortTrades; + if (!canTrade) + { + return; + } + + // + // Check Max Open Trades ... + int openPositions = xTESTTrader.Count(); + int openTradeKinds = xTESTTrader.CountByKind( + X_SIGNAL_UNKNOWN, + X_KIND_TRADE); + bool canOpenPositions = openTradeKinds < xTESTMaxAllowedTrades; + if (!canOpenPositions) + { + return; + } + + // + // Check Signals Exists ... + double longsForceVolume = 0; + double shortsForceVolume = 0; + bool hasLongSignal = XTESTCanOpenLongTrade(longsForceVolume); + bool hasShortSignal = XTESTCanOpenShortTrade(shortsForceVolume); + if (!hasLongSignal && !hasShortSignal) + { + return; + } + + // + // Open Long Trades ... + if ( + // + hasLongSignal && + xTESTAllowLongTrades) + { + // + bool isOpened = XTESTOpenLongPosition(longsForceVolume); + } + + // + // Open Short Trades ... + if ( + // + hasShortSignal && + xTESTAllowShortTrades) + { + // + bool isOpened = XTESTOpenShortPosition(shortsForceVolume); + } +} + +// +// Handle Close Trades ... +void XTESTHandleCloseTrades() +{ + // + // All Close Mechanism Handles Here ... + // - Force Close; + // - Partial Close; + // - Risk Free Close; + // - Virtual TP/SL Close; + + // + // Force Close Long Trades ... + bool canCloseLongTrades = XTESTCanCloseLongTrade(); + if (xTESTAllowLongTrades && canCloseLongTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG; + + // + XSignal closed[]; + xTESTTrader.ClosePositionsByType( + type, + closed); + + // + bool isClosed = ArraySize(closed) > 0; + if (isClosed) + { + XTESTIssueForceCloseTradesAlert(type); + } + } + + // + // Force Close Short Trades ... + bool canCloseShortTrades = XTESTCanCloseShortTrade(); + if (xTESTAllowShortTrades && canCloseShortTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT; + + // + XSignal closed[]; + xTESTTrader.ClosePositionsByType( + type, + closed); + + // + bool isClosed = ArraySize(closed) > 0; + if (isClosed) + { + XTESTIssueForceCloseTradesAlert(type); + } + } + + // + // Close Risk Free Trades ... + bool canRiskFree = xTESTRiskFreeTradesInPips > 0 && xTESTRiskFreeTrades > 0 && xTESTRiskFreeRate > 0; + if (canRiskFree) + { + XSignal riskFrees[]; + xTESTTrader.RiskFreeSignals(riskFrees); + bool isRiskFree = ArraySize(riskFrees) > 0; + if (isRiskFree) + { + XTESTIssueRiskFreeTradesAlert(); + } + } + + // + XTESTHandleCloseMaxDrawDownTrades(); + + // + XTESTHandleCloseTooOldTrades(); +} + +// +// Handle Supported Trades ... +void XTESTHandleSupportTrades() +{ + // + bool canDoTrade = + xTESTMaxAllowedSupportTrades > 0 && + xTESTMinRewardPerSupportTradesInPips > 0 && + xTESTSupportTradesPriceDistanceInPips > 0; + if (!canDoTrade) + { + return; + } + + // + XSignal supports[]; + bool hasSupportTrade = XTESTOpenSupportTrade(supports); + if (hasSupportTrade) + { + } +} + +// +// Open Long Position ... +bool XTESTOpenLongPosition(double additionalVolumeMultiplier = 0) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double sl = 0; + double tp = xTESTMinRewardPerTrade; + double riskFree = xTESTRiskFreeTrades; + double riskFreeRate = xTESTRiskFreeRate; + double volume = XTESTCalculateVolume(additionalVolumeMultiplier); + + // + XSignal signal = {}; + signal = xTESTTrader.GenerateTradeSignal( + X_SIGNAL_LONG, + tp, + sl, + volume, + riskFree, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xTESTMagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int error = -1; + result = xTESTTrader.ExecuteSignal(signal, error); + if (result) + { + XTESTIssueSignalExecutionAlert(signal); + } + + // + return result; +} + +// +// Open Short Position ... +bool XTESTOpenShortPosition(double additionalVolumeMultiplier = 0) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double sl = 0; + double tp = xTESTMinRewardPerTrade; + double riskFree = xTESTRiskFreeTrades; + double riskFreeRate = xTESTRiskFreeRate; + double volume = XTESTCalculateVolume(additionalVolumeMultiplier); + + // + XSignal signal = {}; + signal = xTESTTrader.GenerateTradeSignal( + X_SIGNAL_SHORT, + tp, + sl, + volume, + riskFree, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xTESTMagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int error = -1; + result = xTESTTrader.ExecuteSignal(signal, error); + if (result) + { + XTESTIssueSignalExecutionAlert(signal); + } + + // + return result; +} + +// +// Open a Support Signal ... +bool XTESTOpenSupportTrade( + XSignal &supports[] // Holds Result ... +) +{ + // + bool result = false; + + // + // Check Can Trade ... + result = xTESTAllowLongTrades || xTESTAllowShortTrades; + if (!result) + { + return result; + } + + // + // Check Support Trades is Enable or not ... + bool isSupportTradesEnabled = + // + xTESTMaxAllowedSupportTrades > 0 && + xTESTMinRewardPerSupportTrades > 0 && + xTESTSupportTradesPriceDistance > 0 + // + ; + if (!isSupportTradesEnabled) + { + return result; + } + + // + // Recieve InDD Open Trades ... + XSignal inDDTrades[]; + xTESTTrader.GetInDrawDownTrades( + xTESTSupportTradesPriceDistance, + X_SIGNAL_UNKNOWN, + X_KIND_TRADE, + inDDTrades); + int inDDTradesCount = ArraySize(inDDTrades); + result = inDDTradesCount > 0; + if (!result) + { + return result; + } + + // + // Check Signals Exists ... + double longsForceVolume = 0; + double shortsForceVolume = 0; + bool hasLongSignal = XTESTCanOpenLongTrade(longsForceVolume); + bool hasShortSignal = XTESTCanOpenShortTrade(shortsForceVolume); + result = hasLongSignal || hasShortSignal; + if (!result) + { + return result; + } + + // + // Loop Through In DrawDown Trades ... + XSignal supportedSignals[]; + for (int i = 0; i < inDDTradesCount; i++) + { + // + // Retrieve Parent Signal ... + XSignal parent = inDDTrades[i]; + + // + // Check if Long Signal Happens ... + if (hasLongSignal && parent.type == X_SIGNAL_LONG) + { + // + // Generate Support Signal ... + XSignal sSignal = GenerateSupportSignal( + longsForceVolume, + X_SIGNAL_LONG, + parent); + + // + // Validate it ... + bool isValidSupport = IsValid(sSignal, xTESTMagicNumber); + if (!isValidSupport) + { + continue; + ; + } + + // + // Try To Execute Support Signal ... + int error = 0; + bool isExecuted = xTESTTrader.ExecuteSupportSignal( + sSignal, + error); + if (isExecuted) + { + // + if (!result) + { + result = true; + } + + // + Add( + sSignal, + supports); + + // + XTESTIssueSignalExecutionAlert(sSignal); + } + + // + continue; + } + + // + // Check if Short Signal Happens ... + if (hasShortSignal && parent.type == X_SIGNAL_SHORT) + { + // + // Generate Support Signal ... + XSignal sSignal = GenerateSupportSignal( + shortsForceVolume, + X_SIGNAL_SHORT, + parent); + + // + // Validate it ... + bool isValidSupport = IsValid(sSignal, xTESTMagicNumber); + if (!isValidSupport) + { + continue; + ; + } + + // + // Try To Execute Support Signal ... + int error = 0; + bool isExecuted = xTESTTrader.ExecuteSupportSignal( + sSignal, + error); + if (isExecuted) + { + // + if (!result) + { + result = true; + } + + // + Add( + sSignal, + supports); + + // + XTESTIssueSignalExecutionAlert(sSignal); + } + + // + continue; + } + } + + // + return result; +} + +// +// Close All InDrawDown Trades ... +void XTESTHandleCloseMaxDrawDownTrades() +{ + // + if (xTESTMaxAllowedDrawDownPerTrades > 0) + { + // + XSignal closed[]; + xTESTTrader.CloseInDrawDownTrades( + xTESTMaxAllowedDrawDownPerTrades, + closed); + + // + int count = ArraySize(closed); + if (count > 0) + { + XTESTIssueLongInDrawdownTradeClosed(); + } + } +} + +// +// Close All Too Old Trades ... +void XTESTHandleCloseTooOldTrades() +{ + // + // in DrawDown Trades ... + if (xTESTMaxInDrawDownTradeAge > 0) + { + // + XSignal oldTrades[]; + xTESTTrader.CloseLongTimeTrades( + xTESTMaxInDrawDownTradeAge, + _Period, + oldTrades); + + // + bool hasOldClosedTrades = ArraySize(oldTrades) > 0; + if (hasOldClosedTrades) + { + // + LogMessage("Old Trade Closed ..."); + } + } +} + +// +// END Provided Functions ... +// + +// +// START Private Functions ... +// + +// +// Calculating Volume for Tradings ... +double XTESTCalculateVolume( + double forceMultiplier = 0 // some times we get more than one signal at the same time, here we increase volume using this ... +) +{ + // + // Assign default Value ... + double result = xTESTStaticVolume; + + // + // we can count open trades and in draw down trades + // then do check volume based on it for gridding ... + XSignal openInProfitTrades[]; + xTESTTrader.GetInProfitTrades( + 0, + X_SIGNAL_UNKNOWN, + X_KIND_TRADE, + openInProfitTrades); + int openTrades = ArraySize(openInProfitTrades); + + // + // Calculate Normalized Multiplier ... + double mVolumeMultiplier = xTESTVolumeMultiplier <= 0 ? 1 : xTESTVolumeMultiplier; + double multiplier = mVolumeMultiplier; + multiplier = multiplier * openTrades; + if (multiplier < 1) + { + multiplier = 1; + } + + // + double growRate = xTESTBalance / xTESTDeposit; + if (growRate >= 1 && multiplier == 1) + { + // + double growDiff = growRate - 1; + if (growDiff < 1) + { + growRate = 1 + (growDiff * mVolumeMultiplier); + } + + // + multiplier = multiplier * growRate; + } + + // + result = multiplier * xTESTStaticVolume; + + // + // Apply Force Multiplier ... + if (forceMultiplier > 1) { + result *= forceMultiplier; + } + + // + // Check Max Allowed Lottage ... + double maxAllowedVolume = xTESTMaxSupportedVolumePerTradeInLots; + if (growRate >= 4 * mVolumeMultiplier) { + maxAllowedVolume *= mVolumeMultiplier; + } + + // + if ( + maxAllowedVolume > 0 && + result > maxAllowedVolume) + { + result = maxAllowedVolume; + } + + // + // Normalize Volume ... + result = NormalizeVolume(result); + + // + return result; +} + +// +// Calculate Signal TP and SL ... +XTPSL XTESTCalculateTPSL( + ENUM_X_SIGNAL_TYPE type // Position Type +) +{ + // + XTPSL result = {}; + + // + // Validate Args ... + if ( + type != X_SIGNAL_LONG && + type != X_SIGNAL_SHORT) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + + // + double ask = GetAsk(); + double bid = GetBid(); + double spread = GetSpread(); + double entry = isLong ? ask : bid; + + // + // TODO: Find Risk .. + double risk = 0; + + // + // Calculate Reward ... + double reward = PipsToPrice(xTESTMinRewardPerTradeInPips) + spread; + + // + // Calculate TP and SL ... + double tp = isLong ? entry + reward : entry - reward; + double sl = 0; + + // + result.type = type; + result.tp = tp; + result.sl = sl; + result.entry = entry; + // + // TODO: Calculate R2R ... + result.r2r = 0; + + // + return result; +} + +// +// Generate Support Signal for Specific Trade ... +XSignal GenerateSupportSignal( + double forceVolumeMultiplier, // how many time increase volume based on signal providers + ENUM_X_SIGNAL_TYPE type, // which type of support signal issued + XSignal &parent // generate support signal for which Trade Kind Position + ) +{ + // + XSignal result = {}; + + // + // Validate Type ... + bool isTypeValid = type == X_SIGNAL_LONG || type == X_SIGNAL_SHORT; + if (!isTypeValid) + { + return result; + } + + // + // Validate Parent Signal ... + bool isValidSignal = IsValid(parent, xTESTMagicNumber); + if (!isValidSignal) + { + return result; + } + + // + // Validate Parent is Kind ... + bool isKindValid = parent.kind == X_KIND_TRADE; + if (!isKindValid) + { + return result; + } + + // + // Check Parent Ticket ... + bool isValidTicket = parent.ticket > 0; + if (!isValidTicket) + { + return result; + } + + // + // Validate DrawDown ... + bool isInDD = parent.profit < 0; + if (!isInDD) + { + return result; + } + + // + // Calculate What we Want ... + // + bool isLong = type == X_SIGNAL_LONG; + + // + // Entry Price ... + // double entry = GetEntry(parent.symbol, type); + + // + // Required for Calculating RiskFree Level of Support Signals ... + double riskFreeRate = 0; + double riskFreePrice = 0; + bool canRiskFree = xTESTRiskFreeRate > 0; + + // + // TP ... + double tp = MathAbs(parent.tp - parent.entry) / 2; + // PriceToPips(MathAbs(parent.tp - parent.entry) / 2); + if (tp <= xTESTMinRewardPerSupportTrades) + { + tp = xTESTMinRewardPerSupportTrades; + } + else if ( + canRiskFree && + tp > xTESTMinRewardPerSupportTrades) + { + // + // Fill Risk Free Info ... + riskFreeRate = xTESTRiskFreeRate; + riskFreePrice = + isLong ? xTESTMinRewardPerSupportTrades : xTESTMinRewardPerSupportTrades; + } + + // + // SL ... + double sl = isLong ? 0 : 0; + + // + // VOLUME ... + int pOpenSupportCount = xTESTTrader.CountSupportedPositions(parent); + double volume = parent.volume * forceVolumeMultiplier; + + // + // Check and Normalize Volume based on MaxAllowed Volume ... + if (xTESTMaxSupportedVolumePerTradeInLots > 0 && volume > xTESTMaxSupportedVolumePerTradeInLots) { + volume = xTESTMaxSupportedVolumePerTradeInLots; + } + + // + // Normalize Volume ... + volume = NormalizeVolume(volume); + + // + // Generating Support Signal for Parent ... + result = xTESTTrader.GenerateSupportSignal( + type, + tp, + sl, + volume, + riskFreePrice, + riskFreeRate, + parent.ticket); + + // + return result; +} + +void XTESTIssueInitializationSucceedAlert() +{ + // + string message = "Initializion of (" + XTESTProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueDeinitializationSucceedAlert() +{ + // + string message = "De Initializion of (" + XTESTProviderName + " Provider" + ") Succeeded ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type) +{ + // + string typeStr = GetSignalType(type); + if (StringLen(typeStr) == 0) + { + return; + } + + // + string message = "Force Close " + typeStr + " Trades ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueMaxAllowedTradesReachedAlert() +{ + // + string message = "reached Max Allowed Same Time Trades ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueMaxAllowedFreeMarginReachedAlert() +{ + // + string message = "reached FreeMarigin For Open Trades ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueMinAllowedBalanceReachedAlert() +{ + // + string message = "doesn't have Minimum Balance For Open Trades ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueSignalExecutionAlert( + XSignal &signal // Executed Signal +) +{ + // + XTESTIssueAlert(signal); +} + +void XTESTIssueSignalExecutionError(int error) +{ + // + string message = GetSignalExecutionError(error); + if (StringLen(message) == 0) + { + return; + } + + // + XTESTIssueAlert(message); +} + +void XTESTIssueRiskFreeTradesAlert() +{ + // + string message = "Make Some Trades Risk Free ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueLongInProfitTradeClosed() +{ + // + string message = "Closed Long Time in Profit Trades ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueLongInDrawdownTradeClosed() +{ + // + string message = "Closed Long Time in Profit Trades ..."; + XTESTIssueAlert(message); +} + +void XTESTIssueAlert(string message) +{ + // + if (xTESTEnableAlerts) + { + SendAlert(message); + } + else + { + LogMessage(message); + } +} +void XTESTIssueAlert(XSignal &signal) +{ + // + string signalStr = xTESTTrader.ToString(signal); + XTESTIssueAlert(signalStr); + + // // + // if (xTESTEnableAlerts) + // { + // SendAlert(signal); + // } + // else + // { + // LogSignal(signal); + // } +} + +// +// END Private Functions ... +// diff --git a/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtm.indicator.helper.lib.mq5 b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtm.indicator.helper.lib.mq5 new file mode 100644 index 0000000..02c0a04 --- /dev/null +++ b/EURUSD-5M-V0.1/MQ5/Libraries/x-saherelm.xtm.indicator.helper.lib.mq5 @@ -0,0 +1,319 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTM Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "..\Libraries\x-saherelm.log.lib.mq5" +#include "..\Libraries\x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; + +// +// XTM Indicator Buffer Lines ... +enum ENUM_X_XTM_BUFFER_LINES +{ + X_XTM_MA_LINE = 0, + X_XTM_MC_COLOR_LINE = 1, + X_XTM_STATE_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +input group "XTM Indicator"; +input int xTMMaPeriod = 14; // Period +input int xTMMaShift = 0; // Shift +input ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_WEIGHTED; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTMHandler = INVALID_HANDLE; +double xTMMaBuffer[]; +double xTMStateBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Init Indicators ... +bool XTMInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Handler ... + ArraySetAsSeries(xTMMaBuffer, true); + ArraySetAsSeries(xTMStateBuffer, true); + xTMHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtm.indicator", + // + // Inputs ... + xTMMaPeriod, + xTMMaShift, + xTMMaMethod, + xTMMaAppliedTo); + if (xTMHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTM Indicator: " + (string)GetLastError()); + return result; + } + + // + // xTMOHandler ... + // ArraySetAsSeries(xTMOBuffer, true); + // xTMOHandler = iCustom( + // _Symbol, + // _Period, + // "x-saherelm.xma.indicator", + // // + // // Inputs ... + // xTMMaPeriod, + // xTMMaShift, + // MODE_SMA, + // PRICE_OPEN); + // if (xTMOHandler == INVALID_HANDLE) + // { + // // + // LogMessage("failed to Initialize XMA Indicator: " + (string)GetLastError()); + // return result; + // } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XTMReleaseHandlers() +{ + IndicatorRelease(xTMHandler); + // IndicatorRelease(xTMOHandler); +} + +// +// Handle Reading Buffers ... +void XTMReadBuffers( + int xTMItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // Ma Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_MA_LINE, + 0, + xTMItemsPerTick, + xTMMaBuffer); + + // + // State Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_STATE_LINE, + 0, + xTMItemsPerTick, + xTMStateBuffer); + + // + // XTMO Buffer ... + // CopyBuffer( + // xTMOHandler, + // 0, + // 0, + // xTMItemsPerTick, + // xTMOBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START Signal Related Conditions ... +// + +// +// XTM Long Conditions ... +bool XTMHasLongConditions( + int xTMItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isVale = XTMIsVale(); + + // + result = + // + isVale + // + ; + + // + return result; +} + +// +// XTM Short Conditions ... +bool XTMHasShortConditions( + int xTMItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + bool result = false; + + // + bool isPeak = XTMIsPeak(); + + // + result = + // + isPeak + // + ; + + // + return result; +} + +// +// END Signal Related Conditions ... +// + +// +// START XTM Custom Functions ... +// + +// +// Find Peak based On this Indicator ... +bool XTMIsPeak() +{ + // + bool result = false; + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + 20, + 5, + xTMMaBuffer); + + // + // Must Increasing ... + bool isDecreasing = IsDecreasing( + 5, + 1, + xTMMaBuffer); + + // + // Calculate Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// Find Vale based On this Indicator ... +bool XTMIsVale() +{ + // + bool result = false; + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + 5, + 1, + xTMMaBuffer); + + // + // Must Increasing ... + bool isDecreasing = IsDecreasing( + 20, + 5, + xTMMaBuffer); + + // + // Calculate Result ... + result = + // + isIncreasing + // + && + // + isDecreasing + // + ; + + // + return result; +} + +// +// END XTM Custom Functions ... +// diff --git a/EURUSD-5M-V0.1/Version.txt b/EURUSD-5M-V0.1/Version.txt new file mode 100644 index 0000000..15c2a42 --- /dev/null +++ b/EURUSD-5M-V0.1/Version.txt @@ -0,0 +1 @@ +packed at: Sunday, December 3, 2023 7:12:48 PM \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..40eff0f --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# xSaherElmEAPacks + +this is a submodule repo of **xTradeBotWorkspace** which contains all published packs of SaherElm IT Center EAs. + +## Maintainer + +Hadi Khazaee asl + +[https://www.saherelm.ir](https://www.saherelm.ir) + +[hadi_khazaee_asl@yahoo.com](mailto:hadi_khazaee_asl@yahoo.com) \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/Ex4/Experts/x-saherelm.ea.ex4 b/XAUUSD-15M-V1.0/Ex4/Experts/x-saherelm.ea.ex4 new file mode 100644 index 0000000..e277c98 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Experts/x-saherelm.ea.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.ma.ex4 b/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.ma.ex4 new file mode 100644 index 0000000..9829822 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.ma.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.xrange.ex4 b/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.xrange.ex4 new file mode 100644 index 0000000..c454474 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.xrange.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.xtpow.ex4 b/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.xtpow.ex4 new file mode 100644 index 0000000..6e81928 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Indicators/x-saherelm.xtpow.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.dialog.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.dialog.ex4 new file mode 100644 index 0000000..b92c876 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.dialog.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.draw.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.draw.lib.ex4 new file mode 100644 index 0000000..99f8ece Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.draw.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.indicator.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.indicator.lib.ex4 new file mode 100644 index 0000000..56a524e Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.indicator.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.lib.ex4 new file mode 100644 index 0000000..e295982 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.log.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.log.lib.ex4 new file mode 100644 index 0000000..bf2e8ee Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.log.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.models.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.models.lib.ex4 new file mode 100644 index 0000000..aac8c2f Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.models.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.signal.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.signal.lib.ex4 new file mode 100644 index 0000000..ac56a7d Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.signal.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.x.signal.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.x.signal.lib.ex4 new file mode 100644 index 0000000..143e2bd Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.x.signal.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.xr.signal.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.xr.signal.lib.ex4 new file mode 100644 index 0000000..8013260 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.xr.signal.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.xtpw.signal.lib.ex4 b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.xtpw.signal.lib.ex4 new file mode 100644 index 0000000..67576a4 Binary files /dev/null and b/XAUUSD-15M-V1.0/Ex4/Libraries/x-saherelm.xtpw.signal.lib.ex4 differ diff --git a/XAUUSD-15M-V1.0/MQ4/Experts/x-saherelm.ea.mq4 b/XAUUSD-15M-V1.0/MQ4/Experts/x-saherelm.ea.mq4 new file mode 100644 index 0000000..7af93af --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Experts/x-saherelm.ea.mq4 @@ -0,0 +1,1116 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XST Strategy Expert Advisor +// --------------------------------------------- +// saherelm implementation of strategy expert advisor ... +// in this EA, we try to combine multiple tools, to ashive best +// results ... +// +// ShortName: XST +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +989121694056 +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XST Strategy Expert Advisor" +#property strict + +// +// START Inputs ... +// +// +// Signal Prefixe ... +input string signalPrefix = "XST_EA"; // Signal Prefix + +// +// Signal Draw Specifications ... +input string bullishSignalLabel = "X_BUY"; // Bullish Signal Label +input color bullishSignalColor = clrAqua; // Bullish Signal Color + +// +input string bearishSignalLabel = "X_SELL"; // Bearish Signal Label +input color bearishSignalColor = clrFuchsia; // Bearish Signal Color + +// +input color signalEntryColor = clrAquamarine; // Signal Entry Ptice Color +input color signalSLColor = clrRed; // Signal SL Color +input color signalTPColor = clrGreen; // Signal TP Color + +// +input int candleGapBetweenSignals = 7; // How many Candle waits to new Signal from last one + +// +// Trade ... +input bool allowTrade = true; // Allow Trade Based on given Signals +input bool allowLongTrades = true; // Allow Long Trades +input bool allowShortTrades = true; // Allow Short Trades + +// +// Balance and Finanical Specifications ... +input double lotsPerTradePercent = 0.00001; // Lots Per Trade Percent +input int maxOpenTrades = 4; // Maximum Open Trade +input double maxDrawdownPercentPerPTrade = 0.1; // Maximum DrawDown Per Trade +input double minBalancePercent = 0.5; // Minimum Balance for Trading +input double maxEquityPercent = 0.1; // Maximum Trade Equity + +// +// START Global Definitions: Variables, Properties and etc ... +// +int lastSignalledBar = 0; + +// +// Includes our shared library ... +#include "../Libraries/x-saherelm.lib.mq4" + +// +// TODO: Complete this ... +// Include Dialog Handler ... +// #include "../Libraries/x-saherelm.dialog.mq4" + +// +// Includes our shared library ... +#include "../Libraries/x-saherelm.signal.lib.mq4" + +// +// Add Logging Inputs ... +// +input string xAlertingLabel = "- Alerts -"; // --> Alerts <-- + +// +// Alerts ... + +// +// Alert Bot Events ... +input bool logEvents = true; // Log Events +input bool alertEvents = true; // Alert Events + +// +// Alert Types ... +input bool terminalAlert = false; // Terminal Alert +input bool pushAlert = false; // Push Notification Alerts + +// +// Positions ... +input bool alertPositions = true; // Alert Positions +input bool longPositionAlerts = true; // Alert Long Positions +input bool shortPositionAlerts = true; // Alert Short Positions + +// +input bool enableNewDayAlert = true; // New Day Alert +input bool enableNewHourAlert = true; // New Hour Alert + +// +int maxMarketLength = 0; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// Start Event Handlers ... +// +// +// Initialization ... +int OnInit() { + // + // Validate Inputs ... + bool inputsNotValiid = + // + // EA ... + maxOpenTrades <= 0 + || maxEquityPercent < 0 + || minBalancePercent < 0 + || lotsPerTradePercent < 0 + || maxDrawdownPercentPerPTrade < 0 + ; + + // + if (inputsNotValiid) { + return INIT_PARAMETERS_INCORRECT; + } + + // + totalSignals = 0; + totalLongSignals = 0; + totalShortSignals = 0; + + // + initialBalance = 0; + + // + // START Define Array Series ... + // + // + // END Define Array Series ... + // + + // + // here we specify logging enabled or not ... + enableLogging = true; + + // + // this is a Tag which attached to our Logger ... + logTag = "XST"; + + // + ClearSignalConditions(); + + // + maxMarketLength = MathMax(0, GetDailyCandleCount()); + + // + // TODO: Complete this ... + // try to Create App Window ... + // CreateDialog(logTag); + + // + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) { + // + // TODO: Complete this ... + // Destroy Dialog ... + // DestroyDialog(reason); +} + +// +// Handling Chart Events ... +void OnChartEvent( + const int id, // event ID + const long& lparam, // event parameter of the long type + const double& dparam, // event parameter of the double type + const string& sparam // event parameter of the string type +) { + // + // TODO: Complete this ... + // DialogChartEvent( + // id, + // lparam, + // dparam, + // sparam + // ); +} + +// +// Ticker Event Handler ... +void OnTick() { + // + isNewDay = IsNewDay(); + if ( + isNewDay + && enableNewDayAlert + ) { + // + SendAlert( + StringConcatenate( + "New Day ..." + ) + ); + } + + // + isNewHour = IsNewHour(); + if ( + isNewHour + && enableNewHourAlert + ) { + // + SendAlert( + StringConcatenate( + "New Hour ..." + ) + ); + } + + // + // Process Signals to Open Positions ... + ProcessSignals(); + + // + // Checking State for Signal Handling ... + CheckState(); + + // + // Process Open Positions for Trailing Stop Loss or Close ... + ProcessOpenPositions(); +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Check State for Signal Handling ... +void CheckState() { + // + // Here we Must to Check Market State for enable or disable + // Signal Handlers and also make dection to close all long/short + // trades ... +} + +// +// Calculate Signals and Process Based on Exists Signals ... +void ProcessSignals() { + // + XSignalRequest request = {}; + request.type = X_SIGNAL_NONE; + request.hasSignal = false; + + // + // Prevent Multiple Calculating on Same Bars ... + isNewBar = IsNewBar(); + if (isNewBar) { + countedBars++; + } + + // + if (countedBars < maxMarketLength) { + return; + } + + // + bool allowDoTrade = true; + + // + // Check Balance ... + if (initialBalance > 0) { + // + // Retrieve Account Balance ... + double balance = AccountInfoDouble(ACCOUNT_BALANCE); + double minimumBalanceForTrade = + balance > initialBalance + ? + minBalancePercent * balance + : + minBalancePercent * initialBalance; + + // + // Retrieve Account Equity ... + double equity = AccountInfoDouble(ACCOUNT_EQUITY); + double maxAllowedEquity = balance - (balance * maxEquityPercent); + + // + // Retrieve Free Marigin ... + double freeMargin = AccountFreeMargin(); + double maximumMariginRisk = balance - (balance * maxEquityPercent); + + // + if ( + // + // Do not Open Positions if equity not passed ... + equity < maxAllowedEquity || + // + // Do not Open Positions if free margin not passed ... + freeMargin <= maximumMariginRisk || + // + // Do not open positions if balance less than minimum ... + balance <= minimumBalanceForTrade + ) { + // + static bool tradingPauseAlerted; + + // + allowDoTrade = false; + + // + if (!tradingPauseAlerted) { + // + string message = StringConcatenate( + "Trading Pause => ", + "Balance: ", balance, + ", Equity: ", equity, + ", FreeMargin: ", freeMargin + ); + + // + LogMessage(message); + SendAlert(message); + + // + tradingPauseAlerted = true; + } + } + } + + // + // Retrieve Signal Exists ... + request = GenerateSignal(0); + + // + // Prevent doing anything else, if there is no signals ... + if ( + !allowDoTrade || + !request.hasSignal || + request.type == X_SIGNAL_NONE + ) { + return; + } + + // + bool hasLongSignal = request.type == X_SIGNAL_LONG; + + // + // Check last Signalled Bar with Counted Bars ... + // Prevent Multiple Signalling on Same Bar ... + bool isInLastSignalledBars = false; + for (int i=0; i < candleGapBetweenSignals; i++) { + // + isInLastSignalledBars = + isInLastSignalledBars + || lastSignalledBar == countedBars - i + ; + } + if (isInLastSignalledBars) { + // + // Clear Signal Conditions ... + if (hasLongSignal) { + ClearLongSignalConditions(); + } else { + ClearShortSignalConditions(); + } + + // + return; + } + + // + // increase last signalled bar ... + lastSignalledBar = countedBars; + + // + // Calculate Can Trade or not ... + allowDoTrade = allowTrade + && ( + hasLongSignal ? + allowLongTrades : + allowShortTrades + ); + + // + // Chack Maximum Open Positions ... + int openTrades = CountOpenTrades(); + if (maxOpenTrades > 0) { + // + if (openTrades >= maxOpenTrades) { + // + allowDoTrade = false; + + // + if (!allowDoTrade) { + // + string message = StringConcatenate( + "Trading Pause => ", + "Max Open Trades (", + maxOpenTrades, + ") reached ..." + ); + + // + LogMessage(message); + SendAlert(message); + } + } + } + + // + // Check Trading is Enable or not ... + // nothing to do if trading is disabled ... + if (!allowDoTrade) { + // + // Clear Signal Conditions ... + if (hasLongSignal) { + ClearLongSignalConditions(); + } else { + ClearShortSignalConditions(); + } + + // + string message = StringConcatenate( + "Trading Not Allowed ..." + ); + + // + LogMessage(message); + SendAlert(message); + return; + } + + // + // Retrieve Signal Lots Per Trade ... + double lPTradePercent = GetSignalLottage( + request.signal, + lotsPerTradePercent + ); + + // + bool isPositionOpened = TradeSignal( + request.signal, + lPTradePercent, + // + bullishSignalLabel, + bullishSignalColor, + bearishSignalLabel, + bearishSignalColor + ); + + // + totalSignals++; + if (hasLongSignal) { + // + totalLongSignals++; + ClearLongSignalConditions(); + } else { + // + totalShortSignals++; + ClearShortSignalConditions(); + } + + // + if (isPositionOpened) { + // + bool canAlert = + alertPositions + && ( + hasLongSignal ? + longPositionAlerts + : + shortPositionAlerts + ); + + // + if (canAlert) { + // + // Alert Message ... + string message = StringConcatenate( + "Trade on Signal ID: ", request.signal.id, + ", ProvidedBy: ", GetSignalProviderIdentifier(request.signal.provider), + ", Entry: ", request.signal.entry, + ", TP: ", request.signal.tp + ); + + // + // Terminal Alert ... + if (terminalAlert) { + Alert(message); + } + + // + // Push Alert ... + if (pushAlert) { + SendNotification(message); + } + } + } +} + +// +// Process All Open Positions ... +void ProcessOpenPositions() { + // + // XSignalling ... + if (enableXSignalling) { + // + // Close All XXX Provided Signals on it's Specific Condition ... + if (xCloseLongTrades) { + // + CloseAllProviderLongTrades(X_XXX_PROVIDER); + + // + xCloseLongTrades = false; + } + + // + if (xCloseShortTrades) { + // + CloseAllProviderShortTrades(X_XTPW_PROVIDER); + + // + xCloseShortTrades = false; + } + + // + // Close Maximum DrawDown Passed Trades ... + + // + // Longs ... + bool hasClosedLongInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( + xLongMaxDrawdownPerTradePercent, + X_SIGNAL_LONG, + X_XXX_PROVIDER + ); + + // + // Shorts ... + bool hasClosedShortInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( + xShortMaxDrawdownPerTradePercent, + X_SIGNAL_SHORT, + X_XXX_PROVIDER + ); + + // + // Close All Long Time Trades based on Provider provided Length ... + bool hasClosedLongTimeTrade = CloseAllLongTimeTrades( + xMaximumCandlesPerTrade, + X_XXX_PROVIDER + ); + + // + if ( + hasClosedLongTimeTrade + || hasClosedLongInDrawDownLongTrade + || hasClosedShortInDrawDownLongTrade + ) { + xFailedSignals++; + } + } + + // + // XR Signalling ... + if (enableXRSignalling) { + // + if (xRCloseLongTrades) { + // + CloseAllProviderLongTrades(X_XR_PROVIDER); + + // + xRCloseLongTrades = false; + } + + // + if (xRCloseShortTrades) { + // + CloseAllProviderShortTrades(X_XR_PROVIDER); + + // + xRCloseShortTrades = false; + } + + // + // Close Maximum DrawDown Passed Trades ... + + // + // Longs ... + bool hasClosedLongInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( + xRLongMaxDrawdownPerTradePercent, + X_SIGNAL_LONG, + X_XR_PROVIDER + ); + + // + // Shorts ... + bool hasClosedShortInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( + xRShortMaxDrawdownPerTradePercent, + X_SIGNAL_SHORT, + X_XR_PROVIDER + ); + + // + // Close All Long Time Trades based on Provider provided Length ... + bool hasClosedLongTimeTrade = CloseAllLongTimeTrades( + xRMaximumCandlesPerTrade, + X_XR_PROVIDER + ); + + // + if ( + hasClosedLongTimeTrade + || hasClosedLongInDrawDownLongTrade + || hasClosedShortInDrawDownLongTrade + ) { + xRFailedSignals++; + } + } + + // + // XTPW Signalling ... + if (enableXTPWSignalling) { + // + if (xTPWCloseLongTrades) { + // + CloseAllProviderLongTrades(X_XTPW_PROVIDER); + + // + xTPWCloseLongTrades = false; + } + + // + if (xTPWCloseShortTrades) { + // + CloseAllProviderShortTrades(X_XTPW_PROVIDER); + + // + xTPWCloseShortTrades = false; + } + + // + // Close Maximum DrawDown Passed Trades ... + + // + // Longs ... + bool hasClosedLongInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( + xTPWLongMaxDrawdownPerTradePercent, + X_SIGNAL_LONG, + X_XTPW_PROVIDER + ); + + // + // Shorts ... + bool hasClosedShortInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( + xTPWShortMaxDrawdownPerTradePercent, + X_SIGNAL_SHORT, + X_XTPW_PROVIDER + ); + + // + // Close All Long Time Trades based on Provider provided Length ... + bool hasClosedLongTimeTrade = CloseAllLongTimeTrades( + xTPWMaximumCandlesPerTrade, + X_XTPW_PROVIDER + ); + + // + if ( + hasClosedLongTimeTrade + || hasClosedLongInDrawDownLongTrade + || hasClosedShortInDrawDownLongTrade + ) { + xTPWFailedSignals++; + } + } + + // + // Close Maximum DrawDown Passed Trades ... + // this is the Maximum Controller ... + // + double maxOfXPercent = enableXSignalling ? + MathMax( + xLongMaxDrawdownPerTradePercent, + xShortMaxDrawdownPerTradePercent + ) : 0 + ; + + // + double maxOfXRPercent = enableXRSignalling ? + MathMax( + xRLongMaxDrawdownPerTradePercent, + xRShortMaxDrawdownPerTradePercent + ) : 0 + ; + + // + double maxOfXTPWPercent = enableXTPWSignalling ? + MathMax( + xTPWLongMaxDrawdownPerTradePercent, + xTPWShortMaxDrawdownPerTradePercent + ) : 0 + ; + + // + double maxDrawDownPercent = MathMax( + maxOfXPercent, + maxOfXRPercent + ); + maxDrawDownPercent = MathMax( + maxDrawDownPercent, + maxOfXTPWPercent + ); + maxDrawDownPercent = MathMax( + maxDrawDownPercent, + maxDrawdownPercentPerPTrade + ); + + // + // we Calculate Max DrawDown Percent Per Trade ... + // then try to Close based on them ... + bool hasClosedInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( + maxDrawDownPercent + ); +} + +// +// Send Special Type of Alerts ... +void SendAlert(string message) { + // + if ( + !logEvents + && !alertEvents + ) { + return; + } + + // + // Log Handling ... + if (logEvents) { + LogMessage(message); + } + + // + // Alert Handling ... + if (alertEvents) { + // + // Terminal Alert ... + if (terminalAlert) { + Alert(message); + } + + // + // Push Alert ... + if (pushAlert) { + SendNotification(message); + } + } +} +// +// END Functions ... +// + +// +// +// Calculate Signal ... +// in this function we calculate a signal exists in +// specific bar or not ... +XSignalRequest GenerateSignal( + const int bar_index // Bar Index ... +) { + // + // create temp result ... + XSignalRequest result = {}; + result.hasSignal = false; + result.type = X_SIGNAL_NONE; + result.provider = X_UNKNOWN_PROVIDER; + + // + bool hasSignal = false; + bool hasLongSignal = false; + bool hasShortSignal = false; + + // + XSignal signal = {}; + + // + // Define Template Signal Requests for Managing Multiple Signals ... + // + // X ... + XSignalRequest xLongSignalRequest = {}; + XSignalRequest xShortSignalRequest = {}; + // + // XR ... + XSignalRequest xrLongSignalRequest = {}; + XSignalRequest xrShortSignalRequest = {}; + // + // XTPW ... + XSignalRequest xTPWLongSignalRequest = {}; + XSignalRequest xTPWShortSignalRequest = {}; + + // + // START XR Signal Handler ... + // + // + if (enableXRSignalling) { + // + CheckXRSignalHandler( + bar_index + ); + + // + // Long Trades ... + if (allowTrade && allowLongTrades) { + // + if (xRWaitForLongSignals) { + // + CheckXRLongSignalConditions( + bar_index + ); + + // + xrLongSignalRequest = GenerateXRSignal( + X_SIGNAL_LONG, + signalPrefix, + bar_index + ); + + // + if (xrLongSignalRequest.hasSignal) { + // + // Here we can Check and Filter Signals Based On State ... + bool isReady = IsReadyForXRSignals( + xrLongSignalRequest.signal + ); + + // + if (isReady && xRWaitForLongSignals) { + // + hasLongSignal = true; + signal = xrLongSignalRequest.signal; + } else { + ClearXRLongSignalConditions(); + } + } + } else { + ClearXRLongSignalConditions(); + } + } + + // + // Short Trades ... + if (allowTrade && allowShortTrades) { + // + if (xRWaitForShortSignals) { + // + CheckXRShortSignalConditions( + bar_index + ); + + // + xrShortSignalRequest = GenerateXRSignal( + X_SIGNAL_SHORT, + signalPrefix, + bar_index + ); + + // + if (xrShortSignalRequest.hasSignal) { + // + // Here we can Check and Filter Signals Based On State ... + bool isReady = IsReadyForXRSignals( + xrShortSignalRequest.signal + ); + + // + if (isReady && xRWaitForShortSignals) { + // + hasShortSignal = true; + signal = xrShortSignalRequest.signal; + } else { + ClearXRShortSignalConditions(); + } + } + } else { + ClearXRShortSignalConditions(); + } + } + } + // + // END XR Signal Handler ... + // + + // + // START XTPW Signal Handler ... + // + if (enableXTPWSignalling) { + // + CheckXTPWSignalHandler( + bar_index + ); + + // + // Long Trades ... + if (allowTrade && allowLongTrades) { + // + if (xTPWWaitForLongSignals) { + // + CheckXTPWLongSignalConditions( + bar_index + ); + + // + xTPWLongSignalRequest = GenerateXTPWSignal( + X_SIGNAL_LONG, + signalPrefix, + bar_index + ); + + // + if (xTPWLongSignalRequest.hasSignal) { + // + // Here we can Check and Filter Signals Based On State ... + bool isReady = IsReadyForXTPWSignals( + xTPWLongSignalRequest.signal + ); + + // + if (isReady && xTPWWaitForLongSignals) { + // + hasLongSignal = true; + signal = xTPWLongSignalRequest.signal; + } else { + ClearXTPWLongSignalConditions(); + } + } + } else { + ClearXTPWLongSignalConditions(); + } + } + + // + // Short Trades ... + if (allowTrade && allowShortTrades) { + // + if (xTPWWaitForShortSignals) { + // + CheckXTPWShortSignalConditions( + bar_index + ); + + // + xTPWShortSignalRequest = GenerateXTPWSignal( + X_SIGNAL_SHORT, + signalPrefix, + bar_index + ); + + // + if (xTPWShortSignalRequest.hasSignal) { + // + // Here we can Check and Filter Signals Based On State ... + bool isReady = IsReadyForXTPWSignals( + xTPWShortSignalRequest.signal + ); + + // + if (isReady && xTPWWaitForShortSignals) { + // + hasShortSignal = true; + signal = xTPWShortSignalRequest.signal; + } else { + ClearXTPWShortSignalConditions(); + } + } + } else { + ClearXTPWShortSignalConditions(); + } + } + } + // + // END XTPW Signal Handler ... + // + + // + // START X Signal Handler ... + // + // + if (enableXSignalling) { + // + CheckXSignalHandler( + bar_index + ); + + // + // Long Trades ... + if (allowTrade && allowLongTrades) { + // + if (xWaitForLongSignals) { + // + CheckXLongSignalConditions( + bar_index + ); + + // + xLongSignalRequest = GenerateXSignal( + X_SIGNAL_LONG, + signalPrefix, + bar_index + ); + + // + if (xLongSignalRequest.hasSignal) { + // + // Here we can Check and Filter Signals Based On State ... + bool isReady = IsReadyForXSignals( + xLongSignalRequest.signal + ); + + // + if (isReady && xWaitForLongSignals) { + // + hasLongSignal = true; + signal = xLongSignalRequest.signal; + } else { + ClearXLongSignalConditions(); + } + } + } else { + ClearXLongSignalConditions(); + } + } + + // + // Short Trades ... + if (allowTrade && allowShortTrades) { + // + if (xWaitForShortSignals) { + // + CheckXShortSignalConditions( + bar_index + ); + + // + xShortSignalRequest = GenerateXSignal( + X_SIGNAL_SHORT, + signalPrefix, + bar_index + ); + + // + if (xShortSignalRequest.hasSignal) { + // + // Here we can Check and Filter Signals Based On State ... + bool isReady = IsReadyForXSignals( + xShortSignalRequest.signal + ); + + // + if (isReady && xWaitForShortSignals) { + // + hasShortSignal = true; + signal = xShortSignalRequest.signal; + } else { + ClearXShortSignalConditions(); + } + } + } else { + ClearXShortSignalConditions(); + } + } + } + // + // END XR Signal Handler ... + // + + // + hasSignal = hasLongSignal || hasShortSignal; + + // + if (!hasSignal) { + // + signal.type = X_SIGNAL_NONE; + result.type = X_SIGNAL_NONE; + } + + // + // Normalize TP, SL and Entry Price ... + signal.tp = NormalizeDouble(signal.tp, _Digits); + signal.sl = NormalizeDouble(signal.sl, _Digits); + signal.entry = NormalizeDouble(signal.entry, _Digits); + + // + result.signal = signal; + result.type = signal.type; + result.hasSignal = hasSignal; + result.provider = signal.provider; + + // + // Return Result ... + return result; +} diff --git a/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.ma.mq4 b/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.ma.mq4 new file mode 100644 index 0000000..e3a5737 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.ma.mq4 @@ -0,0 +1,173 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MA Indicator +// --------------------------------------------- +// saherelm implementation of above indicator ... +// this indicator uses two ma line: +// - fast ma; +// - slow ma; +// +// 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 MA Indicator" +#property strict + +// +// START Inputs ... +// +// +// Fast MA ... +input int maLength = 20; // MA Length +input int maShift = 0; // MA Shift +input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method +input ENUM_APPLIED_PRICE maAppliedPrice = PRICE_CLOSE; // MA Applied Price + +// +// START Global Definitions: Variables, Properties and etc ... +// +#property indicator_chart_window + +// +#property indicator_buffers 1 + +// +#property indicator_plots 1 + +// +// Start Define Indicator Buffer Styles ... +// +// +// Fast Ma Buffer ... +#property indicator_label1 "Ma" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrYellow +#property indicator_style1 STYLE_DOT +#property indicator_width1 2 + +// +// End Define Indicator Buffer Styles ... +// + +// +// Buffers ... +#define maBufferIndex 0 + +double maBuffer[]; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// Start Event Handlers ... +// +// +// Initialization ... +int OnInit() { + // + // Initialize what we want ... + if (maLength <= 0) { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Start Set Index Buffers ... + // + // + // Ma ... + SetIndexBuffer(maBufferIndex, maBuffer); + SetIndexDrawBegin(maBufferIndex, maLength + 1); + // + // End Set Index Buffers ... + // + + // + return INIT_SUCCEEDED; +} + +// +// Calculating what we want ... +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[] +) { + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, maLength); + + // + // input variable, we return 0 means nothing passed ... + if (rates_total < maxLength) { + return 0; + } + + // + // found which candles calculated before ... + limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1; + + // + // this is the main loop of calculations, for each bar index ... + for (int i = limit - 1; i >= 0; i--) { + // + // Start Calculation here ... + // i is bar_index ... + + // + // Calculate Ma ... + CalculateMa(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Calculating Ma ... +void CalculateMa( + const int &bar_index +) { + // + // Calculating Fast Ma ... + double ma = iMA( + _Symbol, + _Period, + maLength, + maShift, + maMethod, + maAppliedPrice, + bar_index + ); + + // + maBuffer[bar_index] = ma; +} +// +// END Functions ... +// \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.xrange.mq4 b/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.xrange.mq4 new file mode 100644 index 0000000..1359f57 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.xrange.mq4 @@ -0,0 +1,294 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XRange Indicator +// --------------------------------------------- +// saherelm implementation of above indicator ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XRange Indicator" +#property strict + +// +// START Inputs ... +// +input int marketLength = 14; +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 + +// +#property indicator_plots 3 + +// +// Start Define Indicator Buffer Styles ... +// +// +// Highest High Buffer ... +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrGreen +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Lowest Low Buffer ... +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Middle Buffer ... +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrYellow +#property indicator_style3 STYLE_DASH +#property indicator_width3 1 +// +// End Define Indicator Buffer Styles ... +// + +// +// Buffers ... +// +#define highestHighBufferIndex 0 +#define lowestLowBufferIndex 1 +#define middleBufferIndex 2 + +// +double highestHighBuffer[]; +double lowestLowBuffer[]; +double middleBuffer[]; + +// +datetime startTime; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// Start Event Handlers ... +// +// +// Initialization ... +int OnInit() { + // + // Initialize what we want ... + if ( + marketLength <= 0 + ) { + return INIT_PARAMETERS_INCORRECT; + } + + // + string hhLbl = StringConcatenate( + "XR HH(", marketLength, ")" + ); + SetIndexBuffer(highestHighBufferIndex, highestHighBuffer); + SetIndexLabel(highestHighBufferIndex, hhLbl); + + // + string llLbl = StringConcatenate( + "XR LL(", marketLength, ")" + ); + SetIndexBuffer(lowestLowBufferIndex, lowestLowBuffer); + SetIndexLabel(lowestLowBufferIndex, llLbl); + + // + string midLbl = StringConcatenate( + "XR Mid(", marketLength, ")" + ); + SetIndexBuffer(middleBufferIndex, middleBuffer); + SetIndexLabel(middleBufferIndex, midLbl); + + // + return INIT_SUCCEEDED; +} + +// +// Calculating what we want ... +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[] +) { + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, marketLength); + + // + // input variable, we return 0 means nothing passed ... + if (rates_total < maxLength) { + return 0; + } + + // + // found which candles calculated before ... + limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1; + + // + // this is the main loop of calculations, for each bar index ... + for (int i = limit - 1; i >= 0; i--) { + // + // Start Calculation here ... + // i is bar_index ... + + // + // Calculations ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Calculations ... +void CalculateBuffers( + const int &bar_index +) { + // + // Retrieve Bar Time ... + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + if (startTime == 0) { + // + startTime = barTime; + SetIndicatorBuffersNone(bar_index); + return; + } + + // + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime + ); + + // + int startDistance = startBarIndex - bar_index; + if (startDistance < marketLength) { + // + SetIndicatorBuffersNone(bar_index); + return; + } + + // + // Highest High ... + int hhIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + marketLength, + bar_index + ); + double hh = iHigh( + _Symbol, + _Period, + hhIdx + ); + highestHighBuffer[bar_index] = hh; + + // + // Lowest Low ... + int llIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + marketLength, + bar_index + ); + double ll = iLow( + _Symbol, + _Period, + llIdx + ); + lowestLowBuffer[bar_index] = ll; + + // + // Middle Buffer ... + double mid = (hh + ll) / 2; + middleBuffer[bar_index] = mid; + + // + // Reset Start Time ... + startTime = 0; +} + +// +void SetIndicatorBuffersNone( + const int bar_index +) { + // + int lastBarIndex = bar_index + 1; + + // + double lastHighestHigh; + double lastLowestLow; + + // + // Highest High ... + if (ArraySize(highestHighBuffer) > lastBarIndex) { + lastHighestHigh = highestHighBuffer[lastBarIndex]; + } else { + lastHighestHigh = 0; + } + + // + // Lowest Low ... + if (ArraySize(lowestLowBuffer) > lastBarIndex) { + lastLowestLow = lowestLowBuffer[lastBarIndex]; + } else { + lastLowestLow = 0; + } + + // + highestHighBuffer[bar_index] = lastHighestHigh; + lowestLowBuffer[bar_index] = lastLowestLow; + + // + double mid = (lastHighestHigh + lastLowestLow) / 2; + middleBuffer[bar_index] = mid; +} +// +// END Functions ... +// \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.xtpow.mq4 b/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.xtpow.mq4 new file mode 100644 index 0000000..46ff59e --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Indicators/x-saherelm.xtpow.mq4 @@ -0,0 +1,275 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center Trend Power Indicator +// --------------------------------------------- +// saherelm implementation of above indicator ... +// this indicator uses two ma line: +// - fast ma; +// - slow ma; +// +// 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 MA Indicator" +#property strict + +// +// START Inputs ... +// +input int marketLength = 7; // Market Length +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +#property indicator_separate_window + +// +#property indicator_plots 3 +#property indicator_buffers 3 +#property indicator_minimum 0 +#property indicator_maximum 100 + +// +#property indicator_levelcolor clrGray +#property indicator_levelstyle STYLE_DOT + +// +// Start Define Indicator Buffer Styles ... +// +#property indicator_type1 DRAW_HISTOGRAM +#property indicator_color1 clrLime +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +#property indicator_type2 DRAW_HISTOGRAM +#property indicator_color2 clrRed +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrYellow +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// End Define Indicator Buffer Styles ... +// + +// +// Buffers ... +#define powerUpBufferIndex 0 +#define powerDownBufferIndex 1 +#define signalBufferIndex 2 + +double powerUpBuffer[]; +double powerDownBuffer[]; +double signalBuffer[]; + +// +#include "../Libraries/x-saherelm.lib.mq4" +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// Start Event Handlers ... +// +// +// Initialization ... +int OnInit() { + // + // Initialize what we want ... + if (marketLength <= 0) { + return INIT_PARAMETERS_INCORRECT; + } + + // + SetLevelValue(0, 0.0); + IndicatorSetString(INDICATOR_LEVELTEXT,0,""); + + // + SetLevelValue(1, 20.0); + IndicatorSetString(INDICATOR_LEVELTEXT,1,""); + + // + SetLevelValue(2, 50); + IndicatorSetString(INDICATOR_LEVELTEXT,2,""); + + // + SetLevelValue(3, 100); + IndicatorSetString(INDICATOR_LEVELTEXT,3,""); + + // + string pUpLbl = StringConcatenate( + "P Up (", marketLength, ")" + ); + SetIndexLabel(powerUpBufferIndex, pUpLbl); + SetIndexBuffer(powerUpBufferIndex, powerUpBuffer); + SetIndexDrawBegin(powerUpBufferIndex, marketLength + 1); + + // + string pDownLbl = StringConcatenate( + "P Down (", marketLength, ")" + ); + SetIndexLabel(powerDownBufferIndex, pDownLbl); + SetIndexBuffer(powerDownBufferIndex, powerDownBuffer); + SetIndexDrawBegin(powerDownBufferIndex, marketLength + 1); + + // + string pSignalLbl = StringConcatenate( + "P Signal (", marketLength, ")" + ); + SetIndexLabel(signalBufferIndex, pSignalLbl); + SetIndexBuffer(signalBufferIndex, signalBuffer); + SetIndexDrawBegin(signalBufferIndex, marketLength + 1); + + // + // here we specify logging enabled or not ... + enableLogging = true; + + // + // this is a Tag which attached to our Logger ... + logTag = "X_TPW_OSC"; + + // + return INIT_SUCCEEDED; +} + +// +// Calculating what we want ... +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[] +) { + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, marketLength); + + // + // input variable, we return 0 means nothing passed ... + if (rates_total < maxLength) { + return 0; + } + + // + // found which candles calculated before ... + limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1; + + // + // this is the main loop of calculations, for each bar index ... + for (int i = limit - 1; i >= 0; i--) { + // + // Start Calculation here ... + // i is bar_index ... + + // + // Calculate Buffers ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Calculating Ma ... +void CalculateBuffers( + const int &bar_index +) { + // + double powerUp = 0; + double powerDown = 0; + + // + int dailyCount = GetDailyCandleCount(); + double dailyHH = GetMarketHighestHigh( + bar_index, + dailyCount + ); + double dailyLL = GetMarketLowestLow( + bar_index, + dailyCount + ); + double dailyDiff = dailyHH - dailyLL; + double rate = dailyDiff / 100; + + // + for (int i = bar_index; i < bar_index + marketLength; i++) { + // + XOHCL c = GetCandleModel(i); + + // + double cRange = + MathAbs(c.open - c.close) + // MathAbs(c.high - c.low) + ; + bool isBullish = c.open < c.close; + + // + if (isBullish) { + powerUp += cRange; + } else { + powerDown += cRange; + } + } + + // + powerUp = powerUp / rate; + powerDown = powerDown / rate; + + // + int doubleMarketLength = (marketLength * 2); + double ema = GetMA( + bar_index, + doubleMarketLength, + 0, + MODE_EMA, + PRICE_WEIGHTED + ); + + // + double emaRate = GetMarketHighestHigh(bar_index, doubleMarketLength) - GetMarketLowestLow(bar_index, doubleMarketLength) / 100; + + // + double signal = (ema / 100) * rate; + double signalAddition = MathMin(powerUp, powerDown); + + // + powerUpBuffer[bar_index] = powerUp; + powerDownBuffer[bar_index] = powerDown; + signalBuffer[bar_index] = signal + signalAddition; +} +// +// END Functions ... +// \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.dialog.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.dialog.mq4 new file mode 100644 index 0000000..c00318e --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.dialog.mq4 @@ -0,0 +1,110 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 Dialog Library +// --------------------------------------------- +// saherelm useful tools and definitions +// for handling dialogs ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes Logger library ... +// #include "../Libraries/x-saherelm.lib.mq4" +#include "../Libraries/x-saherelm.log.lib.mq4" + +// +#include + +// +CAppDialog AppWindow; + +// +// Prefix for Created Dialogs ... +string windowPrefix = "XWinD"; + +// +// Generate a random number for dialogs ... +int GenerateWindowNumber() { + // + int result = MathRand() + 1; + + // + return result; +} + +// +// Generate a Window Prefix ID ... +string GenerateWindowID() { + // + string result = windowPrefix; + + // + // Generate INT ID ... + int idNum = GenerateWindowNumber(); + + // + result += "_" + StringConcatenate(idNum); + + // + return result; +} + +// +bool CreateDialog( + const string title = "" +) { + // + // string windowID = GenerateWindowID(); + + // + // Try to Create Window ... + bool result = AppWindow.Create( + 0, + title, + 0, + 20, + 20, + 360, + 324 + ); + + // + if (result) { + AppWindow.Run(); + } + + // + return result; +} + +// +void DestroyDialog(const int reason) { + AppWindow.Destroy(reason); +} + +// +// Apply Chart Event on Created Window ... +void DialogChartEvent( + const int id, // event ID + const long& lparam, // event parameter of the long type + const double& dparam, // event parameter of the double type + const string& sparam // event parameter of the string type +) { + // + AppWindow.ChartEvent( + id, + lparam, + dparam, + sparam + ); +} \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.draw.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.draw.lib.mq4 new file mode 100644 index 0000000..776cde4 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.draw.lib.mq4 @@ -0,0 +1,2010 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 Draw Global Library +// --------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes our shared library ... +#include "../Libraries/x-saherelm.log.lib.mq4" + +// +// Draw Highest High ... +bool DrawHighestHigh( + const int bar_index, + const int marketLen, + const string tag, + const int drawUntilBarIndex = 0, + const long chartID = 0, + const int subWindow = 0, + const color clr = clrAqua, + const ENUM_LINE_STYLE style = STYLE_DOT, + const int width = 1, + const bool back = false, + const bool selection = false, + const bool hidden = false, + const long zOrder = 0 +) { + // + bool result = false; + + // + // Calculate Highest High ... + int hhIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + marketLen, + bar_index + ); + + // + datetime hhTime = iTime( + _Symbol, + _Period, + hhIdx + ); + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + datetime drawUntilTime = + drawUntilBarIndex != bar_index ? + iTime( + _Symbol, + _Period, + drawUntilBarIndex + ) : + barTime + ; + + // + double hh = iHigh( + _Symbol, + _Period, + hhIdx + ); + + // + int rnd = rand(); + + // + // Define Label ... + string lbl = StringConcatenate( + tag, + "_HH(", marketLen ,")_", + hh, + "_", rnd + ); + + // + result = ObjectDelete( + chartID, + lbl + ); + + // + // Draw a Trend Line ... + result = DrawTrendLine( + chartID, + lbl, + subWindow, + hhTime, + hh, + drawUntilTime, + hh, + clr, + style, + width, + back, + selection, + hidden, + zOrder + ); + + // + return result; +} + +// +// Draw Lowest Low ... +bool DrawLowestLow( + const int bar_index, + const int marketLen, + const string tag, + const int drawUntilBarIndex = 0, + const long chartID = 0, + const int subWindow = 0, + const color clr = clrFuchsia, + const ENUM_LINE_STYLE style = STYLE_DOT, + const int width = 1, + const bool back = false, + const bool selection = false, + const bool hidden = false, + const long zOrder = 0 +) { + // + bool result = false; + + // + // Calculate Highest High ... + int llIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + marketLen, + bar_index + ); + + // + datetime llTime = iTime( + _Symbol, + _Period, + llIdx + ); + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + datetime drawUntilTime = + drawUntilBarIndex != bar_index ? + iTime( + _Symbol, + _Period, + drawUntilBarIndex + ) : + barTime + ; + + // + double ll = iLow( + _Symbol, + _Period, + llIdx + ); + + // + int rnd = rand(); + + // + // Define Label ... + string lbl = StringConcatenate( + tag, + "_LL(", marketLen ,")_", + ll, + "_", rnd + ); + + // + result = ObjectDelete( + chartID, + lbl + ); + + // + // Draw a Trend Line ... + result = DrawTrendLine( + chartID, + lbl, + subWindow, + llTime, + ll, + drawUntilTime, + ll, + clr, + style, + width, + back, + selection, + hidden, + zOrder + ); + + // + return result; +} + +// +// Draw Market Middle ... +bool DrawMarketMiddle( + const int bar_index, + const int marketLen, + const string tag, + const int drawUntilBarIndex = 0, + const long chartID = 0, + const int subWindow = 0, + const color clr = clrYellow, + const ENUM_LINE_STYLE style = STYLE_DOT, + const int width = 1, + const bool back = false, + const bool selection = false, + const bool hidden = false, + const long zOrder = 0 +) { + // + bool result = false; + + // + // Calculate Highest High ... + int llIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + marketLen, + bar_index + ); + + // + datetime llTime = iTime( + _Symbol, + _Period, + llIdx + ); + + // + double ll = iLow( + _Symbol, + _Period, + llIdx + ); + + // + // Calculate Highest High ... + int hhIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + marketLen, + bar_index + ); + + // + datetime hhTime = iTime( + _Symbol, + _Period, + hhIdx + ); + + // + double hh = iHigh( + _Symbol, + _Period, + hhIdx + ); + + // + double middle = ll + ((hh - ll) / 2); + datetime middleTime = hhIdx < llIdx + ? hhTime + : llTime + ; + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + datetime drawUntilTime = + drawUntilBarIndex != bar_index ? + iTime( + _Symbol, + _Period, + drawUntilBarIndex + ) : + barTime + ; + + // + int rnd = rand(); + + // + // Define Label ... + string lbl = StringConcatenate( + tag, + "_MID(", marketLen ,")_", + middle, + "_", rnd + ); + + // + result = ObjectDelete( + chartID, + lbl + ); + + // + // Draw a Trend Line ... + result = DrawTrendLine( + chartID, + lbl, + subWindow, + middleTime, + middle, + drawUntilTime, + middle, + clr, + style, + width, + back, + selection, + hidden, + zOrder + ); + + // + return result; +} + +// +// Start Arrow Functions ... +// +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = OBJ_ARROW_UP, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) { + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // create an arrow ... + if(!ObjectCreate(chartID, name, OBJ_ARROW, subWindow, time, price)) { + // + string message = StringConcatenate(__FUNCTION__, + ": failed to create an arrow! Error code = ", + GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID,name, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID,name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return(true); +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) { + // + // if point position is not set, move it to the current bar having Bid price ... + if(!time) { + time = TimeCurrent(); + } + + // + if(!price) { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value + ResetLastError(); + + // + // move the anchor point ... + if(!ObjectMove(chartID, name, 0, time, price)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move the anchor point! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) { + // + // reset the error value ... + ResetLastError(); + + // + // delete an arrow ... + if(!ObjectDelete(chartID, name)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to delete an arrow! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) { + // + // reset the error value ... + ResetLastError(); + + // + // change the arrow code ... + if(!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to change the arrow code! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name="Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) { + // + // reset the error value ... + ResetLastError(); + + // + // change anchor type ... + if(!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to change anchor type! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price +) { + // + // if the point's time is not set, it will be on the current bar ... + if(!time) { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if(!price) { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// End Arrow Functions ... +// + +// +// Start Horizontal Line Functions ... +// +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) { + // + // if the price is not set, set it at the current Bid price level ... + if(!price) { + price=SymbolInfoDouble(Symbol(),SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // create a horizontal line ... + if(!ObjectCreate(chartID, name, OBJ_HLINE, subWindow, 0, price)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to create a horizontal line! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set line color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return(true); +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) { + // + // if the line price is not set, move it to the current Bid price level ... + if(!price) { + price = SymbolInfoDouble(Symbol(),SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move a horizontal line ... + if(!ObjectMove(chartID, name, 0, 0, price)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move the horizontal line! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) { + // + // reset the error value ... + ResetLastError(); + + // + // delete a horizontal line ... + if(!ObjectDelete(chartID, name)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to delete a horizontal line! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} +// +// End Horizontal Line Functions ... +// + +// +// Start Vertical Line Functions ... +// +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int sub_window = 0, // subwindow index + datetime time = 0, // line time + const color clr=clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) { + // + // if the line time is not set, draw it via the last bar ... + if (!time) { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // create a vertical line ... + if (!ObjectCreate(chartID, name, OBJ_VLINE, sub_window, time, 0)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to create a vertical line! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) { + // + // if line time is not set, move the line to the last bar ... + if (!time) { + time = TimeCurrent(); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the vertical line ... + if(!ObjectMove(chartID, name, 0, time, 0)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move the vertical line! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) { + // + // reset the error value ... + ResetLastError(); + + // + // delete the vertical line ... + if (!ObjectDelete(chartID, name)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to delete the vertical line! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// End Vertical Line Functions ... +// + +// +// Start RectangleLabel Functions ... +// +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color back_clr = C'236,233,216', // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) { + // + // reset the error value ... + ResetLastError(); + + // + //--- create a rectangle label + if(!ObjectCreate(chartID, name, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to create a rectangle label! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, name, OBJPROP_BGCOLOR, back_clr); + + // + // set border type ... + ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the label by mouse ... + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return(true); +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y=0 // Y coordinate +) { + // + // reset the error value ... + ResetLastError(); + + // + // move the rectangle label ... + if(!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move X coordinate of the label! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + if(!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move Y coordinate of the label! Error code = ",GetLastError() + ); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) { + // + // reset the error value ... + ResetLastError(); + + // + // delete the label ... + if(!ObjectDelete(chartID, name)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to delete a rectangle label! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) { + // + // reset the error value ... + ResetLastError(); + + // + // change label size ... + if(!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to change the label's width! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + if(!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to change the label's height! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) { + // + // reset the error value ... + ResetLastError(); + + // + // change border type ... + if(!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to change the border type! Error code = ",GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} +// +// End RectangleLabel Functions ... +// + +// +// Start TrendLine Funcions ... +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) { + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2 + ); + + // + // reset the error value ... + ResetLastError(); + + // + // create a trend line by the given coordinates ... + if(!ObjectCreate(chartID, name, OBJ_TREND, subWindow, time1, price1, time2, price2)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to create a trend line! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set line color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, name, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return(true); +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) { + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) { + time = TimeCurrent(); + } + + // + if (!price) { + price = SymbolInfoDouble(Symbol(),SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move trend line's anchor point ... + if(!ObjectMove(chartID, name, pointindex, time, price)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move the anchor point! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) { + // + // reset the error value ... + ResetLastError(); + + // + // delete a trend line ... + if(!ObjectDelete(chartID, name)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to delete a trend line! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2 +) { + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) { + price2 = price1; + } +} +// +// End TrendLine Functions ... +// + +// +// Start Text Functions ... +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) { + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time,price); + + // + // reset the error value ... + ResetLastError(); + + // + //--- create Text object + if(!ObjectCreate(chartID, name, OBJ_TEXT, subWindow, time, price)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to create \"Text\" object! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set the text ... + ObjectSetString(chartID, name , OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, name, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, name, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, name, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the object by mouse ... + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID ,name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return(true); +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) { + // + //--- if point position is not set, move it to the current bar having Bid price + if (!time) { + time = TimeCurrent(); + } + + // + if (!price) { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point .. + if(!ObjectMove(chartID, name, 0, time, price)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move the anchor point! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) { + // + // reset the error value ... + ResetLastError(); + + // + // change object text ... + if(!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to change the text! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) { + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if(!ObjectDelete(chartID, name)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to delete \"Text\" object! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution + return(true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price +) { + // + // if the point's time is not set, it will be on the current bar ... + if(!time) { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if(!price) { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + } +// +// End Text Functions ... +// + +// +// Start Fibonacchi Functions ... +// +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name="Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) { + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to create \"Fibonacci Retracement\"! Error code = " , GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, name, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return(true); +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) { + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to create \"Fibonacci Retracement\"! Error code = " , GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set color ... + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, name, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, name, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + bool result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + name + ); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) { + // + // check array sizes ... + if( + levels!=ArraySize(colors) || + levels!=ArraySize(styles) || + levels!=ArraySize(widths) || + levels!=ArraySize(widths) + ) { + // + string message = StringConcatenate( + __FUNCTION__, + ": array length does not correspond to the number of levels, error!" + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for(int i = 0; i < levels; i++) { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return(true); +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) { + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) { + time = TimeCurrent(); + } + + // + if (!price) { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point ... + if(!ObjectMove(chartID, name, pointIndex, time, price)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to move the anchor point! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) { + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if(!ObjectDelete(chartID, name)) { + // + string message = StringConcatenate( + __FUNCTION__, + ": failed to delete \"Fibonacci Retracement\"! Error code = ", GetLastError() + ); + + // + LogMessage(message); + + // + return(false); + } + + // + // successful execution ... + return(true); +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2 +) { + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(),Period(),time2,10,temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} +// +// End Fibonacci Functions ... +// + + +// +// Start General Functions ... +// +// +// Remove all Drawn Objects ... +void RemoveDraws(const string &tag) { + // + for(int iObj=ObjectsTotal()-1; iObj >= 0; iObj--) { + // + string on = ObjectName(iObj); + if (StringFind(on, tag) == 0) { + ObjectDelete(on); + } + } +} +// +// End General Functions ... +// \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.indicator.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.indicator.lib.mq4 new file mode 100644 index 0000000..0e4b162 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.indicator.lib.mq4 @@ -0,0 +1,450 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 Indicator Global Library +// --------------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes library ... +#include "../Libraries/x-saherelm.lib.mq4" + +// +// Includes Models library ... +#include "../Libraries/x-saherelm.models.lib.mq4" + +// +// START Global Requirement Functions ... +// +// +// Reading specified Buffer From ADX Indicator ... +double ReadXMABuffer( + const int bar_index, + const int buffer_index, + // + const int marketLen, + // + const double stp, + const double mxm, + // + const int shortCycleMult, + const int mediumCycleMult, + const int longCycleMult +) { + // + string xmaIndicatorName = "x-saherelm.x.xma"; + + // + double result = iCustom( + _Symbol, + _Period, + xmaIndicatorName, + // + // Inputs ... + marketLen, + stp, + mxm, + shortCycleMult, + mediumCycleMult, + longCycleMult, + MODE_SMA, + // + buffer_index, + bar_index + ); + + // + return result; +} + +// +// Reading specified Buffer from XHL Indicator ... +double ReadXHLBuffer( + const int bar_index, + const int buffer_index, + // + const int marketLen, + // + const int shortCycleMult, + const int mediumCycleMult, + const int longCycleMult +) { + // + string xhlIndicatorName = "x-saherelm.x.hl"; + + // + double result = iCustom( + _Symbol, + _Period, + xhlIndicatorName, + // + // Inputs ... + marketLen, + shortCycleMult, + mediumCycleMult, + longCycleMult, + MODE_SMA, + // + buffer_index, + bar_index + ); + + // + return result; +} + +// +// Reading ADX Values ... +double ReadADX( + const int bar_index, + const int marketLen, + const int mult +) { + // + double result; + + // + int period = marketLen * mult; + + // + result = iADX( + _Symbol, + _Period, + period, + PRICE_CLOSE, + MODE_MAIN, + bar_index + ); + + // + return result; +} + +// +// Reading Pivot States ... +XPvtState GetPVTState( + const int bar_index, + const int marketLen +) { + // + XPvtState result = {}; + + // + double hh = GetMarketHighestHigh( + bar_index, + marketLen + ); + + // + double ho = GetMarketHighestOpen( + bar_index, + marketLen + ); + + // + double hc = GetMarketHighestClose( + bar_index, + marketLen + ); + + // + double hl = GetMarketHighestLow( + bar_index, + marketLen + ); + + // + double ll = GetMarketLowestLow( + bar_index, + marketLen + ); + + // + double lo = GetMarketLowestOpen( + bar_index, + marketLen + ); + + // + double lc = GetMarketLowestClose( + bar_index, + marketLen + ); + + // + double lh = GetMarketLowestHigh( + bar_index, + marketLen + ); + + // + // Filling Result ... + // + result.hh = hh; + result.ho = ho; + result.hc = hc; + result.hl = hl; + + // + result.ll = ll; + result.lo = lo; + result.lc = lc; + result.lh = lh; + + // + return result; +} + +// +// Calculate XRange from Market ... +static XRState lastXRState; +XRState GetXRange( + const int bar_index, + const int rangeMarketLength +) { + // + XRState result = {}; + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + int marketBarIndex = bar_index + rangeMarketLength; + + // + // Highest High ... + // + int hhIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + marketBarIndex, + bar_index + ); + + // + double hh = iHigh( + _Symbol, + _Period, + hhIdx + ); + + // + // Lowest Low ... + // + int llIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + marketBarIndex, + bar_index + ); + + // + double ll = iLow( + _Symbol, + _Period, + llIdx + ); + + // + if (lastXRState.start == 0) { + // + lastXRState.start = barTime; + lastXRState.length = rangeMarketLength; + + // + lastXRState.hh = hh; + lastXRState.ll = ll; + + // + // Middle ... + double mid = (hh + ll) / 2; + lastXRState.mid = mid; + } else { + // + int startBarIndex = iBarShift( + _Symbol, + _Period, + lastXRState.start + ); + + // + if (startBarIndex - bar_index >= rangeMarketLength) { + // + lastXRState.start = barTime; + lastXRState.length = rangeMarketLength; + + // + lastXRState.hh = hh; + lastXRState.ll = ll; + + // + // Middle ... + double mid = (hh + ll) / 2; + lastXRState.mid = mid; + } + } + + // + result = lastXRState; + + // + return result; +} + +// +// Reading XTPowState from Indicatoe ... +XTPOWState GetXTPowState( + const int bar_index, + const int marketLen +) { + // + XTPOWState result = {}; + + // + // + double powerUp = 0; + double powerDown = 0; + double signal = 0; + + // + string indicatorName = "x-saherelm.xtpow"; + + // + int pUpIndex = 0; + int pDownIndex = 1; + int signalIndex = 2; + + // + powerUp = iCustom( + _Symbol, + _Period, + indicatorName, + // + marketLen, + // + pUpIndex, + bar_index + ); + + // + powerDown = iCustom( + _Symbol, + _Period, + indicatorName, + // + marketLen, + // + pDownIndex, + bar_index + ); + + // + signal = iCustom( + _Symbol, + _Period, + indicatorName, + // + marketLen, + // + signalIndex, + bar_index + ); + + // + result.signal = signal; + result.powerUp = powerUp; + result.powerDown = powerDown; + + // + return result; +} + +// +// Reading XRState From Indicator ... +XRState ReadXRange( + const int bar_index, + const int marketLen +) { + // + XRState result = {}; + + // + // Define Buffer Indexes ... + int hhBufferIndex = 0; + int llBufferIndex = 1; + int midBufferIndex = 2; + + // + string indicatorName = "x-saherelm.xrange"; + + // + // Read Values From XRange Indicator ... + + // + double hh = iCustom( + _Symbol, + _Period, + indicatorName, + // + // Inputs ... + marketLen, + // + hhBufferIndex, // Buffer Index ... + bar_index + ); + + // + double ll = iCustom( + _Symbol, + _Period, + indicatorName, + // + // Inputs ... + marketLen, + // + llBufferIndex, // Buffer Index ... + bar_index + ); + + // + double mid = iCustom( + _Symbol, + _Period, + indicatorName, + // + // Inputs ... + marketLen, + // + midBufferIndex, // Buffer Index ... + bar_index + ); + + // + // Filling Result ... + result.hh = hh; + result.ll = ll; + result.mid = mid; + + // + return result; +} +// +// END Indicator Reading Data ... +// diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.lib.mq4 new file mode 100644 index 0000000..9cbc3d6 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.lib.mq4 @@ -0,0 +1,1695 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 Global Library +// --------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes Logger library ... +#include "../Libraries/x-saherelm.log.lib.mq4" + +// +// Includes Drawing library ... +#include "../Libraries/x-saherelm.draw.lib.mq4" + +// +static datetime lastBarTime; + +// +struct XOHCL { + double high; + double open; + double close; + double low; +}; + +// +struct XRange { + // + datetime time; + + // + double highestHigh; + double lowestLow; + + // + int levels; + int marketLength; + + // + double rate; +}; + +// +struct XPrice { + // + double askPrice; + double bidPrice; + double priceGap; + + // + double longEntry; + double longExit; + + // + double shortEntry; + double shortExit; +}; + +// +// START Functions ... +// + +// +// Determines current working is New Bar or not ... +bool IsNewBar() { + // + // Reading Last Bar Date ... + datetime curbar = (datetime)SeriesInfoInteger( + _Symbol, + _Period, + SERIES_LASTBAR_DATE + ); + + // + if(lastBarTime != curbar) { + // + lastBarTime = curbar; + return true; + } + + // + return false; +} + +// +// Determines we are in new Day or not ... +bool IsNewDay() { + // + bool result = false; + + // + // Reading Last Bar Date ... + datetime curbar = (datetime)SeriesInfoInteger( + _Symbol, + _Period, + SERIES_LASTBAR_DATE + ); + + // + if (lastBarTime == 0) { + lastBarTime = curbar; + } + + // + if (curbar == lastBarTime) { + return result; + } + + // + // Retrieve Day and Month and Year for Last Bar Time ... + int lastBarDay = TimeDay(lastBarTime); + int lastBarMonth = TimeMonth(lastBarTime); + int lastBarYear = TimeYear(lastBarTime); + + // + // Retrieve Day and Month and Year for Current Bar Time ... + int curBarDay = TimeDay(curbar); + int curBarMonth = TimeMonth(curbar); + int curBarYear = TimeYear(curbar); + + // + result = curBarDay > lastBarDay + || curBarMonth > lastBarMonth + || curBarYear > lastBarYear; + + // + return result; +} + +// +// Determines we are in new Hour or not ... +bool IsNewHour() { + // + // Save Last Hour value ... + static int lastHour = 0; + + // + bool isInNewDay = IsNewDay(); + if (isInNewDay) { + // + // Reset Last Hour if it's in New Day ... + lastHour = 0; + } + + // + // Retrieve Current Hour value ... + int currentHour = Hour(); + + // + // Check values ... + bool result = currentHour > lastHour; + if (result) { + // + // Update Last Hour value ... + lastHour = currentHour; + } + + // + // returns result ... + return result; +} + +// +// Retrieve Number of Candles in a Day ... +int GetDailyCandleCount() { + // + int seconds = PeriodSeconds(_Period); + + // + int daySeconds = 24 * 60 * 60; + + // + int result = daySeconds / seconds; + + // + return result; +} + +// +// XRange Detector ... +XRange GetMarketRange( + const int bar_index, + const int marketLen, + const int levels +) { + // + XRange result = {}; + + // + result.levels = levels; + result.marketLength = marketLen; + + // + datetime time = iTime( + _Symbol, + _Period, + bar_index + ); + result.time = time; + + // + double highestHigh = GetMarketHighestHigh( + bar_index, + marketLen + ); + result.highestHigh = highestHigh; + + // + double lowestLow = GetMarketLowestLow( + bar_index, + marketLen + ); + result.lowestLow = lowestLow; + + // + double diff = highestHigh - lowestLow; + double rate = diff / levels; + + // + result.rate = rate; + + // + return result; +} + +// +// Retrieve RMA on Specific Candle ... +double GetRMA( + int bar_index, + int length +) { + // + double shortSMA = iMA(_Symbol, _Period, length, 0, MODE_SMA, PRICE_CLOSE, bar_index); + double mediumSMA = iMA(_Symbol, _Period, length * 2, 0, MODE_SMA, PRICE_CLOSE, bar_index); + double longSMA = iMA(_Symbol, _Period, length * 3, 0, MODE_SMA, PRICE_CLOSE, bar_index); + + // + double result = longSMA - mediumSMA + shortSMA; + + // + return result; +} + +// +// Retrieve Moving Average ... +double GetMA( + const int bar_index, + const int maLength, + const int maShift, + const ENUM_MA_METHOD maMethod, + const ENUM_APPLIED_PRICE appliedPrice +) { + // + double result = iMA( + _Symbol, + _Period, + maLength, + maShift, + maMethod, + appliedPrice, + bar_index + ); + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction +) { + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? + upPrice - pLevel : + downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} + +// +// Retrieve True Range ... +double GetTR( + const int bar_index +) { + // + double result = 0; + + // + double high = iHigh( + _Symbol, + _Period, + bar_index + ); + + // + double low = iLow( + _Symbol, + _Period, + bar_index + ); + + // + double prevClose = iClose( + _Symbol, + _Period, + bar_index + 1 + ); + + // + double highLowDif = high - low; + double hpCDif = MathAbs(high - prevClose); + double lpCDiff = MathAbs(low - prevClose); + + // + result = MathMax(highLowDif, hpCDif); + result = MathMax(result, lpCDiff); + + // + return result; +} + +// +// Calculate True Range Simple Moving Average ... +double GetMarketTRSMA( + const int bar_index, + const int marketLen +) { + // + double result = 0; + + // + // Create Barket Length Trs ... + double trs[]; + ArrayResize( + trs, + marketLen + ); + int index = 0; + double trSum = 0; + for (int i = bar_index; i < bar_index + marketLen; i++) { + // + double tr = GetTR(i); + trs[index] = tr; + + // + trSum += tr; + + // + index++; + } + + // + result = trSum / marketLen; + + // + return result; +} + +// +// Retrieve Commodity Channel ... +double GetMarketCCI( + const int bar_index, + const int marketLen, + const ENUM_APPLIED_PRICE appliedPrice = PRICE_CLOSE +) { + // + double result = 0; + + // + result = iCCI( + _Symbol, + _Period, + marketLen, + appliedPrice, + bar_index + ); + + // + return result; +} + +// +// this function check crossing up two Buffers ... +bool IsCrossedOver( + double &arr1[], + double &arr2[], + int index1, + int index2 = -1 +) { + // + // Normalize Index 2 Value ... + if (index2 < 0) { + index2 = index1 + 1; + } + + // + bool result = (arr1[index1] > arr2[index1]) && !(arr1[index2] > arr2[index2]); + + // + return result; +} + +// +// this function check crossing down two Buffers ... +bool IsCrossedUnder( + double &arr1[], + double &arr2[], + int index1, + int index2 = -1 +) { + // + // Normalize Index 2 Value ... + if (index2 < 0) { + index2 = index1 + 1; + } + + // + bool result = (arr1[index1] < arr2[index1]) && !(arr1[index2] < arr2[index2]); + + // + return result; +} + +// +// Convert points to Actual Point ... +double PointsToDouble(int points) { + // + double result = points * _Point; + return result; +} + +// +// Converts Pips to Points ... +int PipsToPoints(int pips) { + // + int result = pips * ((_Digits == 3 || _Digits == 5) ? 10 : 1); + return result; +} + +// +// Converts Pips to Double ... +double PipsToDouble(int pips) { + // + double result = PointsToDouble(PipsToPoints(pips)); + return result; +} + +// +// Converts Double Value to Pips ... +int PriceToPips(double value) { + // + if (value <= 0) { + return 0; + } + + // + double pipValue = _Point * MathPow(10, _Digits); + int result = (int)(value / pipValue); + + // + return result; +} + +// +// Converts Pips to Double ... +double PipsToPrice(int pips) { + // + if (pips <= 0) { + return 0; + } + + // + double pipValue = _Point * MathPow(10, _Digits); + double result = pipValue * pips; + + // + return result; +} + +// +// Generate ATR StopLoss Value ... +double CalculateATRSL( + int period, + double multiplier +) { + // + if (period <= 0 || multiplier <= 0) { + return 0; + } + + // + double atrValue = iATR( + _Symbol, + _Period, + period, + 0 + ); + + // + double result = atrValue * multiplier; + + // + return result; +} + +// +// Detect Candle Type ... +// Bullish => means close > open ... +bool IsBullishCandle( + const int bar_index +) { + // + // Temp Result ... + bool result = false; + + // + if (bar_index < 0) { + return result; + } + + // + double open = iOpen( + _Symbol, + _Period, + bar_index + ); + + // + double close = iClose( + _Symbol, + _Period, + bar_index + ); + + // + result = IsBullishCandle( + open, + close + ); + + // + return result; +} + +bool IsBullishCandle( + const double open, + const double close +) { + // + // Temp Result ... + bool result = false; + + // + result = open < close; + + // + return result; +} + +// +// Detect Candle Type ... +// Bearish => means close < open ... +bool IsBearishCandle( + const int bar_index +) { + // + // Temp Result ... + bool result = false; + + // + if (bar_index < 0) { + return result; + } + + // + double open = iOpen( + _Symbol, + _Period, + bar_index + ); + + // + double close = iClose( + _Symbol, + _Period, + bar_index + ); + + // + result = IsBearishCandle( + open, + close + ); + + // + return result; +} + +bool IsBearishCandle( + const double open, + const double close +) { + // + // Temp Result ... + bool result = false; + + // + result = open > close; + + // + return result; +} + +// +// Retrieve a Candle Info ... +XOHCL GetCandleModel( + const int bar_index +) { + // + XOHCL result = {}; + + // + double high = iHigh( + _Symbol, + _Period, + bar_index + ); + result.high = high; + + // + double open = iOpen( + _Symbol, + _Period, + bar_index + ); + result.open = open; + + // + double close = iClose( + _Symbol, + _Period, + bar_index + ); + result.close = close; + + // + double low = iLow( + _Symbol, + _Period, + bar_index + ); + result.low = low; + + // + return result; +} + +// +// Retrieve Market Current Prices for Signals ... +XPrice GetPrice() { + // + XPrice result = {}; + + // + RefreshRates(); + + // + double askPrice = SymbolInfoDouble( + _Symbol, + SYMBOL_ASK + ); + + // + double bidPrice = SymbolInfoDouble( + _Symbol, + SYMBOL_BID + ); + + // + double priceGap = MathAbs(bidPrice - askPrice); + + // + result.askPrice = askPrice; + result.bidPrice = bidPrice; + result.priceGap = priceGap; + + // + result.longEntry = askPrice; + result.longExit = bidPrice; + + // + result.shortEntry = bidPrice; + result.shortExit = askPrice; + + // + return result; +} + +// +// Detect Market Has Sharp Bullish or not ... +bool IsSharpBullishDetected( + const int bar_index, // Bar Index ... + const int marketLen, // Market Length ... + // + const double shpDetectMultipliers // Sharp Detect Multiplier +) { + // + bool result = false; + + // + double open = iOpen( + _Symbol, + _Period, + bar_index + ); + + // + double close = iClose( + _Symbol, + _Period, + bar_index + ); + + // + double high = iHigh( + _Symbol, + _Period, + bar_index + ); + + // + double low = iLow( + _Symbol, + _Period, + bar_index + ); + + // + double minValue = 0; + double maxValue = 0; + int positionedLength = bar_index + marketLen; + + // + for (int i = bar_index; i < positionedLength; i++) { + // + double cHigh = iHigh( + _Symbol, + _Period, + i + ); + + // + double cLow = iLow( + _Symbol, + _Period, + i + ); + + // + minValue += MathMin(cLow, cHigh); + maxValue += MathMax(cLow, cHigh); + } + + // + double minAvg = minValue / positionedLength; + double maxAvg = maxValue / positionedLength; + + // + double shpValue = shpDetectMultipliers * _Point; + + // + result = (low - minAvg) > shpValue; + + // + int index = bar_index; + while ( + index < positionedLength + || !result + ) { + // + low = iLow( + _Symbol, + _Period, + index + ); + + // + result = result + || (low - minAvg) > shpValue; + + // + index++; + }; + + // + return result; +} + +// +// Detect Market Has Sharp Bullish or not ... +bool IsSharpBearishDetected( + const int bar_index, // Bar Index ... + const int marketLen, // Market Length ... + // + const double shpDetectMultipliers // Sharp Detect Multiplier +) { + // + bool result = false; + + // + double open = iOpen( + _Symbol, + _Period, + bar_index + ); + + // + double close = iClose( + _Symbol, + _Period, + bar_index + ); + + // + double high = iHigh( + _Symbol, + _Period, + bar_index + ); + + // + double low = iLow( + _Symbol, + _Period, + bar_index + ); + + // + double minValue = 0; + double maxValue = 0; + int positionedLength = bar_index + marketLen; + + // + for (int i = bar_index; i < positionedLength; i++) { + // + double cHigh = iHigh( + _Symbol, + _Period, + i + ); + + // + double cLow = iLow( + _Symbol, + _Period, + i + ); + + // + minValue += MathMin(cLow, cHigh); + maxValue += MathMax(cLow, cHigh); + } + + // + double minAvg = minValue / positionedLength; + double maxAvg = maxValue / positionedLength; + + // + double shpValue = shpDetectMultipliers * _Point; + + // + result = (high - maxAvg) > shpValue; + + // + int index = bar_index; + while ( + index < positionedLength + || !result + ) { + // + high = iHigh( + _Symbol, + _Period, + index + ); + + // + result = result + || (high - maxAvg) > shpValue; + + // + index++; + }; + + // + return result; +} + +// +// Retrieve Highest High Value based on Given Market ... +double GetMarketHighestHigh( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iHighest( + _Symbol, + _Period, + MODE_HIGH, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iHigh( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Retrieve Highest Low Value based on Given Market ... +double GetMarketHighestLow( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iHighest( + _Symbol, + _Period, + MODE_LOW, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iLow( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Retrieve Highest Open Value based on Given Market ... +double GetMarketHighestOpen( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iHighest( + _Symbol, + _Period, + MODE_OPEN, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iOpen( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Retrieve Highest Close Value based on Given Market ... +double GetMarketHighestClose( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iHighest( + _Symbol, + _Period, + MODE_CLOSE, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iClose( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Retrieve Lowest Low Value based on Given Market ... +double GetMarketLowestLow( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iLowest( + _Symbol, + _Period, + MODE_LOW, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iLow( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Retrieve Lowest High Value based on Given Market ... +double GetMarketLowestHigh( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iLowest( + _Symbol, + _Period, + MODE_HIGH, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iHigh( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Retrieve Lowest Open Value based on Given Market ... +double GetMarketLowestOpen( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iLowest( + _Symbol, + _Period, + MODE_OPEN, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iOpen( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Retrieve Lowest Close Value based on Given Market ... +double GetMarketLowestClose( + // + const int bar_index, // Bar Index ... + const int marketLen // Market Length ... +) { + // + // Empty Result ... + double result = 0.0; + + // + // Retrieve Desired Bar Index ... + int foundedBarIndex = iLowest( + _Symbol, + _Period, + MODE_CLOSE, + marketLen, + bar_index + ); + + // + // Retrieve Price ... + result = iClose( + _Symbol, + _Period, + foundedBarIndex + ); + + // + return result; +} + +// +// Find last Candle which it's Low Price is +// less than given price ... +double GetLowLessCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iLow( + _Symbol, + _Period, + index + ); + + // + while (result >= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetLowLessCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iLow( + _Symbol, + _Period, + result + ); + + // + while (cP >= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Find last Candle which it's Low Price is +// great than given price ... +double GetLowGreatCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iLow( + _Symbol, + _Period, + index + ); + + // + while (result >= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetLowGreatCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iLow( + _Symbol, + _Period, + result + ); + + // + while (cP >= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Find last Candle which it's High Price is +// less than given price ... +double GetHighLessCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iHigh( + _Symbol, + _Period, + index + ); + + // + while (result >= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetHighLessCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iHigh( + _Symbol, + _Period, + result + ); + + // + while (cP >= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Find last Candle which it's High Price is +// great than given price ... +double GetHighGreatCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iHigh( + _Symbol, + _Period, + index + ); + + // + while (result <= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetHighGreatCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iHigh( + _Symbol, + _Period, + result + ); + + // + while (cP <= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Find last Candle which it's Open Price is +// less than given price ... +double GetOpenLessCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iOpen( + _Symbol, + _Period, + index + ); + + // + while (result >= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetOpenLessCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iOpen( + _Symbol, + _Period, + result + ); + + // + while (cP >= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Find last Candle which it's Open Price is +// less than given price ... +double GetOpenGreatCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iOpen( + _Symbol, + _Period, + index + ); + + // + while (result <= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetOpenGreatCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iOpen( + _Symbol, + _Period, + result + ); + + // + while (cP <= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Find last Candle which it's Close Price is +// less than given price ... +double GetCloseLessCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iClose( + _Symbol, + _Period, + index + ); + + // + while (result >= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetCloseLessCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iClose( + _Symbol, + _Period, + result + ); + + // + while (cP >= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Find last Candle which it's Close Price is +// great than given price ... +double GetCloseGreatCandlePrice( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int index = bar_index + 1; + double result = iClose( + _Symbol, + _Period, + index + ); + + // + while (result <= price) { + // + index++; + + // + result = iLow( + _Symbol, + _Period, + index + ); + } + + // + return result; +} +int GetCloseGreatCandleIndex( + // + const int bar_index, // Bar Index ... + const double price // Position Open Price ... +) { + // + int result = bar_index + 1; + double cP = iClose( + _Symbol, + _Period, + result + ); + + // + while (cP <= price) { + // + result++; + + // + cP = iLow( + _Symbol, + _Period, + result + ); + } + + // + return result; +} + +// +// Get Slope of a Line by it's two Point ... +double GetSlope( + double x1, + double y1, + double x2, + double y2 +) { + // + double result = (y2 - y1)/MathAbs(x2 - x1); + return result; +} +// +// END Functions ... +// \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.log.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.log.lib.mq4 new file mode 100644 index 0000000..066b3f7 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.log.lib.mq4 @@ -0,0 +1,91 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 Draw Global Library +// --------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Log Tag ... +static string logTag = ""; + +// +// Enable or Disable Logging ... +static bool enableLogging = false; + +// +// Start Log Messages ... +// + +// +// Logging a Message, specified for this EA ... +// using provided LogTag ... +void LogMessage(string message) { + // + if (!enableLogging) { + return; + } + + // + Print(logTag, " > ", message); +} + +// +// this used for logging series ... +void LogSeries( + double &series[], // which series to Log ... + int length = 0, // number of items to Log, 0 means all ... + int skip = 0 // number of items which skip before logging ... +) { + // + string msg = ""; + + // + int seriesSize = ArraySize(series); + if ( + skip < 0 + || length < 0 + || seriesSize == 0 + || skip > seriesSize + || skip + length > seriesSize + ) { + return; + } + + // + length = length == 0 ? + seriesSize : + length; + int start = skip > 1 ? + skip - 1 : + skip == 1 ? + 1 : + 0; + + // + // Loop through series items ... + for (int i = start; i < start + length; i++) { + // + msg += StringConcatenate( + "i[", i, "]: ", series[i], ", " + ); + } + + // + LogMessage(msg); +} +// +// End Log Messages ... +// + diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.models.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.models.lib.mq4 new file mode 100644 index 0000000..6899040 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.models.lib.mq4 @@ -0,0 +1,155 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 Models Global Library +// --------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START STATIC Variables ... +// +// +static int totalSignals = 0; +static int totalLongSignals = 0; +static int totalShortSignals = 0; + +// +static double initialBalance = 0; + +// +static int countedBars = 0; +static bool isNewBar = false; +static bool isNewDay = false; +static bool isNewHour = false; +// +// END STATIC Variables ... +// + +// +// Start Models ... +// +// +// Signal Providers ... +enum ENUM_X_SIGNAL_PROVIDER { + X_UNKNOWN_PROVIDER, + X_XXX_PROVIDER, + X_XR_PROVIDER, + X_XTPW_PROVIDER +}; + +// +// these are different signal types ... +enum ENUM_X_SIGNAL_TYPE { + X_SIGNAL_NONE, + X_SIGNAL_LONG, + X_SIGNAL_SHORT, +}; + +// +// Model Market Highs and Lows ... +struct XPvtState { + // + double hh; + double ho; + double hc; + double hl; + + // + double ll; + double lo; + double lc; + double lh; +}; + +// +// we Model each signals as this type ... +struct XSignal { + // + // Signal Symbol ... + string symbol; + + // + // Signal Type ... + ENUM_X_SIGNAL_TYPE type; + + // + // Signal ID ... + int id; + + // + // Signal Ticket Number, when Opening Trade ... + int ticket; + + // + // Signal Provider ... + ENUM_X_SIGNAL_PROVIDER provider; + + // + // Target Point ... + double tp; + + // + // Stop Loss ... + double sl; + + // + // Signal Entry Price ... + double entry; + + // + // Signalling Time ... + datetime time; + + // + // Signal Comments ... + string comment; + + // + // Signal TAG ... + string tag; +}; + +// +// this is Signal Request Response model ... +struct XSignalRequest { + bool hasSignal; + XSignal signal; + ENUM_X_SIGNAL_TYPE type; + ENUM_X_SIGNAL_PROVIDER provider; +}; + +// +struct XRState { + // + datetime start; + int length; + + // + double hh; + double ll; + double mid; +}; + +// +struct XTPOWState { + // + double powerUp; + double powerDown; + + // + double signal; +}; +// +// End Models ... +// diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.signal.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.signal.lib.mq4 new file mode 100644 index 0000000..097ce74 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.signal.lib.mq4 @@ -0,0 +1,1756 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 Signal Draw Global Library +// --------------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes library ... +#include "../Libraries/x-saherelm.lib.mq4" + +// +// Includes Indicator library ... +#include "../Libraries/x-saherelm.indicator.lib.mq4" + +// +// Includes Models library ... +#include "../Libraries/x-saherelm.models.lib.mq4" + +// +// Includes Drawing library ... +#include "../Libraries/x-saherelm.draw.lib.mq4" + +// +#include "../Libraries/x-saherelm.x.signal.lib.mq4" +#include "../Libraries/x-saherelm.xr.signal.lib.mq4" +#include "../Libraries/x-saherelm.xtpw.signal.lib.mq4" + +// +// START Global Requirement Functions ... +// +// +// END Global Requirement Functions ... +// + +// +// START Signal Related Functions ... +// +// +// Retrieve Signal Bar Index ... +int GetSignalBarIndex(XSignal &signal) { + // + // Temp Result ... + int result = -1; + + // + // Retriev Signal Bar Index ... + result = iBarShift( + _Symbol, + _Period, + signal.time + ); + + // + return result; +} + +// +string GetSignalProviderIdentifier( + ENUM_X_SIGNAL_PROVIDER provider +) { + // + string result = ""; + + // + switch (provider) { + // + case X_XXX_PROVIDER: + result = "XXX"; + break; + + // + case X_XR_PROVIDER: + result = "XR"; + break; + + // + case X_XTPW_PROVIDER: + result = "XTPW"; + break; + + // + default: + result = ""; + break; + } + + // + return result; +} + +// +ENUM_X_SIGNAL_PROVIDER GetSignalProvider(string identifier) { + // + ENUM_X_SIGNAL_PROVIDER result = X_UNKNOWN_PROVIDER; + + // + if ( + StringFind( + identifier, + GetSignalProviderIdentifier(X_XXX_PROVIDER) + ) > -1 + ) { + result = X_XXX_PROVIDER; + } else if ( + StringFind( + identifier, + GetSignalProviderIdentifier(X_XR_PROVIDER) + ) > -1 + ) { + result = X_XR_PROVIDER; + } else if ( + StringFind( + identifier, + GetSignalProviderIdentifier(X_XTPW_PROVIDER) + ) > -1 + ) { + result = X_XTPW_PROVIDER; + } + + // + return result; +} + +// +// Retrieve Signal Lots Per Trade ... +double GetSignalLottage( + const XSignal &signal, + const double defLotsPerTrade +) { + // + double result = defLotsPerTrade; + + // + bool isLong = signal.type == X_SIGNAL_LONG; + + // + switch (signal.provider) { + // + case X_XR_PROVIDER: + // + result = isLong ? + xRLongLotsPerTradePercent : + xRShortLotsPerTradePercent + ; + break; + + // + case X_XXX_PROVIDER: + // + result = isLong ? + xLongLotsPerTradePercent : + xShortLotsPerTradePercent + ; + break; + + // + case X_XTPW_PROVIDER: + // + result = isLong ? + xTPWLongLotsPerTradePercent : + xTPWShortLotsPerTradePercent + ; + break; + } + + // + return result; +} + +// +// Draw Specific Range On Chart ... +void DrawRange( + const XRange &range, + const long chartID = 0, + const int subWindowID = 0, + const string tag = "", + const color clr = clrYellow +) { + // + // Loop through Levels Count ... + for (int i = 0; i <= range.levels; i++) { + // + datetime time1 = iTime( + _Symbol, + _Period, + 1 + ); + + // + datetime time2 = iTime( + _Symbol, + _Period, + 0 + ); + + // + double price = range.lowestLow + (i * range.rate); + + // + string lbl = StringConcatenate( + tag, + "_XRL_", + price + ); + + // + DrawTrendLine( + chartID, + lbl, + subWindowID, + time1, + price, + time2, + price, + clr, + STYLE_DOT + ); + } +} + +// +// Draw Signal Shapes on Chart ... +bool DrawSignal( + const XSignal &signal, + long chartID = 0, + int subWindowID = 0, + const double positionThresholdFactor = 10, + string longSignalLabel = "X-Long", + color longSignalColor = clrAqua, + string shortSignalLabel = "X-Short", + color shortSignalColor = clrFuchsia +) { + // + // Generate isLongSignal Var ... + bool isLongSignal = signal.type == X_SIGNAL_LONG; + + // + // Signal Bar Index ... + int bar_index = iBarShift( + _Symbol, + _Period, + signal.time + ); + + // + // START Draw Signal Arrow ... + // + // + // Arrow Shape Name ... + string arrowName = StringConcatenate(signal.tag, "_Arrow_", signal.id); + + // + // Arrow Price ... + double arrowPrice = 0; + if (isLongSignal) { + // + arrowPrice = iLow( + _Symbol, + _Period, + bar_index + 1 + ); + + // + arrowPrice = arrowPrice - (positionThresholdFactor * _Point); + } else { + // + arrowPrice = iHigh( + _Symbol, + _Period, + bar_index + 1 + ); + + // + arrowPrice = arrowPrice + (positionThresholdFactor * _Point); + } + + // + // Arrow Code ... + uchar arrowCode = isLongSignal ? SYMBOL_ARROWUP : SYMBOL_ARROWDOWN; + + // + // Arrow Anchor Point ... + ENUM_ARROW_ANCHOR arrowAnchorPoint = isLongSignal ? ANCHOR_BOTTOM : ANCHOR_TOP; + + // + // Arrow Color ... + color arrowColor = isLongSignal ? longSignalColor : shortSignalColor; + + // + // Draw Signal Arrow Shape ... + bool result = DrawArrow( + chartID, + arrowName, + subWindowID, + signal.time, + arrowPrice, + arrowCode, + arrowAnchorPoint, + arrowColor + ); + // + // END Draw Signal Arrow ... + // + + // + // START Draw Signal SL/TP ... + // + string slLineName = StringConcatenate(signal.tag, "_SL_", signal.id); + string tpLineName = StringConcatenate(signal.tag, "_TP_", signal.id); + string entryLineName = StringConcatenate(signal.tag, "_ENTRY_", signal.id); + + // + color slColor = shortSignalColor; // isLongSignal ? shortSignalColor : longSignalColor; + color tpColor = longSignalColor; // isLongSignal ? shortSignalColor : longSignalColor; + color entryColor = clrGreen; + + // + datetime time1 = iTime( + _Symbol, + _Period, + bar_index + 1 + ); + + // + // Draw Enrty Price ... + result = DrawTrendLine( + chartID, + entryLineName, + subWindowID, + time1, + signal.entry, + signal.time, + signal.entry, + entryColor, + STYLE_SOLID, + 2 + ); + + // + // Draw Signal SL ... + if (signal.sl > 0) { + // + result = DrawTrendLine( + chartID, + slLineName, + subWindowID, + time1, + signal.sl, + signal.time, + signal.sl, + slColor, + STYLE_SOLID, + 2 + ); + } + + // + // Draw Signal TP ... + if (signal.tp > 0) { + // + result = DrawTrendLine( + chartID, + tpLineName, + subWindowID, + time1, + signal.tp, + signal.time, + signal.tp, + tpColor, + STYLE_SOLID, + 2 + ); + } + // + // END Draw Signal SL/TP ... + // + + // + // Start Draw Signal Label ... + // + // + string labelName = StringConcatenate(signal.tag, "_Label_", signal.id); + + // + double labelPrice = isLongSignal ? arrowPrice - (positionThresholdFactor * _Point) : arrowPrice + (positionThresholdFactor * _Point); + + // + string labelText = isLongSignal ? longSignalLabel : shortSignalLabel; + labelText = StringConcatenate( + labelText, + "_", + GetSignalProviderIdentifier(signal.provider) + ); + + // + result = DrawText( + chartID, + labelName, + subWindowID, + signal.time, + labelPrice, + labelText, + "Arial", + 8, + arrowColor, + 0, + ANCHOR_CENTER + ); + // + // End Draw Signal Label ... + // + + // + return result; +} + +// +// Trade on Specific Signal ... +bool TradeSignal( + XSignal &signal, + // + double volumePercent, + // + // Long ... + const string longSignalLabel, + const color longSignalColor, + // + // Short ... + const string shortSignalLabel, + const color shortSignalColor +) { + // + // Temp Result ... + bool result = false; + + // + if (initialBalance == 0) { + initialBalance = AccountInfoDouble(ACCOUNT_BALANCE); + } + + // + double balance = AccountInfoDouble(ACCOUNT_BALANCE); + int openPositions = CountOpenTrades(); + double volume = (volumePercent * initialBalance); + + // + if ( + signal.type != X_SIGNAL_LONG && + signal.type != X_SIGNAL_SHORT + ) { + return result; + } + + // + bool hasLongSignal = signal.type == X_SIGNAL_LONG; + + // + // Check TP and Entry Price ... + if ( + ( + hasLongSignal + && signal.entry > signal.tp + ) || + ( + !hasLongSignal + && signal.entry < signal.tp + ) + ) { + return result; + } + + // + // Order Operation ... + int operation = hasLongSignal ? + OP_BUY : + OP_SELL; + + // + // Detect Trade Color ... + color clr = hasLongSignal ? + longSignalColor : + shortSignalColor; + + // + // Generate Signal Comment ... + string label = hasLongSignal ? + longSignalLabel : + shortSignalLabel; + + // + // Generate Signal Comment ... + string comment = StringConcatenate( + signal.tag, + "_", signal.id, + "_", GetSignalProviderIdentifier(signal.provider), + "_", label + ); + + // + // Placing Order ... + int orderTicket = OrderSend( + _Symbol, + operation, + volume, + signal.entry, + 3, + signal.sl, + signal.tp, + comment, + signal.id, + 0, + clr + ); + + // + // Draw Signal Shape if Order Opened Successfully ... + if (orderTicket >= 0) { + // + signal.ticket = orderTicket; + + // + // Here i must to Draw Signal Shapes ... + bool isDrawn = DrawSignal( + signal, + 0, + 0, + 50, + longSignalLabel, // Long Signal Label ... + longSignalColor, + shortSignalLabel, // Short Signal Label ... + shortSignalColor + ); + + // + LogMessage( + StringConcatenate( + "Order [", orderTicket ,"]: Provided by: ", GetSignalProviderIdentifier(signal.provider) + ) + ); + + // + // TODO: here we have to check if there are another + // open positions which their entry price is bigger + // than current signal entry price, for long trades and + // their tp is high than current tp, ... + // close in profit trades or modify orders tp to current ... + // // + // if (CountOpenTrades() > 0) { + // // + // // Here we have to + // ModifyOpenTradesBasedOnCurrentTrade(signal); + // } + + // + result = true; + } + + // + return result; +} +// +// END Signal Related Functions ... +// + +// +// START Orders Functions ... +// +// +// Convert To XSignal Model ... +XSignal OrderToSignal() { + // + // Temp Result ... + XSignal result = {}; + result.type = X_SIGNAL_NONE; + + // + // Here we can get some usefull info based on selected order ... + double swap = OrderSwap(); + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + double stopLoss = OrderStopLoss(); + double openPrice = OrderOpenPrice(); + datetime openTime = OrderOpenTime(); + int magicNumber = OrderMagicNumber(); + double takeProfit = OrderTakeProfit(); + string comment = OrderComment(); + + // + ENUM_X_SIGNAL_PROVIDER provider = GetSignalProvider(comment); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // Conver Position to Signal ... + result.sl = stopLoss; + result.tp = takeProfit; + result.time = openTime; + result.symbol = _Symbol; + result.id = magicNumber; + result.comment = comment; + result.entry = openPrice; + result.provider = provider; + result.type = isLongOrder ? X_SIGNAL_LONG : X_SIGNAL_SHORT; + + // + return result; +} + +// +// START Count Orders ... +// +// +// Count Open Positions ... +int CountOpenTrades() { + // + int result = 0; + + // + // Loop through Orders ... + for (int i = 0; i < OrdersTotal(); i++) { + // + // Select indexed Order ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order ... + if (OrderSymbol() == _Symbol) { + result++; + } + } + } + + // + // Return Result ... + return result; +} + +// +// Count Open Long Positions ... +int CountOpenLongTrades() { + // + int result = 0; + + // + // Loop through Orders ... + for (int i = 0; i < OrdersTotal(); i++) { + // + // Select indexed Order ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order ... + if ( + OrderSymbol() == _Symbol + && OrderType() == OP_BUY + ) { + result++; + } + } + } + + // + // Return Result ... + return result; +} + +// +// Count Open Short Positions ... +int CountOpenShortTrades() { + // + int result = 0; + + // + // Loop through Orders ... + for (int i = 0; i < OrdersTotal(); i++) { + // + // Select indexed Order ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order ... + if ( + OrderSymbol() == _Symbol + && OrderType() == OP_SELL + ) { + result++; + } + } + } + + // + // Return Result ... + return result; +} +// +// END Count Orders ... +// + +// +// START Close Orders ... +// +// +// Close All Open Trades ... +bool CloseAllTrades() { + // + // Loop through all Positions ... + bool result = false; + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of All Trade Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + + // + return result; +} + +// +bool CloseAllProviderTrades( + ENUM_X_SIGNAL_PROVIDER provider +) { + // + bool result = false; + + // + // Loop through Signals ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + XSignal signal = OrderToSignal(); + + // + if (signal.provider == provider) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of All Provider Long Trades Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +bool CloseAllProviderLongTrades( + ENUM_X_SIGNAL_PROVIDER provider +) { + // + bool result = false; + + // + // Loop through Signals ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + XSignal signal = OrderToSignal(); + + // + if ( + signal.provider == provider + && signal.type == X_SIGNAL_LONG + ) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of All Provider Long Trades Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +bool CloseAllProviderShortTrades( + ENUM_X_SIGNAL_PROVIDER provider +) { + // + bool result = false; + + // + // Loop through Signals ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + XSignal signal = OrderToSignal(); + + // + if ( + signal.provider == provider + && signal.type == X_SIGNAL_SHORT + ) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of All Provider Long Trades Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +// Close All Open Long Trades ... +bool CloseAllLongTrades() { + // + // Loop through all Positions ... + bool result = false; + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + if (isLongOrder) { + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of All Long Trade Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +// Close All Open Short Trades ... +bool CloseAllShortTrades() { + // + // Loop through all Positions ... + bool result = false; + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + if (!isLongOrder) { + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of All Short Trade Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +// Close All In Profit Trades ... +bool CloseAllInProfitTrades() { + // + // Loop through all Positions ... + bool result = false; + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + if ( + profit > 0 + && profit > 50 * _Point + ) { + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of InProfit Trade Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +// Close All In DrawDown Trades ... +bool CloseAllInDrawDownTrades() { + // + // Loop through all Positions ... + bool result = false; + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + if (profit < 0) { + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of InDrawDown Trade Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +// Close Biggest In DrawDown Trades ... +bool CloseBiggestDrawDownTrade() { + // + // Loop through all Positions ... + bool result = false; + double drawDown = 0; + + // + // Find Biggest In DrawDown ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + if ( + profit < 0 + && MathAbs(profit) > drawDown + ) { + drawDown = profit; + } + } + } + } + + // + // Close Biggest In DrawDown ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + if ( + profit < 0 + && MathAbs(profit) >= drawDown + ) { + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of Max InDrawDown Trade Closing issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +// Close All Long Time Trades ... +bool CloseAllLongTimeTrades( + const int passedCandles, + const ENUM_X_SIGNAL_PROVIDER provider = X_UNKNOWN_PROVIDER +) { + // + bool result = false; + + // + if (passedCandles <= 0) { + return result; + } + + // + int currentBarIndex = iBarShift( + _Symbol, + _Period, + TimeCurrent() + ); + + // + int openTrades = CountOpenTrades(); + + // + // Loop through all Positions ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + datetime openTime = OrderOpenTime(); + int openBarIndex = iBarShift( + _Symbol, + _Period, + openTime + ); + string comment = OrderComment(); + + // + ENUM_X_SIGNAL_PROVIDER orderProvider = GetSignalProvider(comment); + bool isProviderVerified = + provider == X_UNKNOWN_PROVIDER ? + true : + orderProvider != X_UNKNOWN_PROVIDER + && orderProvider == provider + ; + + // + if ( + profit < 0 + && isProviderVerified + && openBarIndex - currentBarIndex >= passedCandles + // || ( + // profit > 0.5 + // && openBarIndex - currentBarIndex >= passedCandles - (passedCandles / 3) + // ) + ) { + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of Long Time issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + // else if ( + // openTrades > 0 + // && openBarIndex - currentBarIndex >= passedCandles - (passedCandles / 2) + // ) { + // result = CloseAllInProfitTrades() + // && CloseBiggestDrawDownTrade(); + // } + } + } + } + + // + return result; +} + +// +// Close all trades which passed Maximum Drawdown ... +bool CloseAllMaximumDrawDownPassedTrades( + const double maxDrDownPercentPerPTrade, + const ENUM_X_SIGNAL_TYPE type = X_SIGNAL_NONE, + const ENUM_X_SIGNAL_PROVIDER provider = X_UNKNOWN_PROVIDER +) { + // + if ( + initialBalance <= 0 + || maxDrDownPercentPerPTrade <= 0 + ) { + return false; + } + + // + // Retrieve Account Balance ... + double balance = AccountInfoDouble(ACCOUNT_BALANCE); + double maxAllowedDrawDown = -1 * (initialBalance * maxDrDownPercentPerPTrade); + + // + // Loop through all Positions ... + bool result = false; + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + string comment = OrderComment(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + bool isTypeVerified = + type == X_SIGNAL_NONE ? + true : + ( isLongOrder + && type == X_SIGNAL_LONG + ) || ( + !isLongOrder + && type == X_SIGNAL_SHORT + ) + ; + + // + ENUM_X_SIGNAL_PROVIDER orderProvider = GetSignalProvider(comment); + bool isProviderVerified = + provider == X_UNKNOWN_PROVIDER ? + true : + orderProvider != X_UNKNOWN_PROVIDER + && orderProvider == provider + ; + + // + if ( + profit < 0 + && isTypeVerified + && isProviderVerified + && MathAbs(profit) >= MathAbs(maxAllowedDrawDown) + ) { + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of Maximum DarwDown issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } + } + } + } + + // + return result; +} + +// +// Close All Trades Which Opens before Specified Length ... +bool CloseAllTradesWhichOpenInPastMarketLength( + const int marketLen +) { + // + bool result = false; + + // + if (marketLen <= 0) { + return result; + } + + // + int currentBarIndex = iBarShift( + _Symbol, + _Period, + TimeCurrent() + ); + + // + int openTrades = CountOpenTrades(); + + // + // Loop through all Positions ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + datetime openTime = OrderOpenTime(); + int openBarIndex = iBarShift( + _Symbol, + _Period, + openTime + ); + + // + if (openBarIndex <= currentBarIndex + marketLen) { + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // Since because of equity ... + // we have to ckose allpositions ... + bool isOrderClosed = OrderClose( + ticket, + lots, + closePrice, + clrYellow + ); + + // + if (isOrderClosed) { + // + LogMessage( + StringConcatenate( + "Order [", ticket, "] Closed because of Market Reverse issue ..." + ) + ); + } + + // + result = + result + || isOrderClosed; + } else if (openTrades > 0) { + // + // Close all InProfit Trdes and Biggest InDrawDown Trades ... + // result = CloseAllInProfitTrades(); + // && CloseBiggestDrawDownTrade(); + } + } + } + } + + // + return result; +} +// +// END Close Orders ... +// + +// +// START Modify Orders ... +// +// +void ModifyAllPriceLesserOpenTrades( + const XSignal &signal +) { + // + // Loop through all Open Trades ... + for (int i = OrdersTotal(); i >= 0; i--) { + // + // Check Order Selected or not ... + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + // + // Check Order Symbol is same as Current Symbol ... + if (OrderSymbol() == _Symbol) { + // + double lots = OrderLots(); + int ticket = OrderTicket(); + double profit = OrderProfit(); + double stopLoss = OrderStopLoss(); + double openPrice = OrderOpenPrice(); + datetime openTime = OrderOpenTime(); + double takeProfit = OrderTakeProfit(); + + // + // find order type ... + bool isLongOrder = OrderType() == OP_BUY; + + // + // find close price ... + double closePrice = isLongOrder ? + SymbolInfoDouble(_Symbol, SYMBOL_BID) : + SymbolInfoDouble(_Symbol, SYMBOL_ASK); + + // + // When new Signal Comming with price less than + // currently open trade and tp less than currently + // open trade, this means a market change happens ... + // here we can Close InProfit Trades or Modify Trades TP ... + if ( + ( + openPrice < signal.entry + || MathAbs(openPrice - signal.entry) < 300 * _Point + ) + && takeProfit > signal.tp + ) { + bool result = OrderModify( + ticket, + openPrice, + signal.sl, + signal.tp, + clrYellow + ); + } + } + } + } +} + +// +void ModifyOpenTradesBasedOnCurrentTrade( + const XSignal &signal +) { + // + ModifyAllPriceLesserOpenTrades(signal); +} +// +// END Modify Orders ... +// +// +// END Orders Functions ... +// + +// +// START Signal Conditions ... +// +// +// Clear Signal Conditions ... +void ClearSignalConditions() { + // + ClearLongSignalConditions(); + ClearShortSignalConditions(); +} + +// +// Clear all Conditions Waiter for Long Signals ... +void ClearLongSignalConditions() { + // + ClearXLongSignalConditions(); + ClearXRLongSignalConditions(); + ClearXTPWLongSignalConditions(); +} + +// +// Clear all Conditions Waiter for Short Signals ... +void ClearShortSignalConditions() { + // + ClearXShortSignalConditions(); + ClearXRShortSignalConditions(); + ClearXTPWShortSignalConditions(); +} +// +// END Signal Conditions ... +// diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.x.signal.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.x.signal.lib.mq4 new file mode 100644 index 0000000..834ddb1 --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.x.signal.lib.mq4 @@ -0,0 +1,1063 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 X Signal Global Library +// --------------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes library ... +#include "../Libraries/x-saherelm.lib.mq4" + +// +// Includes Indicator library ... +#include "../Libraries/x-saherelm.indicator.lib.mq4" + +// +// Includes Models library ... +#include "../Libraries/x-saherelm.models.lib.mq4" + +// +// START Inputs ... +// +// +input string xStarter = "- X Signal Provider -"; // ---> X Signal Provider <--- + +// +input bool enableXSignalling = true; // X Signalling Enable + +// +input bool enableXLong = true; // X Signalling Enable Long +input bool enableXShort = true; // X Signalling Enable Short + +// +input double xShortR2R = 3; // X Short Risk To Reward Ratio +input double xShortLotsPerTradePercent = 0.0002; // X Lots Percent per Short Trades +input double xShortMaxDrawdownPerTradePercent = 0.4; // X Max Allowed DrawDown Percent per Short Trade + +// +input double xLongR2R = 3; // X Long Risk To Reward Ratio +input double xLongLotsPerTradePercent = 0.0002; // X Lots Percent per Short Trades +input double xLongMaxDrawdownPerTradePercent = 0.4; // X Max Allowed DrawDown Percent per Long Trade + +// +input double xSharpDetectorFactor = 700; // X Sharp Detection Factor + +// +input int xMaximumCandlesPerTrade = 206; // X Maximum Candles which a Trade can open + +// +input int xOscillatorLength = 7; // X Oscillator Length + +// +input double xPSarStep = 0.02; // X Parabolic Sar Step +input double xPSarMaximum = 0.2; // X Parabolic Sar Maximum + +// +input int xRangeMarketLength = 5; // X Range Detector Length + +// +input int xSwingLength = 7; // X Signal Swing Length +// +// END Inputs ... +// + +// +// START Global Requirement Functions ... +// +// +// X Based Signal Conditions ... +struct XSignalConditions { + datetime startTime; + datetime signalTime; + datetime entryTime; +}; + +// +struct XMarketState { + double psar; + double fast; + double slow; + double open; + double verifier; + double oscillator; + double oscillatorVerifier; +}; + +// +static XSignalConditions xLongConds; +static bool xCloseLongTrades = false; +static bool xWaitForLongSignals = true; + +// +static XSignalConditions xShortConds; +static bool xCloseShortTrades = false; +static bool xWaitForShortSignals = true; + +// +// Count Number of Closed Maximum DrawDown Trades ... +static int xFailedSignals = 0; + +// +datetime lastVerifierTouched; +// +// END Global Requirement Functions ... +// + +// +// START Functions ... +// +// +// Check and Fill Long and Short Signal Handlers ... +void CheckXSignalHandler( + const int bar_index +) { + // + // Check Market For Enable/Disable Signal Handlers ... + // Checking Market for Long Signals ... + // + if ( + !enableXSignalling + || !(enableXLong || enableXShort) + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + XOHCL candle = GetCandleModel(bar_index); + XOHCL pCandle = GetCandleModel(bar_index + 1); + XTPOWState tPowState = GetXTPowState( + bar_index + 1, + xSwingLength + ); + + // + XMarketState state = GetXMarketState( + bar_index + 1 + ); + + // + // Check Verifier Last Touched ... + bool isVerifierTouched = pCandle.high > state.verifier + && pCandle.low < state.verifier; + + // + // Disable Signals if a signal Failed ... + if (xFailedSignals) { + // + // TODO: Complete this ... + } + + // + // Enable Or Disable Signalling ... + if (isVerifierTouched) { + // + lastVerifierTouched = barTime; + + // + if (xWaitForLongSignals) { + xWaitForLongSignals = false; + } + + // + if (xWaitForShortSignals) { + xWaitForShortSignals = false; + } + } else { + // + int lastVerifierTouchedBarIndex = iBarShift( + _Symbol, + _Period, + lastVerifierTouched + ); + + // + int distance = MathAbs(lastVerifierTouchedBarIndex - bar_index); + + // + if ( + !xWaitForLongSignals + && distance > (xSwingLength * 2) + ) { + xWaitForLongSignals = true; + } + + // + if ( + !xWaitForShortSignals + && ( + distance > (xSwingLength * 2) + || ( + tPowState.powerDown > tPowState.powerUp + && tPowState.powerDown < 49 + ) + ) + ) { + xWaitForShortSignals = true; + } + } + + // + // Close All Long Open Trades ... + if ( + tPowState.powerDown > 55 + && tPowState.powerDown > tPowState.powerUp + ) { + // xCloseLongTrades = true; + } +} + +// +// Check and Fill Long Signal Conditions ... +void CheckXLongSignalConditions( + const int bar_index +) { + // + if ( + !enableXLong + || !enableXSignalling + || !xWaitForLongSignals + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + bool isCrossOver = false; + bool isCrossUnder = false; + + // + XMarketState cState = GetXMarketState(1); + XMarketState pState = GetXMarketState(2); + + // + isCrossUnder = + cState.fast < cState.slow + && !(pState.fast < pState.slow) + ; + + // + isCrossOver = + cState.fast > cState.slow + && !(pState.fast > pState.slow) + ; + + // + if ( + isCrossUnder + && xLongConds.startTime == 0 + ) { + // + xLongConds.startTime = barTime; + return; + } + + // + if ( + isCrossOver + && xLongConds.startTime > 0 + && xLongConds.signalTime == 0 + ) { + // + xLongConds.signalTime = barTime; + xLongConds.entryTime = barTime; + return; + } +} + +// +// Check and Fill Short Signal Conditions ... +void CheckXShortSignalConditions( + const int bar_index +) { + // + if ( + !enableXShort + || !enableXSignalling + || !xWaitForShortSignals + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + bool isCrossOver = false; + bool isCrossUnder = false; + + // + XMarketState cState = GetXMarketState(1); + XMarketState pState = GetXMarketState(2); + + // + isCrossUnder = + cState.fast < cState.slow + && !(pState.fast < pState.slow) + ; + + // + isCrossOver = + cState.fast > cState.slow + && !(pState.fast > pState.slow) + ; + + // + if ( + isCrossOver + && xShortConds.startTime == 0 + ) { + // + xShortConds.startTime = barTime; + return; + } + + // + if ( + isCrossUnder + && xShortConds.startTime > 0 + && xShortConds.signalTime == 0 + ) { + // + xShortConds.signalTime = barTime; + xShortConds.entryTime = barTime; + return; + } +} + +// +// Convert Long Signal Conditions to XSignal ... +XSignalRequest GenerateXSignal( + const ENUM_X_SIGNAL_TYPE type, // Signal Type ... + const string signalTag , // Signal Tag ... + const int bar_index +) { + // + XSignalRequest result = {}; + + // + result.hasSignal = false; + result.type = X_SIGNAL_NONE; + result.provider = X_UNKNOWN_PROVIDER; + + // + if ( + !enableXSignalling + || !(enableXLong || enableXShort) + ) { + return result; + } + + // + bool requestLong = type == X_SIGNAL_LONG; + + // + if (requestLong) { + // + if ( + !ValidateXLongConditions() + ) { + return result; + } + } else { + // + if ( + !ValidateXShortConditions() + ) { + return result; + } + } + + // + // Price Calculations ... + // + RefreshRates(); + + // + double askPrice = SymbolInfoDouble( + _Symbol, + SYMBOL_ASK + ); + + // + double bidPrice = SymbolInfoDouble( + _Symbol, + SYMBOL_BID + ); + + // + double entryPrice = requestLong ? + askPrice : + bidPrice; + + // + double exitPrice = requestLong ? + bidPrice : + askPrice; + + // + double priceGap = MathAbs(entryPrice - exitPrice); + + // + double ll = + // + GetMarketLowestLow( + bar_index, + xSwingLength + ) + ; + + // + double hh = + // + GetMarketHighestHigh( + bar_index, + xSwingLength + ) + ; + + // + double openPrice = iOpen( + _Symbol, + _Period, + bar_index + ); + + // + double closePrice = iClose( + _Symbol, + _Period, + bar_index + ); + + // + double risk = requestLong ? + MathMin(openPrice, closePrice) - ll : + hh - MathMax(openPrice, closePrice) + ; + + // + double reward = + requestLong ? + risk * xLongR2R : + risk * xShortR2R + ; + + // + double sl = requestLong ? + 0 : + 0; + double tp = requestLong ? + entryPrice + reward : + entryPrice - reward + ; + + // + XRState range = GetXRange( + bar_index, + xRangeMarketLength + ); + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + result.signal.tp = tp; + result.signal.sl = sl; + result.signal.type = type; + result.signal.time = barTime; + result.signal.tag = signalTag; + result.signal.symbol = _Symbol; + result.signal.entry = entryPrice; + result.signal.id = totalSignals + 1; + result.signal.provider = X_XXX_PROVIDER; + + // + result.hasSignal = true; + result.type = type; + result.provider = X_XXX_PROVIDER; + + // + return result; +} + +// +// Validate Signal Conditions ... +bool ValidateXLongConditions() { + // + if ( + !enableXLong + || !enableXSignalling + ) { + return false; + } + + // + bool isConditionsFilled = + xLongConds.startTime > 0 + && xLongConds.signalTime > 0 + && xLongConds.entryTime > 0 + ; + + // + bool isBLFilled = false; + if (isConditionsFilled) { + // + int startBarIndex = iBarShift( + _Symbol, + _Period, + xLongConds.startTime + ); + + // + int signalBarIndex = iBarShift( + _Symbol, + _Period, + xLongConds.signalTime + ); + + // + int entryBarIndex = iBarShift( + _Symbol, + _Period, + xLongConds.entryTime + ); + + // + isBLFilled = + // + xLongConds.signalTime > xLongConds.startTime + && xLongConds.entryTime >= xLongConds.signalTime + // && MathAbs(signalBarIndex - startBarIndex) >= 1 + ; + } + + // + bool result = + isBLFilled + && isConditionsFilled + && xWaitForLongSignals + ; + + // + // Since maybe Conditions Filled but + // Slope is Negative, for Handling Next Signals and + // Prevent from infinity loop, here we Clear Signal Conditions ... + if ( + !result + && isConditionsFilled + ) { + ClearXLongSignalConditions(); + } + + // + return result; +} + +// +// Validate Signal Conditions ... +bool ValidateXShortConditions() { + // + if ( + !enableXShort + || !enableXSignalling + ) { + return false; + } + + // + bool isConditionsFilled = + xShortConds.startTime > 0 + && xShortConds.signalTime > 0 + && xShortConds.entryTime > 0 + ; + + // + bool isBLFilled = false; + if (isConditionsFilled) { + // + int startBarIndex = iBarShift( + _Symbol, + _Period, + xShortConds.startTime + ); + + // + int signalBarIndex = iBarShift( + _Symbol, + _Period, + xShortConds.signalTime + ); + + // + int entryBarIndex = iBarShift( + _Symbol, + _Period, + xShortConds.entryTime + ); + + // + isBLFilled = + // + xShortConds.signalTime > xShortConds.startTime + && xShortConds.entryTime >= xShortConds.signalTime + ; + } + + // + bool result = + isBLFilled + && isConditionsFilled + && xWaitForShortSignals + ; + + // + // Since maybe Conditions Filled but + // Slope is Negative, for Handling Next Signals and + // Prevent from infinity loop, here we Clear Signal Conditions ... + if ( + !result + && isConditionsFilled + ) { + ClearXShortSignalConditions(); + } + + // + return result; +} + +// +// Clear Long Signal Conditions for New One ... +void ClearXLongSignalConditions() { + // + xLongConds.startTime = 0; + xLongConds.entryTime = 0; + xLongConds.signalTime = 0; +} + +// +// Clear Short Signal Conditions for New One ... +void ClearXShortSignalConditions() { + // + xShortConds.startTime = 0; + xShortConds.entryTime = 0; + xShortConds.signalTime = 0; +} + +// +// Check State for Long Signals ... +bool IsReadyForXSignals( + const XSignal &signal +) { + // + bool result = false; + + // + if ( + !enableXSignalling + || !(enableXLong || enableXShort) + ) { + return result; + } + + // + int signalBarIndex = iBarShift( + _Symbol, + _Period, + signal.time + ); + + // + // XOHCL candle = GetCandleModel(0); + XOHCL candle = GetCandleModel(signalBarIndex); + XOHCL pCandle = GetCandleModel(signalBarIndex + 1); + + // + // Retrieve Range ... + XRState range = GetXRange( + signalBarIndex, + xRangeMarketLength + ); + + // + // Retrive XMarket States ... + XMarketState xState0 = GetXMarketState(signalBarIndex); + XMarketState xState1 = GetXMarketState(signalBarIndex + 1); + XMarketState xState2 = GetXMarketState(signalBarIndex + 2); + XMarketState xStateLast = GetXMarketState(signalBarIndex + xSwingLength); + + // + // Retrieve Trend Powers ... + XTPOWState xTPow0 = GetXTPowState( + signalBarIndex, + xSwingLength + ); + XTPOWState xTPow1 = GetXTPowState( + signalBarIndex + 1, + xSwingLength + ); + + // + double hh = GetMarketHighestHigh( + signalBarIndex, + xSwingLength + ); + double ll = GetMarketLowestLow( + signalBarIndex, + xSwingLength + ); + double diffChange = (hh - ll); + bool isBigSharpOccured = + diffChange > (xSharpDetectorFactor * _Point) + ; + + // + bool isPSarVerified = false; + bool isTPowVerified = false; + bool isStateVerified = false; + bool isPriceVerified = false; + + // + // Verify Long Signals ... + if (signal.type == X_SIGNAL_LONG) { + // + // Get Price Verification for Long ... + isPriceVerified = + // + // Starter ... + true + // + && !isBigSharpOccured + // + && signal.entry < hh + // + // && signal.entry < range.hh + // && signal.entry > range.mid + // // + // && candle.high > xState0.verifier + // && signal.entry > xState0.verifier + // + // && pCandle.low != ll + && pCandle.high != hh + ; + + // + int above20TPowers = 0; + double signalSlope = 0; + int tPowUnverifyConditions = 0; + int tPowUnverifyConditionsIdx = 0; + for (int i = signalBarIndex; i < signalBarIndex + xSwingLength; i++) { + // + XTPOWState iTPowState = GetXTPowState( + i, + xSwingLength + ); + + // + // Calculate Signal Slope ... + if (i == signalBarIndex) { + // + signalSlope = iTPowState.signal; + } else if (i == signalBarIndex + 1) { + // + signalSlope = GetSlope( + 1, + iTPowState.signal, + 2, + signalSlope + ); + } + + // + if ( + iTPowState.powerUp > iTPowState.powerDown + && MathMax(iTPowState.powerUp, iTPowState.powerDown) > 20 + ) { + above20TPowers++; + } + + // + if (tPowUnverifyConditionsIdx < 3) { + // + if ( + iTPowState.powerUp < iTPowState.powerDown + || iTPowState.signal > MathMax(iTPowState.powerUp, iTPowState.powerDown) + ) { + tPowUnverifyConditions++; + } + + // + tPowUnverifyConditionsIdx++; + } + } + + // + isTPowVerified = + above20TPowers > 1 + && tPowUnverifyConditions == 0 + ; + + // + isPSarVerified = + xState0.psar < signal.entry + && xState0.psar < candle.low; + + // + isStateVerified = + // + // Start ... + true + // + // && xState0.open < xState0.slow + ; + + // + result = + // + // Starter ... + true + // + && isPSarVerified + // + && isTPowVerified + // + && isStateVerified + // + && isPriceVerified + ; + } else + // + // Verify Short Signals ... + if (signal.type == X_SIGNAL_SHORT) { + // + isPSarVerified = + xState0.psar > signal.entry + && xState0.psar > candle.high + ; + + // + // Get Price Verification for Short ... + isPriceVerified = + // + // Starter ... + true + // + && !isBigSharpOccured + // + && signal.entry > ll + && pCandle.low != ll + ; + + // + int above20TPowers = 0; + double signalSlope = 0; + int tPowUnverifyConditions = 0; + int tPowUnverifyConditionsIdx = 0; + for (int i = signalBarIndex; i < signalBarIndex + xSwingLength; i++) { + // + XTPOWState iTPowState = GetXTPowState( + i, + xSwingLength + ); + + // + // Calculate Signal Slope ... + if (i == signalBarIndex) { + // + signalSlope = iTPowState.signal; + } else if (i == signalBarIndex + 1) { + // + signalSlope = GetSlope( + 1, + iTPowState.signal, + 2, + signalSlope + ); + } + + // + if ( + iTPowState.powerUp > iTPowState.powerDown + && MathMax(iTPowState.powerUp, iTPowState.powerDown) > 20 + ) { + above20TPowers++; + } + + // + if (tPowUnverifyConditionsIdx < 3) { + // + if ( + iTPowState.powerUp > iTPowState.powerDown + || iTPowState.signal < MathMax(iTPowState.powerUp, iTPowState.powerDown) + ) { + tPowUnverifyConditions++; + } + + // + tPowUnverifyConditionsIdx++; + } + } + + // + isTPowVerified = + above20TPowers < 1 + && tPowUnverifyConditions == 0 + && MathAbs(xTPow0.powerUp - xTPow0.powerDown) > 50 * _Point + ; + + // + isStateVerified = + // + // Start ... + true + // + // && (xStateLast.verifier - xState0.verifier) >= 0 + // + && xState0.verifier > signal.entry + // + && MathAbs(signal.entry - xState0.verifier) < (xSharpDetectorFactor * _Point) + ; + + // + result = + // + // Starter Condition ... + true + // + && isPSarVerified + // + && isTPowVerified + // + && isStateVerified + // + && isPriceVerified + ; + } + + // + return result; +} +// +// END Functions ... +// + +// +// START Data Provider ... +// +XMarketState GetXMarketState( + const int bar_index +) { + // + XMarketState result = {}; + + // + double fast = GetMA( + bar_index, + xSwingLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double open = GetMA( + bar_index, + xSwingLength, + 0, + MODE_SMA, + PRICE_OPEN + ); + + // + double slow = GetMA( + bar_index, + xSwingLength * 2, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double oscillator = GetMA( + bar_index, + xSwingLength, + 0, + MODE_EMA, + PRICE_CLOSE + ); + + // + double oscillatorVerifier = GetMA( + bar_index, + xSwingLength, + 0, + MODE_EMA, + PRICE_WEIGHTED + ); + + // + int dailyCount = GetDailyCandleCount(); + double verifier = GetMA( + bar_index, + dailyCount, + 0, + MODE_EMA, + PRICE_MEDIAN + ); + + // + double psar = iSAR( + _Symbol, + _Period, + xPSarStep, + xPSarMaximum, + bar_index + ); + + // + result.psar = psar; + result.fast = fast; + result.open = open; + result.slow = slow; + result.verifier = verifier; + result.oscillator = oscillator; + result.oscillatorVerifier = oscillatorVerifier; + + // + return result; +} +// +// END Data Provider ... +// diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.xr.signal.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.xr.signal.lib.mq4 new file mode 100644 index 0000000..53785cf --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.xr.signal.lib.mq4 @@ -0,0 +1,1142 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 X Signal Global Library +// --------------------------------------------------- +// saherelm useful tools and definitions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes library ... +#include "../Libraries/x-saherelm.lib.mq4" + +// +// Includes Indicator library ... +#include "../Libraries/x-saherelm.indicator.lib.mq4" + +// +// Includes Models library ... +#include "../Libraries/x-saherelm.models.lib.mq4" + +// +// START Inputs ... +// +// +input string xRStarter = "- XR Signal Provider -"; // --> XR Signal Provider <-- + +// +input bool enableXRSignalling = false; // XR Signalling Enable + +// +input bool enableXRLong = true; // XR Signalling Enable Long +input bool enableXRShort = true; // XR Signalling Enable Short + +// +input double xRShortR2R = 1.5; // XR Short Risk To Reward Ratio +input double xRShortLotsPerTradePercent = 0.0002; // XR Lots Percent per Short Trades +input double xRShortMaxDrawdownPerTradePercent = 0.15; // XR Max Allowed DrawDown Percent per Short Trade + +// +input double xRLongR2R = 1.5; // XR Long Risk To Reward Ratio +input double xRLongLotsPerTradePercent = 0.0002; // XR Lots Percent per Short Trades +input double xRLongMaxDrawdownPerTradePercent = 0.15; // XR Max Allowed DrawDown Percent per Long Trade + +// +input int xRMaximumCandlesPerTrade = 96; // XR Maximum Candles which a Trade can open + +// +input int xRSwingLength = 48; // XR Swing Length +// +// END Inputs ... +// + +// +input double xRSharpDetectionFactor = 1350; // XR Sharp Detection Factor + +// +// START Global Requirement Functions ... +// +// +// XR Market State ... +struct XRMarketState { + // + double fast; + double slow; + double open; + + // + double range; + double rangeFast; + double rangeSlow; + double rangeOpen; + + // + double verifier; +}; + +// +// XR Based Signal Conditions ... +struct XRSignalConditions { + datetime startTime; + datetime signalTime; + datetime entryTime; +}; + +// +static XRSignalConditions xRLongConds; +static bool xRCloseLongTrades = false; +static bool xRWaitForLongSignals = true; + +// +static XRSignalConditions xRShortConds; +static bool xRCloseShortTrades = false; +static bool xRWaitForShortSignals = true; + +// +// Count Number of Closed Maximum DrawDown Trades ... +static int xRFailedSignals = 0; + +// +double xRMaximumDrawDown = 0; + +// +int fastLength = 0; +int slowLength = 0; + +// +int verifierLength = 0; + +// +int rangeFastLength = 0; +int rangeSlowLength = 0; +// +// END Global Requirement Functions ... +// + +// +// START Functions ... +// +// +// Check and Fill Long and Short Signal Handlers ... +void CheckXRSignalHandler( + const int bar_index +) { + // + // Check Market For Enable/Disable Signal Handlers ... + // Checking Market for Long Signals ... + + // + if ( + !enableXRSignalling + || !(enableXRLong || enableXRShort) + ) { + return; + } +} + +// +// Check and Fill Long Signal Conditions ... +void CheckXRLongSignalConditions( + const int bar_index +) { + // + if ( + !enableXRLong + || !enableXRSignalling + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + // Read Prices ... + XPrice prices = GetPrice(); + + // + // Read XPVTState ... + XPvtState pvt0 = GetPVTState( + bar_index, + xRSwingLength + ); + + // + // Double Length Pivots ... + XPvtState dblPvt0 = GetPVTState( + bar_index, + (xRSwingLength * 2) + ); + + // + // Reading Required Candles ... + XOHCL candle0 = GetCandleModel(bar_index); + XOHCL candle1 = GetCandleModel(bar_index + 1); + XOHCL candle2 = GetCandleModel(bar_index + 2); + XOHCL candle3 = GetCandleModel(bar_index + 3); + + // + // Reding Required XRMarketStates ... + XRMarketState state0 = GetXRMarketState(bar_index); + XRMarketState state1 = GetXRMarketState(bar_index + 1); + XRMarketState state2 = GetXRMarketState(bar_index + 2); + XRMarketState state3 = GetXRMarketState(bar_index + 3); + + // + // Reading required XRangeStates ... + XRState range0 = ReadXRange( + bar_index + xRSwingLength, + xRSwingLength + ); + XRState range1 = ReadXRange( + bar_index + xRSwingLength + 1, + xRSwingLength + ); + XRState range2 = ReadXRange( + bar_index + xRSwingLength + 2, + xRSwingLength + ); + + // + XRState cRange0 = ReadXRange( + bar_index, + xRSwingLength + ); + + // + // Validate Farest Range Values ... + if ( + range2.hh == 0 + || + range2.ll == 0 + || + range2.mid == 0 + ) { + return; + } + + // + // Reading Required XTPowStates ... + XTPOWState tPow0 = GetXTPowState( + bar_index, + xRSwingLength + ); + XTPOWState tPow1 = GetXTPowState( + bar_index + 1, + xRSwingLength + ); + XTPOWState tPow2 = GetXTPowState( + bar_index + 2, + xRSwingLength + ); + + // + // if state verifier below range middle + // this means market is bullish ... + // + // if state verifier above range middle + // this means market is bearish ... + // + + // + bool isMarketBullish = + state0.verifier < range0.mid + && state1.verifier < range1.mid; + bool isMarketBearish = + state0.verifier > range0.mid + && state1.verifier > range1.mid; + bool isMarketGoingBullish = + state0.verifier > range0.mid + && !(state1.verifier > range1.mid); + bool isMarketGoingBearish = + state0.verifier < range0.mid + && !(state1.verifier < range1.mid); + + // + // Check Highest High Conditions ... + bool isHHVerified = + !( + pvt0.hh == dblPvt0.hh + ) + ; + + // + int sharpDetectionLength = 7; + double sharpDetectionValue = xRSharpDetectionFactor * _Point; + + // + int sharpHHIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + sharpDetectionLength, + bar_index + ); + double sharpHH = iHigh( + _Symbol, + _Period, + sharpHHIdx + ); + + // + int sharpLLIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + sharpDetectionLength, + bar_index + ); + double sharpLL = iLow( + _Symbol, + _Period, + sharpLLIdx + ); + + // + double sharpDiff = sharpHH - sharpLL; + bool isSharpOccered = + sharpDiff > sharpDetectionValue; + + // + XRMarketState lastState = GetXRMarketState( + bar_index + sharpDetectionLength + ); + + // + double stateFSDiff = (state0.fast - state0.slow) - (lastState.fast - lastState.slow); + + // + // Start Calculating Long Conditions ... + bool longCondition1 = + // + // Starter ... + true + // + && isMarketBullish + // + && + ( + candle2.high < range2.mid + || ( + candle2.high > range2.mid + && candle2.low < range2.mid + ) + ) + && candle1.low > range1.mid + ; + + // + if ( + // + ( + longCondition1 + ) + // + && xRLongConds.startTime == 0 + && xRLongConds.entryTime == 0 + && xRLongConds.signalTime == 0 + ) { + // + xRLongConds.startTime = barTime; + xRLongConds.entryTime = barTime; + xRLongConds.signalTime = barTime; + + // + return; + } +} + +// +// Check and Fill Short Signal Conditions ... +void CheckXRShortSignalConditions( + const int bar_index +) { + // + if ( + !enableXRShort + || !enableXRSignalling + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + // Read Prices ... + XPrice prices = GetPrice(); + + // + // Read XPVTState ... + XPvtState pvt0 = GetPVTState( + bar_index, + xRSwingLength + ); + + // + // Double Length Pivots ... + XPvtState dblPvt0 = GetPVTState( + bar_index, + (xRSwingLength * 2) + ); + + // + // Reading Required Candles ... + XOHCL candle0 = GetCandleModel(bar_index); + XOHCL candle1 = GetCandleModel(bar_index + 1); + XOHCL candle2 = GetCandleModel(bar_index + 2); + XOHCL candle3 = GetCandleModel(bar_index + 3); + + // + // Reding Required XRMarketStates ... + XRMarketState state0 = GetXRMarketState(bar_index); + XRMarketState state1 = GetXRMarketState(bar_index + 1); + XRMarketState state2 = GetXRMarketState(bar_index + 2); + XRMarketState state3 = GetXRMarketState(bar_index + 3); + + // + // Reading required XRangeStates ... + XRState range0 = ReadXRange( + bar_index + xRSwingLength, + xRSwingLength + ); + XRState range1 = ReadXRange( + bar_index + xRSwingLength + 1, + xRSwingLength + ); + XRState range2 = ReadXRange( + bar_index + xRSwingLength + 2, + xRSwingLength + ); + + // + XRState cRange0 = ReadXRange( + bar_index, + xRSwingLength + ); + + // + // Validate Farest Range Values ... + if ( + range2.hh == 0 + || + range2.ll == 0 + || + range2.mid == 0 + ) { + return; + } + + // + // Reading Required XTPowStates ... + XTPOWState tPow0 = GetXTPowState( + bar_index, + xRSwingLength + ); + XTPOWState tPow1 = GetXTPowState( + bar_index + 1, + xRSwingLength + ); + XTPOWState tPow2 = GetXTPowState( + bar_index + 2, + xRSwingLength + ); + + // + // if state verifier below range middle + // this means market is bullish ... + // + // if state verifier above range middle + // this means market is bearish ... + // + + // + bool isMarketBullish = + state0.verifier < range0.mid + && state1.verifier < range1.mid; + bool isMarketBearish = + state0.verifier > range0.mid + && state1.verifier > range1.mid; + bool isMarketGoingBullish = + state0.verifier > range0.mid + && !(state1.verifier > range1.mid); + bool isMarketGoingBearish = + state0.verifier < range0.mid + && !(state1.verifier < range1.mid); + + // + // Check Highest High Conditions ... + bool isHHVerified = + !( + pvt0.hh == dblPvt0.hh + ) + ; + + // + int sharpDetectionLength = 7; + double sharpDetectionValue = xRSharpDetectionFactor * _Point; + + // + int sharpHHIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + sharpDetectionLength, + bar_index + ); + double sharpHH = iHigh( + _Symbol, + _Period, + sharpHHIdx + ); + + // + int sharpLLIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + sharpDetectionLength, + bar_index + ); + double sharpLL = iLow( + _Symbol, + _Period, + sharpLLIdx + ); + + // + double sharpDiff = sharpHH - sharpLL; + bool isSharpOccered = + sharpDiff > sharpDetectionValue; + + // + XRMarketState lastState = GetXRMarketState( + bar_index + sharpDetectionLength + ); + + // + double stateFSDiff = (state0.fast - state0.slow) - (lastState.fast - lastState.slow); + + // + // Start Calculating Long Conditions ... + bool shortCondition1 = + // + // Starter ... + true + // + && isMarketBearish + // + && + ( + candle2.low > range2.mid + || ( + candle2.high > range2.mid + && candle2.low < range2.mid + ) + ) + && candle1.high < range1.mid + ; + + // + if ( + // + ( + shortCondition1 + ) + // + && xRShortConds.startTime == 0 + && xRShortConds.entryTime == 0 + && xRShortConds.signalTime == 0 + ) { + // + xRShortConds.startTime = barTime; + xRShortConds.entryTime = barTime; + xRShortConds.signalTime = barTime; + + // + return; + } +} + +// +// Convert Long Signal Conditions to XSignal ... +XSignalRequest GenerateXRSignal( + const ENUM_X_SIGNAL_TYPE type, // Signal Type ... + const string signalTag , // Signal Tag ... + const int bar_index +) { + // + XSignalRequest result = {}; + + // + result.hasSignal = false; + result.type = X_SIGNAL_NONE; + result.provider = X_UNKNOWN_PROVIDER; + + // + if ( + !enableXRSignalling + || !(enableXRLong || enableXRShort) + ) { + return result; + } + + // + bool requestLong = type == X_SIGNAL_LONG; + + // + if (requestLong) { + // + if ( + !ValidateXRLongConditions() + ) { + return result; + } + } else { + // + if ( + !ValidateXRShortConditions() + ) { + return result; + } + } + + // + // Price Calculations ... + XPvtState pvts = GetPVTState( + bar_index, + xRSwingLength + ); + XPrice prices = GetPrice(); + + // + double entryPrice = requestLong ? + prices.longEntry : + prices.shortEntry + ; + + // + double openPrice = iOpen( + _Symbol, + _Period, + bar_index + ); + + // + double closePrice = iClose( + _Symbol, + _Period, + bar_index + ); + + // + double risk = requestLong ? + MathMin(openPrice, closePrice) - pvts.ll : + pvts.hh - MathMax(openPrice, closePrice); + if (risk <= 0) { + // + risk = requestLong ? + MathAbs(pvts.hh - entryPrice) : + MathAbs(pvts.ll - entryPrice) + ; + } + + // + double reward = + requestLong ? + risk * xRLongR2R : + risk * xRShortR2R + ; + + // + double sl = requestLong ? + 0 : + 0; + + // + double tp = requestLong ? + entryPrice + reward : + entryPrice - reward + ; + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + result.signal.tp = tp; + result.signal.sl = sl; + result.signal.type = type; + result.signal.time = barTime; + result.signal.tag = signalTag; + result.signal.symbol = _Symbol; + result.signal.entry = entryPrice; + result.signal.id = totalSignals + 1; + result.signal.provider = X_XR_PROVIDER; + + // + result.hasSignal = true; + result.type = type; + result.provider = X_XR_PROVIDER; + + // + return result; +} + +// +// Validate Long Signal Conditions ... +bool ValidateXRLongConditions() { + // + if ( + !enableXRLong + || !enableXRSignalling + ) { + return false; + } + + // + bool isConditionsFilled = + xRLongConds.startTime > 0 + && xRLongConds.signalTime > 0 + && xRLongConds.entryTime > 0 + ; + + // + bool isBLFilled = false; + if (isConditionsFilled) { + // + isBLFilled = + // + xRLongConds.signalTime >= xRLongConds.startTime + && xRLongConds.entryTime >= xRLongConds.signalTime + ; + } + + // + bool result = + isBLFilled + && isConditionsFilled + && xRWaitForLongSignals + ; + + // + // Since maybe Conditions Filled but + // Slope is Negative, for Handling Next Signals and + // Prevent from infinity loop, here we Clear Signal Conditions ... + if ( + !result + && isConditionsFilled + ) { + ClearXRLongSignalConditions(); + } + + // + return result; +} + +// +// Validate Short Signal Conditions ... +bool ValidateXRShortConditions() { + // + if ( + !enableXRShort + || !enableXRSignalling + ) { + return false; + } + + // + bool isConditionsFilled = + xRShortConds.startTime > 0 + && xRShortConds.signalTime > 0 + && xRShortConds.entryTime > 0 + ; + + // + bool isBLFilled = false; + if (isConditionsFilled) { + // + isBLFilled = + // + xRShortConds.signalTime >= xRShortConds.startTime + && xRShortConds.entryTime >= xRShortConds.signalTime + ; + } + + // + bool result = + isBLFilled + && isConditionsFilled + && xRWaitForShortSignals + ; + + // + // Since maybe Conditions Filled but + // Slope is Negative, for Handling Next Signals and + // Prevent from infinity loop, here we Clear Signal Conditions ... + if ( + !result + && isConditionsFilled + ) { + ClearXRShortSignalConditions(); + } + + // + return result; +} + +// +// Clear Long Signal Conditions for New One ... +void ClearXRLongSignalConditions() { + // + xRLongConds.startTime = 0; + xRLongConds.signalTime = 0; + xRLongConds.entryTime = 0; +} + +// +// Clear Short Signal Conditions for New One ... +void ClearXRShortSignalConditions() { + // + xRShortConds.startTime = 0; + xRShortConds.signalTime = 0; + xRShortConds.entryTime = 0; +} + +// +// Check State for Long Signals ... +bool IsReadyForXRSignals( + const XSignal &signal +) { + // + bool result = false; + + // + if ( + !enableXRSignalling + || !(enableXRLong || enableXRShort) + ) { + return result; + } + + // + // Find Signal Bar Index ... + int signalBarIndex = iBarShift( + _Symbol, + _Period, + signal.time + ); + + // + // Read Prices ... + XPrice prices = GetPrice(); + + // + // Read XPVTState ... + XPvtState pvt0 = GetPVTState( + signalBarIndex, + xRSwingLength + ); + + // + // Reading Required Candles ... + XOHCL candle0 = GetCandleModel(signalBarIndex); + XOHCL candle1 = GetCandleModel(signalBarIndex + 1); + XOHCL candle2 = GetCandleModel(signalBarIndex + 2); + XOHCL candle3 = GetCandleModel(signalBarIndex + 3); + + // + // Reding Required XRMarketStates ... + XRMarketState state0 = GetXRMarketState(signalBarIndex); + XRMarketState state1 = GetXRMarketState(signalBarIndex + 1); + XRMarketState state2 = GetXRMarketState(signalBarIndex + 2); + XRMarketState state3 = GetXRMarketState(signalBarIndex + 3); + + // + // Reading required XRangeStates ... + XRState range0 = ReadXRange( + signalBarIndex + xRSwingLength, + xRSwingLength + ); + XRState range1 = ReadXRange( + signalBarIndex + xRSwingLength + 1, + xRSwingLength + ); + XRState range2 = ReadXRange( + signalBarIndex + xRSwingLength + 2, + xRSwingLength + ); + + // + // Reading Required XTPowStates ... + XTPOWState tPow0 = GetXTPowState( + signalBarIndex, + xRSwingLength + ); + XTPOWState tPow1 = GetXTPowState( + signalBarIndex + 1, + xRSwingLength + ); + XTPOWState tPow2 = GetXTPowState( + signalBarIndex + 2, + xRSwingLength + ); + + // + double hhllDiff = MathAbs(pvt0.hh - pvt0.ll); + double sharpDetectionValue = xRSharpDetectionFactor * _Point; + bool isSharpOccured = hhllDiff > sharpDetectionValue; + + // + // Calculate State Min Max Diff ... + // + double state0Min = MathMin(state0.fast, state0.slow); + state0Min = MathMin(state0Min, state0.open); + state0Min = MathMin(state0Min, state0.rangeFast); + state0Min = MathMin(state0Min, state0.rangeSlow); + state0Min = MathMin(state0Min, state0.rangeOpen); + state0Min = MathMin(state0Min, state0.verifier); + + // + double state0Max = MathMax(state0.fast, state0.slow); + state0Max = MathMax(state0Max, state0.open); + state0Max = MathMax(state0Max, state0.rangeFast); + state0Max = MathMax(state0Max, state0.rangeSlow); + state0Max = MathMax(state0Max, state0.rangeOpen); + state0Max = MathMax(state0Max, state0.verifier); + + // + double state0MinMaxDiff = (state0Max - state0Min); + + // + bool isTPowValid = false; + bool isStateValid = false; + bool isRangeValid = false; + + // + // Verify Long Signals ... + if (signal.type == X_SIGNAL_LONG) { + // + // Retrieve TPow Verifications ... + isTPowValid = + // + // Starter ... + true + ; + + // + // Retrieve XMarket Verifications ... + isStateValid = + // + // Starter ... + true + // + // && !(state0MinMaxDiff > sharpDetectionValue) + ; + + // + // Retrieve XRange Verifications ... + isRangeValid = + // + // Starter ... + true + ; + + // + result = + // + // Starter ... + true + // + && isTPowValid + && isStateValid + && isRangeValid + ; + } else + // + // Verify Short Signals ... + if (signal.type == X_SIGNAL_SHORT) { + // + // Retrieve TPow Verifications ... + isTPowValid = + // + // Starter ... + true + ; + + // + // Retrieve XMarket Verifications ... + isStateValid = + // + // Starter ... + true + ; + + // + // Retrieve XRange Verifications ... + isRangeValid = + // + // Starter ... + true + ; + + // + result = + // + // Starter ... + true + // + && isTPowValid + && isStateValid + && isRangeValid + ; + } + + // + return result; +} +// +// END Functions ... +// + +// +// START Data Providers ... +// +// +XRMarketState GetXRMarketState( + const int bar_index +) { + // + XRMarketState result = {}; + + // + // Calculate Market Lengths ... + + // + if (fastLength == 0) { + fastLength = xRSwingLength; + } + + // + if (slowLength == 0) { + slowLength = xRSwingLength * 2; + } + + // + if (verifierLength == 0) { + verifierLength = (GetDailyCandleCount() * 2); + } + + // + if (rangeFastLength == 0) { + rangeFastLength = (int)(verifierLength / 2); + } + + // + if (rangeSlowLength == 0) { + rangeSlowLength = verifierLength; + } + + // + // Reading Values ... + + // + double fast = GetMA( + bar_index, + fastLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double slow = GetMA( + bar_index, + slowLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double open = GetMA( + bar_index, + fastLength, + 0, + MODE_SMA, + PRICE_OPEN + ); + + // + double rangeFast = GetMA( + bar_index, + rangeFastLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double rangeSlow = GetMA( + bar_index, + rangeSlowLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double rangeOpen = GetMA( + bar_index, + rangeFastLength, + 0, + MODE_SMA, + PRICE_OPEN + ); + + // + double verifier = GetMA( + bar_index, + verifierLength, + 0, + MODE_EMA, + PRICE_MEDIAN + ); + + // + // Filling Result ... + result.fast = fast; + result.slow = slow; + result.open = open; + result.verifier = verifier; + result.rangeFast = rangeFast; + result.rangeSlow = rangeSlow; + result.rangeOpen = rangeOpen; + + // + return result; +} +// +// END Data Providers ... +// \ No newline at end of file diff --git a/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.xtpw.signal.lib.mq4 b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.xtpw.signal.lib.mq4 new file mode 100644 index 0000000..4bf02ce --- /dev/null +++ b/XAUUSD-15M-V1.0/MQ4/Libraries/x-saherelm.xtpw.signal.lib.mq4 @@ -0,0 +1,1332 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL4 XTPW Signal Global Library +// --------------------------------------------------- +// XSaherElm EA Signal Provider based on +// XTPow Indicator... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes library ... +#include "../Libraries/x-saherelm.lib.mq4" + +// +// Includes Indicator library ... +#include "../Libraries/x-saherelm.indicator.lib.mq4" + +// +// Includes Models library ... +#include "../Libraries/x-saherelm.models.lib.mq4" + +// +// START Inputs ... +// +// +input string xTPWStarter = "- XTPW Signal Provider -"; // ---> XTPW Signal Provider <--- + +// +input bool enableXTPWSignalling = true; // XTPW Signalling Enable + +// +input bool enableXTPWLong = true; // XTPW Signalling Enable Long +input bool enableXTPWShort = true; // XTPW Signalling Enable Short + +// +input double xTPWShortR2R = 2; // XTPW Short Risk To Reward Ratio +input double xTPWShortLotsPerTradePercent = 0.0002; // XTPW Lots Percent per Short Trades +input double xTPWShortMaxDrawdownPerTradePercent = 0.3; // XTPW Max Allowed DrawDown Percent per Short Trade + +// +input double xTPWLongR2R = 2; // XTPW Long Risk To Reward Ratio +input double xTPWLongLotsPerTradePercent = 0.0002; // XTPW Lots Percent per Short Trades +input double xTPWLongMaxDrawdownPerTradePercent = 0.3; // XTPW Max Allowed DrawDown Percent per Long Trade + +// +input int xTPWMaximumCandlesPerTrade = 206; // XTPW Maximum Candles which a Trade can open + +// +input double xTPWPSarStep = 0.02; // XTPW Parabolic Sar Step +input double xTPWPSarMaximum = 0.2; // XTPW Parabolic Sar Maximum + +// +input int xTPWSwingLength = 7; // XTPW Signal Swing Length +// +// END Inputs ... +// + +// +input double xTPWSharpDetectionFactor = 650; // XTPW Sharp Detection Factor + +// +// START Global Requirement Functions ... +// +// +// XTPW Based Signal Conditions ... +struct XTPWSignalConditions { + datetime startTime; + datetime signalTime; + datetime entryTime; +}; + +// +struct XTPWMarketState { + // + double psar; + + // + double scFast; + double scSlow; + double scWeight; + + // + double mcFast; + double mcSlow; + double mcWeight; + + // + double lcFast; + double lcSlow; + double lcWeight; +}; + +// +struct XLHS { + // + double scHH; + double scLL; + + // + double mcHH; + double mcLL; + + // + double lcHH; + double lcLL; +}; + +// +static XTPWSignalConditions xTPWLongConds; +static bool xTPWCloseLongTrades = false; +static bool xTPWWaitForLongSignals = true; + +// +static XTPWSignalConditions xTPWShortConds; +static bool xTPWCloseShortTrades = false; +static bool xTPWWaitForShortSignals = true; + +// +// Count Number of Closed Maximum DrawDown Trades ... +static int xTPWFailedSignals = 0; + +// +double tPowerVerifier = 20; +double tPowerMaxVerifier = 55; + +// +int scFastLength = 0; +int scSlowLength = 0; + +// +int mcFastLength = 0; +int mcSlowLength = 0; + +// +int lcFastLength = 0; +int lcSlowLength = 0; + +// +datetime lastTurnOffLongTradesTime; +datetime lastTurnOffShortTradesTime; +// +// END Global Requirement Functions ... +// + +// +// START Functions ... +// +// +// Check and Fill Long and Short Signal Handlers ... +void CheckXTPWSignalHandler( + const int bar_index +) { + // + // Check Market For Enable/Disable Signal Handlers ... + // Checking Market for Long Signals ... + + // + if ( + !enableXTPWSignalling + || !(enableXTPWLong || enableXTPWShort) + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + XOHCL candle0 = GetCandleModel(bar_index); + XOHCL candle1 = GetCandleModel(bar_index + 1); + XOHCL candle2 = GetCandleModel(bar_index + 1); + + // + XTPOWState tPow0 = GetXTPowState( + bar_index, + xTPWSwingLength + ); + XTPOWState tPow1 = GetXTPowState( + bar_index + 1, + xTPWSwingLength + ); + XTPOWState tPow2 = GetXTPowState( + bar_index + 2, + xTPWSwingLength + ); + + // + XTPWMarketState state0 = GetXTPWMarketState( + bar_index + ); + XTPWMarketState state1 = GetXTPWMarketState( + bar_index + 1 + ); + XTPWMarketState state2 = GetXTPWMarketState( + bar_index + 2 + ); + + // // + // // Disable Long Conditions ... + // if ( + // xTPWWaitForLongSignals + // && + // ( + // isRangeCrossOverRangeWeight + // || + // isRangeCrossUnderRangeWeight + // || + // isTPowUpperAboveMaxVerifier + // ) + // ) { + // // + // xTPWWaitForLongSignals = false; + // lastTurnOffLongTradesTime = barTime; + // } + + // // + // // Enable Long Conditions ... + // if ( + // !xTPWWaitForLongSignals + // && lastTurnOffLongTradesTime > 0 + // && ( + // // isFastCrossOverSlow + // // || + // // isFastCrossUnderSlow + // isRangeCrossOverRangeWeight + // || + // isRangeCrossUnderRangeWeight + // || + // isTPowUpperBelowMaxVerifier + // ) + // ) { + // // + // // Find Last Turn Off Bar Index ... + // int lastTurnOffLongTradesBarIndex = iBarShift( + // _Symbol, + // _Period, + // lastTurnOffLongTradesTime + // ); + + // // + // // the Distance must be bigger than market length ... + // if (MathAbs(lastTurnOffLongTradesBarIndex - bar_index) > xTPWSwingLength) { + // // + // xTPWWaitForLongSignals = true; + // lastTurnOffLongTradesTime = 0; + // } + // } +} + +// +// Check and Fill Long Signal Conditions ... +void CheckXTPWLongSignalConditions( + const int bar_index +) { + // + if ( + !enableXTPWLong + || !enableXTPWSignalling + || !xTPWWaitForLongSignals + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + // Retrieve TPow States ... + XTPOWState tPow0 = GetXTPowState( + bar_index, + xTPWSwingLength + ); + XTPOWState tPow1 = GetXTPowState( + bar_index + 1, + xTPWSwingLength + ); + XTPOWState tPow2 = GetXTPowState( + bar_index + 2, + xTPWSwingLength + ); + + // + // Retrieve TPowMarket State ... + XTPWMarketState state0 = GetXTPWMarketState( + bar_index + ); + XTPWMarketState state1 = GetXTPWMarketState( + bar_index + 1 + ); + XTPWMarketState state2 = GetXTPWMarketState( + bar_index + 2 + ); + + // + // Retrieve XPrice Model ... + XPrice prices = GetPrice(); + + // + // Retrieve Candles ... + XOHCL candle0 = GetCandleModel(bar_index); + XOHCL candle1 = GetCandleModel(bar_index + 1); + XOHCL candle2 = GetCandleModel(bar_index + 2); + + // + XLHS lhs = GetXTPWLHS(bar_index); + + // + bool isHHSame = + lhs.scHH == lhs.mcHH + && lhs.mcHH == lhs.lcHH + ; + + // + bool isLLSame = + lhs.scLL == lhs.mcLL + && lhs.mcLL == lhs.lcLL + ; + + // + bool startCondition = false; + bool signalCondition = false; + bool entryCondition = false; + + // + bool longCondition1 = + // + true + // + && !isHHSame + // + && !( + lhs.scLL == lhs.mcLL + ) + // + && !( + lhs.scHH == lhs.mcHH + ) + // + && !( + prices.longEntry + && candle0.high < state0.scFast + && candle0.high < state0.scSlow + && candle0.high < state0.mcFast + && candle0.high < state0.mcSlow + && candle0.high < state0.lcFast + && candle0.high < state0.lcSlow + ) + // + && tPow0.powerDown > tPowerMaxVerifier + && tPow1.powerDown > tPowerMaxVerifier + && tPow0.powerDown < MathMax(tPow1.powerUp, tPow1.powerDown) + && MathMax(tPow1.powerUp, tPow1.powerDown) > tPowerMaxVerifier + ; + + // + // Start Conditions ... + startCondition = ( + longCondition1 + ) + ; + + // + if ( + startCondition + && xTPWLongConds.startTime == 0 + && xTPWLongConds.signalTime == 0 + && xTPWLongConds.entryTime == 0 + ) { + // + xTPWLongConds.startTime = barTime; + xTPWLongConds.signalTime = barTime; + xTPWLongConds.entryTime = barTime; + + // + return; + } +} + +// +// Check and Fill Short Signal Conditions ... +void CheckXTPWShortSignalConditions( + const int bar_index +) { + // + if ( + !enableXTPWShort + || !enableXTPWSignalling + || !xTPWWaitForShortSignals + ) { + return; + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + // Retrieve TPower State ... + XTPOWState tPow0 = GetXTPowState( + bar_index, + xTPWSwingLength + ); + XTPOWState tPow1 = GetXTPowState( + bar_index + 1, + xTPWSwingLength + ); + XTPOWState tPow2 = GetXTPowState( + bar_index + 2, + xTPWSwingLength + ); + + // + // Retrieve TPWMarket State ... + XTPWMarketState state0 = GetXTPWMarketState( + bar_index + ); + XTPWMarketState state1 = GetXTPWMarketState( + bar_index + 1 + ); + XTPWMarketState state2 = GetXTPWMarketState( + bar_index + 2 + ); + + // + // Retrieve Candles ... + XOHCL candle0 = GetCandleModel(bar_index); + XOHCL candle1 = GetCandleModel(bar_index + 1); + XOHCL candle2 = GetCandleModel(bar_index + 2); + + // + XPrice prices = GetPrice(); + XLHS lhs = GetXTPWLHS(bar_index); + + // + double sharpDetectionValue = + xTPWSharpDetectionFactor * _Point; + + // + bool isHHSame = + lhs.scHH == lhs.mcHH + && lhs.mcHH == lhs.lcHH + ; + + // + bool isLLSame = + lhs.scLL == lhs.mcLL + && lhs.mcLL == lhs.lcLL + ; + + // + bool startCondition = false; + bool signalCondition = false; + bool entryCondition = false; + + // + bool shortCondition1 = + // + true + // + && tPow1.powerDown > tPowerMaxVerifier + && tPow2.powerDown < tPowerMaxVerifier + ; + + // + startCondition = ( + shortCondition1 + ) + ; + + // + if ( + startCondition + && xTPWShortConds.startTime == 0 + && xTPWShortConds.signalTime == 0 + && xTPWShortConds.entryTime == 0 + ) { + // + xTPWShortConds.startTime = barTime; + xTPWShortConds.signalTime = barTime; + xTPWShortConds.entryTime = barTime; + + // + return; + } +} + +// +// Convert Long Signal Conditions to XSignal ... +XSignalRequest GenerateXTPWSignal( + const ENUM_X_SIGNAL_TYPE type, // Signal Type ... + const string signalTag , // Signal Tag ... + const int bar_index +) { + // + XSignalRequest result = {}; + + // + result.hasSignal = false; + result.type = X_SIGNAL_NONE; + result.provider = X_UNKNOWN_PROVIDER; + + // + if ( + !enableXTPWSignalling + || !(enableXTPWLong || enableXTPWShort) + ) { + return result; + } + + // + bool requestLong = type == X_SIGNAL_LONG; + + // + // Check Condition Validations ... + if (requestLong) { + // + // Check Long Condtion is Valid, if Long Requested ... + if ( + !ValidateXTPWLongConditions() + ) { + return result; + } + } else { + // + // Check Short Condtion is Valid, if Short Requested ... + if ( + !ValidateXTPWShortConditions() + ) { + return result; + } + } + + // + double ll = + // + GetMarketLowestLow( + bar_index, + xTPWSwingLength + ) + ; + + // + double hh = + // + GetMarketHighestHigh( + bar_index, + xTPWSwingLength + ) + ; + + // + double openPrice = iOpen( + _Symbol, + _Period, + bar_index + ); + + // + double closePrice = iClose( + _Symbol, + _Period, + bar_index + ); + + // + // Price Calculations ... + XPrice prices = GetPrice(); + + // + // Read State ... + XTPWMarketState state0 = GetXTPWMarketState(bar_index); + + // + XOHCL candle0 = GetCandleModel(bar_index); + XOHCL candle1 = GetCandleModel(bar_index + 1); + XOHCL candle2 = GetCandleModel(bar_index + 2); + XOHCL candle3 = GetCandleModel(bar_index + 2); + + // + double risk = requestLong ? + // + MathMin(openPrice, closePrice) - ll : + hh - MathMax(openPrice, closePrice) + ; + + // + double longR2R = xTPWLongR2R; + double shortR2R = xTPWShortR2R; + + // + double sharpDetectorValue = xTPWSharpDetectionFactor * _Point; + + // + if ( + risk > 0 + && requestLong + ) { + return result; + } + + // + // Define Entry Price ... + double entryPrice = requestLong + ? + prices.longEntry + : + prices.shortEntry + ; + + // + // Fix TP Detects for Short Signals ... + if (!requestLong) { + risk = 0; + } + + // + double reward = requestLong ? + risk * longR2R : + risk * shortR2R + ; + + // + if (risk == 0) { + // + // Calculate Reward ... + reward = requestLong + ? + MathAbs(hh - entryPrice) + : + MathAbs(hh - entryPrice) + ; + + // + // Detect Sharp Change Occured or not ... + bool isSharpOccured = reward > sharpDetectorValue + || MathAbs(reward - sharpDetectorValue) < (50 * _Point); + + // + // Change Rewards on Special Conditions ... + if ( + ( + requestLong + && isSharpOccured + && ( + state0.lcFast < state0.lcSlow + || ( + state0.mcFast > state0.mcSlow + && state0.mcWeight < state0.mcSlow + ) + ) + ) + ) { + reward = reward / 2; + } + + // + if (reward < 50 * _Point) { + reward = (50 * _Point) + prices.priceGap; + } + + // // + // if (!requestLong) { + // reward = reward * shortR2R; + // } + } + + // + double sl = requestLong ? + 0 : + 0; + double tp = requestLong ? + entryPrice + reward : + entryPrice - reward + ; + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index + ); + + // + result.signal.tp = tp; + result.signal.sl = sl; + result.signal.type = type; + result.signal.time = barTime; + result.signal.tag = signalTag; + result.signal.symbol = _Symbol; + result.signal.entry = entryPrice; + result.signal.id = totalSignals + 1; + result.signal.provider = X_XTPW_PROVIDER; + + // + result.hasSignal = true; + result.type = type; + result.provider = X_XTPW_PROVIDER; + + // + return result; +} + +// +// Validate Signal Conditions ... +bool ValidateXTPWLongConditions() { + // + if ( + !enableXTPWLong + || !enableXTPWSignalling + ) { + return false; + } + + // + bool isConditionsFilled = + xTPWLongConds.startTime > 0 + && xTPWLongConds.signalTime > 0 + && xTPWLongConds.entryTime > 0 + ; + + // + bool isBLFilled = false; + if (isConditionsFilled) { + // // + // int startBarIndex = iBarShift( + // _Symbol, + // _Period, + // xTPWLongConds.startTime + // ); + + // // + // int signalBarIndex = iBarShift( + // _Symbol, + // _Period, + // xTPWLongConds.signalTime + // ); + + // // + // int entryBarIndex = iBarShift( + // _Symbol, + // _Period, + // xTPWLongConds.entryTime + // ); + + // // + // int startSignalDiff = (signalBarIndex - startBarIndex); + // int entrySignalDiff = (entryBarIndex - signalBarIndex); + // int maxDiff = MathMax(startSignalDiff, entrySignalDiff); + + // + isBLFilled = + // + // Starter ... + true + // + && xTPWLongConds.signalTime >= xTPWLongConds.startTime + && xTPWLongConds.entryTime >= xTPWLongConds.signalTime + // + // && maxDiff < (xTPWSwingLength * 2) + ; + } + + // + bool result = + isBLFilled + && isConditionsFilled + && xTPWWaitForLongSignals + ; + + // + // Since maybe Conditions Filled but + // Slope is Negative, for Handling Next Signals and + // Prevent from infinity loop, here we Clear Signal Conditions ... + if ( + !result + && isConditionsFilled + ) { + ClearXTPWLongSignalConditions(); + } + + // + return result; +} + +// +// Validate Signal Conditions ... +bool ValidateXTPWShortConditions() { + // + if ( + !enableXTPWShort + || !enableXTPWSignalling + ) { + return false; + } + + // + bool isConditionsFilled = + xTPWShortConds.startTime > 0 + && xTPWShortConds.signalTime > 0 + && xTPWShortConds.entryTime > 0 + ; + + // + bool isBLFilled = false; + if (isConditionsFilled) { + // // + // int startBarIndex = iBarShift( + // _Symbol, + // _Period, + // xTPWShortConds.startTime + // ); + + // // + // int signalBarIndex = iBarShift( + // _Symbol, + // _Period, + // xTPWShortConds.signalTime + // ); + + // // + // int entryBarIndex = iBarShift( + // _Symbol, + // _Period, + // xTPWShortConds.entryTime + // ); + + // + isBLFilled = + // + // Starter ... + true + // + && xTPWShortConds.signalTime >= xTPWShortConds.startTime + && xTPWShortConds.entryTime >= xTPWShortConds.signalTime + ; + } + + // + bool result = + isBLFilled + && isConditionsFilled + && xTPWWaitForShortSignals + ; + + // + // Since maybe Conditions Filled but + // Slope is Negative, for Handling Next Signals and + // Prevent from infinity loop, here we Clear Signal Conditions ... + if ( + !result + && isConditionsFilled + ) { + ClearXTPWShortSignalConditions(); + } + + // + return result; +} + +// +// Clear Long Signal Conditions for New One ... +void ClearXTPWLongSignalConditions() { + // + xTPWLongConds.startTime = 0; + xTPWLongConds.entryTime = 0; + xTPWLongConds.signalTime = 0; +} + +// +// Clear Short Signal Conditions for New One ... +void ClearXTPWShortSignalConditions() { + // + xTPWShortConds.startTime = 0; + xTPWShortConds.entryTime = 0; + xTPWShortConds.signalTime = 0; +} + +// +// Check State for Long Signals ... +bool IsReadyForXTPWSignals( + const XSignal &signal +) { + // + bool result = false; + + // + if ( + !enableXTPWSignalling + || !(enableXTPWLong || enableXTPWShort) + ) { + return result; + } + + // + int signalBarIndex = iBarShift( + _Symbol, + _Period, + signal.time + ); + + // + // XOHCL candle = GetCandleModel(0); + XOHCL candle0 = GetCandleModel(signalBarIndex); + XOHCL candle1 = GetCandleModel(signalBarIndex + 1); + + // + // Retrieve TPow State ... + XTPOWState tPow0 = GetXTPowState( + signalBarIndex, + xTPWSwingLength + ); + XTPOWState tPow1 = GetXTPowState( + signalBarIndex + 1, + xTPWSwingLength + ); + + // + // Retrive XMarket States ... + XTPWMarketState state0 = GetXTPWMarketState(signalBarIndex); + XTPWMarketState state1 = GetXTPWMarketState(signalBarIndex + 1); + XTPWMarketState state2 = GetXTPWMarketState(signalBarIndex + 2); + + // + bool isPSarVerified = false; + bool isTPowVerified = false; + bool isStateVerified = false; + bool isPriceVerified = false; + + // + // Calculate Sharp Detection Value ... + double sharpDetectionValue = + xTPWSharpDetectionFactor * _Point; + + // + // Find State0 Min ... + double state0Min = MathMin(state0.scFast, state0.scSlow); + state0Min = MathMin(state0Min, state0.mcFast); + state0Min = MathMin(state0Min, state0.mcSlow); + state0Min = MathMin(state0Min, state0.lcFast); + state0Min = MathMin(state0Min, state0.lcSlow); + + // + // Find State0 Min ... + double state0Max = MathMax(state0.scFast, state0.scSlow); + state0Max = MathMax(state0Max, state0.mcFast); + state0Max = MathMax(state0Max, state0.mcSlow); + state0Max = MathMax(state0Max, state0.lcFast); + state0Max = MathMax(state0Max, state0.lcSlow); + + // + // Find Distance Between State0 Min and Max ... + double state0MinMaxDistance = MathAbs(state0Max - state0Min); + + // + // Verify Long Signals ... + if (signal.type == X_SIGNAL_LONG) { + // + // Get Price Verification for Long ... + isPriceVerified = + // + // Starter ... + true + // + ; + + // + isTPowVerified = + // + // Starter ... + true + // + && tPow0.powerDown > tPowerMaxVerifier + && tPow1.powerDown > tPowerMaxVerifier + && tPow0.powerDown < MathMax(tPow1.powerUp, tPow1.powerDown) + && MathMax(tPow1.powerUp, tPow1.powerDown) > tPowerMaxVerifier + ; + + // + isPSarVerified = + // + // Starter ... + true + // + ; + + // + isStateVerified = + // + // Start ... + true + // + && state0.mcFast > state0.mcSlow + && state1.mcFast > state1.mcSlow + // + && !( + state0.lcFast > state0.mcSlow + && state0.lcFast < state0.mcFast + ) + // + && MathAbs(state1.mcFast - state1.mcSlow) > (50 * _Point) + ; + + // + result = + // + // Starter ... + true + // + && isPSarVerified + // + && isTPowVerified + // + && isStateVerified + // + && isPriceVerified + ; + } else + // + // Verify Short Signals ... + if (signal.type == X_SIGNAL_SHORT) { + // + isPSarVerified = + // + // Starter ... + true + ; + + // + // Get Price Verification for Short ... + isPriceVerified = + // + // Starter ... + true + ; + + // + isTPowVerified = + // + // Starter ... + true + // + && tPow0.signal > MathMax(tPow0.powerUp, tPow0.powerDown) + ; + + // + isStateVerified = + // + // Start ... + true + // + && ( + // + state0.scFast < state0.scSlow + && state0.mcFast < state0.mcSlow + && state0.lcFast < state0.lcSlow + ? + signal.entry > state0.scFast + : + // + // Find Minimum and Maximum Distance of State ... + state0MinMaxDistance > sharpDetectionValue + ? + signal.entry > state0Min + : + true + ) + // + && MathAbs(state0.mcFast - state0.mcSlow) > 50 * _Point + ; + + // + result = + // + // Starter Condition ... + true + // + && isPSarVerified + // + && isTPowVerified + // + && isStateVerified + // + && isPriceVerified + ; + } + + // + return result; +} +// +// END Functions ... +// + +// +// START Data Provider ... +// +// +// Retrieve Market State ... +XTPWMarketState GetXTPWMarketState( + const int bar_index +) { + // + XTPWMarketState result = {}; + + // + int dayCount = GetDailyCandleCount(); + int halfDayCount = (int)(dayCount / 2); + + // + if (scFastLength == 0) { + scFastLength = xTPWSwingLength; + } + + // + if (scSlowLength == 0) { + scSlowLength = xTPWSwingLength * 2; + } + + // + if (mcFastLength == 0) { + mcFastLength = halfDayCount; + } + + // + if (mcSlowLength == 0) { + mcSlowLength = dayCount; + } + + // + if (lcFastLength == 0) { + lcFastLength = halfDayCount * 3; + } + + // + if (lcSlowLength == 0) { + lcSlowLength = dayCount * 3; + } + + // + double scFast = GetMA( + bar_index, + scFastLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double scSlow = GetMA( + bar_index, + scSlowLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double scWeight = GetMA( + bar_index, + scSlowLength, + 0, + MODE_EMA, + PRICE_MEDIAN + ); + + // + double mcFast = GetMA( + bar_index, + mcFastLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double mcSlow = GetMA( + bar_index, + mcSlowLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double mcWeight = GetMA( + bar_index, + mcSlowLength, + 0, + MODE_EMA, + PRICE_MEDIAN + ); + + // + double lcFast = GetMA( + bar_index, + lcFastLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double lcSlow = GetMA( + bar_index, + lcSlowLength, + 0, + MODE_SMA, + PRICE_CLOSE + ); + + // + double lcWeight = GetMA( + bar_index, + lcSlowLength, + 0, + MODE_EMA, + PRICE_MEDIAN + ); + + // + double psar = iSAR( + _Symbol, + _Period, + xTPWPSarStep, + xTPWPSarMaximum, + bar_index + ); + + // + result.psar = psar; + result.scFast = scFast; + result.scSlow = scSlow; + result.mcFast = mcFast; + result.mcSlow = mcSlow; + result.lcFast = lcFast; + result.lcSlow = lcSlow; + result.scWeight = scWeight; + result.mcWeight = mcWeight; + result.lcWeight = lcWeight; + + // + return result; +} + +// +// Retrieve Highest Highs and Lowest Lows in Cycles ... +XLHS GetXTPWLHS( + const int bar_index +) { + // + XLHS result = {}; + + // + // Retrieve LL and HH (s) ... + + // + // SC HH ... + double scHH = GetMarketHighestHigh( + bar_index, + scFastLength + ); + + // + // SC LL ... + double scLL = GetMarketHighestHigh( + bar_index, + scFastLength + ); + + // + // MC HH ... + double mcHH = GetMarketHighestHigh( + bar_index, + mcFastLength + ); + + // + // MC LL ... + double mcLL = GetMarketHighestHigh( + bar_index, + mcFastLength + ); + + // + // LC HH ... + double lcHH = GetMarketHighestHigh( + bar_index, + lcFastLength + ); + + // + // LC LL ... + double lcLL = GetMarketHighestHigh( + bar_index, + lcFastLength + ); + + // + result.scHH = scHH; + result.scLL = scLL; + result.mcHH = mcHH; + result.mcLL = mcLL; + result.lcHH = lcHH; + result.lcLL = lcLL; + + // + return result; +} +// +// END Data Provider ... +// diff --git a/XAUUSD-15M-V1.0/Version.txt b/XAUUSD-15M-V1.0/Version.txt new file mode 100644 index 0000000..630faf8 --- /dev/null +++ b/XAUUSD-15M-V1.0/Version.txt @@ -0,0 +1 @@ +packed at: Tue Oct 10 2023 01:05:43 GMT+0330 (Iran Standard Time) \ No newline at end of file diff --git a/XEU5-0/Classes/.gitkeep b/XEU5-0/Classes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Classes/x-saherelm.class.lib.mq5 b/XEU5-0/Classes/x-saherelm.class.lib.mq5 new file mode 100644 index 0000000..4cfbd0e --- /dev/null +++ b/XEU5-0/Classes/x-saherelm.class.lib.mq5 @@ -0,0 +1,10286 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XClass +// Description: provides all classes for use ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include +#include +#include +#include +#include +#include +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Constant Definitions ... +// + +static uchar _md5_PADDING[64] = + { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define _md5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define _md5_I(x, y, z) ((y) ^ ((x) | (~z))) +#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +#define _md5_FF(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define _md5_GG(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define _md5_HH(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define _md5_II(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +#define _md5_INIT_STATE_0 0x67452301 +#define _md5_INIT_STATE_1 0xefcdab89 +#define _md5_INIT_STATE_2 0x98badcfe +#define _md5_INIT_STATE_3 0x10325476 + +#define _md5_S11 7 +#define _md5_S12 12 +#define _md5_S13 17 +#define _md5_S14 22 + +#define _md5_S21 5 +#define _md5_S22 9 +#define _md5_S23 14 +#define _md5_S24 20 + +#define _md5_S31 4 +#define _md5_S32 11 +#define _md5_S33 16 +#define _md5_S34 23 + +#define _md5_S41 6 +#define _md5_S42 10 +#define _md5_S43 15 +#define _md5_S44 21 + +// +// END Constant Definitions ... +// + +// +// START Model Definitions ... +// + +// +string X_SIGNAL_TP = "TP"; +string X_SIGNAL_SL = "SL"; +string X_SIGNAL_TYPE = "TY"; +string X_SIGNAL_TICKET = "T"; +string X_SIGNAL_RISKFREE_STEP = "RFS"; +string X_SIGNAL_RISKFREE_RATE = "RFR"; + +// +// Model Signal Handler Result on XCTrade Class ... +struct XTraderHandlerResult +{ + // + // List Of Closed On SL Signals ... + XSignal sl[]; + + // + // List Of Closed On TP Signals ... + XSignal tp[]; + + // + // List Of Risk Free Signals ... + XSignal rf[]; +}; + +// +// Model OnTrade Event Handler Result on XCTrade Class ... +struct XOnTradeHandlerResult +{ + // + bool hasNewDeal; + int newDeals; + + // + bool hasNewOrder; + int newOrders; + + // + bool hasNewPosition; + int newPositions; + + // + bool hasNewHistoryOrder; + int newHistoryOrders; +}; + +// +// Model Guard Action Applied Signals ... +struct XGuardHandlerResult +{ + // + // Critical Guard ... + XSignal criticals[]; + + // + // Max Guard ... + XSignal maxes[]; + + // + // Old ... + XSignal olds[]; + + // + // Determines Stopout Action Cals or not ... + bool isStopOut; +}; + +// +// Define Volume States ... +struct XVolumeInfo +{ + // + // Current Available Static Volume ... + double staticVolume; + + // + // Static Volume Calculation Method ... + string staticVolumeCalculationMethod; + + // + // Current Maximum Appliable Volume ... + double maxAllowedVolume; + + // + // Static Volume Increase Multiplier ... + double volumeIncreaseMultiplier; + + // + // Multiply Volume Based On Balance Growing ... + double balanceGowingToApplyMultiplier; + + // + // Where to Increase MaxAllowed Volume ... + double balanceGrowingToIncreaseMaxAllowedVolume; +}; + +// +// Model a Simple Provider Status ... +struct XSignallerInfo +{ + // + // Provider Name ... + string name; + + // + // Number of Longs ... + int longs; + + // + // Number of Shorts ... + int shorts; +}; + +// +// Model Some of Usefull Signals and Market Data ... +struct XSummaryInfo +{ + // + // Define Max Signal Volume ... + double maxSignalVolume; + + // + // Max DrawDown ... + double maxDrawDown; + + // + // Max DrawUp ... + double maxDrawUp; + + // + // Max Number of Same Time Signals ... + int maxSameTimeSignals; + + // + // Number of Long Trades ... + int longSignals; + + // + // Number of Short Trades ... + int shortSignals; + + // + // Number of TPs Attached ... + int numberOfTPs; + + // + // Number of SLs Attached ... + int numberOfSLs; +}; + +// +// Model Account info ... +struct XAccountInfo +{ + // + // User Account ... + string user; + + // + // Name of Client ... + string name; + + // + // Trade Server Name ... + string server; + + // + // Broker Name ... + string broker; + + // + // Account Trade Mode ... + ENUM_ACCOUNT_TRADE_MODE mode; + + // + // Account Leverage ... + long leverage; + + // + // Currency ... + string currency; + + // + // Deposit ... + double deposit; + + // + // Balance ... + double balance; + + // + // Min Balance for Open Trades ... + double minBalanceForOpenTrades; +}; + +// +// this is a Model Which holds Reports for Specific Time Periods ... +struct XReport +{ + // + datetime start; + + // + datetime end; + + // + XAccountInfo accountInfo; + + // + XVolumeInfo volumeInfo; + + // + XSignallerInfo signallersInfo[]; + + // + XSummaryInfo summaryInfo; +}; + +// +// an Enumeration Object which determines Report Type ... +enum ENUM_XREPORT_TYPES +{ + // + // Main Report ... + XREPORT_MAIN, + // + // Daily Report ... + XREPORT_DAILY, + // + // Weekly Report ... + XREPORT_WEEKLY, + // + // Monthly Report ... + XREPORT_MONTHLY, +}; + +// +// a Signal Protection Structure ... +struct XProtectedSignal +{ + // + ulong ticket; + + // + datetime time[]; + + // + double profit[]; +}; + +// +// Represent Collector State Based on Time ... +struct XCollector +{ + // + // time in checking ... + datetime time; + + // + // Signal Volume ... + double volume; + + // + // Max DrawDown in Check Time ... + double maxDrawDown; + + // + // Max Allowed Volume in Check Time ... + double maxAllowedVolume; + + // + // Minimum required Balance for Opening Trades at Check Time ... + double minBalanceForOpenTrade; +}; + +// +// the Action which Guard Handler Can Done when Attacked ... +enum ENUM_X_GUARD_ACTIONS +{ + // + // Do Nothing ... + X_GUARD_DO_NOTHING, + // + // Close All Open Positions ... + X_GUARD_CLOSE_ALL, + // + // Close Max In Drawdown Position ... + X_GUARD_CLOSE_MAX_IN_DD, + // + // Partial Close Max In Drawdown Position by 1% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1, + // + // Partial Close Max In Drawdown Position by 2% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2, + // + // Partial Close Max In Drawdown Position by 3% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3, + // + // Partial Close Max In Drawdown Position by 5% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5, + // + // Partial Close Max In Drawdown Position by 10% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10, + // + // Partial Close Max In Drawdown Position by 15% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15, + // + // Partial Close Max In Drawdown Position by 20% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20, + // + // Partial Close Max In Drawdown Position by 25% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25, + // + // Partial Close Max In Drawdown Position by 30% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30, + // + // Partial Close Max In Drawdown Position by 40% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40, + // + // Partial Close Max In Drawdown Position by 50% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50, + // + // Partial Close Max In Drawdown Position by 60% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60, + // + // Partial Close Max In Drawdown Position by 70% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70, + // + // Partial Close Max In Drawdown Position by 75% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75, +}; + +// +// Guard Reason ... +enum ENUM_X_GUARD_REASONS +{ + // + // Critical ... + X_GUARDED_CRITICAL, + // + // Max ... + X_GUARDED_MAX, + // + // Old ... + X_GUARDED_OLD +}; + +// +// All Suuported Support Positions Guard ... +enum ENUM_X_GUARD_SUPPORT_METHODS +{ + // + // Ignore Supporting ... + X_SUPPORT_DO_NOTHING, + // + // Full Both Side Support ... + X_SUPPORT_FULL, + // + // Indirectional Supports On Drawing Down ... + X_SUPPORT_IN_DRAWDOWN_INDIRECTIONAL, + // + // Directional Supports On Drawing Up ... + X_SUPPORT_IN_DRAWUP_DIRECTIONAL, +}; + +// +// END Model Definitions ... +// + +// +// START Overrides ... +// + +// +// XBase Class ... +class XCBase +{ + // + // Public ... +public: + // + // Protected ... +protected: + // + void AddItemToBuffer( + double item, // Specified Item + double &buffer[] // Specified Buffer + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; + } + void AddItemToBuffer( + datetime item, // Specified Item + datetime &buffer[] // Specified Buffer + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; + } + void AddItemToBuffer( + XSignal &item, + XSignal &buffer[]) + { + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; + } + void AddItemToBuffer( + XCollector &item, // Specified Item + XCollector &buffer[] // Specified Buffer + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; + } + void AddItemToBuffer( + XSignallerInfo &item, + XSignallerInfo &buffer[]) + { + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; + } + void AddItemToBuffer( + XProtectedSignal &item, // Item ... + XProtectedSignal &buffer[] // Buffer ... + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + buffer[bufferSize] = item; + } + + // + void CleanBuffer(double &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XDeal &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XOrder &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XSignal &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XCollector &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XSignallerInfo &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XProtectedSignal &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + + // + void CopyBuffer( + const XSignallerInfo &source[], // Source Buffer ... + XSignallerInfo &dest[] // Dest Buffer ... + ) + { + // + CleanBuffer(dest); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < sourceCount; i++) + { + // + XSignallerInfo iInfo = source[i]; + + // + AddItemToBuffer( + iInfo, + dest); + } + } + void CopyBuffer( + XProtectedSignal &source[], // Source Buffer to Copy + XProtectedSignal &dest[] // Fill this buffer using source + ) + { + // + CleanBuffer(dest); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + XProtectedSignal iItem = source[i]; + + // + AddItemToBuffer( + iItem, + dest); + } + } + + // + // Private ... +private: +}; + +// +// XCTrade Base Class ... +class XSCTrade : public CTrade +{ +public: + // + // Modify Specific Position, by Specific Comment ... + bool PositionModify( + const string symbol, // Symbol + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!SelectPosition(symbol)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + bool PositionModify( + const ulong ticket, // Position Ticket + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.position = ticket; + m_request.symbol = PositionGetString(POSITION_SYMBOL); + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + + // + // Close Specific Position, by Specific Comment ... + bool PositionClose( + const string symbol, // Symbol + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + bool partial_close = false; + int retry_count = 10; + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + do + { + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specify Comment ... + m_request.comment = comment; + + // + // check volume + double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + if (m_request.volume > max_volume) + { + // + m_request.volume = max_volume; + partial_close = true; + } + else + { + partial_close = false; + } + + // + // hedging? just send order + if (IsHedging()) + { + return (OrderSend(m_request, m_result)); + } + + // + // order send + if (!OrderSend(m_request, m_result)) + { + // + if (--retry_count != 0) + { + continue; + } + + // + if (retcode == TRADE_RETCODE_DONE_PARTIAL) + { + m_result.retcode = retcode; + } + + // + return (false); + } + + // + //--- WARNING. If position volume exceeds the maximum volume allowed for deal, + //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, + //--- but partially. It is decreased by the maximum volume allowed for deal. + if (m_async_mode) + { + break; + } + + // + retcode = TRADE_RETCODE_DONE_PARTIAL; + if (partial_close) + { + Sleep(1000); + } + } while (partial_close); + + // + // succeed + return (true); + } + bool PositionClose( + const ulong ticket, // Position Ticket + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specify Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } + + // + // Partial Close Specific Position, by Specific Comment ... + bool PositionClosePartial( + const string symbol, // Symbol + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // hedging? just send order + return (OrderSend(m_request, m_result)); + } + bool PositionClosePartial( + const ulong ticket, // Position Ticket + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } +}; +// +// END Overrides ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// XCMD5 a library for Hashing ... +class XCMD5 : public XCBase +{ + // + // Public Provides ... +public: + // + // Protected Provides ... + + // + // Constructor ... + XCMD5(void) {} + + // + // Deconstructor ... + ~XCMD5(void) {} + + // + // Hash Specified Char Array ... + string Hash( + uchar &source[], // Specify Char Array to Hash + int length = 0 // Specify Length of Char Array which required to hash + ) + { + // + string result = ""; + + // + int sourceCount = ArraySize(source); + + // + // Validate Args ... + if ( + sourceCount <= 0 || + (sourceCount > 0 && length > sourceCount)) + { + return result; + } + + // + // Normalize Args ... + if (length == 0) + { + length = sourceCount; + } + + // + // Init MD5 ... + MD5Init(); + + // + // Update Buffer ... + MD5Update(source, length); + + // + // Calculate Result ... + result = MD5Final(); + + // + return result; + } + + // + // Hash Specified String ... + string Hash( + string source // Specified String + ) + { + // + string result = ""; + + // + // Converts String to Char Array ... + uchar bytes[]; + StringToCharArray( + source, + bytes, + 0, + StringLen(source)); + + // + result = Hash( + bytes, + ArraySize(bytes)); + + // + return result; + } + +protected: + // + // Private Provides ... +private: + // + uint m_lMD5[4]; + uint m_nCount[2]; + uchar m_lpszBuffer[64]; + + // + // Convert Byte to DWord ... + void ByteToDWord(int &out[], uint &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24; + } + } + + // + // Convert DWord to Byte ... + void DWordToByte(uchar &out[], int &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + // + out[j] = (uchar)(in[i] & 0xff); + out[j + 1] = (uchar)((in[i] >> 8) & 0xff); + out[j + 2] = (uchar)((in[i] >> 16) & 0xff); + out[j + 3] = (uchar)((in[i] >> 24) & 0xff); + } + } + + // + // Init MD5 Array ... + void MD5Init() + { + // + ArrayInitialize(m_lpszBuffer, 64); + + // + m_nCount[0] = m_nCount[1] = 0; + m_lMD5[0] = _md5_INIT_STATE_0; + m_lMD5[1] = _md5_INIT_STATE_1; + m_lMD5[2] = _md5_INIT_STATE_2; + m_lMD5[3] = _md5_INIT_STATE_3; + } + + // + // Update MD5 ... + void MD5Update(uchar &inBuf[], uint inLen) + { + // + int i, ii; + int mdi; + + // + uint in[16]; + int i0 = 0; + + // + mdi = (int)((m_nCount[0] >> 3) & 0x3F); + + // + if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0]) + { + m_nCount[1]++; + } + + // + m_nCount[0] += ((uint)inLen << 3); + m_nCount[1] += ((uint)inLen >> 29); + + // + while ((inLen--) > 0) + { + // + m_lpszBuffer[mdi++] = inBuf[i0++]; + if (mdi == 0x40) + { + // + for (i = 0, ii = 0; i < 16; i++, ii += 4) + { + in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]); + } + + // + Transform(m_lMD5, in); + + // + mdi = 0; + } + } + } + + // + // Finalize an MD5 Expression ... + string MD5Final() + { + // + uchar bits[8]; + int nIndex; + uint nPadLen; + const int nMD5Size = 16; + uchar lpszMD5[16]; + string temp; + string out = ""; + int i; + + // + DWordToByte(bits, m_nCount, 8); + nIndex = (int)((m_nCount[0] >> 3) & 0x3f); + nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); + MD5Update(_md5_PADDING, nPadLen); + MD5Update(bits, 8); + DWordToByte(lpszMD5, m_lMD5, nMD5Size); + + // + for (i = 0; i < nMD5Size; i++) + { + // + if (lpszMD5[i] == 0) + { + temp = "00"; + } + else if (lpszMD5[i] <= 15) + { + temp = StringFormat("0%x", lpszMD5[i]); + } + else + { + temp = StringFormat("%x", lpszMD5[i]); + } + + // + out += temp; + } + + // + lpszMD5[0] = '\0'; + + // + return (out); + } + + // + // Transform Buffers ... + void Transform(uint &buf[], uint &in[]) + { + // + uint a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + // + _md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478); + _md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756); + _md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB); + _md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE); + _md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF); + _md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A); + _md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613); + _md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501); + _md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8); + _md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF); + _md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1); + _md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE); + _md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122); + _md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193); + _md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E); + _md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821); + + // + _md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562); + _md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340); + _md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51); + _md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA); + _md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D); + _md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453); + _md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681); + _md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8); + _md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6); + _md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6); + _md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87); + _md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED); + _md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905); + _md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8); + _md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9); + _md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A); + + // + _md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942); + _md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681); + _md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122); + _md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C); + _md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44); + _md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9); + _md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60); + _md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70); + _md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6); + _md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA); + _md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085); + _md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05); + _md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039); + _md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5); + _md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8); + _md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665); + + // + _md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244); + _md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97); + _md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7); + _md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039); + _md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3); + _md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92); + _md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D); + _md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1); + _md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F); + _md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0); + _md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314); + _md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1); + _md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82); + _md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235); + _md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB); + _md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391); + + // + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; + } +}; + +// +// XSaherElm Account Info Class ... +class XCAccountInfo : public XCBase +{ + // + // Public properties ... +public: + // + // Constructro ... + void XCAccountInfo() + { + // + mAccountInfo = new CAccountInfo(); + + // + mInitialBalance = mAccountInfo.Balance(); + } + + // + // Deconstructor ... + void ~XCAccountInfo() + { + // + mInitialBalance = 0; + } + + // + // User Account ... + long GetUserAccount() + { + return mAccountInfo.Login(); + } + + // + // Account Leverage ... + long GetLeverage() + { + return mAccountInfo.Leverage(); + } + + // + // Get Trade Expert State ... + bool CanExpertTrade() + { + return mAccountInfo.TradeExpert(); + } + + // + // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... + // -------------------------- + // ACCOUNT_TRADE_MODE_DEMO + // ACCOUNT_TRADE_MODE_CONTEST + // ACCOUNT_TRADE_MODE_REAL + ENUM_ACCOUNT_TRADE_MODE GetTradeMode() + { + return mAccountInfo.TradeMode(); + } + + // + // Get Account Balance ... + double GetBalance() + { + return mAccountInfo.Balance(); + } + + // + // Get Initial Deposit Balance ... + double GetInitialBalance() + { + return mInitialBalance; + } + + // + // Get the amount of give Credit ... + double GetCredit() + { + return mAccountInfo.Credit(); + } + + // + // Get the amount of current Profit on account ... + double GetProfit() + { + return mAccountInfo.Profit(); + } + + // + // Get the amount of current Equity on account ... + double GetEquity() + { + return mAccountInfo.Equity(); + } + + // + // Get the amount of reserved Margin ... + double GetMargin() + { + return mAccountInfo.Margin(); + } + + // + // Get the amount of free Margin ... + double GetFreeMargin() + { + return mAccountInfo.FreeMargin(); + } + + // + // Get the Level of Margin ... + double GetMarginLevel() + { + return mAccountInfo.MarginLevel(); + } + + // + // Get the Level Of Margin for a Deposit ... + double GetMarginCall() + { + return mAccountInfo.MarginCall(); + } + + // + // Get the Level of Margin for Stop out ... + double GetMarginStopOut() + { + return mAccountInfo.MarginStopOut(); + } + + // + // Get the Client Name ... + string GetName() + { + return mAccountInfo.Name(); + } + + // + // Get the Trade Server Name ... + string GetServerName() + { + return mAccountInfo.Server(); + } + + // + // Get deposit Currency Name ... + string GetCurrency() + { + return mAccountInfo.Currency(); + } + + // + // Get the Company Name that serves an Account ... + string GetCompany() + { + return mAccountInfo.Company(); + } + + // + // Calculate Profits for the current account based on passed parameters ... + double CalculateTradeProfit( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry, // open price + double exit // close price + ) + { + // + double result = mAccountInfo.OrderProfitCheck( + symbol, + type, + volume, + entry, + exit); + + // + return result; + } + + // + // Calculate amount of margin which required for trade operation ... + double CalculateMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.MarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate amount of free margin left after trade operation ... + double CalculateFreeMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.FreeMarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate the Maximum possible volume of trade operation ... + double CalculateMaxVolume( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double entry, // open price + double percent = 100 // percent of available margin + ) + { + // + double result = mAccountInfo.MaxLotCheck( + symbol, + type, + entry, + percent); + + // + return result; + } + + // + // Protected properties ... +protected: + // + // Private properties ... +private: + // + // Initial Account Balance ... + double mInitialBalance; + + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// XSaherElm Report Info Class ... +class XCReporter : public XCBase +{ + // + // Public Provided ... +public: + // + // Constructro ... + void XCReporter() + { + // + mAccountInfo = new XCAccountInfo(); + + // + Reset(); + } + + // + // Deconstructor ... + void ~XCReporter() + { + } + + // + // Reset Specific Report ... + void Reset( + ENUM_XREPORT_TYPES type // Specify Report Type + ) + { + CleanReport(type); + } + + // + // Reset All Reports ... + void Reset() + { + // + CleanReport(XREPORT_MAIN); + CleanReport(XREPORT_MONTHLY); + CleanReport(XREPORT_WEEKLY); + CleanReport(XREPORT_DAILY); + } + + // + // Update Volume Info ... + void UpdateReportVolumeInfo( + ENUM_XREPORT_TYPES type, // Specified Report Type + // + double staticVolume, // Current Available Static Volume + string staticVolumeCalculationMethod, // Static Volume Calculation Method + double maxAllowedVolume, // Current Maximum Appliable Volume + double volumeIncreaseMultiplier, // Static Volume Increase Multiplier + double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing + double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume + ) + { + // + // Filling Account Info ... + FillReportAccountInfo(type); + + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + // + FillingVolumeInfo( + mMainReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + // + FillingVolumeInfo( + mMonthlyReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + // + FillingVolumeInfo( + mWeeklyReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + + // + // Daily ... + case XREPORT_DAILY: + // + FillingVolumeInfo( + mDailyReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + } + } + + // + // Update Volume Info on All Reports ... + void UpdateReportsVolumeInfo( + double staticVolume, // Current Available Static Volume + string staticVolumeCalculationMethod, // Static Volume Calculation Method + double maxAllowedVolume, // Current Maximum Appliable Volume + double volumeIncreaseMultiplier, // Static Volume Increase Multiplier + double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing + double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume + ) + { + // + // Main ... + UpdateReportVolumeInfo( + XREPORT_MAIN, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Monthly ... + UpdateReportVolumeInfo( + XREPORT_MONTHLY, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Weekly ... + UpdateReportVolumeInfo( + XREPORT_WEEKLY, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Daily ... + UpdateReportVolumeInfo( + XREPORT_DAILY, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + } + + // + // Add Specific Signal to Report ... + void AddSignalToReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + const XSignal &signal, // Specified Signal + const string &providers[] // Specified Signal Providers + ) + { + // + // + // Filling Account Info ... + FillReportAccountInfo(type); + + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + AddSignalToReport( + mMainReport, + signal, + providers); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + AddSignalToReport( + mMonthlyReport, + signal, + providers); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + AddSignalToReport( + mWeeklyReport, + signal, + providers); + break; + + // + // Daily ... + case XREPORT_DAILY: + AddSignalToReport( + mDailyReport, + signal, + providers); + break; + } + } + + // + // Add Specific Signal to All Reports ... + void AddSignalToReports( + const XSignal &signal, // Specified Signal + const string &providers[] // Specified Signal Providers + ) + { + // + // Main ... + AddSignalToReport( + XREPORT_MAIN, + signal, + providers); + + // + // Monthly ... + AddSignalToReport( + XREPORT_MONTHLY, + signal, + providers); + + // + // Weekly ... + AddSignalToReport( + XREPORT_WEEKLY, + signal, + providers); + + // + // Daily ... + AddSignalToReport( + XREPORT_DAILY, + signal, + providers); + } + + // + // Report a TP for Specific Report ... + void AddTradeTPInReport( + ENUM_XREPORT_TYPES type // Specified Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + AddTradeTPInReport(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + AddTradeTPInReport(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + AddTradeTPInReport(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + AddTradeTPInReport(mDailyReport); + break; + } + } + + // + // Report a TP for All Reports ... + void AddTradeTPInReports() + { + // + // Main ... + AddTradeTPInReport(XREPORT_MAIN); + + // + // Monthly ... + AddTradeTPInReport(XREPORT_MONTHLY); + + // + // Weekly ... + AddTradeTPInReport(XREPORT_WEEKLY); + + // + // Daily ... + AddTradeTPInReport(XREPORT_DAILY); + } + + // + // Report a SL for Specific Report ... + void AddTradeSLInReport( + ENUM_XREPORT_TYPES type // Specified Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + AddTradeSLInReport(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + AddTradeSLInReport(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + AddTradeSLInReport(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + AddTradeSLInReport(mDailyReport); + break; + } + } + + // + // Report a SL for All Reports ... + void AddTradeSLInReports() + { + // + // Main ... + AddTradeSLInReport(XREPORT_MAIN); + + // + // Monthly ... + AddTradeSLInReport(XREPORT_MONTHLY); + + // + // Weekly ... + AddTradeSLInReport(XREPORT_WEEKLY); + + // + // Daily ... + AddTradeSLInReport(XREPORT_DAILY); + } + + // + // Update Number of Same Time Trades in Specific Report ... + void UpdateMaxSameTimeTradesInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + int value // number of same time trades + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMaxSameTimeTradesInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMaxSameTimeTradesInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMaxSameTimeTradesInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMaxSameTimeTradesInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Number of Same Time Trades in All Report ... + void UpdateMaxSameTimeTradesInReports( + int value // number of same time trades + ) + { + // + // Main ... + UpdateMaxSameTimeTradesInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMaxSameTimeTradesInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMaxSameTimeTradesInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMaxSameTimeTradesInReport( + XREPORT_DAILY, + value); + } + + // + // Update Max DrawDown in Specific Report ... + void UpdateMaxDrawDownInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + double value // draw down value + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMaxDrawDownInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMaxDrawDownInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMaxDrawDownInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMaxDrawDownInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Max DrawDown in All Report ... + void UpdateMaxDrawDownInReports( + double value // draw down value + ) + { + // + // Main ... + UpdateMaxDrawDownInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMaxDrawDownInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMaxDrawDownInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMaxDrawDownInReport( + XREPORT_DAILY, + value); + } + + // + // Update Max DrawUp in Specific Report ... + void UpdateMaxDrawUpInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + double value // draw up value + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMaxDrawUpInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMaxDrawUpInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMaxDrawUpInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMaxDrawUpInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Max DrawUp in All Report ... + void UpdateMaxDrawUpInReports( + double value // draw up value + ) + { + // + // Main ... + UpdateMaxDrawUpInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMaxDrawUpInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMaxDrawUpInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMaxDrawUpInReport( + XREPORT_DAILY, + value); + } + + // + // Update Min Balance for Open Trades in Specific Report ... + void UpdateMinBalanceForOpenTradesInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + double value // min balance for open trades + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMinBalanceForOpenTradesInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMinBalanceForOpenTradesInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMinBalanceForOpenTradesInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMinBalanceForOpenTradesInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Min Balance for Open Trades in All Report ... + void UpdateMinBalanceForOpenTradesInReports( + double value // min balance for open trades + ) + { + // + // Main ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_DAILY, + value); + } + + // + // Gnerate Specific Type Of Report String Representation ... + string GenerateReportString( + ENUM_XREPORT_TYPES type, // Specified Report Type + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + result = GenerateReportString( + mMainReport, + separator); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + result = GenerateReportString( + mMonthlyReport, + separator); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + result = GenerateReportString( + mWeeklyReport, + separator); + break; + + // + // Daily ... + case XREPORT_DAILY: + result = GenerateReportString( + mDailyReport, + separator); + break; + } + + // + return result; + } + + // + // Protected Provided ... +protected: + // + // Private Provided ... +private: + // + // Account Info Instance ... + XCAccountInfo mAccountInfo; + + // + // Main Report ... + XReport mMainReport; + + // + // Monthly Report ... + XReport mMonthlyReport; + + // + // Weekly Report ... + XReport mWeeklyReport; + + // + // Daily Report ... + XReport mDailyReport; + + // + // Clean Specific Report ... + void CleanReport( + XReport &report // Specified Report + ) + { + // + datetime time = TimeCurrent(); + + // + // Reset Times ... + report.start = time; + report.end = -1; + + // + // Reset Account Info ... + FillReportAccountInfo(report); + + // + // Reset Summary Info ... + report.summaryInfo.maxDrawUp = 0; + report.summaryInfo.maxDrawDown = 0; + report.summaryInfo.longSignals = 0; + report.summaryInfo.numberOfTPs = 0; + report.summaryInfo.numberOfSLs = 0; + report.summaryInfo.shortSignals = 0; + report.summaryInfo.maxSignalVolume = 0; + report.summaryInfo.maxSameTimeSignals = 0; + + // + // Reset Volume Info ... + report.volumeInfo.staticVolume = 0; + report.volumeInfo.maxAllowedVolume = 0; + report.volumeInfo.volumeIncreaseMultiplier = 0; + report.volumeInfo.balanceGowingToApplyMultiplier = 0; + report.volumeInfo.staticVolumeCalculationMethod = NULL; + report.volumeInfo.balanceGrowingToIncreaseMaxAllowedVolume = 0; + + // + // Reset Signallers Info ... + CleanBuffer(report.signallersInfo); + } + void CleanReport( + ENUM_XREPORT_TYPES type // Specify Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + CleanReport(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + CleanReport(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + CleanReport(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + CleanReport(mDailyReport); + break; + } + } + + // + // Update Specific Reports End Time ... + void FillReportEndTime( + XReport &report // Specified Report + ) + { + // + datetime time = TimeCurrent(); + report.end = time; + } + + // + // Filleing Report Account Info ... + void FillReportAccountInfo( + XReport &report // Specified Report + ) + { + // + FillReportEndTime(report); + + // + report.accountInfo.user = (string)mAccountInfo.GetUserAccount(); + report.accountInfo.name = mAccountInfo.GetName(); + report.accountInfo.server = mAccountInfo.GetServerName(); + report.accountInfo.broker = mAccountInfo.GetCompany(); + report.accountInfo.mode = mAccountInfo.GetTradeMode(); + report.accountInfo.leverage = mAccountInfo.GetLeverage(); + report.accountInfo.currency = mAccountInfo.GetCurrency(); + report.accountInfo.deposit = mAccountInfo.GetInitialBalance(); + report.accountInfo.balance = mAccountInfo.GetBalance(); + } + void FillReportAccountInfo( + ENUM_XREPORT_TYPES type // Specify Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + FillReportAccountInfo(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + FillReportAccountInfo(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + FillReportAccountInfo(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + FillReportAccountInfo(mDailyReport); + break; + } + } + + // + // Filling Volume Info ... + void FillingVolumeInfo( + XReport &report, // Specified Report + // + double staticVolume, // Current Available Static Volume + string staticVolumeCalculationMethod, // Static Volume Calculation Method + double maxAllowedVolume, // Current Maximum Appliable Volume + double volumeIncreaseMultiplier, // Static Volume Increase Multiplier + double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing + double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume + ) + { + // + FillReportEndTime(report); + + // + report.volumeInfo.staticVolume = staticVolume; + report.volumeInfo.maxAllowedVolume = maxAllowedVolume; + report.volumeInfo.volumeIncreaseMultiplier = volumeIncreaseMultiplier; + report.volumeInfo.staticVolumeCalculationMethod = staticVolumeCalculationMethod; + report.volumeInfo.balanceGowingToApplyMultiplier = balanceGowingToApplyMultiplier; + report.volumeInfo.balanceGrowingToIncreaseMaxAllowedVolume = balanceGrowingToIncreaseMaxAllowedVolume; + } + + // + // Add Signal to Report ... + void AddSignalToReport( + XReport &report, // Specified Report + const XSignal &signal, // Specified Signal + const string &providers[] // Specified Signal Providers + ) + { + // + FillReportEndTime(report); + + // + double volume = signal.volume; + bool isLong = signal.type == X_SIGNAL_LONG; + + // + // Update Longs and Shorts ... + if (isLong) + { + report.summaryInfo.longSignals++; + } + else + { + report.summaryInfo.shortSignals++; + } + + // + // Chack Max Volume ... + if (volume > report.summaryInfo.maxSignalVolume) + { + report.summaryInfo.maxSignalVolume = volume; + } + + // + // Update Signallers Info ... + for (int i = 0; i < ArraySize(providers); i++) + { + // + string iProvider = providers[i]; + + // + AddOrUpdateSignaller( + report, + iProvider, + signal); + } + } + + // + // Add or Update Signaller Info of Specific Report ... + void AddOrUpdateSignaller( + XReport &report, // Specified Report + const string provider, // Signal Provider name + const XSignal &signal // Specified Signal + ) + { + // + int providerIdx = -1; + int signallersInfoCount = 0; + bool isLong = signal.type == X_SIGNAL_LONG; + + // + // Prepare New One Provider ... + XSignallerInfo info = {}; + info.name = provider; + if (isLong) + { + info.longs = 1; + } + else + { + info.shorts = 1; + } + + // + // Find Provider idx if Exists ... + providerIdx = FindProviderInSignallersInfo( + provider, + report.signallersInfo); + + // + // Check IDX ... + if (providerIdx > -1) + { + // + // Update Exists ... + if (isLong) + { + report.signallersInfo[providerIdx].longs++; + } + else + { + report.signallersInfo[providerIdx].shorts++; + } + } + else + { + // + // Add New One ... + AddItemToBuffer( + info, + report.signallersInfo); + } + } + + // + // Add TP in Report ... + void AddTradeTPInReport( + XReport &report // Specified Report + ) + { + // + FillReportEndTime(report); + + // + report.summaryInfo.numberOfTPs++; + } + + // + // Add SL in Report ... + void AddTradeSLInReport( + XReport &report // Specified Report + ) + { + // + FillReportEndTime(report); + + // + report.summaryInfo.numberOfSLs++; + } + + // + // Update Number of Same Time Trades in Report ... + void UpdateMaxSameTimeTradesInReport( + XReport &report, // Specified Report + int value // number of same time trades + ) + { + // + // Validate Args ... + if (value <= report.summaryInfo.maxSameTimeSignals) + { + return; + } + + // + FillReportEndTime(report); + + // + report.summaryInfo.maxSameTimeSignals = value; + } + + // + // Update Number of Same Time Trades in Report ... + void UpdateMaxDrawUpInReport( + XReport &report, // Specified Report + double value // draw up value + ) + { + // + // Validate Args ... + if (value <= report.summaryInfo.maxDrawUp) + { + return; + } + + // + FillReportEndTime(report); + + // + report.summaryInfo.maxDrawUp = value; + } + + // + // Update Number of Same Time Trades in Report ... + void UpdateMaxDrawDownInReport( + XReport &report, // Specified Report + double value // draw down value + ) + { + // + // Validate Args ... + if (value <= report.summaryInfo.maxDrawDown) + { + return; + } + + // + FillReportEndTime(report); + + // + report.summaryInfo.maxDrawDown = value; + } + + // + // Update Min Balance for Open Trades Value in Report ... + void UpdateMinBalanceForOpenTradesInReport( + XReport &report, // Specified Report + double value // min balance for open trades + ) + { + // + // Validate Arg ... + if (value <= 0) + { + return; + } + + // + FillReportEndTime(report); + + // + report.accountInfo.minBalanceForOpenTrades = value; + } + + // + // Generate Specific Report String Representation ... + string GenerateReportString( + XReport &report, // Specified Report + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Start and End Date ... + result += "Start: " + (string)report.start + separator; + result += "End: " + (string)report.end + separator; + + // + // Account Info ... + string accountStr = GenerateAccountInfoReportString(report.accountInfo); + result += "Account: " + separator + accountStr + separator; + + // + // Summary Info ... + string summaryStr = GenerateSummaryInfoReportString(report.summaryInfo); + result += "Summary: " + separator + summaryStr + separator; + + // + // Volume Info ... + string volumeStr = GenerateVolumeInfoReportString(report.volumeInfo); + result += "Volume: " + separator + volumeStr + separator; + + // + // Signallers Info ... + string signallersStr = GenerateSignallersInfoReportString(report.signallersInfo); + result += "Signallers: " + separator + signallersStr + separator; + + // + return result; + } + + // + // Generate Account info String Representation ... + string GenerateAccountInfoReportString( + XAccountInfo &info, // Specified Account Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Generate Report ... + result += "user: " + info.user + separator; + result += "name: " + info.name + separator; + result += "server: " + info.server + separator; + result += "broker: " + info.broker + separator; + result += "mode: " + EnumToString(info.mode) + separator; + result += "leverage: " + (string)info.leverage + separator; + result += "currency: " + info.currency + separator; + result += "deposit: " + (string)info.deposit + separator; + result += "balance: " + (string)info.balance + separator; + result += "minBalanceForTrading: " + (string)info.minBalanceForOpenTrades + separator; + + // + return result; + } + + // + // Generate Summary info String Representation ... + string GenerateSummaryInfoReportString( + XSummaryInfo &info, // Specified Summary Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Generate Report ... + result += "longSignals: " + (string)info.longSignals + separator; + result += "shortSignals: " + (string)info.shortSignals + separator; + result += "numberOfTps: " + (string)info.numberOfTPs + separator; + result += "numberOfSLs: " + (string)info.numberOfSLs + separator; + result += "maxDrawUp: " + (string)info.maxDrawUp + separator; + result += "maxDrawDown: " + (string)info.maxDrawDown + separator; + result += "maxSignalVolume: " + (string)info.maxSignalVolume + separator; + result += "maxSameTimeSignals: " + (string)info.maxSameTimeSignals + separator; + + // + return result; + } + + // + // Generate Volume info String Representation ... + string GenerateVolumeInfoReportString( + XVolumeInfo &info, // Specified Volume Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Generate Report ... + result += "staticVolume: " + (string)info.staticVolume + separator; + result += "staticVolumeCalculationMethod: " + info.staticVolumeCalculationMethod + separator; + result += "maxAllowedVolume: " + (string)info.maxAllowedVolume + separator; + result += "volumeIncreaseMultiplier: " + (string)info.volumeIncreaseMultiplier + separator; + result += "balanceGowingToApplyMultiplier: " + (string)info.balanceGowingToApplyMultiplier + separator; + result += "balanceGrowingToIncreaseMaxAllowedVolume: " + (string)info.balanceGrowingToIncreaseMaxAllowedVolume + separator; + + // + return result; + } + + // + // Generate Signallers info String Representation ... + string GenerateSignallersInfoReportString( + XSignallerInfo &infos[], // Specified Signallers Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Validate Signallers Array Size ... + int signallersCount = ArraySize(infos); + if (signallersCount <= 0) + { + // + result += "EMPTY" + separator; + return result; + } + + // + // Generate Report ... + for (int i = 0; i < signallersCount; i++) + { + // + XSignallerInfo iSignaller = infos[i]; + + // + result += "name: " + iSignaller.name + separator; + result += "longs: " + (string)iSignaller.longs + separator; + result += "shorts: " + (string)iSignaller.shorts + separator; + + // + if (i < signallersCount - 1) + { + result += separator; + } + } + // + return result; + } + + // + // Find a Provider Index in SignallersInfo ... + int FindProviderInSignallersInfo( + string provider, // Specified Provider Name ... + XSignallerInfo &infoBuffer[] // Specified XSignallerInfo Buffer ... + ) + { + // + int result = -1; + + // + int bufferSize = ArraySize(infoBuffer); + if (bufferSize <= 0) + { + return result; + } + + // + // Loop through buffer to find provider index ... + for (int i = 0; i < bufferSize; i++) + { + // + XSignallerInfo iInfo = infoBuffer[i]; + + // + if (iInfo.name != provider) + { + continue; + } + + // + result = i; + } + + // + return result; + } +}; + +// +// a Class For Collectiong Info ... +class XCCollector : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCCollector() + { + Reset(); + } + + // + // Deconstructor ... + ~XCCollector() {} + + // + // Reset All Collectors ... + void Reset() + { + Clean(); + } + + // + // Count Data ... + int Count() + { + // + int result = 0; + + // + result = ArraySize(mTimes); + + // + return result; + } + + // + // TODO: Implement Business Logic here ... + + // + // Add Specific item to Collection ... + bool Add( + XCollector &item // Specified Info + ) + { + // + bool result = false; + + // + // Validate Args ... + result = IsValid( + item, + false); + if (!result) + { + return result; + } + + // + // Add Items Values to Buffers ... + // + AddItemToBuffer( + item.time, + mTimes); + + // + AddItemToBuffer( + item.volume, + mVolumes); + + // + AddItemToBuffer( + item.maxDrawDown, + mMaxDrawDowns); + + // + AddItemToBuffer( + item.maxAllowedVolume, + mMaxAllowedVolumes); + + // + AddItemToBuffer( + item.minBalanceForOpenTrade, + mMinBalanceForTradePrices); + + // + return result; + } + + // + // Retrieve Specific Item ... + bool Get( + XCollector &item, // Hold's Result + int index = 0 // Specified Index to Retrieve + ) + { + // + bool result = false; + + // + result = IsValidIndex(index); + if (!result) + { + return result; + } + + // + // Filling Item ... + item.time = mTimes[index]; + item.volume = mVolumes[index]; + item.maxDrawDown = mMaxDrawDowns[index]; + item.maxAllowedVolume = mMaxAllowedVolumes[index]; + item.minBalanceForOpenTrade = mMinBalanceForTradePrices[index]; + + // + return result; + } + XCollector Get( + int index = 0 // Specified Index to Retrieve + ) + { + // + XCollector result = {}; + + // + bool isValidIndex = IsValidIndex(index); + if (!isValidIndex) + { + return result; + } + + // + // Filling Item ... + result.time = mTimes[index]; + result.volume = mVolumes[index]; + result.maxDrawDown = mMaxDrawDowns[index]; + result.maxAllowedVolume = mMaxAllowedVolumes[index]; + result.minBalanceForOpenTrade = mMinBalanceForTradePrices[index]; + + // + return result; + } + bool Get( + XCollector &item, // Hold's Result + datetime time // Specified Index to Retrieve + ) + { + // + bool result = false; + + // + if (time <= 0) + { + return result; + } + + // + int timesCount = ArraySize(mTimes); + result = timesCount > 0; + if (!result) + { + return result; + } + + // + int index = -1; + for (int i = 0; i < timesCount; i++) + { + // + datetime iTime = mTimes[i]; + + // + if (iTime == time) + { + // + index = i; + break; + } + } + + // + result = index >= 0; + if (!result) + { + return result; + } + + // + result = Get( + item, + index); + + // + return result; + } + XCollector Get( + datetime time // Specified Index to Retrieve + ) + { + // + XCollector result = {}; + + // + if (time <= 0) + { + return result; + } + + // + int timesCount = ArraySize(mTimes); + if (timesCount <= 0) + { + return result; + } + + // + int index = -1; + for (int i = 0; i < timesCount; i++) + { + // + datetime iTime = mTimes[i]; + + // + if (iTime == time) + { + // + index = i; + break; + } + } + + // + if (index <= -1) + { + return result; + } + + // + result = Get( + index); + + // + return result; + } + + // + // Retrieve All ... + void GetAll( + XCollector &result[], // Hold's Result + bool reversal = false // Extract Direction + ) + { + // + CleanBuffer(result); + + // + int timesCount = ArraySize(mTimes); + if (timesCount <= 0) + { + return; + } + + // + if (!reversal) + { + // + for (int i = 0; i < timesCount; i++) + { + // + XCollector iCollector = Get(i); + + // + AddItemToBuffer( + iCollector, + result); + } + } + else + { + // + for (int i = timesCount - 1; i >= 0; i--) + { + // + XCollector iCollector = Get(i); + + // + AddItemToBuffer( + iCollector, + result); + } + } + } + + // + // Extract History ... + void Extract( + XCollector &result[], // Hold's Result + int start, // Start Index + int end // End Index + ) + { + // + CleanBuffer(result); + + // + // Validate Args ... + if ( + end < 0 || + start < 0 || + (start == 0 && end == 0) || + MathAbs(start - end == 0)) + { + return; + } + + // + // Validate Start and End Index ... + bool isValidEnd = IsValidIndex(end); + bool isValidStart = IsValidIndex(start); + if (!isValidEnd || !isValidStart) + { + return; + } + + // + bool direction = end > start; + if (direction) + { + // + for (int i = start; i < end - 1; i++) + { + // + XCollector iCollect = Get(i); + + // + AddItemToBuffer( + iCollect, + result); + } + } + else + { + // + for (int i = end - 1; i >= start; i--) + { + // + XCollector iCollect = Get(i); + + // + AddItemToBuffer( + iCollect, + result); + } + } + } + + // + // Validate an Item ... + bool IsValid( + XCollector &item, // Specified Info + bool ignoreTime = true // Ignore Times Checking ... + ) + { + // + bool result = false; + + // + // Check Each Items contains Correct Value ... + // + result = item.volume >= 0; + if (!result) + { + return result; + } + + // + result = item.maxDrawDown >= 0; + if (!result) + { + return result; + } + + // + result = item.maxAllowedVolume >= 0; + if (!result) + { + return result; + } + + // + result = item.minBalanceForOpenTrade >= 0; + if (!result) + { + return result; + } + + // + // Check Time has Proper Value ... + result = item.time > 0; + if (!result) + { + return result; + } + + // + // Check time bigger than last Time ... + int timesCount = ArraySize(mTimes); + if ( + !ignoreTime && + timesCount >= 0) + { + // + // Retrieve Last Added Times ... + datetime lastTime; + result = GetLastItem(lastTime, mTimes); + if (!result) + { + return result; + } + + // + // Compare Last Time by current Time ... + result = item.time > lastTime; + if (!result) + { + return result; + } + } + + // + return result; + } + + // + // Generate Logging String Representation ... + string GenerateString( + XCollector &item, // Specified Info + string separator = "\n" // Separator Character + ) + { + // + string result = ""; + + // + result += "time: " + (string)item.time + separator; + result += "volume: " + (string)item.volume + separator; + result += "maxDrawDown: " + (string)item.maxDrawDown + separator; + result += "maxAllowedVolume: " + (string)item.maxAllowedVolume + separator; + result += "minBalanceForOpenTrade: " + (string)item.minBalanceForOpenTrade + separator; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Max Draw Up touched till now ... + double mMaxDrawUp; + + // + // Max Draw Down touched till now ... + double mMaxDrawDown; + + // + // Last Time for Checks ... + datetime mTimes[]; + + // + // Volume at the Check Time ... + double mVolumes[]; + + // + // DrawDown for each Check ... + double mMaxDrawDowns[]; + + // + // Max Allowed Volume for each check ... + double mMaxAllowedVolumes[]; + + // + // Min Balance for Open Trades for Each Check ... + double mMinBalanceForTradePrices[]; + + // + // Reset ... + void Clean() + { + // + mMaxDrawUp = 0; + mMaxDrawDown = 0; + + // + CleanBuffer(mTimes); + CleanBuffer(mVolumes); + CleanBuffer(mMaxDrawDowns); + CleanBuffer(mMaxAllowedVolumes); + CleanBuffer(mMinBalanceForTradePrices); + } + + // + // Validate Index ... + bool IsValidIndex( + int index // Specified Index + ) + { + // + bool result = false; + + // + int bufferSize = ArraySize(mTimes); + if (bufferSize <= 0) + { + return result; + } + + // + result = index <= bufferSize - 1; + + // + return result; + } +}; + +// +// a Class for Managing Volumes ... +class XCVolumeManager : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCVolumeManager( + double staticVolumeRate, // Static Volume Calculation Mutiplier + ENUM_STATIC_VOLUME_METHODS volumeMethod = X_STATIC_VOLUME_BASED_ON_DEPOSIT, // How to Calculate Static Volume + double volumeMultiplier = 0, // Volume Multiplier + double volumeMultiplierAppliedRate = 0, // Apply Volume Multiplier when Balance Increased by this rate + double maxAllowedVolume = 0, // Max Allowed Volume + double increaseMaxAllowedVolumeRate = 0 // Increase Max Allowed Volumes when Balance Increased by this rate + ) + { + // + mAccountInfo = new XCAccountInfo(); + + // + ResetForceVolumeMultiplier(); + + // + mVolumeMethod = volumeMethod; + mStaticVoluemRate = staticVolumeRate; + mVolumeMultiplier = volumeMultiplier; + mMaxAllowedVolume = maxAllowedVolume; + mVolumeMultiplierAppliedRate = volumeMultiplierAppliedRate; + mIncreaseMaxAllowedVolumeRate = increaseMaxAllowedVolumeRate; + } + + // + // Deconstructor ... + ~XCVolumeManager(void) {} + + // + // Check Volume Multiplier ... + bool CanUseVolumeMultiplier() + { + // + bool result = false; + + // + result = + mVolumeMultiplier > 0 && + mVolumeMultiplierAppliedRate > 0; + + // + return result; + } + + // + // Check Max Volume ... + bool CanUseMaxVolume() + { + // + bool result = false; + + // + result = + mMaxAllowedVolume > 0; + + // + return result; + } + + // + // Calculate Volume for Position ... + double CalculateVolume( + int numberOfOpenPositions = 0, // Number Of Open Signals + string symbol = NULL // Specify Symbol + ) + { + // + double result = 0; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Static Volume ... + result = GetStaticVolume(); + + // + double multiplier = GetVolumeMultiplier(); + result *= multiplier; + + // + // Check Max Allowed Volume Exists ... + double maxAllowedVolume = GetMaxAllowedVolume(); + if (maxAllowedVolume > 0) + { + // + result = + result > maxAllowedVolume + ? maxAllowedVolume + : result; + } + + // + // Check Number of Open Positions ... + if (numberOfOpenPositions >= 0) + { + // + // Decrease Volume ... + result /= (1 + numberOfOpenPositions); + } + + // + // Apply Force Volume Multiplier ... + result *= mForceVolumeMultiplier; + + // + // Retrieve Symbol Volume Info ... + result = NormalizeVolume(result, symbol, 2); + + // + return result; + } + + // + // Calculate Volume Multiplier ... + double GetVolumeMultiplier() + { + // + double result = 1; + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + bool canUseVolumeMultiplier = CanUseVolumeMultiplier(); + if ( + balance < deposit || + !canUseVolumeMultiplier) + { + return result; + } + + // + // Apply Multiplier to Volume ... + double baseGrowBalance = deposit * mVolumeMultiplierAppliedRate; + double balanceGrows = balance - deposit; + if (balanceGrows < baseGrowBalance) + { + return result; + } + + // + double applyMultiplierTimes = balanceGrows / baseGrowBalance; + double roundedApplyMultiplierTimes = MathRound(applyMultiplierTimes); + + // + if (applyMultiplierTimes < roundedApplyMultiplierTimes) + { + applyMultiplierTimes -= (1 - (roundedApplyMultiplierTimes - applyMultiplierTimes)); + } + + // + // Calculate result ... + result = applyMultiplierTimes * mVolumeMultiplier; + + // + return result; + } + + // + // Retrieve Required Balance Grows for Increase Max Allowed Volume ... + double GetIncreaseMaxAllowedVolumeBalance() + { + // + double result = 0; + + // + if ( + mMaxAllowedVolume <= 0 || + mIncreaseMaxAllowedVolumeRate <= 0) + { + return result; + } + + // + result = mAccountInfo.GetInitialBalance() * mIncreaseMaxAllowedVolumeRate; + + // + return result; + } + + // + // Calculate Max Allowed Volume ... + double GetMaxAllowedVolume() + { + // + double result = 0; + + // + // Validate Args ... + result = + mMaxAllowedVolume <= 0 + ? 0 + : mMaxAllowedVolume; + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + bool canUseMaxAllowedVolume = CanUseMaxVolume(); + if ( + balance <= deposit || + !canUseMaxAllowedVolume || + mIncreaseMaxAllowedVolumeRate <= 0) + { + // + return result; + } + + // + // Apply Multiplier to Volume ... + double baseGrowBalance = GetIncreaseMaxAllowedVolumeBalance(); + double balanceGrows = balance - deposit; + if (balanceGrows < baseGrowBalance) + { + return result; + } + + // + double applyMultiplierTimes = balanceGrows / baseGrowBalance; + double roundedApplyMultiplierTimes = MathRound(applyMultiplierTimes); + + // + if (applyMultiplierTimes < roundedApplyMultiplierTimes) + { + applyMultiplierTimes -= (1 - (roundedApplyMultiplierTimes - applyMultiplierTimes)); + } + + // + result *= applyMultiplierTimes; + + // + return result; + } + + // + // Get Static Volume ... + double GetStaticVolume() + { + // + double result = 0; + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + + // + switch (mVolumeMethod) + { + // + case X_STATIC_VOLUME_BASED_ON_DEPOSIT: + result = mStaticVoluemRate * deposit; + break; + + // + case X_STATIC_VOLUME_BASED_ON_BALANCE: + result = mStaticVoluemRate * balance; + break; + } + + // + return result; + } + + // + // Reset Froce Volume Multiplier ... + void ResetForceVolumeMultiplier() + { + mForceVolumeMultiplier = 1; + } + + // + // Retrieve Current Force Volume Multiplier ... + double GetCurrentForceVolumeMultiplier() + { + return mForceVolumeMultiplier; + } + + // + // Retrieve Next Increase Multiplier Price ... + double GetIncreaseMultiplierBalance() + { + return mAccountInfo.GetInitialBalance() * mVolumeMultiplierAppliedRate; + } + + // + // Change Force Volume Multiplier ... + void ChangeForceVolumeMultiplier( + double rate // Change rate + ) + { + // + // Normalize rate ... + if (rate <= 1) + { + rate = 1; + } + + // + mForceVolumeMultiplier = rate; + } + + // + // Increase Force Volume Multiplier ... + void IncreaseForceVolumeMultiplier() + { + mForceVolumeMultiplier += 0.5; + } + + // + // Decrease Force Volume Multiplier ... + void DecreaseForceVolumeMultiplier() + { + // + if (mForceVolumeMultiplier <= 1) + { + return; + } + + // + mForceVolumeMultiplier -= 0.5; + } + + // + // Generate Current State Log String ... + string GenerateStateString( + string separator = "\n" // Log Separator ... + ) + { + // + string result = ""; + + // + // Normallize Separator ... + if (StringLen(separator) == 0) + { + separator = "\n"; + } + + // + result += "ForceVolumeMultiplier: " + (string)mForceVolumeMultiplier + separator; + // + result += "StaticVoluemRate: " + (string)mStaticVoluemRate + separator; + result += "StaticVoluem: " + (string)GetStaticVolume() + separator; + result += "VolumeMethod: " + EnumToString(mVolumeMethod) + separator; + // + result += "VolumeMultiplier: " + (string)mVolumeMultiplier + separator; + result += "VolumeMultiplierAppliedRate: " + (string)mVolumeMultiplierAppliedRate + separator; + // + result += "MaxAllowedVolume: " + (string)mMaxAllowedVolume + separator; + result += "IncreaseMaxAllowedVolumeRate: " + (string)mIncreaseMaxAllowedVolumeRate + separator; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // an Instance of Account Info for reading Balance and Deposit and etc ... + XCAccountInfo mAccountInfo; + + // + // Force Volume Rate Multiplier ... + double mForceVolumeMultiplier; + + // + // Static Volume Calculation Mutiplier ... + double mStaticVoluemRate; + + // + // How to Calculate Static Volume ... + ENUM_STATIC_VOLUME_METHODS mVolumeMethod; + + // + // Volume Multiplier ... + double mVolumeMultiplier; + + // + // Apply Volume Multiplier when Balance Increased by this rate ... + double mVolumeMultiplierAppliedRate; + + // + // Max Allowed Volume + double mMaxAllowedVolume; + + // + // Increase Max Allowed Volumes when Balance Increased by this rate + double mIncreaseMaxAllowedVolumeRate; +}; + +// +// a Class For Managing Signals Additional Data ... +class XCSignalManager : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCSignalManager(void) + { + CleanData(); + } + + // + // Deconstructor ... + ~XCSignalManager(void) {} + + // + void Reset() + { + CleanData(); + } + + // + // Retrieve All Signals ... + void GetAll( + XSignal &result[] // Hold's Result + ) + { + // + CleanBuffer(result); + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + AddItemToBuffer( + iSignal, + result); + } + } + + // + // Count Items ... + int Count() + { + return ArraySize(mSignals); + } + + // + // Retrieve Specific Signal by Ticket ... + XSignal Get( + ulong ticket // Signals Ticket ... + ) + { + // + XSignal result = {}; + + // + // Check Exists ... + bool isExists = IsExists(ticket); + if (!isExists) + { + return result; + } + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket == ticket) + { + // + result = iSignal; + break; + } + } + + // + return result; + } + + // + // Check Signal Exists or not ... + bool IsExists( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket == ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + bool IsExists( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket == signal.ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + + // + // Add Signal ... + bool Add( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Validate Args ... + if (signal.ticket <= 0) + { + return result; + } + + // + // Chekc Signal Exists ... + bool isExists = IsExists(signal); + if (isExists) + { + return result; + } + + // + AddItemToBuffer( + signal, + mSignals); + result = true; + + // + return result; + } + + // + // Update Specific Buffer ... + bool Update( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Validate Args ... + if (signal.ticket <= 0) + { + return result; + } + + // + // Chekc Signal Exists ... + bool isExists = IsExists(signal); + if (!isExists) + { + return result; + } + + // + // Remove Signal ... + Remove(signal); + + // + // Add new One ... + AddItemToBuffer( + signal, + mSignals); + + // + result = true; + + // + return result; + } + + // + // Remove Signal ... + bool Remove( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + // Check Signal Exists ... + bool isExists = IsExists(ticket); + if (!isExists) + { + return result; + } + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + XSignal signals[]; + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket != ticket) + { + AddItemToBuffer( + iSignal, + signals); + } + } + + // + // Now we have to Clean All Signals and Replace them by signals[] buffer ... + UpdateData(signals); + + // + result = true; + return result; + } + bool Remove( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Check Signal Exists ... + bool isExists = IsExists(signal); + if (!isExists) + { + return result; + } + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + XSignal signals[]; + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket != signal.ticket) + { + AddItemToBuffer( + iSignal, + signals); + } + } + + // + // Now we have to Clean All Signals and Replace them by signals[] buffer ... + UpdateData(signals); + + // + result = true; + return result; + } + + // + // Add Or Update ... + bool AddOrUpdate( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Validate Args ... + if (signal.ticket <= 0) + { + return result; + } + + // + // Chekc Signal Exists ... + bool isExists = IsExists(signal); + if (!isExists) + { + result = Add(signal); + } + else + { + result = Update(signal); + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Holds Signals ... + XSignal mSignals[]; + + // + // Clean All Exists Data ... + void CleanData() + { + CleanBuffer(mSignals); + } + + // + // Update Data ... + void UpdateData( + XSignal &source[] // a Buffer which needs to Replace ... + ) + { + // + CleanData(); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + XSignal iSignal = source[i]; + + // + AddItemToBuffer( + iSignal, + mSignals); + } + } +}; + +// +// XSaherElm Trade Class ... +class XCTrade : public XCBase +{ + // + // all public features ... +public: + // + // Constructor ... + void XCTrade( + string tag, // Specify a Tag for Trader instance + string symbol, // Specify Trader Symbol + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + bool useVirtualTPSL, // Use Virtual TP SL + int maxAllowedTrades, // Specify Max Allowed Trades + double minBallanceForOpenTrades, // Specify Minimum Balance for Open Trades + double minAllowedFreeMarginForOpenTrades, // Specify Minimum Free Marging for Open Trades + bool useSignalProtector = true // Specify Use Signal Protector or not + ) + { + // + mTag = tag; + mSymbol = symbol; + mSlippage = slippage; + mMagicNumber = magicNumber; + mUseVirtualTPSL = useVirtualTPSL; + mMaxAllowedTrades = maxAllowedTrades; + mMinBallanceForOpenTrades = minBallanceForOpenTrades; + mMinAllowedFreeMarginForOpenTrades = minAllowedFreeMarginForOpenTrades; + + // + mTrader = new XSCTrade(); + + // + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + mSignalManager = new XCSignalManager(); + + // + Reset(); + } + + // + // Deconstructor ... + void ~XCTrade() + { + } + + // + // START Configuring Class Functions ... + // + + // + // Reset all Variables ... + void Reset() + { + // + mSignalManager.Reset(); + + // + mDaysForRead = 1; + mScanStarted = false; + + // + // Reset On Trade Counter ... + ResetOnTradeContext(); + + // + // Init On Trade Context ... + InitOnTradeContext(); + } + + // + // END Configuring Class Functions ... + // + + // + // START Count ... + // + + // + // Count Open Positions ... + int Count() + { + // + int result = 0; + + // + int total = PositionsTotal(); + for (int i = 0; i < total; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + result++; + } + + // + return result; + } + + // + // Count Longs ... + int CountLongs() + { + int result = CountByType(X_SIGNAL_LONG); + return result; + } + + // + // Count Shorts ... + int CountShorts() + { + int result = CountByType(X_SIGNAL_SHORT); + return result; + } + + // + // Count Specific Type Of Positions ... + int CountByType(ENUM_POSITION_TYPE type) + { + // + int result = 0; + + // + int total = PositionsTotal(); + for (int i = 0; i < total; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + if (mPositionInfo.PositionType() != type) + { + continue; + } + + // + result++; + } + + // + return result; + } + + // + // Count By Type ... + int CountByType(ENUM_X_SIGNAL_TYPE type) + { + // + // Validate Args ... + ENUM_POSITION_TYPE mType = POSITION_TYPE_BUY; + if (type == X_SIGNAL_LONG) + { + mType = POSITION_TYPE_BUY; + } + else if (type == X_SIGNAL_SHORT) + { + mType = POSITION_TYPE_SELL; + } + + // + int result = CountByType(mType); + return result; + } + + // + // END Count ... + // + + // + // START Retrieve ... + // + + // + // Retrieve Specified Position by it's Ticket ... + XSignal GetSignal( + ulong ticket // Specified Ticket + ) + { + // + XSignal result = {}; + + // + result = PositionToSignal(ticket); + + // + return result; + } + + // + // Get Last Signal ... + XSignal GetLastSignal() + { + // + XSignal result = {}; + + // + XSignal signals[]; + GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + result = signals[0]; + + // + return result; + } + + // + // Retrieve Last Executed Signal ... + bool GetLastSignal(XSignal &signal) + { + // + bool result = false; + + // + XSignal signals[]; + GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + signal = signals[0]; + result = true; + + // + return result; + } + + // + // Retrieve All Positions ... + void GetSignals( + XSignal &result[] // Holds Result ... + ) + { + // + CleanBuffer(result); + + // + int totalPositions = PositionsTotal(); + for (int i = 0; i < totalPositions; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + // Position to Signal ... + XSignal signal = PositionToSignal(i); + Add( + signal, + result); + } + } + + // + // Retrieve Type Specific Signals ... + void GetSignals( + XSignal &result[], // Holds Result ... + ENUM_X_SIGNAL_TYPE type // Specified Sginal Type ... + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals(signals); + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = signalsCount - 1; i >= 0; i--) + { + // + XSignal iSignal = signals[i]; + + // + if (type == X_SIGNAL_UNKNOWN) + { + Add( + iSignal, + result); + } + else if (iSignal.type == type) + { + Add( + iSignal, + result); + } + } + } + + // + // Filter Signals By Searching Comments ... + void FilterSignals( + XSignal &result[], // Holds Result ... + const string query, // Search in Comment Qeury ... + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specified Sginal Type ... + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + + // + // Validate Args ... + if ( + StringLen(query) <= 0 || + signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + int queryPos = StringFind( + iSignal.comment, + query); + bool isContains = queryPos > -1; + if (!isContains) + { + continue; + } + + // + Add( + iSignal, + result); + } + } + + // + // Get All Trades Which Candle Passed after Open ... + void GetOldSignals( + XSignal &result[], // Holds Result + int life, // Max Candle Passed after Trades Open + ENUM_TIMEFRAMES period = NULL, // Calculate Candles based on time frame + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + // Normalize Period ... + if (period == NULL) + { + period = _Period; + } + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Current Time Frame Candle Index ... + int currentBarIndex = 0; + + // + // Loop through Positions ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + // Retrieve Trade Open Bar Index based on Current Period ... + int tradeOpenBarIndex = iBarShift( + mSymbol, + period, + iSignal.time); + + // + // Calculate Trade Life ... + int diff = MathAbs(currentBarIndex - tradeOpenBarIndex); + + // + bool isPassed = diff >= life; + if (isPassed) + { + // + Add( + iSignal, + result); + } + } + } + + // + // Get In Profit Signals ... + void GetInProfitSignals( + XSignal &result[], // Holds Result + double minProfit = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isPassed = minProfit <= 0 && iSignal.profit > 0 + ? true + : iSignal.profit >= minProfit; + if (isPassed) + { + Add( + iSignal, + result); + } + } + } + + // + // Get In Drawdown Signals ... + void GetInDrawdownSignals( + XSignal &result[], // Holds Result + double maxDrawDown = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isPassed = maxDrawDown <= 0 && iSignal.profit < 0 + ? true + : iSignal.profit >= (-1 * maxDrawDown); + if (isPassed) + { + Add( + iSignal, + result); + } + } + } + + // + // Retrieve Max In Draw Down Trade ... + XSignal GetMaxInDrawdownSignal( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + XSignal result = {}; + + // + XSignal signals[]; + GetInDrawdownSignals( + signals, + 0, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + result = + (result.ticket <= 0 && + result.profit == 0) || + result.profit > iSignal.profit + ? iSignal + : result; + } + + // + return result; + } + + // + // Calculate Profits Of all Open Signals ... + double GetSignalsProfit( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + double result = 0; + + // + XSignal signals[]; + GetSignals(signals, type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + result += iSignal.profit; + } + + // + return result; + } + + // + // END Retrieve ... + // + + // + // START Signal Execution Actions ... + // + + // + // Execute a Signal in Market ... + ENUM_EXECUTION_SIGNAL_RESULT ExecuteSignal( + XSignal &signal, // Specified Signal + bool ignoreNumberOfTraes = false, // Ignore Number of Trades + bool checkAccountConditions = true // Check Account Balance, Equity and Free Margin for Signal Execution + ) + { + // + ENUM_EXECUTION_SIGNAL_RESULT result = X_TRADER_UNKNOWN_ERROR; + + // + // Validate Signal ... + bool isValid = IsValidSignal(signal); + if (!isValid) + { + // + result = X_TRADER_INVALID_SIGNAL_ERROR; + return result; + } + + // + // Check Account Equity ... + bool isEquityPassed = !checkAccountConditions + ? true + : IsEquityReadyForTrade(); + if (!isEquityPassed) + { + // + result = X_TRADER_NOT_ENOUGH_EQUITY_ERROR; + return result; + } + + // + // Check Account Balance ... + bool isBalancePassed = !checkAccountConditions + ? true + : IsBalanceReadyForTrade(); + if (!isBalancePassed) + { + // + result = X_TRADER_NOT_ENOUGH_BALANCE_ERROR; + return result; + } + + // + // Check Account FreeMargin ... + bool isFreeMarginPassed = !checkAccountConditions + ? true + : IsFreeMarginReadyForTrade(); + if (!isFreeMarginPassed) + { + // + result = X_TRADER_NOT_ENOUGH_MARIGIN_ERROR; + return result; + } + + // + // Check Number of Open Trades ... + int openTradesCount = Count(); + bool isTradeCountPassed = ignoreNumberOfTraes + ? true + : openTradesCount < mMaxAllowedTrades; + if (!isTradeCountPassed) + { + // + result = X_TRADER_MAX_TRADES_REACHED_ERROR; + return result; + } + + // + bool isExecuted = + signal.type == X_SIGNAL_LONG + ? Buy( + signal.volume, + signal.entry, + mUseVirtualTPSL + ? 0 + : signal.sl, + mUseVirtualTPSL + ? 0 + : signal.tp, + signal.comment) + : signal.type == X_SIGNAL_SHORT + ? Sell( + signal.volume, + signal.entry, + mUseVirtualTPSL + ? 0 + : signal.sl, + mUseVirtualTPSL + ? 0 + : signal.tp, + signal.comment) + : false; + if (isExecuted) + { + // + ulong ticket = PositionGetTicket(PositionsTotal() - 1); + + // + signal.id = ticket; + signal.ticket = ticket; + + // + AddOrUpdateSignalInfo(signal); + + // + result = X_TRADER_SUCCEED_EXECUTION; + } + + // + return result; + } + + // + // This Function, Handling Following Works on Open Positions: + // - Close On SL if Reached ... + // - Close On TP if Reached ... + // - Make Risk Free Trades ... + bool HandleSignals( + XTraderHandlerResult &handlerResult, // Holds Result + bool ignoreRiskFree = false // Ignore Risk Free Trdaes + ) + { + // + bool result = false; + + // + // Cleanup Result ... + CleanBuffer(handlerResult.sl); + CleanBuffer(handlerResult.tp); + CleanBuffer(handlerResult.rf); + + // + // Reading Open Positions ... + XSignal signals[]; + GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + double deviation = mSlippage * GetPoints(mSymbol); + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isLong = iSignal.type == X_SIGNAL_LONG; + double entry = GetEntry(iSignal.symbol, iSignal.type); + double exit = GetExit(iSignal.symbol, iSignal.type); + double spread = GetSpread(iSignal.symbol); + double appliedTPPrice = + iSignal.tp > 0 + ? isLong + ? iSignal.tp - deviation + : iSignal.tp + deviation + : 0; + double appliedSLPrice = + iSignal.sl > 0 + ? isLong + ? iSignal.sl + deviation + : iSignal.sl - deviation + : 0; + + // + double usedPrice = exit; + + // + bool isSLTouched = + isLong + ? usedPrice <= appliedSLPrice + : usedPrice >= appliedSLPrice; + + // + bool isTPTouched = + isLong + ? usedPrice >= appliedTPPrice + : usedPrice <= appliedTPPrice; + + // + // Handle SL ... + if ( + // + iSignal.sl > 0 + // + && + // + isSLTouched + // + && + // + mUseVirtualTPSL) + { + // + string comment = GenerateSignalSLComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + AddItemToBuffer( + iSignal, + handlerResult.sl); + } + } + + // + // Handle TP ... + if ( + // + iSignal.tp > 0 + // + && + // + isTPTouched + // + && + // + mUseVirtualTPSL) + { + // + string comment = GenerateSignalTPComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + AddItemToBuffer( + iSignal, + handlerResult.tp); + } + } + + // + // Handle Risk Free ... + if ( + // + !ignoreRiskFree + // + && + // + iSignal.riskFreeStep > 0 + // + && + // + iSignal.riskFreeRate > 0 + // + ) + { + // + // Make Signals Risk Free Only if Signal In Profit ... + if (iSignal.profit <= 0) + { + continue; + } + + // + // Base Price is ENTRY, then Last Level, in each level SL is Last Level ... + // + // Calculate Risk Free Level/Multiplier ... + double level = 0; + double roundedLevel = 0; + double rStepPrice = PipsToPrice(iSignal.riskFreeStep); + double rBasePrice = + iSignal.sl > 0 && + iSignal.sl > iSignal.entry + ? iSignal.sl + : iSignal.entry; + + // + double exit = GetExit(iSignal.type); + + // + // Check Base Price for Signal reached with Exit Price ... + bool isExitPriceReachedBasePrice = + isLong + ? exit > rBasePrice + : exit < rBasePrice; + if (!isExitPriceReachedBasePrice) + { + continue; + } + + // + // Calculate Risk Free Step Multiplier ... + level = MathAbs(exit - rBasePrice) / rStepPrice; + + // + // Check Level Must Bigger than 1 ... + if (level < 1) + { + continue; + } + + // + // Normalize Level ... + roundedLevel = MathRound(level); + if (level < roundedLevel) + { + level -= (1 - (roundedLevel - level)); + } + else if (level > roundedLevel) + { + level -= (level - roundedLevel); + } + + // + // Generate Comment ... + string comment = GenerateSignalRFComment(iSignal, (int)level); + + // + // Calculate SL ... + double slDistance = spread; + double sl = + isLong + ? exit - slDistance + : exit + slDistance; + + // + // Increase TP One Level if Exists ... + double tp = iSignal.tp; + if (iSignal.tp > 0 && (isLong + ? iSignal.tp < rBasePrice + rStepPrice + : iSignal.tp > rBasePrice - rStepPrice)) + { + // + tp = + isLong + ? iSignal.tp + rStepPrice + : iSignal.tp - rStepPrice; + } + + // + double rVolume = NormalizeVolume((iSignal.volume * iSignal.riskFreeRate), iSignal.symbol); + + // + // Update Signal Volume ... + double volume = iSignal.volume - rVolume; + + // + bool isClosedPartial = + ClosePartial( + iSignal.ticket, + rVolume, + comment); + if (isClosedPartial) + { + // + bool isModified = true; + if (!mUseVirtualTPSL) + { + // + isModified = Modify( + iSignal.ticket, + sl, + tp, + comment); + } + + // + if (isModified) + { + // + // Try to Update Signal ... + XSignal s = mSignalManager.Get(iSignal.ticket); + + // + // Apply Changes on Signal ... + s.sl = sl; + s.tp = tp; + s.volume = volume; + + // + // Update Signal ... + bool isUpdated = false; + bool isRemoved = false; + if (volume == 0) + { + isRemoved = mSignalManager.Remove(s); + } + else if (volume > 0) + { + isUpdated = mSignalManager.AddOrUpdate(s); + } + if ( + isUpdated || + isRemoved) + { + // + AddItemToBuffer( + s, + handlerResult.rf); + } + } + } + else + { + mSignalManager.Remove(iSignal.ticket); + } + } + } + + // + result = + ArraySize(handlerResult.tp) > 0 || + ArraySize(handlerResult.sl) > 0 || + ArraySize(handlerResult.rf) > 0; + + // + return result; + } + + // + // Close All Trades ... + void CloseSignals( + XSignal &result[], // Holds Result + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalForceCloseComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // Close Pyramid Signals ... + void CloseInPyramidSignals( + XSignal &result[], // Holds Result + double pyramid = 0, // Close Pyramid Profit + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + double profit = 0; + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + profit += iSignal.profit; + } + + // + // Normalize Pyramid ... + if (pyramid < 0) + { + pyramid = 0; + } + + // + if (profit > pyramid) + { + CloseSignals(result); + } + } + + // + // Close All Trades Which Candle Passed after Open ... + void CloseOldSignals( + XSignal &result[], // Holds Result + int life, // Max Candle Passed after Trades Open + ENUM_TIMEFRAMES period = NULL, // Calculate Candles based on time frame + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetOldSignals( + signals, + life, + period, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalAgeComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // Close In Profit Signals ... + void CloseInProfitSignals( + XSignal &result[], // Holds Result + double minProfit = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetInProfitSignals( + signals, + minProfit, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalProfitComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // Close In Drawdown Signals ... + void CloseInDrawdownSignals( + XSignal &result[], // Holds Result + double maxDrawDown = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetInDrawdownSignals( + signals, + maxDrawDown, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalProfitComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // END Signal Execution Actions ... + // + + // + // START Actions ... + // + + // + // Force Open a Buy/Long Position ... + bool Buy( + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + const string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.Buy( + volume, + mSymbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.BuyLimit( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.BuyStop( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Force Open a Sell/Short Position ... + bool Sell( + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + const string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.Sell( + volume, + mSymbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.SellLimit( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.SellStop( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Modify Position ... + bool Modify( + const ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0, // take profit + const string comment = "" // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + if (tp <= 0 && sl <= 0) + { + result = false; + return result; + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment); + if (result) + { + // + if (mSignalManager.IsExists(ticket)) + { + // + XSignal signal = GetSignal(ticket); + + // + mSignalManager.Update(signal); + } + } + + // + return result; + } + + // + // Close Position By Ticket ... + bool Close( + ulong ticket, // Position Ticket + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + // Try to Select Position ... + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + // Close Position By Specific Comment ... + result = mTrader.PositionClose( + ticket, + mSlippage, + comment); + if (result) + { + // + if (mSignalManager.IsExists(ticket)) + { + mSignalManager.Remove(ticket); + } + } + + // + return result; + } + + // + // Close Partial By Ticket ... + bool ClosePartial( + ulong ticket, // Position Ticket + double volume, // Volume Size for Partial Closing + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + result = mTrader.PositionClosePartial( + ticket, + volume, + mSlippage, + comment); + if (result) + { + // + if (mSignalManager.IsExists(ticket)) + { + // + XSignal signal = GetSignal(ticket); + + // + mSignalManager.Update(signal); + } + } + + // + return result; + } + + // + // END Actions ... + // + + // + // START Account Related ... + // + + // + // Retrieve Minimum Balance For Open Trades ... + double GetMinBalanceForOpenTrades() + { + // + double result = mMinBallanceForOpenTrades; + + // + double balance = mAccountInfo.GetBalance(); + double deposit = mAccountInfo.GetInitialBalance(); + if (balance > deposit) + { + // + double rate = mMinBallanceForOpenTrades / deposit; + + // + double ratedBalance = balance * rate; + + // + result = MathMax(mMinBallanceForOpenTrades, ratedBalance); + } + + // + return result; + } + + // + // Check Account Has Minimum Balance For Trade ... + bool IsBalanceReadyForTrade() + { + // + bool result = false; + + // + double minBalance = GetMinBalanceForOpenTrades(); + result = mAccountInfo.GetBalance() >= minBalance; + + // + return result; + } + + // + // Check Free Margin Has Enough For Trade ... + bool IsFreeMarginReadyForTrade() + { + // + bool result = false; + + // + double freeMargin = mAccountInfo.GetFreeMargin(); + + // + result = freeMargin >= mMinAllowedFreeMarginForOpenTrades; + + // + return result; + } + + // + // Check Equity Has Enough For Trade ... + bool IsEquityReadyForTrade() + { + // + bool result = false; + + // + double equity = mAccountInfo.GetEquity(); + + // + result = equity >= mMinAllowedFreeMarginForOpenTrades; + + // + return result; + } + + // + // END Account Related ... + // + + // + // START Signal Related ... + // + + // + // Validate Signal ... + bool IsValidSignal( + XSignal &signal // Specified Signal for Execution + ) + { + // + bool result = false; + + // + // Validate Signal Type ... + result = signal.type != X_SIGNAL_UNKNOWN; + if (!result) + { + return result; + } + + // + // Check Symbol ... + result = StringLen(signal.symbol) == 0 ? true : signal.symbol == mSymbol; + if (!result) + { + return result; + } + + // + // Check magic number ... + result = signal.magicNumber <= 0 ? true : signal.magicNumber == mMagicNumber; + if (!result) + { + return result; + } + + // + // Check Entry ... + result = signal.entry > 0; + if (!result) + { + return result; + } + + // // + // // Check SL ... + // // For Fix RiskFree Issues Ignore this ... + // result = signal.sl == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.sl < signal.entry + // : signal.sl > signal.entry; + // if (!result) + // { + // return result; + // } + + // + // Check TP ... + result = signal.tp == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.tp > signal.entry + : signal.tp < signal.entry; + if (!result) + { + return result; + } + + // + // Check Volume ... + result = signal.volume > 0; + if (!result) + { + return result; + } + + // + // Check Time ... + result = signal.time > 0; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Get Signal InDirection (Reversal) Type ... + ENUM_X_SIGNAL_TYPE GetSignalIndirectionType( + XSignal &signal // Specified Signal + ) + { + // + ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; + + // + switch (signal.type) + { + // + case X_SIGNAL_LONG: + result = X_SIGNAL_SHORT; + break; + + // + case X_SIGNAL_SHORT: + result = X_SIGNAL_LONG; + break; + } + + // + return result; + } + + // + // Get Signal InDirection (Reversal) Type ... + ENUM_X_SIGNAL_TYPE GetIndirectionSignalType( + ENUM_X_SIGNAL_TYPE type // Specified Type + ) + { + // + ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; + + // + switch (type) + { + // + case X_SIGNAL_LONG: + result = X_SIGNAL_SHORT; + break; + + // + case X_SIGNAL_SHORT: + result = X_SIGNAL_LONG; + break; + } + + // + return result; + } + + // + // Calculate SignalAge ... + int GetSignalAge( + datetime time // Signal Execution Time + ) + { + // + int result = 0; + + // + // Validate Arg ... + if (time <= 0) + { + return result; + } + + // + int sIndex = iBarShift( + mSymbol, + _Period, + time); + + // + datetime cTime = iTime( + mSymbol, + _Period, + 0); + int cIndex = iBarShift( + mSymbol, + _Period, + cTime); + + // + result = MathAbs(cIndex - sIndex); + + // + return result; + } + int GetSignalAge( + datetime time, // Signal Execution Time + ENUM_TIMEFRAMES period // Specify Time Frame + ) + { + // + int result = 0; + + // + // Validate Arg ... + if (time <= 0) + { + return result; + } + + // + int sIndex = iBarShift( + mSymbol, + period, + time); + + // + datetime cTime = iTime( + mSymbol, + period, + 0); + int cIndex = iBarShift( + mSymbol, + _Period, + cTime); + + // + result = MathAbs(cIndex - sIndex); + + // + return result; + } + int GetSignalAge( + XSignal &signal // Specified Signal + ) + { + // + int result = 0; + + // + // Validate Arg ... + if ( + signal.time <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GetSignalAge(signal.time); + + // + return result; + } + int GetSignalAge( + XSignal &signal, // Specify Signal + ENUM_TIMEFRAMES period // Specify Time Frame + ) + { + // + int result = 0; + + // + // Validate Arg ... + if ( + signal.time <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GetSignalAge( + signal.time, + period); + + // + return result; + } + + // + // Prepare a Signall ... + XSignal GenerateSignal( + ENUM_X_SIGNAL_TYPE type, // Signal Type + double tp = 0, // Take Profit + double sl = 0, // Stop Loss + double volume = 0, // Volume + double riskFreeStep = 0, // Risk Free Step Price + double riskFreeRate = 0 // Risk Free Rate + ) + { + // + XSignal result = {}; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + // Check Signal Type ... + bool isLong = type == X_SIGNAL_LONG; + + // + // Retrieve entry Price ... + double entry = GetEntry(mSymbol, type); + double spread = GetSpread(mSymbol); + + // + result.tp = tp; + result.sl = sl; + result.type = type; + result.entry = entry; + result.symbol = mSymbol; + result.magicNumber = mMagicNumber; + result.riskFreeStep = riskFreeStep; + result.riskFreeRate = riskFreeRate; + result.time = iTime(mSymbol, _Period, 0); + result.volume = NormalizeVolume(volume, mSymbol); + + // + // Since we Use signal instance to Generate Comment, this must be at the end ... + result.comment = GenerateSignalComment(result); + + // + return result; + } + + // + // Convert a Signal to String Representation ... + string ToString( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + if (!IsValid(signal, mMagicNumber) || signal.ticket <= 0) + { + return result; + } + + // + // TICKET ... + // it is very importants since they hold position info ... + result += X_SIGNAL_TICKET + "(" + (string)signal.ticket + ")"; + + // + // TYPE ... + string typeStr = GetSignalType(signal.type); + result += "_" + X_SIGNAL_TYPE + "(" + typeStr + ")"; + + // + // TP ... + result += "_" + X_SIGNAL_TP + "(" + (string)signal.tp + ")"; + + // + // SL ... + result += "_" + X_SIGNAL_SL + "(" + (string)signal.sl + ")"; + + // + // RFS ... + result += "_" + X_SIGNAL_RISKFREE_STEP + "(" + (string)signal.riskFreeStep + ")"; + + // + // RFR ... + result += "_" + X_SIGNAL_RISKFREE_RATE + "(" + (string)signal.riskFreeRate + ")"; + + // + return result; + } + + // + // Generate Comments for Specific Signal ... + string GenerateSignalComment( + ENUM_X_SIGNAL_TYPE type, // Specify Kind Signal Type + double volume, // Signal Volume + bool isCrossSignal = false // Specify Signal Cross + ) + { + // + string result = ""; + + // + string typeStr = GetSignalType(type); + if ( + volume <= 0 || + StringLen(typeStr) == 0) + { + return result; + } + + // + volume = NormalizeVolume(volume, mSymbol); + + // + result = mTag + (!isCrossSignal ? "" : "_Cross_") + "_" + typeStr; + + // + return result; + } + string GenerateSignalComment( + XSignal &signal, // Specified Signal + bool isCrossSignal = false // Specify Signal Cross + ) + { + // + string result = GenerateSignalComment( + signal.type, + signal.volume, + isCrossSignal + // + ); + + // + return result; + } + + // + // Generate Signal RF TP Comment ... + string GenerateSignalRFComment( + XSignal &signal, // Specified Signal + int level // Which Step of RFS + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); + + // + string prefix = X_SIGNAL_RISKFREE_STEP + "(" + (string)signal.ticket + ")"; + // + result = + // + level > 0 + ? prefix + "_" + (string)level + ": " + (string)exit + : prefix + ": " + (string)exit; + // + ; + + // + return result; + } + + // + // Generate Signal TP Comment ... + string GenerateSignalTPComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); + + // + result = + // + X_SIGNAL_TP + "(" + (string)signal.ticket + "): " + (string)exit; + // + ; + + // + return result; + } + + // + // Generate Signal SL Comment ... + string GenerateSignalSLComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); + + // + result = + // + X_SIGNAL_SL + "(" + (string)signal.ticket + "): " + (string)exit; + // + ; + + // + return result; + } + + // + // Generate Signal Profit Comment ... + string GenerateSignalProfitComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + result = + // + "Profit(" + (string)signal.ticket + "): " + (string)signal.profit; + // + ; + + // + return result; + } + + // + // Generate Signal Force Close Comment ... + string GenerateSignalForceCloseComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + result = + // + "FC(" + (string)signal.ticket + "): " + (string)signal.profit; + // + ; + + // + return result; + } + + // + // Generate Signal Age Comment ... + string GenerateSignalAgeComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + int age = GetSignalAge(signal); + + // + result = + // + "(" + (string)signal.ticket + ") A: " + (string)age + ", P:" + (string)signal.profit; + // + ; + + // + return result; + } + + // + // Generate a Signal Object name for Draw Events On Chart ... + string GenerateSignalObjectName( + ulong ticket // Specify Ticket + ) + { + // + string result = ""; + + // + // Validate Arg ... + if (ticket <= 0) + { + return result; + } + + // + // TICKET ... + // it is very importants since they hold position info ... + result += "T(" + (string)ticket + ")"; + + // + return result; + } + string GenerateSignalObjectName( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Arg ... + if (!IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GenerateSignalObjectName(signal.ticket); + + // + return result; + } + + // + // Genrate a Signal Event Object Name ... + string GenerateSignalEventObjectName( + ulong ticket // Specify Ticket + ) + { + // + string result = ""; + + // + result = GenerateSignalObjectName(ticket) + "_Event"; + + // + return result; + } + string GenerateSignalEventObjectName( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + result = GenerateSignalEventObjectName(signal.ticket); + + // + return result; + } + + // + // END Signal Related ... + // + + // + // START Deals ... + // + + // + // Count Deals ... + int DealsCount( + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + int result = 0; + + // + XDeal deals[]; + GetDeals( + deals, + start, + end); + result = ArraySize(deals); + + // + return result; + } + + // + // Retrieve All Deals ... + void GetDeals( + XDeal &result[], // Hold's Result + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + CleanBuffer(result); + + // + // Select History if Start and End date provided ... + if (start > -1) + { + // + // Normalize End date ... + if (end == -1) + { + end = TimeCurrent(); + } + + // + bool isSelect = HistorySelect(start, end); + if (!isSelect) + { + return; + } + } + + // + int total = HistoryDealsTotal(); + if (total <= 0) + { + return; + } + + // + // Loop ... + for (int i = total - 1; i >= 0; i--) + { + // + // Select by Index ... + bool isSelect = mDealInfo.SelectByIndex(i); + if (!isSelect) + { + continue; + } + + // + // Check Magic ... + ulong magic = mDealInfo.Magic(); + bool isMagicSame = magic == mMagicNumber; + if (!isMagicSame) + { + continue; + } + + // + // Check Symbol ... + string symbol = mDealInfo.Symbol(); + bool isSymbolSame = symbol == mSymbol; + if (!isSymbolSame) + { + continue; + } + + // + XDeal deal = ToXDealByIndex(i); + + // + Add( + deal, + result); + } + } + + // + // Retrieve Last Deal ... + XDeal GetLastDeal() + { + // + XDeal result = {}; + + // + XDeal deals[]; + GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount <= 0) + { + return result; + } + + // + result = deals[0]; + + // + return result; + } + + // + // END Deals ... + // + + // + // START Orders ... + // + + // + // Count Orders ... + int OrdersCount( + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + int result = 0; + + // + XOrder orders[]; + GetOrders( + orders, + start, + end); + result = ArraySize(orders); + + // + return result; + } + + // + // Retrieve Orders ... + void GetOrders( + XOrder &result[], // Hold's Result + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + CleanBuffer(result); + + // + // Select History if Start and End date provided ... + if (start > -1) + { + // + // Normalize End date ... + if (end == -1) + { + end = TimeCurrent(); + } + + // + bool isSelect = HistorySelect(start, end); + if (!isSelect) + { + return; + } + } + + // + int total = HistoryOrdersTotal(); + if (total <= 0) + { + return; + } + + // + // Loop ... + for (int i = total - 1; i >= 0; i--) + { + // + // Select by Index ... + bool isSelect = mOrderInfo.SelectByIndex(i); + if (!isSelect) + { + continue; + } + + // + // Check Magic ... + ulong magic = mOrderInfo.Magic(); + bool isMagicSame = magic == mMagicNumber; + if (!isMagicSame) + { + continue; + } + + // + // Check Symbol ... + string symbol = mOrderInfo.Symbol(); + bool isSymbolSame = symbol == mSymbol; + if (!isSymbolSame) + { + continue; + } + + // + XOrder order = ToXOrderByIndex(i); + + // + Add( + order, + result); + } + } + + // + // Retrieve Last Order ... + XOrder GetLastOrder() + { + // + XOrder result = {}; + + // + XOrder orders[]; + GetOrders(orders); + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + result = orders[0]; + + // + return result; + } + + // + // END Orders ... + // + + // + // START OnTrade Handlers ... + // + + // + // Handle OnTrade Event ... + void HandleOnTradeEvent( + XOnTradeHandlerResult &result // Hold's Result + ) + { + // + if (mScanStarted) + { + ProcessOnTradeContext(result); + } + else + { + InitOnTradeContext(); + } + } + + // + // END OnTrade Handlers ... + // + + // + // Retrieve Magic Number ... + ulong GetMagicNumber() + { + return mMagicNumber; + } + + // + // all protected features ... +protected: + // + // all private features ... +private: + // + // Specified Unique Tag ... + string mTag; + + // + // which Symbol ... + string mSymbol; + + // + // using deviation, it must be in Point ... + int mSlippage; + + // + // using magic number ... + ulong mMagicNumber; + + // + // Detect Using Virtual TP or SL ... + bool mUseVirtualTPSL; + + // + // Specify Max Allowed Trades + int mMaxAllowedTrades; + + // + // Minimum Free Marging for Open Trades + double mMinAllowedFreeMarginForOpenTrades; + + // + // Minimum Balance for Open Trades + double mMinBallanceForOpenTrades; + + // + // using CTrade instance ... + XSCTrade mTrader; + + // + // Deals Info ... + CDealInfo mDealInfo; + + // + // Order Info ... + COrderInfo mOrderInfo; + + // + // An Instance Of XCAccount Info for Handling Account Related Actions ... + XCAccountInfo mAccountInfo; + + // + // using PositionInfo instance ... + CPositionInfo mPositionInfo; + + // + // Signal Manager ... + XCSignalManager mSignalManager; + + // + // START OnTrade Handlers ... + // + + // + int mDaysForRead; + + // + // set the limits of the trade history on the global scope ... + + // + // // start date for trade history in cache ... + datetime mStartDate; + + // + // end date for trade history in cache ... + datetime mEndDate; + + // + // global OnTrade counters ... + + // + // number of active orders ... + int mOrdersCount; + + // + // number of open positions ... + int mPositionsCount; + + // + // number of deals in the trade history cache ... + int mDealsCount; + + // + // number of orders in the trade history cache ... + int mHistoryOrdersCount; + + // + // flag of counter relevance ... + bool mScanStarted; + + // + // Check Statrt Date In Trade History ... + void CheckStartDateInTradeHistory() + { + // + // initial interval, if we were to start working right now .. + datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + + // + // make sure that the start limit of the trade history has not gone + // more than 1 day over the intended date ... + if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) + { + // + // correct the start date of history to be loaded in the cache ... + mStartDate = currStart; + + // + // now reload the trade history for the updated interval ... + HistorySelect(mStartDate, mEndDate); + + // + // correct the deal and order counters in history for further comparison + mHistoryOrdersCount = HistoryOrdersTotal(); + mDealsCount = HistoryDealsTotal(); + } + } + + // + // Process On Trade Context ... + void ProcessOnTradeContext( + XOnTradeHandlerResult &result // Hold's Result + ) + { + // + mEndDate = TimeCurrent(); + + // + ResetLastError(); + + // + // download trading history from the specified interval to the program cache ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + // + LogMessage("Failed to Load OnTrade Context History ..."); + + // + return; + } + + // + // get the current values ... + int currOrders = OrdersTotal(); + int currPositions = PositionsTotal(); + int currDeals = HistoryDealsTotal(); + int currHistoryOrders = HistoryOrdersTotal(); + + // + // Orders ... + // check if the number of active orders has been changed ... + if (currOrders != mOrdersCount) + { + // + // number of active orders has been changed ... + result.hasNewOrder = true; + result.newOrders = currOrders - mOrdersCount; + + // + // update the value ... + mOrdersCount = currOrders; + } + + // + // Positions ... + // changes in the number of open positions ... + if (currPositions != mPositionsCount) + { + // + // number of open positions has been changed ... + result.hasNewPosition = true; + result.newPositions = currPositions - mPositionsCount; + + // + // update the value ... + mPositionsCount = currPositions; + } + + // + // Deals ... + // changes in the number of deals in the trade history cache ... + if (currDeals != mDealsCount) + { + // + // number of deals in the trade history cache has been changed ... + result.hasNewDeal = true; + result.newDeals = currDeals - mDealsCount; + + // + // update the value ... + mDealsCount = currDeals; + } + + // + // History Orders ... + // changes in the number of history orders in the trade history cache ... + if (currHistoryOrders != mHistoryOrdersCount) + { + // + // number of history orders in the trade history cache has been changed ... + result.hasNewHistoryOrder = true; + result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; + + // + // update the value ... + mHistoryOrdersCount = currHistoryOrders; + } + + // + // checking if it is necessary to change the limits of the trade history to be requested in cache ... + CheckStartDateInTradeHistory(); + } + + // + // Reset On Trade Scanner Context ... + void ResetOnTradeContext() + { + // + mEndDate = TimeCurrent(); + mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + } + + // + // Initial Context Of Trade Scanner ... + void InitOnTradeContext() + { + // + ResetLastError(); + + // + // load history ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + // + LogMessage("Failed to Load OnTrade Context History ..."); + + // + return; + } + + // + // get the current value ... + mOrdersCount = OrdersTotal(); + mPositionsCount = PositionsTotal(); + mDealsCount = HistoryDealsTotal(); + mHistoryOrdersCount = HistoryOrdersTotal(); + + // + mScanStarted = true; + } + + // + // END OnTrade Handlers ... + // + + // + // START Signal Private ... + // + + // + // Add Or Update Signal ... + void AddOrUpdateSignalInfo( + XSignal &signal // Specified Signal + ) + { + // + bool isExists = mSignalManager.IsExists(signal); + if (isExists) + { + mSignalManager.Remove(signal.ticket); + } + + // + bool isAddOrUpdated = mSignalManager.AddOrUpdate(signal); + if (isAddOrUpdated) + { + // + color longColor = clrAqua; + color shortColor = clrFuchsia; + + // + DrawSignalShape( + signal, + longColor, + shortColor); + } + } + + // + // Retrieve Signal String From Chart Event ... + XSignal RetrieveSignal( + ulong ticket // Specify Position Ticket + ) + { + // + XSignal result = {}; + + // + if (ticket <= 0) + { + return result; + } + + // + result = mSignalManager.Get(ticket); + + // + return result; + } + void RetrieveSignal( + XSignal &signal // Specified Signal + ) + { + + // + XSignal tSignal = mSignalManager.Get(signal.ticket); + + // + // Fill signal by tSignal Data ... + // since tese properties may change in signal manipulation times ... + signal.tp = tSignal.tp; + signal.sl = tSignal.sl; + signal.riskFreeStep = tSignal.riskFreeStep; + signal.riskFreeRate = tSignal.riskFreeRate; + } + + // + // Convert Position to Signal by Index ... + XSignal PositionToSignal(int index) + { + // + XSignal result = {}; + + // + if (!mPositionInfo.SelectByIndex(index)) + { + return result; + } + + // + ulong ticket = mPositionInfo.Ticket(); + result = PositionToSignal(ticket); + + // + return result; + } + + // + // Position To Signal by Ticket ... + XSignal PositionToSignal(ulong ticket) + { + // + XSignal result = {}; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + bool isExists = mSignalManager.IsExists(ticket); + if (isExists) + { + result = RetrieveSignal(ticket); + } + + // + // Ticket ... + result.ticket = mPositionInfo.Ticket(); + + // + // ID ... + result.id = mPositionInfo.Identifier(); + + // + // Symbol ... + result.symbol = mPositionInfo.Symbol(); + + // + // Type ... + ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType(); + ENUM_X_SIGNAL_TYPE type = pType == POSITION_TYPE_BUY ? X_SIGNAL_LONG : X_SIGNAL_SHORT; + result.type = type; + + // + // MagicNumber ... + result.magicNumber = mPositionInfo.Magic(); + + // + // Entry/Open Price ... + result.entry = mPositionInfo.PriceOpen(); + + // + // Take Profit ... + result.tp = result.tp <= 0 && mPositionInfo.TakeProfit() > 0 + ? mPositionInfo.TakeProfit() + : result.tp; + + // + // Stop Loss ... + result.sl = result.sl <= 0 && mPositionInfo.StopLoss() > 0 + ? mPositionInfo.StopLoss() + : result.sl; + + // + // Profit ... + result.profit = mPositionInfo.Profit(); + + // + // Time ... + result.time = mPositionInfo.Time(); + + // + // Volume ... + result.volume = mPositionInfo.Volume(); + + // + // Comment ... + result.comment = mPositionInfo.Comment(); + + // + return result; + } + + // + // Converts a Deal to XDeal by Index ... + XDeal ToXDealByIndex(int index) + { + // + XDeal result = {}; + + // + bool isSelect = mDealInfo.SelectByIndex(index); + if (!isSelect) + { + return result; + } + + // + // Read Deal Ticket ... + ulong ticket = mDealInfo.Ticket(); + result = ToXDealByTicket(ticket); + + // + return result; + } + + // + // Converts a Deal to XDeal by Ticket ... + XDeal ToXDealByTicket(ulong ticket) + { + // + XDeal result = {}; + + // + mDealInfo.Ticket(ticket); + + // + result.time = mDealInfo.Time(); + result.swap = mDealInfo.Swap(); + result.magic = mDealInfo.Magic(); + result.order = mDealInfo.Order(); + result.entry = mDealInfo.Entry(); + result.price = mDealInfo.Price(); + result.ticket = mDealInfo.Ticket(); + result.symbol = mDealInfo.Symbol(); + result.type = mDealInfo.DealType(); + result.profit = mDealInfo.Profit(); + result.volume = mDealInfo.Volume(); + result.comment = mDealInfo.Comment(); + result.positionId = mDealInfo.PositionId(); + result.commission = mDealInfo.Commission(); + result.reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( + ticket, + DEAL_REASON); + + // + return result; + } + + // + // Convert an Order to XOrder by Index ... + XOrder ToXOrderByIndex(int index) + { + // + XOrder result = {}; + + // + bool isSelect = mOrderInfo.SelectByIndex(index); + if (!isSelect) + { + return result; + } + + // + ulong ticket = mOrderInfo.Ticket(); + result = ToXOrderByTicket(ticket); + + // + return result; + } + + // + // Convert an Order to XOrder by Ticket ... + XOrder ToXOrderByTicket(ulong ticket) + { + // + XOrder result = {}; + + // + bool isSelect = mOrderInfo.Select(ticket); + if (!isSelect) + { + return result; + } + + // + result.state = mOrderInfo.State(); + result.magic = mOrderInfo.Magic(); + result.ticket = mOrderInfo.Ticket(); + result.symbol = mOrderInfo.Symbol(); + result.type = mOrderInfo.OrderType(); + result.comment = mOrderInfo.Comment(); + result.stopLoss = mOrderInfo.StopLoss(); + result.typeTime = mOrderInfo.TypeTime(); + result.timeDone = mOrderInfo.TimeDone(); + result.timeSetup = mOrderInfo.TimeSetup(); + result.positionId = mOrderInfo.PositionId(); + result.priceOpen = mOrderInfo.PriceOpen(); + result.takeProfit = mOrderInfo.TakeProfit(); + result.typeFilling = mOrderInfo.TypeFilling(); + result.priceCurrent = mOrderInfo.PriceCurrent(); + result.volumeInitial = mOrderInfo.VolumeInitial(); + result.volumeCurrent = mOrderInfo.VolumeCurrent(); + result.timeExpiration = mOrderInfo.TimeExpiration(); + result.priceStopLimit = mOrderInfo.PriceStopLimit(); + result.reason = (ENUM_ORDER_REASON)HistoryOrderGetInteger( + ticket, + ORDER_REASON); + + // + return result; + } + // + // END Signal Private ... + // +}; + +// +// a Class For Guard Account ... +class XCGuard : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCGuard( + int oldAge, // Age for Old Trades + ENUM_X_GUARD_ACTIONS oldGuardAction, // Guard Action for Too Old State + double criticalFactor, // Critical DrawDown Factor based On Balance + ENUM_X_GUARD_ACTIONS criticalAction, // Guard Action for Critical State + double maxFactor, // Max DrawDown Factor based on Balance + ENUM_X_GUARD_ACTIONS maxAction, // Guard Action for Max State + int GuardStopoutFiredAfterTouches, // Guard Stopout if Max State touched + ENUM_X_GUARD_SUPPORT_METHODS supportMethod // How to Support Signals + ) + { + // + mSupportPrefix = "SPT"; + mDirectional = "SPD"; + mInDirectional = "SPIND"; + + // + mOldAge = oldAge; + mOldGuardAction = oldGuardAction; + + // + mMaxFactor = maxFactor; + mMaxAction = maxAction; + mCriticalFactor = criticalFactor; + mCriticalAction = criticalAction; + mGuardStopoutFiredAfterTouches = GuardStopoutFiredAfterTouches; + + // + mSupportMethod = supportMethod; + + // + mAccountInfo = new XCAccountInfo(); + + // + double deposit = mAccountInfo.GetInitialBalance(); + + // + if ( + maxFactor > 0 && + maxFactor < 1) + { + mMaxValue = maxFactor * deposit; + } + + // + if ( + criticalFactor > 0 && + criticalFactor < 1) + { + mCriticalValue = criticalFactor * deposit; + } + + // + Reset(); + ResetMaxDrawDownTouches(); + } + + // + // Deconstructor ... + ~XCGuard() {} + + // + // Reset List ... + void Reset() + { + // + CleanBuffer(mGuardedSignals); + CleanBuffer(mSupportedSignals); + } + + // + // Reset Consecutive Max DrawDown Touches ... + void ResetMaxDrawDownTouches() + { + mOccuredconsecutiveMaxDraDownTouches = 0; + } + + // + // Calculate and Retrieve Critical DrawDown Value ... + double GetCriticalValue() + { + // + double result = mCriticalValue; + if (mCriticalFactor <= 0) + { + return result; + } + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + + // + if (balance > deposit) + { + // + double balanceBasedCriticalDrawDown = mCriticalFactor * balance; + + // + result = MathMax( + mCriticalValue, + balanceBasedCriticalDrawDown); + } + + // + return result; + } + + // + // Calculate and Retrieve Max Allowed DrawDown Value ... + double GetMaxValue() + { + // + double result = mMaxValue; + if (mMaxValue <= 0) + { + return result; + } + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + + // + if (balance > deposit) + { + // + double balanceBasedMaxAllwedDrawDown = mMaxFactor * balance; + + // + result = MathMax( + mMaxValue, + balanceBasedMaxAllwedDrawDown); + } + + // + return result; + } + + // + // Guard Account Protection ... + bool Guard( + XGuardHandlerResult &guardResult, // Hold's Message + string &message, // Hold's Message + XCTrade &trader, // Specified Trader + ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages + ) + { + // + message = ""; + + // + // Clean Result of Guard ... + CleanBuffer(guardResult.olds); + CleanBuffer(guardResult.maxes); + CleanBuffer(guardResult.criticals); + + // + bool result = false; + + // + // So Important is to Guard DrawDowns ... + result = GuardDrawDown( + guardResult, + message, + trader); + if (result) + { + return result; + } + + // + // Then we have to Guard Old Trades ... + result = GuardOlds( + guardResult, + message, + trader); + + // + return result; + } + + // + // Handle Guard Old Trades ... + bool GuardOlds( + XGuardHandlerResult &guardResult, // Hold's Message + string &message, // Hold's Message + XCTrade &trader, // Specified Trader + ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages + ) + { + // + // Cleanup Message ... + message = ""; + + // + // Clean Result of Guard ... + CleanBuffer(guardResult.olds); + + // + bool result = false; + + // + // Validate Args ... + if ( + mOldAge <= 0 || + mOldGuardAction == X_GUARD_DO_NOTHING) + { + return result; + } + + // + // Normalize Args ... + if (period == NULL) + { + period = _Period; + } + + // + // Retrieve Old Trades ... + XSignal oldSignals[]; + trader.GetOldSignals( + oldSignals, + mOldAge, + period); + int oldSignalsCount = ArraySize(oldSignals); + if (oldSignalsCount <= 0) + { + return result; + } + + // + result = DoGuardAction( + guardResult, + message, + trader, + mOldGuardAction, + X_GUARDED_OLD, // Specify Guard Reason + period // Specified Running Time Frame for Signal Age Calculations + ); + + // + return result; + } + + // + // Hnadle Guard DrawDown ... + bool GuardDrawDown( + XGuardHandlerResult &guardResult, // Hold's Message + string &message, // Hold's Message + XCTrade &trader // Specified Trader + ) + { + // + message = ""; + + // + // Clean Result of Guard ... + CleanBuffer(guardResult.maxes); + CleanBuffer(guardResult.criticals); + + // + bool result = false; + + // + // Check State for Guard ... + bool isCriticalGuardEnabled = mCriticalFactor > 0; + bool isMaxGuardEnabled = mMaxFactor > 0; + bool isGuardEnabled = + isMaxGuardEnabled; + + // + if (!isGuardEnabled) + { + return result; + } + + // + double maxValue = GetMaxValue(); + double criticalValue = GetCriticalValue(); + + // + double profitSums = trader.GetSignalsProfit(); + + // + bool isMaxReached = + profitSums < 0 && + isMaxGuardEnabled && + MathAbs(profitSums) >= maxValue; + bool isCriticalReached = + profitSums < 0 && + isCriticalGuardEnabled && + MathAbs(profitSums) >= criticalValue; + + // + if (!isMaxReached && !isCriticalReached) + { + // + // Reset Consecutive Max DrawDown Touches ... + ResetMaxDrawDownTouches(); + + // + return result; + } + + // + // Check For Critical Guard ... + if (isCriticalReached && !isMaxReached) + { + // + result = DoGuardAction( + guardResult, + message, + trader, + mCriticalAction, + X_GUARDED_CRITICAL); + } + else if (isMaxReached) + { + // + result = DoGuardAction( + guardResult, + message, + trader, + mMaxAction, + X_GUARDED_MAX); + + // + // Handle Guard StopOut Action ... + mOccuredconsecutiveMaxDraDownTouches++; + if ( + mMaxAction != X_GUARD_DO_NOTHING && + mMaxAction != X_GUARD_CLOSE_ALL && + mGuardStopoutFiredAfterTouches > 0 && + mOccuredconsecutiveMaxDraDownTouches >= mGuardStopoutFiredAfterTouches) + { + // + XSignal closed[]; + trader.CloseSignals(closed); + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + // + XSignal iSignal = closed[i]; + + // + AddItemToBuffer( + iSignal, + guardResult.maxes); + } + + // + message = "Guard StopOut Action Closed (" + (string)closedCount + ") Signals and Release Account ..."; + + // + guardResult.isStopOut = true; + + // + result = true; + } + } + } + + // + return result; + } + + // + // Do Signal Protections and apply Support ... + bool ProtectSignals( + XSignal &mResult[], // Hold's Result + XCTrade &trader, // Specified Trader + int numberOfItemsCheck = 30 // Number of Items to check + ) + { + // + bool result = false; + + // + CleanBuffer(mResult); + + // + // Check Supports Enabled ... + result = IsSupportEnabled(); + if (!result) + { + return result; + } + + // + // Update Supports ... + XSignal signals[]; + trader.GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount > 0) + { + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isExists = IsSupportExists(iSignal.ticket); + if (isExists) + { + UpdateSupport(iSignal); + } + } + } + + // + // Count Supporteds ... + XProtectedSignal supporteds[]; + GetAllSupports(supporteds); + int supportedCount = ArraySize(supporteds); + result = supportedCount > 0; + if (!result) + { + return result; + } + + // + // Loop through ... + for (int i = 0; i < supportedCount; i++) + { + // + XProtectedSignal iP = supporteds[i]; + + // + bool canDoDirectional = CanDoDirectionalSupport( + trader, + iP.ticket, + numberOfItemsCheck); + bool canDoInDirectional = CanDoInDirectionalSupport( + trader, + iP.ticket, + numberOfItemsCheck); + + // + if ( + !canDoDirectional && + !canDoInDirectional) + { + continue; + } + + // + // Do Directional ... + if (canDoDirectional) + { + // + // Generate Propper Signal ... + XSignal sdSignal = GenerateDirectionalSupportSignal( + iP.ticket, + trader); + + // + ENUM_EXECUTION_SIGNAL_RESULT executionResult = trader.ExecuteSignal( + sdSignal, + true, + false); + bool isExecuted = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (isExecuted) + { + // + XSignal eSignal = trader.GetSignal(sdSignal.ticket); + + // + AddItemToBuffer( + eSignal, + mResult); + } + } + // + // Do Indirectional ... + else if (canDoInDirectional) + { + // + // Generate Propper Signal ... + XSignal sindSignal = GenerateDirectionalSupportSignal( + iP.ticket, + trader); + + // + ENUM_EXECUTION_SIGNAL_RESULT executionResult = trader.ExecuteSignal( + sindSignal, + true, + false); + bool isExecuted = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (isExecuted) + { + // + XSignal eSignal = trader.GetSignal(sindSignal.ticket); + + // + AddItemToBuffer( + eSignal, + mResult); + } + } + } + + // + result = ArraySize(mResult) > 0; + + // + return result; + } + + // + // Validate State ... + bool Validate() + { + // + bool result = false; + + // + result = + mMaxFactor > 0 && + (mCriticalFactor > 0 + ? mCriticalFactor < mMaxFactor + : true); + + // + return result; + } + + // + // START Guarded Signals Functions ... + // + + // + // Add new Protecte Signal ... + bool Add( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsExists(signal.ticket); + if (isExists) + { + return result; + } + + // + XProtectedSignal item; + + // + datetime time = TimeCurrent(); + + // + item.ticket = signal.ticket; + + // + AddItemToBuffer( + time, + item.time); + + // + AddItemToBuffer( + signal.profit, + item.profit); + + // + AddItemToBuffer( + item, + mGuardedSignals); + + // + return result; + } + + // + // Get All ... + void GetAll( + XProtectedSignal &result[] // Hold's Result + ) + { + // + CopyBuffer( + mGuardedSignals, + result); + } + + // + // Get ... + XProtectedSignal Get( + ulong ticket // Specified Signal Ticket + ) + { + // + XProtectedSignal result; + + // + bool isExists = IsExists(ticket); + if (!isExists) + { + return result; + } + + // + int protectedCounts = ArraySize(mGuardedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mGuardedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = iProtected; + break; + } + } + + // + return result; + } + + // + // Remove ... + bool Remove( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + result = IsExists(ticket); + if (!result) + { + return result; + } + + // + int protectedCounts = ArraySize(mGuardedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + XProtectedSignal cleared[]; + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mGuardedSignals[i]; + + // + if (iProtected.ticket != ticket) + { + AddItemToBuffer( + iProtected, + cleared); + } + } + + // + // Update Source by Cleared ... + CopyBuffer( + cleared, + mGuardedSignals); + + // + result = true; + + // + return result; + } + + // + // Update ... + bool Update( + ulong ticket, // Specified Signal Ticket + datetime time, // Specified Last Checked time + double profit // Specified Signal Profit + // XProtectedSignal &item // Specified which object to Update + ) + { + // + bool result = false; + + // + int protectedCounts = ArraySize(mGuardedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + result = IsExists(ticket); + if (!result) + { + return result; + } + + // + // Retrieve Struct ... + XProtectedSignal item = Get(ticket); + AddItemToBuffer( + time, + item.time); + AddItemToBuffer( + profit, + item.profit); + + // + result = Remove(ticket); + if (!result) + { + return result; + } + + // + AddItemToBuffer( + item, + mGuardedSignals); + result = true; + + // + return result; + } + bool Update( + XProtectedSignal &item // Specified Protected Item + ) + { + // + bool result = false; + + // + datetime time; + result = GetLastItem( + time, + item.time); + if (!result) + { + return result; + } + + // + double profit; + result = GetLastItem( + profit, + item.profit); + if (!result) + { + return result; + } + + // + result = Update( + item.ticket, time, profit); + + // + return result; + } + bool Update( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + ulong ticket = signal.ticket; + datetime time = TimeCurrent(); + double profit = signal.profit; + + // + result = Update( + ticket, + time, + profit); + + // + return result; + } + + // + // Add Or Update ... + bool AddOrUpdate( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsExists(signal.ticket); + if (!isExists) + { + result = Add(signal); + } + else + { + result = Update(signal); + } + + // + return result; + } + + // + // Check Exists ... + bool IsExists( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + int protectedCounts = ArraySize(mGuardedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mGuardedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + + // + // Count Protecteds ... + int Count() + { + // + int result = 0; + + // + result = ArraySize(mGuardedSignals); + + // + return result; + } + + // + // END Guarded Signals Functions ... + // + + // + // START Supported Signals Functions ... + // + + // + // Check can Handle Support Signals or not ... + bool IsSupportEnabled() + { + // + bool result = false; + + // + result = + mSupportMethod != X_SUPPORT_DO_NOTHING; + + // + return result; + } + + // + // Retrieve List Of Supported Signals ... + void GetSupportSignals( + XSignal &result[], // Hold's Result ... + XCTrade &trader // Specified Trader class Instance ... + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + trader.GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = -0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isSupport = IsSupport(iSignal.comment); + if (isSupport) + { + AddItemToBuffer( + iSignal, + result); + } + } + } + + // + // Retrieve List Of Specific Signals Supported Signals ... + void GetSignalSupports( + XSignal &result[], // Hold's Result ... + XCTrade &trader, // Specified Trader class Instance ... + ulong ticket // Specified Signal Ticket ... + ) + { + // + CleanBuffer(result); + + // + // Validate Args ... + if (ticket <= 0) + { + return; + } + + // + // Check Signal Exists using Trader ... + XSignal parentSignal = trader.GetSignal(ticket); + bool isValid = + parentSignal.ticket > 0 && + parentSignal.ticket == ticket && + StringLen(parentSignal.comment) > 0; + if (!isValid) + { + return; + } + + // + XSignal supportSignals[]; + GetSupportSignals( + supportSignals, + trader); + int supportSignalsCount = ArraySize(supportSignals); + if (supportSignalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < supportSignalsCount; i++) + { + // + XSignal iSignal = supportSignals[i]; + + // + bool isBelongsToParent = IsBelongsToParent( + ticket, + iSignal.comment); + if (isBelongsToParent) + { + AddItemToBuffer( + iSignal, + result); + } + } + } + + // + // Check Specific Support Conditions for Opening Directional Support ... + bool CanDoDirectionalSupport( + XCTrade &trader, // Specified Trader class Instance ... + ulong ticket, // Specified Signal Ticket ... + int numberOfItemsCheck = 30 // Number of Items to check ... + ) + { + // + bool result = false; + + // + // Check Supports Enabled ... + result = IsSupportEnabled(); + if (!result) + { + return result; + } + + // + // Check Support Method Allows Directional ... + result = + mSupportMethod == X_SUPPORT_FULL || + mSupportMethod == X_SUPPORT_IN_DRAWUP_DIRECTIONAL; + if (!result) + { + return result; + } + + // + // Validate Ticket ... + result = ticket > 0; + if (!result) + { + return result; + } + + // + // Check Supports Count ... + int supportedCount = ArraySize(mSupportedSignals); + result = supportedCount > 0; + if (!result) + { + return result; + } + + // + // Check Ticket Exists in Supports ... + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + // Check signal Doesn't have any Support ... + XSignal supports[]; + GetSignalSupports( + supports, + trader, + ticket); + int supportsCount = ArraySize(supports); + result = supportsCount <= 0; + if (!result) + { + return result; + } + + // + // Retrieve Support Model ... + XProtectedSignal sInfo = GetSupport(ticket); + + // + // Validate Model ... + int sTimesCount = ArraySize(sInfo.time); + int sProfitsCount = ArraySize(sInfo.profit); + result = + sInfo.ticket == ticket && + sTimesCount == sProfitsCount && + sTimesCount >= numberOfItemsCheck && + sProfitsCount >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Validate Signal Age ... + XSignal sSignal = trader.GetSignal(ticket); + int sSignalAge = trader.GetSignalAge(sSignal.time); + result = sSignalAge >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Extrat Profits ... + double lastProfits[]; + for (int i = sProfitsCount - 1; i >= (sProfitsCount - numberOfItemsCheck); i++) + { + // + double iProfit = sInfo.profit[i]; + + // + AddItemToBuffer( + iProfit, + lastProfits); + } + + // + string logMsg = ToString(lastProfits); + LogMessage("" + (string)ticket + " lastProfits: \n" + logMsg); + + // + result = false; + + // + // Now implement Business Logics ... + + // + return result; + } + + // + // Check Specific Support Conditions for Opening InDirectional Support ... + bool CanDoInDirectionalSupport( + XCTrade &trader, // Specified Trader class Instance ... + ulong ticket, // Specified Signal Ticket ... + int numberOfItemsCheck = 30 // Number of Items to check ... + ) + { + // + bool result = false; + + // + // Check Supports Enabled ... + result = IsSupportEnabled(); + if (!result) + { + return result; + } + + // + // Check Support Method Allows Directional ... + result = + mSupportMethod == X_SUPPORT_FULL || + mSupportMethod == X_SUPPORT_IN_DRAWDOWN_INDIRECTIONAL; + if (!result) + { + return result; + } + + // + // Validate Ticket ... + result = ticket > 0; + if (!result) + { + return result; + } + + // + // Check Supports Count ... + int supportedCount = ArraySize(mSupportedSignals); + result = supportedCount > 0; + if (!result) + { + return result; + } + + // + // Check Ticket Exists in Supports ... + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + // Check signal Doesn't have any Support ... + XSignal supports[]; + GetSignalSupports( + supports, + trader, + ticket); + int supportsCount = ArraySize(supports); + result = supportsCount <= 0; + if (!result) + { + return result; + } + + // + // Retrieve Support Model ... + XProtectedSignal sInfo = GetSupport(ticket); + + // + // Validate Model ... + int sTimesCount = ArraySize(sInfo.time); + int sProfitsCount = ArraySize(sInfo.profit); + result = + sInfo.ticket == ticket && + sTimesCount == sProfitsCount && + sTimesCount >= numberOfItemsCheck && + sProfitsCount >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Validate Signal Age ... + XSignal sSignal = trader.GetSignal(ticket); + int sSignalAge = trader.GetSignalAge(sSignal.time); + result = sSignalAge >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Extrat Profits ... + double lastProfits[]; + for (int i = sProfitsCount - 1; i >= (sProfitsCount - numberOfItemsCheck); i++) + { + // + double iProfit = sInfo.profit[i]; + + // + AddItemToBuffer( + iProfit, + lastProfits); + } + + // + string logMsg = ToString(lastProfits); + LogMessage("" + (string)ticket + " lastProfits: \n" + logMsg); + + // + result = false; + + // + // Now implement Business Logics ... + + // + return result; + } + + // + // Generate Directional Support Signal for Parent Signal ... + XSignal GenerateDirectionalSupportSignal( + ulong ticket, // Specified Parent Signal Ticket ... + XCTrade &trader // Specified Trader Class ... + ) + { + // + XSignal result = {}; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + XSignal pSignal = trader.GetSignal(ticket); + bool isValidParent = + pSignal.ticket > 0 && + pSignal.ticket == ticket && + StringLen(pSignal.comment) > 0; + if (!isValidParent) + { + return result; + } + + // + ENUM_X_SIGNAL_TYPE type = pSignal.type; + bool isLong = IsLong(type); + + // + double entry = GetEntry( + pSignal.symbol, + type); + double exit = GetExit( + pSignal.symbol, + type); + + // + double reward = PipsToPrice( + pSignal.symbol, + 6); + double risk = PipsToPrice( + pSignal.symbol, + 1); + + // + double tp = + isLong + ? entry + reward + : entry - reward; + + // + double sl = + isLong + ? exit - risk + : exit + risk; + + // + double rfStep = 2; + double rfRate = 0.5; + + // + double volume = NormalizeVolume( + pSignal.volume / 2, + pSignal.symbol, + 2); + + // + // Generate Signal using Trader Class Instance ... + result = trader.GenerateSignal( + // + type, + tp, + sl, + volume, + rfStep, + rfRate + // + ); + + // + return result; + } + + // + // Generate InDirectional Support Signal for Parent Signal ... + XSignal GenerateInDirectionalSupportSignal( + ulong ticket, // Specified Parent Signal Ticket ... + XCTrade &trader // Specified Trader Class ... + ) + { + // + XSignal result = {}; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + XSignal pSignal = trader.GetSignal(ticket); + bool isValidParent = + pSignal.ticket > 0 && + pSignal.ticket == ticket && + StringLen(pSignal.comment) > 0; + if (!isValidParent) + { + return result; + } + + // + ENUM_X_SIGNAL_TYPE type = trader + .GetIndirectionSignalType(pSignal.type); + bool isLong = IsLong(type); + + // + double entry = GetEntry( + pSignal.symbol, + type); + double exit = GetExit( + pSignal.symbol, + type); + + // + double reward = PipsToPrice( + pSignal.symbol, + 6); + double risk = PipsToPrice( + pSignal.symbol, + 1); + + // + double tp = + isLong + ? entry + reward + : entry - reward; + + // + double sl = + isLong + ? exit - risk + : exit + risk; + + // + double rfStep = 2; + double rfRate = 0.5; + + // + double volume = NormalizeVolume( + pSignal.volume / 2, + pSignal.symbol, + 2); + + // + // Generate Signal using Trader Class Instance ... + result = trader.GenerateSignal( + // + type, + tp, + sl, + volume, + rfStep, + rfRate + // + ); + + // + return result; + } + + // + // Generate Specific Signals Support Signal Comment ... + string GenerateSupportSignalComment( + ulong ticket, // Specified Parent Signal Ticket + ENUM_X_SIGNAL_TYPE type, // Specified Support Signal Type + bool isInDirectional = false // Specified Support Signal Direction + ) + { + // + string result = ""; + + // + if (ticket <= 0) + { + return result; + } + + // + string typeString = GetSignalType(type); + string directionStr = GenerateSupportDirection(isInDirectional); + + // + result = + mSupportPrefix + "(" + (string)ticket + ")_" + + X_SIGNAL_TYPE + "(" + typeString + ")_" + + directionStr; + + // + return result; + } + + // + // Get Support Direction String Representation ... + string GenerateSupportDirection( + bool isInDirectional = false // Specified Support Signal Direction + ) + { + // + string result = ""; + + // + result = + isInDirectional + ? mInDirectional + : mDirectional; + + // + return result; + } + + // + // Check an String Is Directional Or not ... + bool IsDirectionalSupport( + string comment // Specified Comment ... + ) + { + // + bool result = false; + + // + result = IsSupport(comment); + if (!result) + { + return result; + } + + // + int sPos = StringFind( + comment, + mDirectional); + result = sPos >= 0; + + // + return result; + } + + // + // Check an String Is In Directional Or not ... + bool IsInDirectionalSupport( + string comment // Specified Comment ... + ) + { + // + bool result = false; + + // + result = IsSupport(comment); + if (!result) + { + return result; + } + + // + int sPos = StringFind( + comment, + mInDirectional); + result = sPos >= 0; + + // + return result; + } + + // + // Check an String Is Support or not ... + bool IsSupport( + string comment // Specified Comment ... + ) + { + // + bool result = false; + + // + int sPos = StringFind( + comment, + mSupportPrefix); + result = sPos >= 0; + + // + return result; + } + + // + // Extract Parent of Support Signal Ticket from a comment ... + ulong ExtractParentTicket( + string comment // Specified Comment ... + ) + { + // + ulong result = 0; + + // + bool isSupport = IsSupport(comment); + if (!isSupport) + { + return result; + } + + // + // TICKET ... + string ticketStr = ExtractString( + comment, + mSupportPrefix + "(", + ")"); + if (StringLen(ticketStr) > 0) + { + result = (ulong)ticketStr; + } + + // + return result; + } + + // + // Check a Comment belongs to Support Signal or not ... + bool IsBelongsToParent( + ulong ticket, // Specified Parent Signal Ticket + string comment // Specified Support Signal Comment + ) + { + // + bool result = false; + + // + // Validate Arg ... + if (ticket <= 0) + { + return result; + } + + // + result = IsSupport(comment); + if (!result) + { + return result; + } + + // + ulong spTicket = ExtractParentTicket(comment); + result = spTicket == ticket; + + // + return result; + } + + // + // Add new Protecte Signal ... + bool AddSupport( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsSupportExists(signal.ticket); + if (isExists) + { + return result; + } + + // + XProtectedSignal item; + + // + datetime time = TimeCurrent(); + + // + item.ticket = signal.ticket; + + // + AddItemToBuffer( + time, + item.time); + + // + AddItemToBuffer( + signal.profit, + item.profit); + + // + AddItemToBuffer( + item, + mSupportedSignals); + + // + return result; + } + + // + // Get All ... + void GetAllSupports( + XProtectedSignal &result[] // Hold's Result + ) + { + // + CopyBuffer( + mSupportedSignals, + result); + } + + // + // Get ... + XProtectedSignal GetSupport( + ulong ticket // Specified Signal Ticket + ) + { + // + XProtectedSignal result; + + // + bool isExists = IsSupportExists(ticket); + if (!isExists) + { + return result; + } + + // + int protectedCounts = ArraySize(mSupportedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mSupportedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = iProtected; + break; + } + } + + // + return result; + } + + // + // Remove ... + bool RemoveSupport( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + int protectedCounts = ArraySize(mSupportedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + XProtectedSignal cleared[]; + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mSupportedSignals[i]; + + // + if (iProtected.ticket != ticket) + { + AddItemToBuffer( + iProtected, + cleared); + } + } + + // + // Update Source by Cleared ... + CopyBuffer( + cleared, + mSupportedSignals); + + // + result = true; + + // + return result; + } + + // + // Update ... + bool UpdateSupport( + ulong ticket, // Specified Signal Ticket + datetime time, // Specified Last Checked time + double profit // Specified Signal Profit + ) + { + // + bool result = false; + + // + int protectedCounts = ArraySize(mSupportedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + // Retrieve Struct ... + XProtectedSignal item = GetSupport(ticket); + AddItemToBuffer( + time, + item.time); + AddItemToBuffer( + profit, + item.profit); + + // + result = RemoveSupport(ticket); + if (!result) + { + return result; + } + + // + AddItemToBuffer( + item, + mSupportedSignals); + result = true; + + // + return result; + } + bool UpdateSupport( + XProtectedSignal &item // Specified Protected Item + ) + { + // + bool result = false; + + // + datetime time; + result = GetLastItem( + time, + item.time); + if (!result) + { + return result; + } + + // + double profit; + result = GetLastItem( + profit, + item.profit); + if (!result) + { + return result; + } + + // + result = UpdateSupport( + item.ticket, time, profit); + + // + return result; + } + bool UpdateSupport( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + ulong ticket = signal.ticket; + datetime time = TimeCurrent(); + double profit = signal.profit; + + // + result = UpdateSupport( + ticket, + time, + profit); + + // + return result; + } + + // + // Add Or Update ... + bool AddOrUpdateSupport( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsSupportExists(signal.ticket); + if (!isExists) + { + result = Add(signal); + } + else + { + result = Update(signal); + } + + // + return result; + } + + // + // Check Exists ... + bool IsSupportExists( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + int protectedCounts = ArraySize(mSupportedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mSupportedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + + // + // Count Protecteds ... + int CountSupports() + { + // + int result = 0; + + // + result = ArraySize(mSupportedSignals); + + // + return result; + } + + // + // END Suppoprted Signals Functions ... + // + + // + // START Getter/Setter(s) ... + // + + // + int GetOldAge() + { + return mOldAge; + } + + // + bool SetOldAge(int value) + { + // + bool result = false; + + // + result = + value > 0 && + mOldAge != value; + if (!result) + { + return result; + } + + // + mOldAge = value; + + // + return result; + } + + // + ENUM_X_GUARD_ACTIONS GetOldGuardAction() + { + return mOldGuardAction; + } + + // + bool SetOldGuardAction(ENUM_X_GUARD_ACTIONS value) + { + // + bool result = false; + + // + result = value != mOldGuardAction; + if (!result) + { + return result; + } + + // + mOldGuardAction = value; + + // + return result; + } + + // + double GetCriticalFactor() + { + return mCriticalFactor; + } + + // + bool SetCriticalFactor(bool value) + { + // + bool result = false; + + // + result = + value > 0 && + value < 1 && + mCriticalFactor != value; + if (!result) + { + return result; + } + + // + mCriticalFactor = value; + + // + double deposit = mAccountInfo.GetInitialBalance(); + mCriticalValue = deposit * value; + + // + return result; + } + + // + ENUM_X_GUARD_ACTIONS GetCriticalAction() + { + return mCriticalAction; + } + + // + bool SetCriticalAction(ENUM_X_GUARD_ACTIONS value) + { + // + bool result = false; + + // + result = + value != mCriticalAction; + if (!result) + { + return result; + } + + // + mCriticalAction = value; + + // + return result; + } + + // + double GetMaxFactor() + { + return mMaxFactor; + } + + // + bool SetMaxFactor(bool value) + { + // + bool result = false; + + // + result = + value > 0 && + value < 1 && + mMaxFactor != value; + if (!result) + { + return result; + } + + // + mMaxFactor = value; + + // + double deposit = mAccountInfo.GetInitialBalance(); + mMaxValue = deposit * value; + + // + return result; + } + + // + ENUM_X_GUARD_ACTIONS GetMaxAction() + { + return mMaxAction; + } + + // + bool SetMaxAction(ENUM_X_GUARD_ACTIONS value) + { + // + bool result = false; + + // + result = + value != mMaxAction; + if (!result) + { + return result; + } + + // + mMaxAction = value; + + // + return result; + } + + // + ENUM_X_GUARD_SUPPORT_METHODS GetSupportMethod() + { + return mSupportMethod; + } + + // + bool SetSupportMethod(ENUM_X_GUARD_SUPPORT_METHODS value) + { + // + bool result = false; + + // + result = + value != mSupportMethod; + if (!result) + { + return result; + } + + // + mSupportMethod = value; + + // + return result; + } + + // + // END Getter/Setter(s) ... + // + + // + // Generate Signal Guard Attacked Message ... + string GenerateGuardedSignalComment( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason // Specified Guard Reason + ) + { + // + string result = ""; + + // + string reasonMessage = + ( + // + reason == X_GUARDED_OLD + ? "Because of Old Issue" + : reason == X_GUARDED_CRITICAL + ? "Because Of Crtical Drawdown Isuue" + : reason == X_GUARDED_MAX + ? "Because of Max Drawdown Issue" + : "" + // + ) + + " On Profit: " + (string)signal.profit; + + // + result += "Guard Attacked (" + (string)signal.ticket + "), " + reasonMessage + " ..."; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + string mSupportPrefix; + string mDirectional; + string mInDirectional; + + // + XProtectedSignal mGuardedSignals[]; + XProtectedSignal mSupportedSignals[]; + + // + int mOldAge; + ENUM_X_GUARD_ACTIONS mOldGuardAction; + + // + // Critical DrawDown Factor based On Balance ... + double mCriticalFactor; + double mCriticalValue; + + // + // Guard Action for Critical State ... + ENUM_X_GUARD_ACTIONS mCriticalAction; + + // + // Max DrawDown Factor based on Balance ... + double mMaxFactor; + double mMaxValue; + // + // Guard Stopout if Max State touched ... + int mOccuredconsecutiveMaxDraDownTouches; + int mGuardStopoutFiredAfterTouches; + + // + // Guard Action for Max State ... + ENUM_X_GUARD_ACTIONS mMaxAction; + + // + // How to Support Signals ... + ENUM_X_GUARD_SUPPORT_METHODS mSupportMethod; + + // + // Account Info Instance ... + XCAccountInfo mAccountInfo; + + // + // Get Volume Multiplier for Specified Guard Action ... + double GetGuardActionVolumeMultiplier( + ENUM_X_GUARD_ACTIONS action = X_GUARD_DO_NOTHING // Specified Action + ) + { + // + // Partial Close Max In Drawdown Trade ... + double result = 0.0; + if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1) + { + result = 0.01; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2) + { + result = 0.02; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3) + { + result = 0.03; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5) + { + result = 0.05; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10) + { + result = 0.10; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15) + { + result = 0.15; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20) + { + result = 0.20; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25) + { + result = 0.25; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30) + { + result = 0.30; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40) + { + result = 0.40; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50) + { + result = 0.50; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60) + { + result = 0.60; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70) + { + result = 0.70; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75) + { + result = 0.75; + } + + // + return result; + } + + // + // Do Specified Guard Action ... + bool DoGuardAction( + XGuardHandlerResult &guardResult, // Hold's Result ... + string &message, // Hold's Message ... + XCTrade &trader, // Specified Trader Class ... + ENUM_X_GUARD_ACTIONS action, // Specified Which Action to Do ... + ENUM_X_GUARD_REASONS reason, // Specified Guard Reason ... + ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages ... + ) + { + // + bool result = false; + + // + message = ""; + + // + string reasonString = + reason == X_GUARDED_OLD + ? "Because of Age Issue" + : "Because of DD " + ( + // + reason == X_GUARDED_CRITICAL ? "Critical" : "Max" + // + ) + + " Issue"; + + // + // Validate Args ... + if (action == X_GUARD_DO_NOTHING) + { + // + message = "Max Allowed Drawdown Reached, but nothing Happens ..."; + + // + return result; + } + + // + // Normalize Period ... + if (period == NULL) + { + period = _Period; + } + + // + // Close All Signals ... + XSignal closed[]; + XSignal maxInDDSignal; + + // + // Handle Perform Guard Action ... + switch (action) + { + // + // Close All ... + case X_GUARD_CLOSE_ALL: + { + // + trader.CloseSignals(closed); + int closedCount = ArraySize(closed); + result = closedCount > 0; + if (!result) + { + break; + } + + // + message = "Closed (" + (string)closedCount + ") Trades by Guard, " + reasonString + " ..."; + } + break; + + // + case X_GUARD_CLOSE_MAX_IN_DD: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75: + { + // + // Retrieve Max In Drawdown Trade ... + maxInDDSignal = trader.GetMaxInDrawdownSignal(); + bool isValid = IsValid(maxInDDSignal, trader.GetMagicNumber()) && maxInDDSignal.ticket > 0; + if (!isValid) + { + break; + } + + // + // Close Max In Drawdown Trade ... + if (action == X_GUARD_CLOSE_MAX_IN_DD) + { + // + string comment = "Signal (" + (string)maxInDDSignal.ticket + ") Closed by Guard ..."; + result = trader.Close( + maxInDDSignal.ticket, + comment); + if (result) + { + message = comment; + } + + // + break; + } + + // + int signalAge = 0; + bool canGuard = true; + bool isGuardedBefore = false; + + // + // Do Some Additional Verifications if Guard for Olds Trades ... + if (reason == X_GUARDED_OLD) + { + // + // Retrieve Signal Age ... + signalAge = trader.GetSignalAge( + maxInDDSignal, + period); + + // + // Check Guarded Before Or Not ... + isGuardedBefore = IsExists(maxInDDSignal.ticket); + if (isGuardedBefore) + { + // + // Now We Have to Check Signal Age growse required times to apply Guard Action again ... + // First Calculate Guard Grow Step ... + int ageGrowStep = mOldAge / 10; + + // + XProtectedSignal guardItem = Get(maxInDDSignal.ticket); + datetime lastGuardTime = 0; + if (GetLastItem(lastGuardTime, guardItem.time)) + { + // + int lastGuardIndex = iBarShift( + maxInDDSignal.symbol, + period, + lastGuardTime); + + // + canGuard = + MathAbs(lastGuardIndex) >= ageGrowStep; + } + } + else + { + // + // Check Signal age ... + canGuard = signalAge >= mOldAge; + } + } + + // + // Prevent Moving Forward ... + if (!canGuard) + { + // + result = false; + break; + } + + // + // Partial Close Max In Drawdown Trade ... + double volumeRate = GetGuardActionVolumeMultiplier(action); + + // + double volume = NormalizeVolume( + maxInDDSignal.volume * volumeRate, + maxInDDSignal.symbol); + + // + string commentPrefix = "Signal (" + (string)maxInDDSignal.ticket + ") Partial Closed (" + (string)volumeRate + ") by Guard"; + string comment = commentPrefix + " ..."; + + // + result = trader.ClosePartial( + maxInDDSignal.ticket, + volume, + comment); + if (result) + { + // + reasonString = + reasonString + + (reason == X_GUARDED_OLD + ? " (" + (string)signalAge + ")" + : " (" + (string)maxInDDSignal.profit + ")"); + + // + // Update Guarded Signals ... + if (isGuardedBefore) + { + // + XSignal tSignal = trader.GetSignal(maxInDDSignal.ticket); + + // + if (tSignal.ticket > 0 && tSignal.volume > 0) + { + // + // Update In Guardeds ... + Update(tSignal); + } + else + { + // + // Remove From Guardeds ... + Remove(tSignal.ticket); + } + } + else if (reason == X_GUARDED_OLD) + { + // + // Added to Guardeds ... + Add(maxInDDSignal); + } + + // + message = commentPrefix + reasonString + " ..."; + } + } + break; + + // + // Nothing ... + // Default ... + default: + message = "Max Allowed Drawdown Reached ..."; + break; + } + + // + result = StringLen(message) > 0; + if (!result) + { + return result; + } + + // + if (result) + { + // + if (reason == X_GUARDED_OLD) + { + // + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + AddItemToBuffer( + closed[i], + guardResult.olds); + } + } + + // + if (maxInDDSignal.ticket > 0) + { + AddItemToBuffer( + maxInDDSignal, + guardResult.olds); + } + } + else if (reason == X_GUARDED_CRITICAL) + { + // + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + AddItemToBuffer( + closed[i], + guardResult.criticals); + } + } + + // + if (maxInDDSignal.ticket > 0) + { + AddItemToBuffer( + maxInDDSignal, + guardResult.criticals); + } + } + else if (reason == X_GUARDED_MAX) + { + // + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + AddItemToBuffer( + closed[i], + guardResult.maxes); + } + } + + // + if (maxInDDSignal.ticket > 0) + { + AddItemToBuffer( + maxInDDSignal, + guardResult.maxes); + } + } + } + + // + return result; + } +}; + +// +// END Global Definitions: Variables, Properties and etc ... +// diff --git a/XEU5-0/Classes/x-saherelm.nn.lib.mq5 b/XEU5-0/Classes/x-saherelm.nn.lib.mq5 new file mode 100644 index 0000000..8fa40f5 --- /dev/null +++ b/XEU5-0/Classes/x-saherelm.nn.lib.mq5 @@ -0,0 +1,258 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 NN Class Library +// ---------------------------------------- +// Name: XNNClass +// Description: provides all classes for implementing +// Neural Network ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Global Definitions: Variables, Properties and etc ... +// +class XCNNBase +{ + // + // Public Definitions ... +public: + // + // Constructor ... + void XCNNBase( + int nodes = 10, // Number of Input Nodes + double starterWeight = 0.5, // start weight for each input + double coEfficient = 0.1, // COEfficient Multiplier + double upperRange = 1, // Upper Normal Range Value + double lowerRange = -1, // Lower Normal Range Value + double learningRates = 0.1 // Back Propagation Learning Rate + ) { + // + mNodes = nodes; + mUpperRange = upperRange; + mLowerRange = lowerRange; + mCoEfficient = coEfficient; + mLearningRates = learningRates; + mStarterWeight = starterWeight; + + // + ReConstructWeights(); + } + + // + // Deconstructor ... + void ~XCNNBase() {} + + // + // Protected Definitions ... + void NormalizeInputs(double &inputs[], double &result[]) + { + // + ArrayFree(result); + ArrayResize(result, 1); + + // + // Validate inputs ... + if (ArraySize(inputs) != mNodes) + { + return; + } + + // + // Prepare Result ... + ArrayResize(result, mNodes); + + // + // Calculating min and max range value ... + double minRangeValue = inputs[ArrayMinimum(inputs)]; + double maxRangeValue = inputs[ArrayMaximum(inputs)]; + + // + // Loop through Inputs nd Normalize them ... + for (int i = 0; i < mNodes; i++) + { + // + double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange; + result[i] = normalValue; + } + } + + // + // Hyperbolic Tangent Activation Function ... + double TanHActivationFunction(double weightedInputs) + { + // + double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs)); + return result; + } + + // + // Calculate Weighted Inputs ... + double CalculateWeightedInputs( + double &inputs[], + bool applyCOEfficient = true) + { + // + double result = 0; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) + { + // + result = -1; + return result; + } + + // + for (int i = 0; i < mNodes; i++) + { + result += inputs[i] * mWeights[i]; + } + + // + // Multiply if required ... + if (applyCOEfficient) + { + result *= mCoEfficient; + } + + // + return result; + } + + // + // Calculate Hidden Layers ... + virtual double CalculateHiddenLayer(double &inputs[]) + { + // + // this is Default Activation Function which used ... + // you can override this by writing your own ... + double totalWeightedInputs = CalculateWeightedInputs(inputs); + double result = TanHActivationFunction(totalWeightedInputs); + + // + return result; + } + + // + // Calculate Output Layers ... + double CalculateOutputLayer(double &inputs[]) + { + // + double result = -1; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return result; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return result; + } + + // + double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs); + + // + result = 1 * hiddenLayerResult; + + // + return result; + } + + // + // Basck Propaggation Learning ... + void BackPropagation( + double &inputs[], + double &outputs, + double targetOutput + ) { + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return; + } + + // + double error = targetOutput - outputs; + double derivative = 1 - MathPow(outputs, 2); + + // + for (int i = 0; i < mNodes; i++) { + // + double gradient = error * derivative * inputs[i]; + mWeights[i] = mLearningRates * gradient; + } + } + +protected: + // + // Private Definitions ... +private: + // + // Number of Input Nodes ... + int mNodes; + + // + // Specify Upper range of Normal Values ... + double mUpperRange; + + // + // Specify Lower range of Normal Values ... + double mLowerRange; + + // + // Starter Weight for each input node ... + double mStarterWeight; + + // + // double Input Node Weights ... + double mWeights[]; + + // + // CoEfficient is a multiplyer for weighted inputs ... + double mCoEfficient; + + // + // Back Propagation Learning Rates ... + double mLearningRates; + + // + // ReConstruct Weights ... + void ReConstructWeights() { + // + ArrayFree(mWeights); + ArrayResize(mWeights, mNodes); + + // + for (int i = 0; i< mNodes; i++) { + mWeights[i] = mStarterWeight; + } + } +} +// +// END Global Definitions: Variables, Properties and etc ... +// diff --git a/XEU5-0/Documents/.gitkeep b/XEU5-0/Documents/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Documents/Reports/.gitkeep b/XEU5-0/Documents/Reports/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Documents/Settings/.gitkeep b/XEU5-0/Documents/Settings/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Documents/Settings/xeu5ea.set b/XEU5-0/Documents/Settings/xeu5ea.set new file mode 100644 index 0000000..1c8b53c Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea.vbb.set b/XEU5-0/Documents/Settings/xeu5ea.vbb.set new file mode 100644 index 0000000..c657295 Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea.vbb.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea.vbd.set b/XEU5-0/Documents/Settings/xeu5ea.vbd.set new file mode 100644 index 0000000..dbd7ac8 Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea.vbd.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_just_xtam_and_xstfi.set b/XEU5-0/Documents/Settings/xeu5ea_just_xtam_and_xstfi.set new file mode 100644 index 0000000..3cec62f Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_just_xtam_and_xstfi.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_just_xtam_and_xstfi_xtam_signaller.set b/XEU5-0/Documents/Settings/xeu5ea_just_xtam_and_xstfi_xtam_signaller.set new file mode 100644 index 0000000..a2caf34 Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_just_xtam_and_xstfi_xtam_signaller.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller.final.set b/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller.final.set new file mode 100644 index 0000000..d459e7a Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller.final.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller_longs.final.set b/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller_longs.final.set new file mode 100644 index 0000000..5bb7081 Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller_longs.final.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller_shorts.final.set b/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller_shorts.final.set new file mode 100644 index 0000000..243aa1f Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_xtam_signaller_shorts.final.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller.final.set b/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller.final.set new file mode 100644 index 0000000..c5fadae Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller.final.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller_longs.final.set b/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller_longs.final.set new file mode 100644 index 0000000..d2b9f29 Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller_longs.final.set differ diff --git a/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller_shorts.final.set b/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller_shorts.final.set new file mode 100644 index 0000000..de350ab Binary files /dev/null and b/XEU5-0/Documents/Settings/xeu5ea_xtsfi_signaller_shorts.final.set differ diff --git a/XEU5-0/Documents/Settings/xts.tpl b/XEU5-0/Documents/Settings/xts.tpl new file mode 100644 index 0000000..f5487f1 Binary files /dev/null and b/XEU5-0/Documents/Settings/xts.tpl differ diff --git a/XEU5-0/Experts/.gitkeep b/XEU5-0/Experts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Experts/x-saherelm.xeu5.ea.ex5 b/XEU5-0/Experts/x-saherelm.xeu5.ea.ex5 new file mode 100644 index 0000000..dcacd44 Binary files /dev/null and b/XEU5-0/Experts/x-saherelm.xeu5.ea.ex5 differ diff --git a/XEU5-0/Experts/x-saherelm.xeu5.ea.mq5 b/XEU5-0/Experts/x-saherelm.xeu5.ea.mq5 new file mode 100644 index 0000000..8b925ae --- /dev/null +++ b/XEU5-0/Experts/x-saherelm.xeu5.ea.mq5 @@ -0,0 +1,347 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: XEU5EA +// Description: this is an expert controller +// advisors which provides a mechanism for use them ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XEU5 EA" +#property strict + +// +// START Inputs ... +// + +input group "Commons"; + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Alert Library ... +#include "../Libraries/x-saherelm.alert.lib.mq5" + +// +// Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// XEU5 Signal Provider ... +#include "../Providers/x-saherelm.xeu5.provider.lib.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +bool isXEU5NewHour; +bool isXEU5NewDay; +bool isXEU5NewWeek; +bool isXEU5NewMonth; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = "XEU5EA"; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Apply default Chart Style for EA ... + ApplyChartStyle(); + + // + // Reset Timings ... + ResetTiming(); + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize XEU5 Provider ... + if (!XEU5InitSignalProviderLibrary()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Initialize XEU5 Provider ... + XEU5DeinitSignalProviderLibrary(reason); + + // + // De Init XDraw Library ... + // OnDeinitDrawLibrary(); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Handle Monthly Alert ... + bool isFirstMonth = xMonth == -1; + isXEU5NewMonth = IsNewMonth(); + bool canMonthlyAlert = + isXEU5NewMonth && + xEU5EnableAlerts && + xEU5EnableMonthlyAlerts; + bool canMonthlyReport = + !isFirstMonth && + canMonthlyAlert && + xEU5EnableMonthlyReports; + if (canMonthlyAlert) + { + // + string message = "New Month ..."; + + // + // Prepare Monthly Report ... + if (canMonthlyReport) + { + // + string report = xEU5Reporter.GenerateReportString(XREPORT_MONTHLY); + + // + message = "Last Month Report:\n" + report; + } + + // + // Reset Report ... + xEU5Reporter.Reset(XREPORT_MONTHLY); + + // + SendAlert(message); + } + + // + // Handle Weekly Alert ... + bool isFirstWeek = xDayOfWeek == -1; + isXEU5NewWeek = IsNewWeek(); + bool canWeeklyAlert = + isXEU5NewWeek && + xEU5EnableAlerts && + xEU5EnableWeeklyAlerts; + bool canWeeklyReport = + !isFirstWeek && + canWeeklyAlert && + xEU5EnableWeeklyReports; + if (canWeeklyAlert) + { + // + string message = "New Week ..."; + + // + // Prepare Weekly Report ... + if (canWeeklyReport) + { + // + string report = xEU5Reporter.GenerateReportString(XREPORT_WEEKLY); + + // + message = "Last Week Report:\n" + report; + } + + // + // Reset Report ... + xEU5Reporter.Reset(XREPORT_WEEKLY); + + // + SendAlert(message); + } + + // + // Handle Daily Alert ... + bool isFirstDay = xDay == -1; + isXEU5NewDay = IsNewDay(); + bool canDailyAlert = + isXEU5NewDay && + xEU5EnableAlerts && + xEU5EnableDailyAlerts; + bool canDailyReport = + !isFirstDay && + canDailyAlert && + xEU5EnableDailyReports; + if (canDailyAlert) + { + // + string message = "New Day ..."; + + // + // Prepare Daily Report ... + if (canDailyReport) + { + // + string report = xEU5Reporter.GenerateReportString(XREPORT_DAILY); + + // + message = "Last Week Report:\n" + report; + } + + // + // Reset Report ... + xEU5Reporter.Reset(XREPORT_DAILY); + + // + SendAlert(message); + } + + // + // Handle Hourly Alert ... + bool isFirstHour = xHour == -1; + isXEU5NewHour = IsNewHour(); + bool canHourlyAlert = + isXEU5NewHour && + xEU5EnableAlerts && + xEU5EnableHourlyAlerts; + if (canHourlyAlert) + { + // + string message = "New Hour ..."; + + // + SendAlert(message); + } + + + // + // Prevent Going Forward if user Disable it ... + if (xEU5EnableProvider) + { + // + // Handle Processing on XEU5 Signal Provider ... + XEU5SignalProviderDoControlState(); + } + + // + if (!IsNewCandle()) + { + return; + } + + // + // Prevent Going Forward if user Disable it ... + if (xEU5EnableProvider) + { + // + // Handle Processing on XEU5 Signal Provider ... + XEU5SignalProviderHandleTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + + // + // Prevent Going Forward if user Disable it ... + if (xEU5EnableProvider) + { + // + // Handle Processing Trades on XEU5 Signal Provider ... + XEU5SignalProviderHandleTrade(); + } +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + + // + // Validate XEU5 Provider Inputs ... + result = XEU5ValidateInputs(); + if (!result) + { + return false; + } + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// END Functions ... +// diff --git a/XEU5-0/Helpers/.gitkeep b/XEU5-0/Helpers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 new file mode 100644 index 0000000..f565e41 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 @@ -0,0 +1,607 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAMA Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 1, + X_XAMA_BEARISH = -1, + X_XAMA_NEUTURAL = 0, +}; + +// +// XAMA Indicator Buffer Lines ... +enum ENUM_X_XAMA_BUFFER_LINES +{ + X_XAMA_MA_LINE = 0, + X_XAMA_MC_COLOR_LINE = 1, + X_XAMA_STATE_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XAMA Indicator"; + +// +// input int xAMALength = 18; // Market Length +// input int xAMAFastEMA = 2; // Fast EMA Period +// input int xAMASlowEMA = 30; // Slow EMA Period +// input int xAMAShift = 0; // Shift +// input ENUM_APPLIED_PRICE xAMAAppliedTo = PRICE_CLOSE; // Applied To + +// +// Configurations ... +int xAMALength = 18; // Market Length +int xAMAFastEMA = 2; // Fast EMA Period +int xAMASlowEMA = 30; // Slow EMA Period +int xAMAShift = 0; // Shift +ENUM_APPLIED_PRICE xAMAAppliedTo = PRICE_CLOSE; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xAMAHandler = INVALID_HANDLE; +double xAMAMaBuffer[]; +double xAMAStateBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XAMAValidateInputs() +{ + // + bool result = false; + + // + result = + xAMALength > 2 && + xAMAFastEMA < xAMALength && + xAMAFastEMA < xAMASlowEMA && + xAMAShift >= 0; + + // + if (!result) + { + // + LogMessage("XAMA Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XAMAInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Indicator Handlers ... + ResetLastError(); + + // + // XAMA Handler ... + ArraySetAsSeries(xAMAMaBuffer, true); + ArraySetAsSeries(xAMAStateBuffer, true); + xAMAHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xama.indicator", + // + // Inputs ... + xAMALength, + xAMAFastEMA, + xAMASlowEMA, + xAMAShift, + xAMAAppliedTo + // + ); + if (xAMAHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XAMA Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XAMAReleaseHandlers() +{ + IndicatorRelease(xAMAHandler); +} + +// +// Handle Reading Buffers ... +void XAMAReadBuffers( + int xAMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XAMA Ma Buffer ... + CopyBuffer( + xAMAHandler, + X_XAMA_MA_LINE, + 0, + xAMAItemsPerTick, + xAMAMaBuffer); + + // + // XAMA State Buffer ... + CopyBuffer( + xAMAHandler, + X_XAMA_STATE_LINE, + 0, + xAMAItemsPerTick, + xAMAStateBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XAMA Custom Functions ... +// + +// +// Check SC is Peak ... +bool XAMAIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xAMAMaBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XAMAIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xAMAMaBuffer + // + ); + + // + return result; +} + +// +// Check TM Crossed Up ... +bool XAMAIsStartBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] != X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Up After Neutural State ... +bool XAMAIsStartBullishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Up State ... +bool XAMAIsBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State ... +bool XAMAIsEndBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] != X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State By Neutural ... +bool XAMAIsEndBullishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down ... +bool XAMAIsStartBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] != X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down After Neutural State ... +bool XAMAIsStartBearishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Down State ... +bool XAMAIsBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State ... +bool XAMAIsEndBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] != X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State By Neutural ... +bool XAMAIsEndBearishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM In Neutural State ... +bool XAMAIsNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XAMAIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xAMAMaBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XAMA Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..d7071b4 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 @@ -0,0 +1,1032 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHLH Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// Cycles Enumeration ... +enum ENUM_X_XCHLH_CYCLES +{ + X_XCHLH_CYCLE_LONG, + X_XCHLH_CYCLE_MEDIUM, + X_XCHLH_CYCLE_SHORT, +}; + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// XCHLH Buffer Lines ... +enum ENUM_X_XCHLH_BUFFER_LINES +{ + X_XCHLH_LC_HH_LINE = 0, + X_XCHLH_LC_LL_LINE = 1, + X_XCHLH_MC_HH_LINE = 2, + X_XCHLH_MC_LL_LINE = 3, + X_XCHLH_SC_HH_LINE = 4, + X_XCHLH_SC_LL_LINE = 5, + X_XCHLH_SIGNAL_T_LINE = 6, + X_XCHLH_SIGNAL_B_LINE = 7, + X_XCHLH_HOT_STATE_LINE = 8, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// // +// input group "XCHLH Oscillator"; + +// // +// // Common ... +// input group "XCHLH Hot Areas"; +// input bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol +// input uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code +// input color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color +// input uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code +// input color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// // +// // LC Inputs ... +// input group "XCHLH Long Cycle"; +// input group "XCHLH LC Market"; +// input int xCHLHLcLength = 288; // Length +// input double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH LC Style"; +// input int xCHLHLcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHLcHHColor = clrAqua; // Highest High Color +// input color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color +// input group "XCHLH LC Drawings"; +// input bool xCHLHLcDrawHH = true; // Draw Highest High +// input bool xCHLHLcDrawLL = true; // Draw Lowest Low + +// // +// // MC Inputs ... +// input group "XCHLH Medium Cycle"; +// input group "XCHLH MC Market"; +// input int xCHLHMcLength = 72; // Length +// input double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH MC Style"; +// input int xCHLHMcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHMcHHColor = clrLime; // Highest High Color +// input color xCHLHMcLLColor = clrRed; // Lowest Low Color +// input group "XCHLH MC Drawings"; +// input bool xCHLHMcDrawHH = true; // Draw Highest High +// input bool xCHLHMcDrawLL = true; // Draw Lowest Low + +// // +// // SC Inputs ... +// input group "XCHLH Short Cycle"; +// input group "XCHLH SC Market"; +// input int xCHLHScLength = 7; // Length +// input double xCHLHScThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH SC Style"; +// input int xCHLHScDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHScHHColor = clrLightBlue; // Highest High Color +// input color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color +// input group "XCHLH SC Drawings"; +// input bool xCHLHScDrawHH = true; // Draw Highest High +// input bool xCHLHScDrawLL = true; // Draw Lowest Low + +// +// Configurations ... +// +// Common ... +bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol +uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code +color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color +uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code +color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +int xCHLHLcLength = 288; // Length +double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHLcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style +color xCHLHLcHHColor = clrAqua; // Highest High Color +color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color +bool xCHLHLcDrawHH = true; // Draw Highest High +bool xCHLHLcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +int xCHLHMcLength = 72; // Length +double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHMcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style +color xCHLHMcHHColor = clrLime; // Highest High Color +color xCHLHMcLLColor = clrRed; // Lowest Low Color +bool xCHLHMcDrawHH = true; // Draw Highest High +bool xCHLHMcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +int xCHLHScLength = 7; // Length +double xCHLHScThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHScDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style +color xCHLHScHHColor = clrLightBlue; // Highest High Color +color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color +bool xCHLHScDrawHH = true; // Draw Highest High +bool xCHLHScDrawLL = true; // Draw Lowest Low + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHLHHandler = INVALID_HANDLE; +double xCHLHLcHHBuffer[]; +double xCHLHLcLLBuffer[]; +double xCHLHMcHHBuffer[]; +double xCHLHMcLLBuffer[]; +double xCHLHScHHBuffer[]; +double xCHLHScLLBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XCHLHValidateInputs() +{ + // + bool result = false; + + // + result = + xCHLHScLength >= 2 && + xCHLHMcLength > xCHLHScLength && + xCHLHLcLength > xCHLHMcLength; + + // + if (!result) + { + // + LogMessage("XCHLH Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XCHLHInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHLH Handler ... + ArraySetAsSeries(xCHLHLcHHBuffer, true); + ArraySetAsSeries(xCHLHLcLLBuffer, true); + ArraySetAsSeries(xCHLHMcHHBuffer, true); + ArraySetAsSeries(xCHLHMcLLBuffer, true); + ArraySetAsSeries(xCHLHScHHBuffer, true); + ArraySetAsSeries(xCHLHScLLBuffer, true); + xCHLHHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchlh.oscillator", + // + // Inputs ... + // + // Commons ... + "", + xCHLHDrawHotAreas, + xCHLHHotHHArrowCode, + xCHLHHotHHArrowColor, + xCHLHHotLLArrowCode, + xCHLHHotLLArrowColor, + // + // LC ... + "", + "", + xCHLHLcLength, + xCHLHLcThresholdInPips, + xCHLHLcHHMode, + xCHLHLcLLMode, + "", + xCHLHLcDrawWidth, + xCHLHLcDrawType, + xCHLHLcDrawStyle, + xCHLHLcHHColor, + xCHLHLcLLColor, + "", + xCHLHLcDrawHH, + xCHLHLcDrawLL, + // + // MC ... + "", + "", + xCHLHMcLength, + xCHLHMcThresholdInPips, + xCHLHMcHHMode, + xCHLHMcLLMode, + "", + xCHLHMcDrawWidth, + xCHLHMcDrawType, + xCHLHMcDrawStyle, + xCHLHMcHHColor, + xCHLHMcLLColor, + "", + xCHLHMcDrawHH, + xCHLHMcDrawLL, + // + // SC ... + "", + "", + xCHLHScLength, + xCHLHScThresholdInPips, + xCHLHScHHMode, + xCHLHScLLMode, + "", + xCHLHScDrawWidth, + xCHLHScDrawType, + xCHLHScDrawStyle, + xCHLHScHHColor, + xCHLHScLLColor, + "", + xCHLHScDrawHH, + xCHLHScDrawLL); + if (xCHLHHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHLH Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHLHReleaseHandlers() +{ + IndicatorRelease(xCHLHHandler); +} + +// +// Handle Reading Buffers ... +void XCHLHReadBuffers( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHLH LC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcHHBuffer); + + // + // XCHLH LC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcLLBuffer); + + // + // XCHLH MC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcHHBuffer); + + // + // XCHLH MC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcLLBuffer); + + // + // XCHLH SC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScHHBuffer); + + // + // XCHLH SC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScLLBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XCHLH Custom Functions ... +// + +// +// Check LC and MC has Same HH ... +bool XCHLHIsLCMCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and MC has Same LL ... +bool XCHLHIsLCMCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and SC has Same HH ... +bool XCHLHIsLCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check LC and SC has Same LL ... +bool XCHLHIsLCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same HH ... +bool XCHLHIsMCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same LL ... +bool XCHLHIsMCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check Is Same Highest Highs ... +bool XCHLHIsSameHHs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check Is Same Lowest Lows ... +bool XCHLHIsSameLLs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check Medium Cycle is On Top of Long Cycle's Mid ... +bool XCHLHIsMCOnTopOfLC( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + ENUM_X_XCHLH_CYCLES sCycle = X_XCHLH_CYCLE_MEDIUM; + ENUM_X_XCHLH_CYCLES dCycle = X_XCHLH_CYCLE_LONG; + + // + result = + // + XCHLHCheckCycleIsOnTopOfAnother( + bar_index, + sCycle, + dCycle) + // + ; + + // + return result; +} + +// +// Check Medium Cycle is In Bottom of Long Cycle's Mid ... +bool XCHLHIsMCInBottomOfLC( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + ENUM_X_XCHLH_CYCLES sCycle = X_XCHLH_CYCLE_MEDIUM; + ENUM_X_XCHLH_CYCLES dCycle = X_XCHLH_CYCLE_LONG; + + // + result = + // + XCHLHCheckCycleIsInBottomOfAnother( + bar_index, + sCycle, + dCycle) + // + ; + + // + return result; +} + +// +// Check and Validate Buffer Sizes ... +bool XCHLHIsValidBufferSizes( + int size // Specified Min Size +) +{ + // + bool result = false; + + // + result = + // + ArraySize(xCHLHLcHHBuffer) > size && + ArraySize(xCHLHLcLLBuffer) > size && + // + ArraySize(xCHLHMcHHBuffer) > size && + ArraySize(xCHLHMcLLBuffer) > size && + // + ArraySize(xCHLHScHHBuffer) > size && + ArraySize(xCHLHScLLBuffer) > size; + + // + return result; +} + +// +// Get Cycle Middle Value ... +double XCHLHGetCycleMid( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Cycle Max Value ... + double iMax = XCHLHGetCycleMax( + bar_index, + cycle); + + // + // Retrieve Cycle Min Value ... + double iMin = XCHLHGetCycleMin( + bar_index, + cycle); + + // + result = (iMax - iMin) / 2; + + // + return result; +} + +// +// Get Cycle Max Value ... +double XCHLHGetCycleMax( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + // Long Cycle ... + case X_XCHLH_CYCLE_LONG: + result = xCHLHLcHHBuffer[1]; + break; + + // + // Medium Cycle ... + case X_XCHLH_CYCLE_MEDIUM: + result = xCHLHMcHHBuffer[1]; + break; + + // + // Short Cycle ... + case X_XCHLH_CYCLE_SHORT: + result = xCHLHScHHBuffer[1]; + break; + } + + // + return result; +} + +// +// Get Specified Cycles Max Value ... +double XCHLHGetCyclesMax( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES &cycles[] // Specified Cycle ... +) +{ + // + bool result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + ArraySize(cycles) <= 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycles); i++) + { + // + ENUM_X_XCHLH_CYCLES iCycle = cycles[i]; + + // + double iValue = XCHLHGetCycleMax( + bar_index, + iCycle); + + // + result = result == 0 || result < iValue ? iValue : result; + } + + // + return result; +} + +// +// Get Cycle Min Value ... +double XCHLHGetCycleMin( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + // Long Cycle ... + case X_XCHLH_CYCLE_LONG: + result = xCHLHLcLLBuffer[1]; + break; + + // + // Medium Cycle ... + case X_XCHLH_CYCLE_MEDIUM: + result = xCHLHMcLLBuffer[1]; + break; + + // + // Short Cycle ... + case X_XCHLH_CYCLE_SHORT: + result = xCHLHScLLBuffer[1]; + break; + } + + // + return result; +} + +// +// Get Specified Cycles Min Value ... +double XCHLHGetCyclesMin( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES &cycles[] // Specified Cycle ... +) +{ + // + bool result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + ArraySize(cycles) <= 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycles); i++) + { + // + ENUM_X_XCHLH_CYCLES iCycle = cycles[i]; + + // + double iValue = XCHLHGetCycleMin( + bar_index, + iCycle); + + // + result = result == 0 || result > iValue ? iValue : result; + } + + // + return result; +} + +// +// Check a Cycle is On Top of Another Cycle's Mid ... +bool XCHLHCheckCycleIsOnTopOfAnother( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES sourceCycle, // Specified Source Cycle which Checks ... + ENUM_X_XCHLH_CYCLES destCycle // Specified Dest Cycle which source Checked based on it ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Min Value of Source Cycle ... + double iMin = XCHLHGetCycleMin( + bar_index, + sourceCycle); + + // + // Retrieve Mid Value of Dest Cycle ... + double iMid = XCHLHGetCycleMid( + bar_index, + destCycle); + + // + // Generate Result ... + result = + // + iMin >= iMid + // + ; + + // + return result; +} + +// +// Check a Cycle is Under Bottom of Another Cycle's Mid ... +bool XCHLHCheckCycleIsInBottomOfAnother( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES sourceCycle, // Specified Source Cycle which Checks ... + ENUM_X_XCHLH_CYCLES destCycle // Specified Dest Cycle which source Checked based on it ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Max Value of Source Cycle ... + double iMax = XCHLHGetCycleMax( + bar_index, + sourceCycle); + + // + // Retrieve Mid Value of Dest Cycle ... + double iMid = XCHLHGetCycleMid( + bar_index, + destCycle); + + // + // Generate Result ... + result = + // + iMax <= iMid + // + ; + + // + return result; +} + +// +// END XCHLH Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..e84d762 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 @@ -0,0 +1,2229 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHMA Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XCHMA Cycles ... +enum ENUM_XCHMA_CYCLES +{ + X_XCHMA_CYCLE_LONG, + X_XCHMA_CYCLE_MEDIUM, + X_XCHMA_CYCLE_SHORT, +}; + +// +// XCHMA Oscillator Hot State Presentation ... +enum ENUM_XCHMA_HOT_STATES +{ + X_XCHMA_HOT_BULLISH = 1, + X_XCHMA_HOT_NEUTURAL = 0, + X_XCHMA_HOT_BEARISH = -1, +}; + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; + +// +// XCHMA Oscillator Buffer Lines ... +enum ENUM_X_XCHMA_BUFFER_LINES +{ + X_XCHMA_LC_FAST_LINE = 0, + X_XCHMA_LC_SLOW_LINE = 1, + X_XCHMA_LC_STATE_LINE = 6, + X_XCHMA_MC_FAST_LINE = 2, + X_XCHMA_MC_SLOW_LINE = 3, + X_XCHMA_MC_STATE_LINE = 7, + X_XCHMA_SC_FAST_LINE = 4, + X_XCHMA_SC_SLOW_LINE = 5, + X_XCHMA_SC_STATE_LINE = 8, + X_XCHMA_HOT_STATE_LINE = 9, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XCHMA Oscillator"; + +// // +// // Commons ... +// input group "XCHMA Hot Areas"; +// input bool xCHMADrawHotAreas = false; // Draw Hot Areas Symbol; +// input uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code; +// input color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color; +// input uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code; +// input color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color; + +// // +// // LC Inputs ... +// input group "XCHMA Long Cycle"; +// input group "XCHMA LC Market"; +// input int xCHMALcFastLength = 288; // Fast Length +// input int xCHMALcSlowLength = 576; // Slow Length +// input ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA LC Style"; +// input int xCHMALcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHMALcFastColor = clrAqua; // Fast Color +// input color xCHMALcSlowColor = clrFuchsia; // Slow Color +// input group "XCHMA LC Drawings"; +// input bool xCHMALcDrawFast = true; // Draw Fast +// input bool xCHMALcDrawSlow = true; // Draw Slow +// input bool xCHMALcDrawCrosses = false; // Draw Cross Lines + +// // +// // MC Inputs ... +// input group "XCHMA Medium Cycle"; +// input group "XCHMA MC Market"; +// input int xCHMAMcFastLength = 72; // Fast Length +// input int xCHMAMcSlowLength = 144; // Slow Length +// input ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA MC Style"; +// input int xCHMAMcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHMAMcFastColor = clrLime; // Fast Color +// input color xCHMAMcSlowColor = clrRed; // Slow Color +// input group "XCHMA MC Drawings"; +// input bool xCHMAMcDrawFast = true; // Draw Fast +// input bool xCHMAMcDrawSlow = true; // Draw Slow +// input bool xCHMAMcDrawCrosses = false; // Draw Cross Lines + +// // +// // SC Inputs ... +// input group "XCHMA Short Cycle"; +// input group "XCHMA SC Market"; +// input int xCHMAScFastLength = 7; // Fast Length +// input int xCHMAScSlowLength = 14; // Slow Length +// input ENUM_MA_METHOD xCHMAScMethod = MODE_SMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA SC Style"; +// input int xCHMAScDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style +// input color xCHMAScFastColor = clrLightBlue; // Fast Color +// input color xCHMAScSlowColor = clrLightSalmon; // Slow Color +// input group "XCHMA SC Drawings"; +// input bool xCHMAScDrawFast = true; // Draw Fast +// input bool xCHMAScDrawSlow = true; // Draw Slow +// input bool xCHMAScDrawCrosses = false; // Draw Cross Lines + +// +// Configurations ... +// +// Commons ... +bool xCHMADrawHotAreas = false; // Draw Hot Areas Symbol; +uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code; +color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color; +uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code; +color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color; + +// +// LC Inputs ... +int xCHMALcFastLength = 288; // Fast Length +int xCHMALcSlowLength = 576; // Slow Length +ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To +int xCHMALcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style +color xCHMALcFastColor = clrAqua; // Fast Color +color xCHMALcSlowColor = clrFuchsia; // Slow Color +bool xCHMALcDrawFast = true; // Draw Fast +bool xCHMALcDrawSlow = true; // Draw Slow +bool xCHMALcDrawCrosses = false; // Draw Cross Lines + +// +// MC Inputs ... +int xCHMAMcFastLength = 72; // Fast Length +int xCHMAMcSlowLength = 144; // Slow Length +ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To +int xCHMAMcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style +color xCHMAMcFastColor = clrLime; // Fast Color +color xCHMAMcSlowColor = clrRed; // Slow Color +bool xCHMAMcDrawFast = true; // Draw Fast +bool xCHMAMcDrawSlow = true; // Draw Slow +bool xCHMAMcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +int xCHMAScFastLength = 7; // Fast Length +int xCHMAScSlowLength = 14; // Slow Length +ENUM_MA_METHOD xCHMAScMethod = MODE_SMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To +int xCHMAScDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style +color xCHMAScFastColor = clrLightBlue; // Fast Color +color xCHMAScSlowColor = clrLightSalmon; // Slow Color +bool xCHMAScDrawFast = true; // Draw Fast +bool xCHMAScDrawSlow = true; // Draw Slow +bool xCHMAScDrawCrosses = false; // Draw Cross Lines + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHMAHandler = INVALID_HANDLE; +double xCHMALcFastBuffer[]; +double xCHMALcSlowBuffer[]; +double xCHMAMcFastBuffer[]; +double xCHMAMcSlowBuffer[]; +double xCHMAScFastBuffer[]; +double xCHMAScSlowBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XCHMAValidateInputs() +{ + // + bool result = false; + + // + result = + xCHMAScFastLength >= 2 && + xCHMAScSlowLength > xCHMAScFastLength && + xCHMAMcFastLength > xCHMAScSlowLength && + xCHMAMcSlowLength > xCHMAMcFastLength && + xCHMALcFastLength > xCHMAMcSlowLength && + xCHMALcSlowLength > xCHMALcFastLength; + + // + if (!result) + { + // + LogMessage("XCHMA Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XCHMAInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHMA Handler ... + ArraySetAsSeries(xCHMALcFastBuffer, true); + ArraySetAsSeries(xCHMALcSlowBuffer, true); + ArraySetAsSeries(xCHMAMcFastBuffer, true); + ArraySetAsSeries(xCHMAMcSlowBuffer, true); + ArraySetAsSeries(xCHMAScFastBuffer, true); + ArraySetAsSeries(xCHMAScSlowBuffer, true); + xCHMAHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchma.oscillator", + // + // Inputs ... + "", + xCHMADrawHotAreas, + xCHMAHotBullishArrowCode, + xCHMAHotBullishArrowColor, + xCHMAHotBearishArrowCode, + xCHMAHotBearishArrowColor, + // + // Long Cycle ... + "", + "", + xCHMALcFastLength, + xCHMALcSlowLength, + xCHMALcMethod, + xCHMALcAppliedTo, + "", + xCHMALcDrawWidth, + xCHMALcDrawType, + xCHMALcDrawStyle, + xCHMALcFastColor, + xCHMALcSlowColor, + "", + xCHMALcDrawFast, + xCHMALcDrawSlow, + xCHMALcDrawCrosses, + // + // Medium Cycle ... + "", + "", + xCHMAMcFastLength, + xCHMAMcSlowLength, + xCHMAMcMethod, + xCHMAMcAppliedTo, + "", + xCHMAMcDrawWidth, + xCHMAMcDrawType, + xCHMAMcDrawStyle, + xCHMAMcFastColor, + xCHMAMcSlowColor, + "", + xCHMAMcDrawFast, + xCHMAMcDrawSlow, + xCHMAMcDrawCrosses, + // + // Short Cycle ... + "", + "", + xCHMAScFastLength, + xCHMAScSlowLength, + xCHMAScMethod, + xCHMAScAppliedTo, + "", + xCHMAScDrawWidth, + xCHMAScDrawType, + xCHMAScDrawStyle, + xCHMAScFastColor, + xCHMAScSlowColor, + "", + xCHMAScDrawFast, + xCHMAScDrawSlow, + xCHMAScDrawCrosses); + if (xCHMAHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHMA Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHMAReleaseHandlers() +{ + IndicatorRelease(xCHMAHandler); +} + +// +// Handle Reading Buffers ... +void XCHMAReadBuffers( + int xCHMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHMA Long Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcSlowBuffer); + + // + // XCHMA Medium Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcSlowBuffer); + + // + // XCHMA Short Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScSlowBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XCHMA Custom Functions ... +// + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMax( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // SC Fast ... + result = MathMax( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMax( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMax( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMax( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMax( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMax( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMin( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = xCHMAScFastBuffer[bar_index]; + + // + // SC Fast ... + result = MathMin( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMin( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMin( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMin( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMin( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMin( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Short Cycle Over Max Of Cycle Channels ... +bool XCHMAIsSCOverMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 > nonOfShortCycleMax1 + // + ; + + // + return result; +} + +// +// Short Cycle Under Max Of Cycle Channels ... +bool XCHMAIsSCUnderMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 < nonOfShortCycleMax1 + // + ; + + // + return result; +} + +// +// Short Cycle Over Min Of Cycle Channels ... +bool XCHMAIsSCOverMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 > nonOfShortCycleMin1 + // + ; + + // + return result; +} + +// +// Short Cycle Under Min Of Cycle Channels ... +bool XCHMAIsSCUnderMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 < nonOfShortCycleMin1 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Over Max Of Cycle Channels ... +bool XCHMAIsSCCrossedOverMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMin2 = XCHMAGetCycleMinValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + double nonOfShortCycleMax2 = XCHMAGetCyclesMaxValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 > nonOfShortCycleMax1 && + shortCycleMin2 <= nonOfShortCycleMax2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Under Max Of Cycle Channels ... +bool XCHMAIsSCCrossedUnderMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMax2 = XCHMAGetCycleMaxValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + double nonOfShortCycleMax2 = XCHMAGetCyclesMaxValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 < nonOfShortCycleMax1 && + shortCycleMax2 >= nonOfShortCycleMax2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Over Min Of Cycle Channels ... +bool XCHMAIsSCCrossedOverMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMin2 = XCHMAGetCycleMinValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + double nonOfShortCycleMin2 = XCHMAGetCyclesMinValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 > nonOfShortCycleMin1 && + shortCycleMin2 <= nonOfShortCycleMin2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Under Min Of Cycle Channels ... +bool XCHMAIsSCCrossedUnderMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMax2 = XCHMAGetCycleMaxValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + double nonOfShortCycleMin2 = XCHMAGetCyclesMinValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 < nonOfShortCycleMin1 && + shortCycleMax2 >= nonOfShortCycleMin2 + // + ; + + // + return result; +} + +// +// Long Cycle ... +// + +// +// Check LC is Peak ... +bool XCHMAIsLCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMALcSlowBuffer + // + ); + + // + return result; +} + +// +// Check LC is Vale ... +bool XCHMAIsLCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMALcSlowBuffer + // + ); + + // + return result; +} + +// +// Check LC Fast Crossed Over Slow ... +bool XCHMAIsLCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Over Slow ... +bool XCHMAIsLCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Crossed Under Slow ... +bool XCHMAIsLCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Under Slow ... +bool XCHMAIsLCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get Trend Power ... +double XCHMAGetLCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMALcFastBuffer[bar_index] - xCHMALcSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsLCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetLCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetLCTrendPower(i + 1); + double iTrend = XCHMAGetLCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsLCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetLCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetLCTrendPower(i + 1); + double iTrend = XCHMAGetLCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Medium Cycle ... +// + +// +// Check MC is Peak ... +bool XCHMAIsMCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMAMcSlowBuffer + // + ); + + // + return result; +} + +// +// Check MC is Vale ... +bool XCHMAIsMCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMAMcSlowBuffer + // + ); + + // + return result; +} + +// +// Check MC Fast Crossed Over Slow ... +bool XCHMAIsMCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Over Slow ... +bool XCHMAIsMCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Crossed Under Slow ... +bool XCHMAIsMCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Under Slow ... +bool XCHMAIsMCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get Trend Power ... +double XCHMAGetMCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMAMcFastBuffer[bar_index] - xCHMAMcSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsMCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetMCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetMCTrendPower(i + 1); + double iTrend = XCHMAGetMCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsMCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetMCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetMCTrendPower(i + 1); + double iTrend = XCHMAGetMCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Short Cycle ... +// + +// +// Check SC is Peak ... +bool XCHMAIsSCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMAScSlowBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XCHMAIsSCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMAScSlowBuffer + // + ); + + // + return result; +} + +// +// Check SC Fast Crossed Over Slow ... +bool XCHMAIsSCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Over Slow ... +bool XCHMAIsSCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Crossed Under Slow ... +bool XCHMAIsSCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Under Slow ... +bool XCHMAIsSCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get SC Trend Power ... +double XCHMAGetSCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMAScFastBuffer[bar_index] - xCHMAScSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check SC Trends Up ... +bool XCHMAIsSCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetSCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetSCTrendPower(i + 1); + double iTrend = XCHMAGetSCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check SC Trends Down ... +bool XCHMAIsSCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetSCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetSCTrendPower(i + 1); + double iTrend = XCHMAGetSCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Utility Functions ... +// + +// +// Check a Cycle is Over of Another ... +bool XCHMAIsCycleOverAnother( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES sourceCycle, // Specified Cycle ... + ENUM_XCHMA_CYCLES destCycle // Specified Cycle ... +) +{ + // + bool result = false; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceMinValue = XCHMAGetCycleMinValue(bar_index, sourceCycle); + double destMaxValue = XCHMAGetCycleMaxValue(bar_index, destCycle); + + // + result = + // + sourceMinValue > destMaxValue + // + ; + + // + return result; +} + +// +// Check a Cycle is Under of Another ... +bool XCHMAIsCycleUnderAnother( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES sourceCycle, // Specified Cycle ... + ENUM_XCHMA_CYCLES destCycle // Specified Cycle ... +) +{ + // + bool result = false; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceMaxValue = XCHMAGetCycleMaxValue(bar_index, sourceCycle); + double destMinValue = XCHMAGetCycleMinValue(bar_index, destCycle); + + // + result = + // + sourceMaxValue < destMinValue + // + ; + + // + return result; +} + +// +// Get Cycle Min Value ... +double XCHMAGetCycleMinValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = MathMin( + xCHMALcFastBuffer[bar_index], + xCHMALcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = MathMin( + xCHMAMcFastBuffer[bar_index], + xCHMAMcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = MathMin( + xCHMAScFastBuffer[bar_index], + xCHMAScSlowBuffer[bar_index]); + break; + } + + // + return result; +} + +// +// Get Cycles Min Value ... +double XCHMAGetCyclesMinValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES &cycle[] // Specified Cycles ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + // + bar_index <= 0 || + ArraySize(cycle) <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1) + // + ) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycle); i++) + { + // + ENUM_XCHMA_CYCLES iCycle = cycle[i]; + double iValue = XCHMAGetCycleMinValue( + bar_index, + iCycle); + + // + result = result == 0 || result > iValue ? iValue : result; + } + + // + return result; +} + +// +// Get Cycle Max Value ... +double XCHMAGetCycleMaxValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = MathMax( + xCHMALcFastBuffer[bar_index], + xCHMALcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = MathMax( + xCHMAMcFastBuffer[bar_index], + xCHMAMcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = MathMax( + xCHMAScFastBuffer[bar_index], + xCHMAScSlowBuffer[bar_index]); + break; + } + + // + return result; +} + +// +// Get Cycles Max Value ... +double XCHMAGetCyclesMaxValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES &cycle[] // Specified Cycles ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + // + bar_index <= 0 || + ArraySize(cycle) <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1) + // + ) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycle); i++) + { + // + ENUM_XCHMA_CYCLES iCycle = cycle[i]; + double iValue = XCHMAGetCycleMaxValue( + bar_index, + iCycle); + + // + result = result == 0 || result < iValue ? iValue : result; + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XCHMAIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xCHMALcFastBuffer) < size || + ArraySize(xCHMALcSlowBuffer) < size || + // + ArraySize(xCHMAMcFastBuffer) < size || + ArraySize(xCHMAMcSlowBuffer) < size || + // + ArraySize(xCHMAScFastBuffer) < size || + ArraySize(xCHMAScSlowBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Add Specified Object to it's correspond Buffer ... +void Add( + ENUM_XCHMA_CYCLES item, + ENUM_XCHMA_CYCLES &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// END XCHMA Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..19d3417 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 @@ -0,0 +1,358 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XFI Oscillator"; + +// // +// input int xFILength = 18; // Market Length +// input ENUM_MA_METHOD xFIMethod = MODE_SMA; // MA Method +// input ENUM_APPLIED_VOLUME xFIAppliedTo = VOLUME_TICK; // Applied To + +// +// Configurations ... +int xFILength = 18; // Market Length +ENUM_MA_METHOD xFIMethod = MODE_SMA; // MA Method +ENUM_APPLIED_VOLUME xFIAppliedTo = VOLUME_TICK; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xFIHandler = INVALID_HANDLE; +double xFIBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XFIValidateInputs() +{ + // + bool result = false; + + // + result = xFILength > 2; + + // + if (!result) + { + // + LogMessage("XFI Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XFIInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XFI Handler ... + ArraySetAsSeries(xFIBuffer, true); + xFIHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xfi.oscillator", + // + // Inputs ... + xFILength, + xFIMethod, + xFIAppliedTo + // + ); + if (xFIHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XFI Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XFIReleaseHandlers() +{ + IndicatorRelease(xFIHandler); +} + +// +// Handle Reading Buffers ... +void XFIReadBuffers( + int xFIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XFI Signal ... + CopyBuffer( + xFIHandler, + 0, + 0, + xFIItemsPerTick, + xFIBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XFI Custom Functions ... +// + +// +// Check SC is Peak ... +bool XFIIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XFIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xFIBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XFIIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XFIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xFIBuffer + // + ); + + // + return result; +} + +// +// Detect XFI Crossed Over Zero ... +bool XFIIsCrossedOverZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] > 0 && + xFIBuffer[bar_index + 1] <= 0; + + // + return result; +} + +// +// Detect XFI Over Zero ... +bool XFIIsOverZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] > 0; + + // + return result; +} + +// +// Detect XFI Crossed Under Zero ... +bool XFIIsCrossedUnderZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] < 0 && + xFIBuffer[bar_index + 1] >= 0; + + // + return result; +} + +// +// Detect XFI Under Zero ... +bool XFIIsUnderZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] < 0; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XFIIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xFIBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XFI Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 new file mode 100644 index 0000000..e6a92f6 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 @@ -0,0 +1,668 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XLH Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XLH Indicator Buffer Lines ... +enum ENUM_X_XLH_BUFFER_LINES +{ + X_XLH_HH_LINE = 0, + X_XLH_LL_LINE = 1, + X_XLH_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XLH Indicator"; + +// input int xLHLength = 72; // Length +// input ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method + +// +// Configurations ... +int xLHLength = 72; // Length +ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +// +int xLHHandler = INVALID_HANDLE; + +// +double xLHHHBuffer[]; +double xLHLLBuffer[]; +double xLHSignalBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XLHValidateInputs() +{ + // + bool result = false; + + // + result = xLHLength >= 2; + + // + if (!result) + { + // + LogMessage("XLH Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XLHInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XLH Handler ... + ArraySetAsSeries(xLHHHBuffer, true); + ArraySetAsSeries(xLHLLBuffer, true); + ArraySetAsSeries(xLHSignalBuffer, true); + + // + xLHHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xlh.indicator", + // + // Inputs ... + xLHLength, + xLHHHMode, + xLHLLMode + // + ); + if (xLHHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XLH Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XLHReleaseHandlers() +{ + IndicatorRelease(xLHHandler); +} + +// +// Handle Reading Buffers ... +void XLHReadBuffers( + int xLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // HH Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_HH_LINE, + 0, + xLHItemsPerTick, + xLHHHBuffer + // + ); + + // + // LL Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_LL_LINE, + 0, + xLHItemsPerTick, + xLHLLBuffer + // + ); + + // + // Signal Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_SIGNAL_LINE, + 0, + xLHItemsPerTick, + xLHSignalBuffer + // + ); +} + +// +// END Handler Funcions ... +// + +// +// START XLH Custom Functions ... +// + +// +// TODO: What we have to Implement ... +// - [] + +// +// Check Candle High is HH ... +bool XLHIsHighAttachedHH( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle = GetCandle(bar_index); + + // + result = + // + candle.high == xLHHHBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Candle Low is LL ... +bool XLHIsLowAttachedLL( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle = GetCandle(bar_index); + + // + result = + // + candle.low == xLHLLBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Jumping Up Signal ... +bool XLHIsPriceCrossedOverSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + XOHCL candle2 = GetCandle(bar_index + 1); + + // + result = + // + candle1.low > xLHSignalBuffer[bar_index] && + candle2.low < xLHSignalBuffer[bar_index + 1] + // + ; + + // + return result; +} + +// +// Check Price Over Signal ... +bool XLHIsPriceOverSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.low > xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Jumping Down Signal ... +bool XLHIsPriceCrossedUnderSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + XOHCL candle2 = GetCandle(bar_index + 1); + + // + result = + // + candle1.high < xLHSignalBuffer[bar_index] && + candle2.high > xLHSignalBuffer[bar_index + 1] + // + ; + + // + return result; +} + +// +// Check Price Down Signal ... +bool XLHIsPriceUnderSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.high < xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Ranging Signal ... +bool XLHIsPriceInSignalRange( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.high > xLHSignalBuffer[bar_index] && + candle1.low < xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check HH Increased ... +bool XLHIsHHIncreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xLHHHBuffer + // + ); + + // + return result; +} + +// +// Check HH Decreased ... +bool XLHIsHHDecreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xLHHHBuffer + // + ); + + // + return result; +} + +// +// Check LL Increased ... +bool XLHIsLLIncreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xLHLLBuffer + // + ); + + // + return result; +} + +// +// Check LL Decreased ... +bool XLHIsLLDecreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xLHLLBuffer + // + ); + + // + return result; +} + +// +// Check HH Same in Length ... +bool XLHIsHHSameInLength( + int bar_index, // Specified Index ... + int length = 5 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + double value1 = xLHHHBuffer[bar_index]; + + // + // Loop ... + result = true; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iValue = xLHHHBuffer[i]; + if (iValue != value1) + { + // + result = false; + + // + break; + } + } + + // + return result; +} + +// +// Check LL Same in Length ... +bool XLHIsLLSameInLength( + int bar_index, // Specified Index ... + int length = 5 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + double value1 = xLHLLBuffer[bar_index]; + + // + // Loop ... + result = true; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iValue = xLHLLBuffer[i]; + if (iValue != value1) + { + // + result = false; + + // + break; + } + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XLHIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xLHHHBuffer) < size || + ArraySize(xLHLLBuffer) < size || + ArraySize(xLHSignalBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XLH Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 new file mode 100644 index 0000000..f90f15b --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 @@ -0,0 +1,249 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XOBD Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XOBD Indicator"; + +// input int xOBDLength = 5; // Swing Length +// input uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code +// input color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color +// input uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code +// input color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color + +// +// Configurations ... +int xOBDLength = 5; // Swing Length +uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code +color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color +uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code +color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +// +int xOBDHandler = INVALID_HANDLE; + +// +double xOBDBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XOBDValidateInputs() +{ + // + bool result = false; + + // + result = xOBDLength >= 2; + + // + if (!result) + { + // + LogMessage("XOBD Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XOBDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XOBD Handler ... + ArraySetAsSeries(xOBDBuffer, true); + + // + xOBDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xobd.indicator", + // + // Inputs ... + xOBDLength, + xOBDSwingHighArrowCode, + xOBDSwingHighArrowColor, + xOBDSwingLowArrowCode, + xOBDSwingLowArrowColor + // + ); + if (xOBDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XOBD Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XOBDReleaseHandlers() +{ + IndicatorRelease(xOBDHandler); +} + +// +// Handle Reading Buffers ... +void XOBDReadBuffers( + int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // OBD Buffer ... + CopyBuffer( + xOBDHandler, + 0, + 0, + xOBDItemsPerTick, + xOBDBuffer + // + ); +} + +// +// END Handler Funcions ... +// + +// +// START XOBD Custom Functions ... +// + +// +// Check is Swing Low Occured or not ... +bool XOBDIsSwingLow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = xOBDBuffer[bar_index] == X_SWING_LOW; + + // + return result; +} + +// +// Check is Swing High Occured or not ... +bool XOBDIsSwingHigh( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = xOBDBuffer[bar_index] == X_SWING_HIGH; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XOBDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xOBDBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XOBD Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..e6971b7 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 @@ -0,0 +1,433 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XRSI Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XRSI Oscillator Buffer Lines ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XRSI Oscillator"; + +// // +// input group "XRSI Market"; +// input int xRSILength = 18; // Market Length +// input ENUM_APPLIED_PRICE xRSIAppliedTo = PRICE_OPEN; // Applied To + +// // +// input group "XRSI Short Entry"; +// input double xRSIShortEntryValue = 70; // Short Entry Level +// input color xRSIShortEntryColor = clrRed; // Short Entry Level Color +// input ENUM_LINE_STYLE xRSIShortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// // +// input group "XRSI Short Exit"; +// input double xRSIShortExitValue = 40; // Short Exit Level +// input color xRSIShortExitColor = clrRed; // Short Exit Level Color +// input ENUM_LINE_STYLE xRSIShortExitLineStyle = STYLE_DOT; // Short Exit Style + +// // +// input group "XRSI Long Entry"; +// input double xRSILongEntryValue = 30; // Long Entry Level +// input color xRSILongEntryColor = clrRed; // Long Entry Level Color +// input ENUM_LINE_STYLE xRSILongEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// // +// input group "XRSI Long Exit"; +// input double xRSILongExitValue = 60; // Long Exit Level +// input color xRSILongExitColor = clrRed; // Long Exit Level Color +// input ENUM_LINE_STYLE xRSILongExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// Configurations ... +int xRSILength = 18; // Market Length +ENUM_APPLIED_PRICE xRSIAppliedTo = PRICE_OPEN; // Applied To + +// +double xRSIShortEntryValue = 70; // Short Entry Level +color xRSIShortEntryColor = clrRed; // Short Entry Level Color +ENUM_LINE_STYLE xRSIShortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// +double xRSIShortExitValue = 40; // Short Exit Level +color xRSIShortExitColor = clrRed; // Short Exit Level Color +ENUM_LINE_STYLE xRSIShortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +double xRSILongEntryValue = 30; // Long Entry Level +color xRSILongEntryColor = clrRed; // Long Entry Level Color +ENUM_LINE_STYLE xRSILongEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// +double xRSILongExitValue = 60; // Long Exit Level +color xRSILongExitColor = clrRed; // Long Exit Level Color +ENUM_LINE_STYLE xRSILongExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xRSIHandler = INVALID_HANDLE; +double xRSIBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XRSIValidateInputs() +{ + // + bool result = false; + + // + result = + xRSILongEntryValue < xRSILongExitValue && + xRSIShortEntryValue > xRSIShortExitValue && + xRSIShortEntryValue > xRSILongExitValue && + xRSIShortExitValue < xRSILongExitValue; + + // + if (!result) + { + // + LogMessage("XRSI Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XRSIInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XRSI Handler ... + ArraySetAsSeries(xRSIBuffer, true); + xRSIHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xrsi.oscillator", + // + // Inputs ... + // + // Market ... + "", + xRSILength, + xRSIAppliedTo, + // + // Short Entry ... + "", + xRSIShortEntryValue, + xRSIShortEntryColor, + xRSIShortEntryLineStyle, + // + // Short Exit ... + "", + xRSIShortExitValue, + xRSIShortExitColor, + xRSIShortExitLineStyle, + // + // Long Entry ... + "", + xRSILongEntryValue, + xRSILongEntryColor, + xRSILongEntryLineStyle, + // + // Long Exit ... + "", + xRSILongExitValue, + xRSILongExitColor, + xRSILongExitLineStyle + // + ); + if (xRSIHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XRSI Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XRSIReleaseHandlers() +{ + IndicatorRelease(xRSIHandler); +} + +// +// Handle Reading Buffers ... +void XRSIReadBuffers( + int xRSIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XRSI Signal ... + CopyBuffer( + xRSIHandler, + 0, + 0, + xRSIItemsPerTick, + xRSIBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XRSI Custom Functions ... +// + +// +// Check SC is Peak ... +bool XRSIIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xRSIBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XRSIIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xRSIBuffer + // + ); + + // + return result; +} + +// +// RSI Value GO Up from Long Entry ... +bool XRSIIsCrossedOverLongEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongEntryValue && + xRSIBuffer[bar_index + 2] <= xRSILongEntryValue; + + // + return result; +} + +// +// RSI Value GO Up from Long Exit ... +bool XRSIIsCrossedOverLongExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongExitValue && + xRSIBuffer[bar_index + 2] <= xRSILongExitValue; + + // + return result; +} + +// +// RSI Value Go Down Short Entry ... +bool XRSIIsCrossedUnderShortEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortEntryValue && + xRSIBuffer[bar_index + 2] >= xRSIShortEntryValue; + + // + return result; +} + +// +// RSI Value Go Down Short Exit ... +bool XRSIIsCrossedUnderShortExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortExitValue && + xRSIBuffer[bar_index + 2] >= xRSIShortExitValue; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XRSIIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xRSIBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XRSI Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..6286228 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 @@ -0,0 +1,931 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTD Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; + +// +// XTD Oscillator Buffer Lines ... +enum ENUM_X_XTD_BUFFER_LINES +{ + X_XTD_BULLISH_POWER_LINE = 0, + X_XTD_BEARISH_POWER_LINE = 1, + X_XTD_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XTD Oscillator"; + +// input int xTDLength = 18; // Market Length +// input bool xTDDrawCrosses = false; // Draw Cross Arrows +// input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code +// input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color +// input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code +// input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color + +// +// Configurations ... +int xTDLength = 18; // Market Length +bool xTDDrawCrosses = false; // Draw Cross Arrows +uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code +color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color +uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code +color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTDHandler = INVALID_HANDLE; +double xTDBullishBuffer[]; +double xTDBearishBuffer[]; +double xTDSignalBuffer[]; +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTDValidateInputs() +{ + // + bool result = false; + + // + result = xTDLength >= 2; + + // + if (!result) + { + // + LogMessage("XTD Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XTDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTD Handler ... + ArraySetAsSeries(xTDBullishBuffer, true); + ArraySetAsSeries(xTDBearishBuffer, true); + ArraySetAsSeries(xTDSignalBuffer, true); + xTDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtd.oscillator", + // + // Inputs ... + xTDLength, + xTDDrawCrosses, + xTDBullishArrowCode, + xTDBullishArrowColor, + xTDBearishArrowCode, + xTDBearishArrowColor); + if (xTDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTD Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XTDReleaseHandlers() +{ + IndicatorRelease(xTDHandler); +} + +// +// Handle Reading Buffers ... +void XTDReadBuffers( + int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BULLISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBullishBuffer); + + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BEARISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBearishBuffer); + + // + // XTD Signal Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_SIGNAL_LINE, + 0, + xTDItemsPerTick, + xTDSignalBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTD Custom Functions ... +// + +// +// Check Signal Vale ... +bool XTDIsSignalVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDSignalBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsSignalPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDSignalBuffer + // + ); + + // + return result; +} + +// +// Check Signal Vale ... +bool XTDIsBullishVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDBullishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsBullishPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDBullishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Vale ... +bool XTDIsBearishVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDBearishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsBearishPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDBearishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... + +// +// Check Bullish Crossed Over Bearish ... +bool XTDIsBullCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Over Bearish ... +bool XTDIsBullOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Crossed Under Bearish ... +bool XTDIsBullCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Under Bearish ... +bool XTDIsBullUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Over Bearish ... +bool XTDIsSignalCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Over Bearish ... +bool XTDIsSignalOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Under Bearish ... +bool XTDIsSignalCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Under Bearish ... +bool XTDIsSignalUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDSignalBuffer) < size) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Count Signal Crossed Over Bear ... +int XTDCountSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Signal Crossed Under Bear ... +int XTDCountSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Over Bear ... +int XTDCountBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Under Bear ... +int XTDCountBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Over Bear ... +int XTDFindLastSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Onder Bear ... +int XTDFindLastSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Over Bear ... +int XTDFindLastBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Under Bear ... +int XTDFindLastBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// END XTD Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 new file mode 100644 index 0000000..a871ed4 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 @@ -0,0 +1,598 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTM Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; + +// +// XTM Indicator Buffer Lines ... +enum ENUM_X_XTM_BUFFER_LINES +{ + X_XTM_MA_LINE = 0, + X_XTM_MC_COLOR_LINE = 1, + X_XTM_STATE_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XTM Indicator"; + +// input int xTMMaPeriod = 18; // Period +// input int xTMMaShift = 0; // Shift +// input ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method +// input ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_OPEN; // Applied To + +// +// Configurations ... +int xTMMaPeriod = 18; // Period +int xTMMaShift = 0; // Shift +ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method +ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_OPEN; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTMHandler = INVALID_HANDLE; +double xTMMaBuffer[]; +double xTMStateBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTMValidateInputs() +{ + // + bool result = false; + + // + result = xTMMaPeriod >= 2; + + // + if (!result) + { + // + LogMessage("XTM Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XTMInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Handler ... + ArraySetAsSeries(xTMMaBuffer, true); + ArraySetAsSeries(xTMStateBuffer, true); + xTMHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtm.indicator", + // + // Inputs ... + xTMMaPeriod, + xTMMaShift, + xTMMaMethod, + xTMMaAppliedTo); + if (xTMHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTM Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XTMReleaseHandlers() +{ + IndicatorRelease(xTMHandler); +} + +// +// Handle Reading Buffers ... +void XTMReadBuffers( + int xTMItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // Ma Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_MA_LINE, + 0, + xTMItemsPerTick, + xTMMaBuffer); + + // + // State Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_STATE_LINE, + 0, + xTMItemsPerTick, + xTMStateBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTM Custom Functions ... +// + +// +// Find Peak based On this Indicator ... +bool XTMIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTMMaBuffer + // + ); + + // + return result; +} + +// +// Find Vale based On this Indicator ... +bool XTMIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTMMaBuffer + // + ); + + // + return result; +} + +// +// Check TM Crossed Up ... +bool XTMIsStartBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] != X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Up After Neutural State ... +bool XTMIsStartBullishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Up State ... +bool XTMIsBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State ... +bool XTMIsEndBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] != X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State By Neutural ... +bool XTMIsEndBullishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL && + xTMStateBuffer[bar_index + 1] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down ... +bool XTMIsStartBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] != X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down After Neutural State ... +bool XTMIsStartBearishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Down State ... +bool XTMIsBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State ... +bool XTMIsEndBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] != X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State By Neutural ... +bool XTMIsEndBearishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL && + xTMStateBuffer[bar_index + 1] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM In Neutural State ... +bool XTMIsNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTMIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xTMMaBuffer) < size || + ArraySize(xTMStateBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XTM Custom Functions ... +// diff --git a/XEU5-0/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 b/XEU5-0/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..875eec0 --- /dev/null +++ b/XEU5-0/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 @@ -0,0 +1,1179 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTS Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// Methods to Calculate TimeFrames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// Buffer Lines ... +enum ENUM_X_XTS_BUFFER_LINES +{ + X_XTS_CURRENT_LINE = 0, + X_XTS_NEAREST_LINE = 1, + X_XTS_MEDIEST_LINE = 2, + X_XTS_FAREST_LINE = 3, +}; + +// +// Periods ... +enum ENUM_X_XTS_PERIODS +{ + // + // Current Period ... + X_XTS_PERIOD_CURRENT, + // + // Nearest Period ... + X_XTS_PERIOD_NEAREST, + // + // Mediest Period ... + X_XTS_PERIOD_MEDIEST, + // + // Farest Period ... + X_XTS_PERIOD_FAREST, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// // +// input group "XTS Oscillator"; + +// // +// input group "XTS Current Period"; +// input ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To +// // +// input group "XTS Nearest Period"; +// input ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +// input ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame +// input ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// // +// input group "XTS Mediest Period"; +// input ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +// input ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame +// input ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// // +// input group "XTS Farest Period"; +// input ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period +// input ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame +// input ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// Configurations ... +ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To +// +ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame +ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// +ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame +ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// +ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period +ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame +ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTSHandler = INVALID_HANDLE; +double xTSCurrentBuffer[]; +double xTSNearestBuffer[]; +double xTSMediestBuffer[]; +double xTSFarestBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTSValidateInputs() +{ + // + bool result = false; + + // + result = true; + + // + if (!result) + { + // + LogMessage("XTS Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XTSInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTS Handler ... + ArraySetAsSeries(xTSCurrentBuffer, true); + ArraySetAsSeries(xTSNearestBuffer, true); + ArraySetAsSeries(xTSMediestBuffer, true); + ArraySetAsSeries(xTSFarestBuffer, true); + xTSHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xts.oscillator", + // + // Inputs ... + "", + xTSCurrentAppliedTo, + "", + xTSNearestMethod, + xTSNearestPeriod, + xTSNearestAppliedTo, + "", + xTSMediestMethod, + xTSMediestPeriod, + xTSMediestAppliedTo, + "", + xTSFarestMethod, + xTSFarestPeriod, + xTSFarestAppliedTo + // + ); + if (xTSHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTS Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XTSReleaseHandlers() +{ + IndicatorRelease(xTSHandler); +} + +// +// Handle Reading Buffers ... +void XTSReadBuffers( + int xTSItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XTS Current ... + CopyBuffer( + xTSHandler, + X_XTS_CURRENT_LINE, + 0, + xTSItemsPerTick, + xTSCurrentBuffer); + + // + // XTS Nearest ... + CopyBuffer( + xTSHandler, + X_XTS_NEAREST_LINE, + 0, + xTSItemsPerTick, + xTSNearestBuffer); + + // + // XTS Mediest ... + CopyBuffer( + xTSHandler, + X_XTS_MEDIEST_LINE, + 0, + xTSItemsPerTick, + xTSMediestBuffer); + + // + // XTS Farest ... + CopyBuffer( + xTSHandler, + X_XTS_FAREST_LINE, + 0, + xTSItemsPerTick, + xTSFarestBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTS Custom Functions ... +// + +// +// Calculate Min Value ... +double XTSGetMinValue( + int bar_index // Specified Index ... +) +{ + // + ENUM_X_XTS_PERIODS periods[]; + XTSGetAllPeriodsEnum(periods); + + // + double result = XTSGetPeriodsMinValue( + periods, + bar_index); + + // + return result; +} + +// +// Calculate Max Value ... +double XTSGetMaxValue( + int bar_index // Specified Index ... +) +{ + // + ENUM_X_XTS_PERIODS periods[]; + XTSGetAllPeriodsEnum(periods); + + // + double result = XTSGetPeriodsMaxValue( + periods, + bar_index); + + // + return result; +} + +// +// Check if all Periods Values are Same ... +bool XTSIsAllSame( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xTSCurrentBuffer[bar_index] == xTSNearestBuffer[bar_index] && + xTSNearestBuffer[bar_index] == xTSMediestBuffer[bar_index] && + xTSMediestBuffer[bar_index] == xTSFarestBuffer[bar_index]; + + // + return result; +} + +// +// Current ... + +// +// Check Current Buffer is Min Or Not ... +bool XTSIsCurrentMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double minValue = XTSGetMinValue(bar_index); + + // + result = + xTSCurrentBuffer[bar_index] == minValue; + + // + return result; +} + +// +// Check Current Buffer is Max Or Not ... +bool XTSIsCurrentMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double maxValue = XTSGetMaxValue(bar_index); + + // + result = + xTSCurrentBuffer[bar_index] == maxValue; + + // + return result; +} + +// +// Current VS Nearest ... + +// +// Check Current Crossed Over Nearest ... +bool XTSIsCurrentCrossedOverNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Over Nearest ... +bool XTSIsCurrentOverNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Nearest ... +bool XTSIsCurrentCrossedUnderNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Under Nearest ... +bool XTSIsCurrentUnderNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Current VS Mediest ... + +// +// Check Current Crossed Over Mediest ... +bool XTSIsCurrentCrossedOverMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Over Mediest ... +bool XTSIsCurrentOverMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Mediest ... +bool XTSIsCurrentCrossedUnderMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Under Mediest ... +bool XTSIsCurrentUnderMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Current VS Farest ... + +// +// Check Current Crossed Over Farest ... +bool XTSIsCurrentCrossedOverFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Over Farest ... +bool XTSIsCurrentOverFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Farest ... +bool XTSIsCurrentCrossedUnderFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Under Farest ... +bool XTSIsCurrentUnderFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Globally Custom Functions ... + +// +// Check a Period Crossed Over another one ... +bool XTSIsPeriodCrossedOverAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + double sourceValue1 = XTSGetPeriodValue( + source, + bar_index + 1); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + double destValue1 = XTSGetPeriodValue( + dest, + bar_index + 1); + + // + result = + sourceValue > destValue && + sourceValue1 <= destValue1; + + // + return result; +} + +// +// Check a Period Over another one ... +bool XTSIsPeriodOverAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + + // + result = + sourceValue > destValue; + + // + return result; +} + +// +// Check a Period Crossed Under another one ... +bool XTSIsPeriodCrossedUnderAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + double sourceValue1 = XTSGetPeriodValue( + source, + bar_index + 1); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + double destValue1 = XTSGetPeriodValue( + dest, + bar_index + 1); + + // + result = + sourceValue < destValue && + sourceValue1 >= destValue1; + + // + return result; +} + +// +// Check a Period Under another one ... +bool XTSIsPeriodUnderAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + + // + result = + sourceValue < destValue; + + // + return result; +} + +// +// Retrieve Specific Period's Value from Buffer for Specific Bar Index ... +double XTSGetPeriodValue( + ENUM_X_XTS_PERIODS period, // Specified Period to read it's Value ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (period) + { + // + case X_XTS_PERIOD_CURRENT: + result = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + result = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + result = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + result = xTSFarestBuffer[bar_index]; + break; + } + + // + return result; +} + +// +// Fill All Exists Periods ... +void XTSGetAllPeriodsEnum( + ENUM_X_XTS_PERIODS &result[] // Hold's Result ... +) +{ + // + CleanBuffer(result); + + // + Add( + X_XTS_PERIOD_CURRENT, + result); + + // + Add( + X_XTS_PERIOD_NEAREST, + result); + + // + Add( + X_XTS_PERIOD_MEDIEST, + result); + + // + Add( + X_XTS_PERIOD_FAREST, + result); +} + +// +// Fill All Exists Periods Except ... +void XTSGetAllPeriodsEnumExcept( + ENUM_X_XTS_PERIODS &result[], // Hold's Result ... + ENUM_X_XTS_PERIODS exception // Excepted Period ... +) +{ + // + CleanBuffer(result); + + // + ENUM_X_XTS_PERIODS allPeriods[]; + XTSGetAllPeriodsEnum(allPeriods); + int periodsCount = ArraySize(allPeriods); + if (periodsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; + + // + if (iPeriod != exception) + { + Add( + iPeriod, + result); + } + } +} + +// +// Fill All Exists Periods Except ... +void XTSGetAllPeriodsEnumExcept( + ENUM_X_XTS_PERIODS &result[], // Hold's Result ... + ENUM_X_XTS_PERIODS &exceptions[] // Excepted Periods ... +) +{ + // + CleanBuffer(result); + + // + ENUM_X_XTS_PERIODS allPeriods[]; + XTSGetAllPeriodsEnum(allPeriods); + int periodsCount = ArraySize(allPeriods); + if (periodsCount <= 0) + { + return; + } + + // + int exceptionsCount = ArraySize(exceptions); + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; + + // + bool canAddIPeriod = false; + if (exceptionsCount <= 0) + { + canAddIPeriod = true; + } + else + { + // + // Loop through Exceptions ... + for (int j = 0; j < exceptionsCount; j++) + { + // + ENUM_X_XTS_PERIODS jException = exceptions[j]; + + // + if (iPeriod == jException) + { + // + canAddIPeriod = false; + break; + } + + // + canAddIPeriod = true; + } + } + + // + if (canAddIPeriod) + { + // + Add( + iPeriod, + result); + } + } +} + +// +// Calculate Periods Min Value ... +double XTSGetPeriodsMinValue( + ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + int periodsCount = ArraySize(periods); + + // + // Validate Args ... + if ( + bar_index < 0 || + periodsCount <= 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = periods[i]; + + // + double iValue = 0; + + // + switch (iPeriod) + { + // + case X_XTS_PERIOD_CURRENT: + iValue = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + iValue = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + iValue = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + iValue = xTSFarestBuffer[bar_index]; + break; + } + + // + // Compare iValue to result ... + result = + result == 0 || + result > iValue + ? iValue + : result; + } + + // + return result; +} + +// +// Calculate Periods Max Value ... +double XTSGetPeriodsMaxValue( + ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + int periodsCount = ArraySize(periods); + + // + // Validate Args ... + if ( + bar_index < 0 || + periodsCount <= 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = periods[i]; + + // + double iValue = 0; + + // + switch (iPeriod) + { + // + case X_XTS_PERIOD_CURRENT: + iValue = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + iValue = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + iValue = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + iValue = xTSFarestBuffer[bar_index]; + break; + } + + // + // Compare iValue to result ... + result = + result == 0 || + result < iValue + ? iValue + : result; + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTSIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xTSCurrentBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +void Add( + ENUM_X_XTS_PERIODS item, // Specified Item ... + ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... +) +{ + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; +} + +void CleanBuffer( + ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... +) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// END XTS Custom Functions ... +// diff --git a/XEU5-0/Indicators/.gitkeep b/XEU5-0/Indicators/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Indicators/x-saherelm.xama.indicator.mq5 b/XEU5-0/Indicators/x-saherelm.xama.indicator.mq5 new file mode 100644 index 0000000..14d1ef7 --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xama.indicator.mq5 @@ -0,0 +1,353 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAMA Indicator +// --------------------------------------------- +// Name: XAMA +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XAMA Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XAMA" + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 1, + X_XAMA_BEARISH = -1, + X_XAMA_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Period +input int fastEMA = 2; // Fast EMA Period +input int slowEMA = 30; // Slow EMA Period +input int maShift = 0; // Shift +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XAMA" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Initializing MA Handler ... + maHandler = iAMA( + _Symbol, + _Period, + length, + fastEMA, + slowEMA, + maShift, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(maHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(fastEMA, slowEMA); + maxLength = MathMax(maxLength, length); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XAMA " + "(" + (string)length + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", length, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XAMA_BULLISH : lineColorIndex == 2 ? X_XAMA_BEARISH + : X_XAMA_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xchlh.oscillator.mq5 b/XEU5-0/Indicators/x-saherelm.xchlh.oscillator.mq5 new file mode 100644 index 0000000..5c74787 --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xchlh.oscillator.mq5 @@ -0,0 +1,753 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel LH Oscillator +// --------------------------------------------------- +// Name: XCHLH +// Description: detecting HH and LL based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHLH Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHLH" + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// Including Models Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotHHArrowCode = 234; // Hot HH Arrow Code +input color hotHHArrowColor = clrAqua; // Hot HH Arrow Color +input uchar hotLLArrowCode = 233; // Hot LL Arrow Code +input color hotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcLength = 28; // Length +input double lcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE lcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE lcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcHHColor = clrAqua; // Highest High Color +input color lcLLColor = clrFuchsia; // Lowest Low Color +input group "LC Drawings"; +input bool lcDrawHH = true; // Draw Highest High +input bool lcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcLength = 14; // Length +input double mcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE mcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE mcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcHHColor = clrLime; // Highest High Color +input color mcLLColor = clrRed; // Lowest Low Color +input group "MC Drawings"; +input bool mcDrawHH = true; // Draw Highest High +input bool mcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scLength = 7; // Length +input double scThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE scHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE scLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_DOT; // Draw Style +input color scHHColor = clrLightBlue; // Highest High Color +input color scLLColor = clrLightSalmon; // Lowest Low Color +input group "SC Drawings"; +input bool scDrawHH = true; // Draw Highest High +input bool scDrawLL = true; // Draw Lowest Low +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 7 +#property indicator_plots 6 + +// +// LC ... +#define lcHHBufferIndex 0 +#define lcLLBufferIndex 1 + +// +double lcHHBuffer[]; +double lcLLBuffer[]; + +// +// MC ... +#define mcHHBufferIndex 2 +#define mcLLBufferIndex 3 + +// +double mcHHBuffer[]; +double mcLLBuffer[]; + +// +// SC ... +#define scHHBufferIndex 4 +#define scLLBufferIndex 5 + +// +double scHHBuffer[]; +double scLLBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcLength, mcLength); + maxLength = MathMax(maxLength, scLength); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = + lcLength >= 4 && + lcLength > mcLength && + lcLength > scLength; + bool isMCInputsValid = + mcLength >= 4 && + mcLength > scLength && + mcLength < lcLength; + bool isSCInputsValid = + scLength >= 4 && + scLength < mcLength && + scLength < lcLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + LCCalculateBuffers(bar_index); + + // + // MC ... + MCCalculateBuffers(bar_index); + + // + // SC ... + SCCalculateBuffers(bar_index); + + // + // SIGNAL ... + SignalCalculateBuffers(bar_index); + + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC HH Buffer ... + string lcHHBufferLabel = ShortName + " LC HH (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcHHDrawType = lcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcHHBufferIndex, PLOT_LABEL, lcHHBufferLabel); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_COLOR, lcHHColor); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_TYPE, lcHHDrawType); + + // + // LC LL Buffer ... + string lcLLBufferLabel = ShortName + " LC LL (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcLLDrawType = lcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcLLBufferIndex, PLOT_LABEL, lcLLBufferLabel); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_COLOR, lcLLColor); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_TYPE, lcLLDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC HH Buffer ... + string mcHHBufferLabel = ShortName + " MC HH (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcHHDrawType = mcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcHHBufferIndex, PLOT_LABEL, mcHHBufferLabel); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_COLOR, mcHHColor); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_TYPE, mcHHDrawType); + + // + // MC LL Buffer ... + string mcLLBufferLabel = ShortName + " MC LL (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcLLDrawType = mcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcLLBufferIndex, PLOT_LABEL, mcLLBufferLabel); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_COLOR, mcLLColor); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_TYPE, mcLLDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC HH Buffer ... + string scHHBufferLabel = ShortName + " SC HH (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scHHDrawType = scDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scHHBufferIndex, PLOT_LABEL, scHHBufferLabel); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_COLOR, scHHColor); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_TYPE, scHHDrawType); + + // + // SC LL Buffer ... + string scLLBufferLabel = ShortName + " SC LL (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scLLDrawType = scDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scLLBufferIndex, PLOT_LABEL, scLLBufferLabel); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_COLOR, scLLColor); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_TYPE, scLLDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Calculations ... +void LCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = lcLength; + ENUM_SERIESMODE hhMode = lcHHMode; + ENUM_SERIESMODE llMode = lcLLMode; + double threshold = PipsToPrice(lcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + lcHHBuffer[bar_index] = hhValue; + lcLLBuffer[bar_index] = llValue; +} + +// +// MC Calculations ... +void MCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = mcLength; + ENUM_SERIESMODE hhMode = mcHHMode; + ENUM_SERIESMODE llMode = mcLLMode; + double threshold = PipsToPrice(mcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + mcHHBuffer[bar_index] = hhValue; + mcLLBuffer[bar_index] = llValue; +} + +// +// SC Calculations ... +void SCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = scLength; + ENUM_SERIESMODE hhMode = scHHMode; + ENUM_SERIESMODE llMode = scLLMode; + double threshold = PipsToPrice(scThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + scHHBuffer[bar_index] = hhValue; + scLLBuffer[bar_index] = llValue; +} + +// +// SIGNAL Calculations ... +void SignalCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC Values ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + double lcDelta = lcHH - lcLL; + double lcAvg = lcDelta / 2; + + // + // MC Values ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + double mcDelta = mcHH - mcLL; + double mcAvg = mcDelta / 2; + + // + // SC Values ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + double scDelta = scHH - scLL; + double scAvg = scDelta / 2; + + // + // Min Value ... + double minValue = MathMin( + scLL, mcLL); + minValue = MathMin( + lcLL, minValue); + + // + // Max Value ... + double maxValue = MathMin( + scHH, mcHH); + maxValue = MathMin( + lcHH, maxValue); +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + // + double lcHH1 = lcHHBuffer[bar_index + 1]; + double lcLL1 = lcLLBuffer[bar_index + 1]; + + // + // MC ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + // + double mcHH1 = mcHHBuffer[bar_index + 1]; + double mcLL1 = mcLLBuffer[bar_index + 1]; + + // + // SC ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + // + double scHH1 = scHHBuffer[bar_index + 1]; + double scLL1 = scLLBuffer[bar_index + 1]; + + // + bool isHotLLState = scLL == mcLL && mcLL == lcLL; + bool isHotLLState1 = scLL1 == mcLL1 && mcLL1 == lcLL1; + // + bool isHotHHState = scHH == mcHH && mcHH == lcHH; + bool isHotHHState1 = scHH1 == mcHH1 && mcHH1 == lcHH1; + + // + bool isHotLL = isHotLLState && !isHotLLState1; + bool isHotHH = isHotHHState && !isHotHHState1; + + // + double hotStateValue = X_XCHLH_NEUTURAL; + if (isHotHH) + { + hotStateValue = X_XCHLH_HOT_HH; + } + else if (isHotLL) + { + hotStateValue = X_XCHLH_HOT_LL; + } + + // + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotHHArea = hotStateValue == 1; + bool isHotLLArea = hotStateValue == -1; + if (isHotHHArea || isHotLLArea) + { + // + bool isHH = isHotHHArea; + + // + double price = isHH ? candle.high : candle.low; + ENUM_ARROW_ANCHOR anchor = isHH ? ANCHOR_BOTTOM : ANCHOR_TOP; + color clr = isHH ? hotHHArrowColor : hotLLArrowColor; + uchar arrowCode = isHH ? hotHHArrowCode : hotLLArrowCode; + string name = "HOT " + (isHH ? "HH" : "LL") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr, + STYLE_SOLID, + 1); + } + } +} +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xchma.oscillator.mq5 b/XEU5-0/Indicators/x-saherelm.xchma.oscillator.mq5 new file mode 100644 index 0000000..12d6c69 --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xchma.oscillator.mq5 @@ -0,0 +1,1153 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel Moving Averages Oscillator +// ---------------------------------------------------------------- +// Name: XCHMA +// Description: trend detecting based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHMA Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHMA" + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotBullishArrowCode = 228; // Hot Bullish Arrow Code +input color hotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color +input uchar hotBearishArrowCode = 230; // Hot Bearish Arrow Code +input color hotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcFastLength = 20; // Fast Length +input int lcSlowLength = 50; // Slow Length +input ENUM_MA_METHOD lcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE lcAppliedTo = PRICE_CLOSE; // Applied To +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcFastColor = clrAqua; // Fast Color +input color lcSlowColor = clrFuchsia; // Slow Color +input group "LC Drawings"; +input bool lcDrawFast = true; // Draw Fast +input bool lcDrawSlow = true; // Draw Slow +input bool lcDrawCrosses = true; // Draw Cross Lines + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcFastLength = 10; // Fast Length +input int mcSlowLength = 30; // Slow Length +input ENUM_MA_METHOD mcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE mcAppliedTo = PRICE_CLOSE; // Applied To +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcFastColor = clrLime; // Fast Color +input color mcSlowColor = clrRed; // Slow Color +input group "MC Drawings"; +input bool mcDrawFast = true; // Draw Fast +input bool mcDrawSlow = true; // Draw Slow +input bool mcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scFastLength = 7; // Fast Length +input int scSlowLength = 14; // Slow Length +input ENUM_MA_METHOD scMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE scAppliedTo = PRICE_CLOSE; // Applied To +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_SOLID; // Draw Style +input color scFastColor = clrLightBlue; // Fast Color +input color scSlowColor = clrLightSalmon; // Slow Color +input group "SC Drawings"; +input bool scDrawFast = true; // Draw Fast +input bool scDrawSlow = true; // Draw Slow +input bool scDrawCrosses = false; // Draw Cross Lines +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 7 +#property indicator_plots 6 + +// +// LC ... +#define lcFastBufferIndex 0 +#define lcSlowBufferIndex 1 + +// +double lcFastBuffer[]; +double lcSlowBuffer[]; + +// +// MC ... +#define mcFastBufferIndex 2 +#define mcSlowBufferIndex 3 + +// +double mcFastBuffer[]; +double mcSlowBuffer[]; + +// +// SC ... +#define scFastBufferIndex 4 +#define scSlowBufferIndex 5 + +// +double scFastBuffer[]; +double scSlowBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// LC ... +int lcFastHandler = INVALID_HANDLE; +int lcSlowHandler = INVALID_HANDLE; + +// +// MC ... +int mcFastHandler = INVALID_HANDLE; +int mcSlowHandler = INVALID_HANDLE; + +// +// SC ... +int scFastHandler = INVALID_HANDLE; +int scSlowHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init All Required Handlers ... + if (!InitHandlers()) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcFastLength, lcSlowLength); + + // + // Get Retrieved Values from indicators ... + // + // LC ... + int lcFastCalculatedBars = BarsCalculated(lcFastHandler); + int lcSlowCalculatedBars = BarsCalculated(lcSlowHandler); + + // + // MC ... + int mcFastCalculatedBars = BarsCalculated(mcFastHandler); + int mcSlowCalculatedBars = BarsCalculated(mcSlowHandler); + + // + // SC ... + int scFastCalculatedBars = BarsCalculated(scFastHandler); + int scSlowCalculatedBars = BarsCalculated(scSlowHandler); + + // + // Check Calculated Bars ... + if ( + // + // LC ... + lcFastCalculatedBars < maxLength || + lcSlowCalculatedBars < maxLength || + // + // MC ... + mcFastCalculatedBars < maxLength || + mcSlowCalculatedBars < maxLength || + // + // SC ... + scFastCalculatedBars < maxLength || + scSlowCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Copy Buffers from indicators ... + // + // LC ... + int lcFastCopiedItems = CopyBuffer(lcFastHandler, 0, 0, limit + 1, lcFastBuffer); + int lcSlowCopiedItems = CopyBuffer(lcSlowHandler, 0, 0, limit + 1, lcSlowBuffer); + + // + // MC ... + int mcFastCopiedItems = CopyBuffer(mcFastHandler, 0, 0, limit + 1, mcFastBuffer); + int mcSlowCopiedItems = CopyBuffer(mcSlowHandler, 0, 0, limit + 1, mcSlowBuffer); + + // + // SC ... + int scFastCopiedItems = CopyBuffer(scFastHandler, 0, 0, limit + 1, scFastBuffer); + int scSlowCopiedItems = CopyBuffer(scSlowHandler, 0, 0, limit + 1, scSlowBuffer); + + // + // Check Copied Items Number ... + if ( + // + // LC ... + lcFastCopiedItems <= 0 || + lcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = lcFastLength >= 4 && lcSlowLength > lcFastLength; + bool isMCInputsValid = mcFastLength >= 4 && mcSlowLength > mcFastLength; + bool isSCInputsValid = scFastLength >= 4 && scSlowLength > scFastLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid && + lcFastLength > mcFastLength && + mcFastLength > scFastLength) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Init Handlers ... +bool InitHandlers() +{ + // + bool result = false; + + // + // LC ... + result = LCInitHandlers(); + if (!result) + { + return result; + } + + // + // MC ... + result = MCInitHandlers(); + if (!result) + { + return result; + } + + // + // SC ... + result = SCInitHandlers(); + if (!result) + { + return result; + } + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC Fast Buffer ... + string lcFastBufferLabel = ShortName + " LC Fast (" + (string)lcFastLength + ")"; + ENUM_DRAW_TYPE lcFastDrawType = lcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcFastBuffer, true); + SetIndexBuffer(lcFastBufferIndex, lcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(lcFastBufferIndex, PLOT_LABEL, lcFastBufferLabel); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_COLOR, lcFastColor); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_BEGIN, lcFastLength); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_TYPE, lcFastDrawType); + + // + // LC Slow Buffer ... + string lcSlowBufferLabel = ShortName + " LC Slow (" + (string)lcSlowLength + ")"; + ENUM_DRAW_TYPE lcSlowDrawType = lcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcSlowBuffer, true); + SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(lcSlowBufferIndex, PLOT_LABEL, lcSlowBufferLabel); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_COLOR, lcSlowColor); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_BEGIN, lcSlowLength); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_TYPE, lcSlowDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC Fast Buffer ... + string mcFastBufferLabel = ShortName + " MC Fast (" + (string)mcFastLength + ")"; + ENUM_DRAW_TYPE mcFastDrawType = mcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcFastBuffer, true); + SetIndexBuffer(mcFastBufferIndex, mcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(mcFastBufferIndex, PLOT_LABEL, mcFastBufferLabel); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_COLOR, mcFastColor); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_BEGIN, mcFastLength); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_TYPE, mcFastDrawType); + + // + // MC Slow Buffer ... + string mcSlowBufferLabel = ShortName + " MC Slow (" + (string)mcSlowLength + ")"; + ENUM_DRAW_TYPE mcSlowDrawType = mcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcSlowBuffer, true); + SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(mcSlowBufferIndex, PLOT_LABEL, mcSlowBufferLabel); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_COLOR, mcSlowColor); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_BEGIN, mcSlowLength); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_TYPE, mcSlowDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC Fast Buffer ... + string scFastBufferLabel = ShortName + " SC Fast (" + (string)scFastLength + ")"; + ENUM_DRAW_TYPE scFastDrawType = scDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scFastBuffer, true); + SetIndexBuffer(scFastBufferIndex, scFastBuffer, INDICATOR_DATA); + PlotIndexSetString(scFastBufferIndex, PLOT_LABEL, scFastBufferLabel); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_COLOR, scFastColor); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_BEGIN, scFastLength); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_TYPE, scFastDrawType); + + // + // SC Slow Buffer ... + string scSlowBufferLabel = ShortName + " SC Slow (" + (string)scSlowLength + ")"; + ENUM_DRAW_TYPE scSlowDrawType = scDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scSlowBuffer, true); + SetIndexBuffer(scSlowBufferIndex, scSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(scSlowBufferIndex, PLOT_LABEL, scSlowBufferLabel); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_COLOR, scSlowColor); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_BEGIN, scSlowLength); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_TYPE, scSlowDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Init Handlers ... +bool LCInitHandlers() +{ + // + ResetLastError(); + + // + // LC Fast Handler ... + lcFastHandler = iMA( + _Symbol, + _Period, + lcFastLength, + 0, + lcMethod, + lcAppliedTo); + if (lcFastHandler == INVALID_HANDLE) + { + // + LogMessage("LC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // LC Slow Handler ... + lcSlowHandler = iMA( + _Symbol, + _Period, + lcSlowLength, + 0, + lcMethod, + lcAppliedTo); + if (lcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("LC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// MC Init Handlers ... +bool MCInitHandlers() +{ + // + ResetLastError(); + + // + // MC Fast Handler ... + mcFastHandler = iMA( + _Symbol, + _Period, + mcFastLength, + 0, + mcMethod, + mcAppliedTo); + if (mcFastHandler == INVALID_HANDLE) + { + // + LogMessage("MC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // MC Slow Handler ... + mcSlowHandler = iMA( + _Symbol, + _Period, + mcSlowLength, + 0, + mcMethod, + mcAppliedTo); + if (mcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("MC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// SC Init Handlers ... +bool SCInitHandlers() +{ + // + ResetLastError(); + + // + // SC Fast Handler ... + scFastHandler = iMA( + _Symbol, + _Period, + scFastLength, + 0, + scMethod, + scAppliedTo); + if (scFastHandler == INVALID_HANDLE) + { + // + LogMessage("SC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // SC Slow Handler ... + scSlowHandler = iMA( + _Symbol, + _Period, + scSlowLength, + 0, + scMethod, + scAppliedTo); + if (scSlowHandler == INVALID_HANDLE) + { + // + LogMessage("SC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// LC State ... +double GetLCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// MC State ... +double GetMCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// SC State ... +double GetSCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcFast = lcFastBuffer[bar_index]; + double lcSlow = lcSlowBuffer[bar_index]; + // + double lcFastPrev = lcFastBuffer[bar_index + 1]; + double lcSlowPrev = lcSlowBuffer[bar_index + 1]; + // + double lcState = GetLCState(bar_index); + + // + // MC ... + double mcFast = mcFastBuffer[bar_index]; + double mcSlow = mcSlowBuffer[bar_index]; + // + double mcFastPrev = mcFastBuffer[bar_index + 1]; + double mcSlowPrev = mcSlowBuffer[bar_index + 1]; + // + double mcState = GetMCState(bar_index); + + // + // SC ... + double scFast = scFastBuffer[bar_index]; + double scSlow = scSlowBuffer[bar_index]; + // + double scFastPrev = scFastBuffer[bar_index + 1]; + double scSlowPrev = scSlowBuffer[bar_index + 1]; + // + double scState = GetSCState(bar_index); + + // + // Detect HOT Bearish Area ... + bool isHotBearishArea = + lcFast < lcSlow && + mcFast < mcSlow && + scFast < scSlow; + // + bool isPrevHotBearishArea = + lcFastPrev < lcSlowPrev && + mcFastPrev < mcSlowPrev && + scFastPrev < scSlowPrev; + + // + // Detect HOT Bearish Area ... + bool isHotBullishArea = + lcFast > lcSlow && + mcFast > mcSlow && + scFast > scSlow; + // + bool isPrevHotBullishArea = + lcFastPrev > lcSlowPrev && + mcFastPrev > mcSlowPrev && + scFastPrev > scSlowPrev; + + // + // Generate HotState Value ... + double hotStateValue = + isHotBullishArea && !isPrevHotBullishArea + ? 1 + : isHotBearishArea && !isPrevHotBearishArea + ? -1 + : 0; + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotBullishArea = hotStateValue == 1; + bool isHotBearishArea = hotStateValue == -1; + if (isHotBullishArea || isHotBearishArea) + { + // + bool isBull = isHotBullishArea; + + // + double price = isBull ? candle.low : candle.high; + ENUM_ARROW_ANCHOR anchor = isBull ? ANCHOR_TOP : ANCHOR_BOTTOM; + color clr = isBull ? hotBullishArrowColor : hotBearishArrowColor; + uchar arrowCode = isBull ? hotBullishArrowCode : hotBearishArrowCode; + string name = "HOT " + (isBull ? "Bullish" : "Bearish") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); + } + } + + // + // Draw LC Crosses ... + if (lcDrawCrosses) + { + // + double lcStateValue = GetLCState(bar_index); + bool isLcFastCrossedOverSlow = lcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isLcFastCrossedUnderSlow = lcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isLcFastCrossedOverSlow || isLcFastCrossedUnderSlow) + { + // + bool isBull = isLcFastCrossedOverSlow; + + // + color clr = isBull ? lcFastColor : lcSlowColor; + string name = "LC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw MC Crosses ... + if (mcDrawCrosses) + { + // + double mcStateValue = GetMCState(bar_index); + bool isMcFastCrossedOverSlow = mcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isMcFastCrossedUnderSlow = mcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isMcFastCrossedOverSlow || isMcFastCrossedUnderSlow) + { + // + bool isBull = isMcFastCrossedOverSlow; + + // + color clr = isBull ? mcFastColor : mcSlowColor; + string name = "MC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw SC Crosses ... + if (scDrawCrosses) + { + // + double scStateValue = GetSCState(bar_index); + bool isScFastCrossedOverSlow = scStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isScFastCrossedUnderSlow = scStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isScFastCrossedOverSlow || isScFastCrossedUnderSlow) + { + // + bool isBull = isScFastCrossedOverSlow; + + // + color clr = isBull ? scFastColor : scSlowColor; + string name = "SC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } +} +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xfi.oscillator.mq5 b/XEU5-0/Indicators/x-saherelm.xfi.oscillator.mq5 new file mode 100644 index 0000000..cfd393c --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xfi.oscillator.mq5 @@ -0,0 +1,317 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator +// --------------------------------------------- +// Name: XFI +// Description: Price Momentum Power Detection +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFI Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XFI" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Length +input ENUM_MA_METHOD method = MODE_SMA; // MA Method +input ENUM_APPLIED_VOLUME appliedTo = VOLUME_TICK; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 2 +#property indicator_plots 1 + +// +// FI Buffer ... +#define fiBufferIndex 0 +#define fiColorBufferIndex 1 + +// +double fiBuffer[]; +double fiColorBuffer[]; + +// +#property indicator_label1 "XFI" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, clrGray, clrFuchsia +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int fiHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + fiHandler = iForce( + _Symbol, + _Period, + length, + method, + appliedTo); + if (fiHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(fiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + // Check Calculated Bars ... + int fiCalculatedBars = BarsCalculated(fiHandler); + if (fiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFis = CopyBuffer(fiHandler, 0, 0, limit, fiBuffer); + if (copiedFis <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string fiBufferLabel = "XFI " + "(" + (string)length + ")"; + + // + // FI Buffer ... + ArraySetAsSeries(fiBuffer, true); + SetIndexBuffer(fiBufferIndex, fiBuffer, INDICATOR_DATA); + PlotIndexSetString(fiBufferIndex, PLOT_LABEL, fiBufferLabel); + + // + // FI Color Buffer ... + ArraySetAsSeries(fiColorBuffer, true); + SetIndexBuffer(fiColorBufferIndex, fiColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + double iValue = fiBuffer[bar_index]; + + // + double iColorIndex = + iValue > 0 ? 0 : iValue < 0 ? 2 + : 1; + + // + // Set Buffer Color Index ... + fiColorBuffer[bar_index] = iColorIndex; +} +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xlh.indicator.mq5 b/XEU5-0/Indicators/x-saherelm.xlh.indicator.mq5 new file mode 100644 index 0000000..4dfc64e --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xlh.indicator.mq5 @@ -0,0 +1,346 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XLH Indicator +// --------------------------------------------- +// Name: XLH +// Description: Moving Average Indicator +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XLH Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XLH" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 14; // Length +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// HH Buffer ... +#define hhBufferIndex 0 + +// +double hhBuffer[]; + +// +#property indicator_label1 "XLH HH" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// LL Buffer ... +#define llBufferIndex 1 + +// +double llBuffer[]; + +// +#property indicator_label2 "XLH LL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrFuchsia +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Signal Buffer ... +#define signalBufferIndex 2 + +// +double signalBuffer[]; + +// +#property indicator_label3 "XLH S" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // HH Buffer ... + string hhBufferLabel = ShortName + " HH " + "(" + (string)length + ")"; + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hhBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(hhBufferIndex, PLOT_LABEL, hhBufferLabel); + + // + // LL Buffer ... + string llBufferLabel = ShortName + " LL " + "(" + (string)length + ")"; + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + PlotIndexSetInteger(llBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(llBufferIndex, PLOT_LABEL, llBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + " S " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Threshold ... + // + // HH Buffer ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + length, + bar_index); + double hhValue = GetAppliedPrice( + hhIndex, + hhMode); + + // + hhBuffer[bar_index] = hhValue; + + // + // LL Buffer ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + length, + bar_index); + double llValue = GetAppliedPrice( + llIndex, + llMode); + + // + llBuffer[bar_index] = llValue; + + // + XOHCL c = GetCandle(bar_index); + double lhDiff = hhValue - llValue; + double signalValue = (lhDiff / 2); + + // + signalBuffer[bar_index] = (hhValue - signalValue); +} +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xobd.indicator.mq5 b/XEU5-0/Indicators/x-saherelm.xobd.indicator.mq5 new file mode 100644 index 0000000..4ac05cf --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xobd.indicator.mq5 @@ -0,0 +1,390 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Indicator +// ----------------------------------------------------- +// Name: XOBD +// Description: detect Order Blocks based on Swings ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XOBD Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XOBD" +// +// END Constants ... +// + +// +// START Inputs ... +// +// +input int length = 5; // Swing Length + +// +input uchar swingHighArrowCode = 108; // Swing High Arrow Code +input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color + +// +input uchar swingLowArrowCode = 108; // Swing Low Arrow Code +input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Include Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 1 +#property indicator_plots 0 + +// +#define swingBufferIndex 0 +double swingBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + OnDeinitDrawLibrary(); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length * 3); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ArraySetAsSeries(swingBuffer, true); + SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // GetCandleSwing(bar_index); + ENUM_X_SWING_TYPE type = X_NO_SWING; + + // + // Try To Detect Order Blocks ... + bool isSwingLow = false; + bool isSwingHigh = false; + + // + // Reading Candles Data ... + XOHCL candles[]; + for (int i = bar_index; i < bar_index + ((length * 2) + 2); i++) + { + // + XOHCL iCandle = GetCandle( + _Symbol, + _Period, + i); + + // + Add( + iCandle, + candles); + } + + // + // Swing Low ... + isSwingLow = + // + candles[1].close > candles[2].close && + candles[2].close > candles[3].close && + // + candles[3].close < candles[4].close && + // + candles[5].close > candles[4].close && + candles[6].close > candles[5].close + // + ; + + // + if (isSwingLow) + { + type = X_SWING_LOW; + } + + // + if (!isSwingLow) + { + // + // Swing High ... + isSwingHigh = + // + candles[1].close < candles[2].close && + candles[2].close < candles[3].close && + // + candles[3].close > candles[4].close && + // + candles[5].close < candles[4].close && + candles[6].close < candles[5].close + // + ; + + // + if (isSwingHigh) + { + type = X_SWING_HIGH; + } + } + + // + switch (type) + { + // + // Swing High ... + case X_SWING_HIGH: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(1, bar_index); + break; + + // + // Swinmg Low ... + case X_SWING_LOW: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(0, bar_index); + break; + + // + // No Swing ... + default: + case X_NO_SWING: + // + swingBuffer[bar_index] = 0; + break; + } +} + +// +// Draw a Swing Arrow Shape ... +void DrawSwingArrow( + int type, // Swing Type: 0 - Low / 1 - High ... + int bar_index) +{ + // + bool isSwingHigh = type == 1; + XOHCL candle = GetCandle(bar_index + 3); + double arrowDistanceInPoint = 0; + + // + // Define Required Object Properties fro Draw an Arrow ... + datetime time = iTime(_Symbol, _Period, bar_index + 3); + double purePrice = isSwingHigh ? candle.high : candle.low; + color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor; + ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP; + uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode); + double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint; + string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice; + + // + // Draw desired Arrow ... + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); +} +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xrsi.oscillator.mq5 b/XEU5-0/Indicators/x-saherelm.xrsi.oscillator.mq5 new file mode 100644 index 0000000..5659e07 --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xrsi.oscillator.mq5 @@ -0,0 +1,397 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Oscillator +// ------------------------------------------------------ +// Name: XRSI +// Description: detect market conditions based on RSI ... +// +// +// 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 XRSI Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XRSI" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 14; // Market Length +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +input group "Short Entry"; +input double shortEntryValue = 70; // Short Entry Level +input color shortEntryColor = clrRed; // Short Entry Level Color +input ENUM_LINE_STYLE shortEntryLineStyle = STYLE_DOT; // Short Entry Style + +// +input group "Short Exit"; +input double shortExitValue = 40; // Short Exit Level +input color shortExitColor = clrRed; // Short Exit Level Color +input ENUM_LINE_STYLE shortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +input group "Long Entry"; +input double longEntryValue = 30; // Long Entry Level +input color longEntryColor = clrRed; // Long Entry Level Color +input ENUM_LINE_STYLE longEntryLineStyle = STYLE_DOT; // Long Entry Style + +// +input group "Long Exit"; +input double longExitValue = 60; // Long Exit Level +input color longExitColor = clrRed; // Long Exit Level Color +input ENUM_LINE_STYLE longExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// START Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_separate_window +#property indicator_buffers 2 +#property indicator_plots 1 + +// +#define rsiBufferIndex 0 +#define rsiColorBufferIndex 1 + +// +double rsiBuffer[]; +double rsiColorBuffer[]; + +// +#property indicator_label1 "XRSI" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, clrGray, clrFuchsia +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int rsiHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + rsiHandler = iRSI( + _Symbol, + _Period, + length, + appliedTo); + if (rsiHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(rsiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + int rsiCalculatedBars = BarsCalculated(rsiHandler); + if (rsiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + if (rsiCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RSI ... + string rsiBufferLabel = ShortName + " (" + (string)length + ")"; + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rsiBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(rsiBufferIndex, PLOT_LABEL, rsiBufferLabel); + + // + // RSI Color Buffer ... + ArraySetAsSeries(rsiColorBuffer, true); + SetIndexBuffer(rsiColorBufferIndex, rsiColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set Indicator Levels here ... + // OB, ExitLong, ExitShort, OS ... + IndicatorSetInteger(INDICATOR_LEVELS, 4); + + // + // SHORTENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, shortEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, shortEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, shortEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 0, "Short Entry"); + + // + // LONGEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, longExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, longExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, shortExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Long Exit"); + + // + // SHORTEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 2, shortExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 2, shortExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 2, longEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 2, "Short Exit"); + + // + // LONGENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 3, longEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 3, longEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 3, longExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 3, "Long Entry"); + + // + // Set Maximum and Minimum for subwindow + IndicatorSetInteger(INDICATOR_DIGITS, 2); + IndicatorSetDouble(INDICATOR_MINIMUM, 0); + IndicatorSetDouble(INDICATOR_MAXIMUM, 100); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + double iValue = rsiBuffer[bar_index]; + + // + double iColorIndex = 0; + + // + if ( + iValue >= shortEntryValue || + iValue <= longEntryValue || + (iValue < longExitValue && + iValue > shortExitValue)) + { + iColorIndex = 0; + } + else if ( + iValue <= shortEntryValue && + iValue >= longExitValue) + { + iColorIndex = 2; + } + else if ( + iValue < shortExitValue && + iValue > longEntryValue) + { + iColorIndex = 1; + } + + // + rsiColorBuffer[bar_index] = iColorIndex; +} + +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xtd.oscillator.mq5 b/XEU5-0/Indicators/x-saherelm.xtd.oscillator.mq5 new file mode 100644 index 0000000..5f46d18 --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xtd.oscillator.mq5 @@ -0,0 +1,465 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Trend Detector Oscillator +// -------------------------------------------------- +// Name: XTD +// Description: trend detecting in both sides ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTD Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTD" + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; +// +// END Constants ... +// + +// +// Include Models Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// START Inputs ... +// +input int length = 14; // Market Length +input bool drawCrosses = true; // Draw Cross Arrows + +// +// Bullish ... +input uchar bullishArrowCode = 228; // Cross Over Arrow Code +input color bullishArrowColor = clrAqua; // Cross Over Arrow Color + +// +// Bearish ... +input uchar bearishArrowCode = 230; // Cross Under Arrow Code +input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +#define bullishBufferIndex 0 +#define bearishBufferIndex 1 +#define signalBufferIndex 2 + +// +double bullishBuffer[]; +double bearishBuffer[]; +double signalBuffer[]; + +// +#property indicator_label1 "XBullPower" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#property indicator_label2 "XBearPower" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#property indicator_label3 "XSignal" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +int xtdBullishCandleCount = 0; +int xtdBearishCandleCount = 0; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i, close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 5) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Bullish Buffer ... + string bullishBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishBuffer, true); + SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel); + + // + // Bearish Buffer ... + string bearishBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishBuffer, true); + SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + "Signal " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, + const double &close[]) +{ + // + // Reset Global Counters ... + xtdBullishCandleCount = 0; + xtdBearishCandleCount = 0; + + // + // Loop through Closes ... + for (int i = bar_index; i <= bar_index + length; i++) + { + for (int j = i + 1; j <= bar_index + length; j++) + { + // + if (close[i] > close[j]) + { + xtdBullishCandleCount++; + } + + // + if (close[i] < close[j]) + { + xtdBearishCandleCount++; + } + } + } + + // + // Bullish Power Buffer ... + bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount); + + // + // Bearish Power Buffer ... + bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount); + + // + // Signal Buffer ... + signalBuffer[bar_index] = bullishBuffer[bar_index] - bearishBuffer[bar_index]; + + // + // Check and Draw Crosses if it's Specified ... + if (drawCrosses) + { + DrawCrosses(bar_index); + } +} + +// +// +double GetState( + int bar_index // Specified Bar Index +) +{ + // + // Check Cross Points ... + // bullishCrossedOverBearish = 2; + // bullishOverBearish = 1; + // bullishCrossedUnderBearish = -2; + // bullishUnderBearish = -1; + // OtherWise = 0; + bool isBullishCrossedOverBearish = IsCrossOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishCrossedUnderBearish = IsCrossUnder( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishOverBearish = IsOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishUnderBearish = IsUnder( + bullishBuffer, + bearishBuffer, + bar_index); + + // + double result = X_XTD_NEUTURAL; + if (isBullishCrossedOverBearish) + { + result = X_XTD_BULLISH_CROSSED_OVER_BEARISH; + } + else if (isBullishCrossedUnderBearish) + { + result = X_XTD_BULLISH_CROSSED_UNDER_BEARISH; + } + else if (isBullishOverBearish) + { + result = X_XTD_BULLISH_OVER_BEARISH; + } + else if (isBullishUnderBearish) + { + result = X_XTD_BULLISH_UNDER_BEARISH; + } + else + { + result = X_XTD_NEUTURAL; + } + + // + return result; +} + +// +// Draw Crosses ... +void DrawCrosses( + int bar_index // the bars which required to draw cross arrow on it ... +) +{ + // + double stateValue = GetState(bar_index); + + // + bool isOver = stateValue == 2; + double low = iLow(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + + // + double price = isOver ? low : high; + datetime time = iTime(_Symbol, _Period, bar_index); + ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM; + uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode; + color arrowColor = isOver ? bullishArrowColor : bearishArrowColor; + string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price; + + // + DrawArrow( + 0, + crossName, + 0, + time, + price, + arrowCode, + anchor, + arrowColor); +} +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xtm.indicator.mq5 b/XEU5-0/Indicators/x-saherelm.xtm.indicator.mq5 new file mode 100644 index 0000000..eac88e0 --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xtm.indicator.mq5 @@ -0,0 +1,349 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Indicator +// --------------------------------------------- +// Name: XTM +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int maPeriod = 14; // Period +input int maShift = 0; // Shift +input ENUM_MA_METHOD maMethod = MODE_SMA; // Method +input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XTM" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + maPeriod, + maShift, + maMethod, + maAppliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, maPeriod); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (maPeriod >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XTM " + "(" + (string)maPeriod + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XTM_BULLISH : lineColorIndex == 2 ? X_XTM_BEARISH + : X_XTM_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/XEU5-0/Indicators/x-saherelm.xts.oscillator.mq5 b/XEU5-0/Indicators/x-saherelm.xts.oscillator.mq5 new file mode 100644 index 0000000..46e9fbf --- /dev/null +++ b/XEU5-0/Indicators/x-saherelm.xts.oscillator.mq5 @@ -0,0 +1,558 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTS Oscillator +// --------------------------------------------- +// Name: XTS +// Description: Time Sections Oscillator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTS Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XTS" + +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// XTS Oscillator States ... + +// +// END Constants ... +// + +// +// START Inputs ... +// +input group "Current Period"; +input ENUM_APPLIED_PRICE currentAppliedTo = PRICE_CLOSE; // Current Applied To +// +input group "Nearest Period"; +input ENUM_X_PERIOD_METHOD nearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +input ENUM_TIMEFRAMES nearestPeriod = NULL; // Nearest Time Frame +input ENUM_APPLIED_PRICE nearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// +input group "Mediest Period"; +input ENUM_X_PERIOD_METHOD mediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +input ENUM_TIMEFRAMES mediestPeriod = NULL; // Mediest Time Frame +input ENUM_APPLIED_PRICE mediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// +input group "Farest Period"; +input ENUM_X_PERIOD_METHOD farestMethod = X_PERIOD_AUTO; // How to Find Farest Period +input ENUM_TIMEFRAMES farestPeriod = NULL; // Farest Time Frame +input ENUM_APPLIED_PRICE farestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// Current ... +#define currentBufferIndex 0 + +double currentBuffer[]; + +#property indicator_label1 "XTS C" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// Nearest ... +#define nearestBufferIndex 1 + +double nearestBuffer[]; + +#property indicator_label2 "XTS N" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrAqua +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// Mediest ... +#define mediestBufferIndex 2 + +double mediestBuffer[]; + +#property indicator_label3 "XTS M" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrLime +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +// Farest ... +#define farestBufferIndex 3 + +double farestBuffer[]; + +#property indicator_label4 "XTS F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrLightBlue +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +ENUM_TIMEFRAMES mNearestPeriod = NULL; +ENUM_TIMEFRAMES mMediestPeriod = NULL; +ENUM_TIMEFRAMES mFarestPeriod = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Oscillator ShortName ... + SetOscillatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = 30; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + int maxLength = 30; + + // + // Current ... + ArraySetAsSeries(currentBuffer, true); + SetIndexBuffer(currentBufferIndex, currentBuffer, INDICATOR_DATA); + PlotIndexSetInteger(currentBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Nearest ... + ArraySetAsSeries(nearestBuffer, true); + SetIndexBuffer(nearestBufferIndex, nearestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(nearestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Mediest ... + ArraySetAsSeries(mediestBuffer, true); + SetIndexBuffer(mediestBufferIndex, mediestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mediestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Farest ... + ArraySetAsSeries(farestBuffer, true); + SetIndexBuffer(farestBufferIndex, farestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(farestBufferIndex, PLOT_DRAW_BEGIN, maxLength); +} + +// +// Set Oscillator Short Name and also we can define Buffers Labels ... +void SetOscillatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Current ... + CalculateCurrent(bar_index); + + // + // Nearest ... + CalculateNearest(bar_index); + + // + // Mediest ... + CalculateMediest(bar_index); + + // + // Farest ... + CalculateFarest(bar_index); + + // + // Commenting ... + string comment = GenerateDescriptionComment(); + Comment(comment); +} + +// +// Current ... +void CalculateCurrent(int bar_index) +{ + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + _Period, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + currentAppliedTo); + + // + currentBuffer[bar_index] = value; +} + +// +// Nearest ... +void CalculateNearest(int bar_index) +{ + // + if (mNearestPeriod == NULL) + { + // + switch (nearestMethod) + { + // + case X_PERIOD_AUTO: + mNearestPeriod = GetNearestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mNearestPeriod = nearestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mNearestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + nearestAppliedTo); + + // + nearestBuffer[bar_index] = value; +} + +// +// Mediest ... +void CalculateMediest(int bar_index) +{ + // + if (mMediestPeriod == NULL) + { + // + switch (mediestMethod) + { + // + case X_PERIOD_AUTO: + mMediestPeriod = GetMediestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mMediestPeriod = mediestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mMediestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + mediestAppliedTo); + + // + mediestBuffer[bar_index] = value; +} + +// +// Farest ... +void CalculateFarest(int bar_index) +{ + // + if (mFarestPeriod == NULL) + { + // + switch (farestMethod) + { + // + case X_PERIOD_AUTO: + mFarestPeriod = GetFarestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mFarestPeriod = farestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mFarestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + farestAppliedTo); + + // + farestBuffer[bar_index] = value; +} + +// +// Generate Comment ... +string GenerateDescriptionComment() +{ + // + string result = ""; + + // + result += "Nearest : " + EnumToString(mNearestPeriod) + "\n"; + result += "Mediest : " + EnumToString(mMediestPeriod) + "\n"; + result += "Farest : " + EnumToString(mFarestPeriod) + "\n"; + + // + return result; +} +// +// END Functions ... +// diff --git a/XEU5-0/Libraries/.gitkeep b/XEU5-0/Libraries/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Libraries/x-saherelm.alert.lib.mq5 b/XEU5-0/Libraries/x-saherelm.alert.lib.mq5 new file mode 100644 index 0000000..1079063 --- /dev/null +++ b/XEU5-0/Libraries/x-saherelm.alert.lib.mq5 @@ -0,0 +1,200 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Alert Library +// -------------------------------------- +// Name: XAlert +// Description: provides Alerts abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Alerts"; +input bool enableAlerts = true; // Enable Alerts +input bool logAlerts = true; // Log Alerts +input bool terminalAlerts = false; // Terminal Alerts +input bool mailAlerts = false; // Mail Alerts +input bool pushAlerts = false; // Push Alerts +// +// END Inputs ... +// + +// +#include "x-saherelm.log.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string alertPrefix = "X-Alert"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitAlertLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitAlertLibrary() +{ +} + +// +// Attach Alert Prefix to Message ... +string PrepareAlertMessage(string message) +{ + // + StringReplace(message, "\n", " | "); + + // + StringConcatenate(message, alertPrefix, " > ", message); + + // + return message; +} + +// +// Logging an Alert ... +void LogAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !logAlerts) + { + return; + } + + // + LogMessage(alertPrefix, message); +} + +// +// Terminal Alert ... +void TerminalAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !terminalAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // Send Terminal Alert ... + Alert(message); +} + +// +// Mail Alert ... +void MailAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !mailAlerts) + { + return; + } + + // + // Send Mail Alert ... + SendMail(alertPrefix, message); +} + +// +// Send Push Notification ... +void PushAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !pushAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); +} + +// +// Alert Sending ... +void SendAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts) + { + return; + } + + // + // Log ... + if (logAlerts) + { + LogAlert(message); + } + + // + // Terminal ... + if (terminalAlerts) + { + TerminalAlert(message); + } + + // + // Mail ... + if (mailAlerts) + { + MailAlert(message); + } + + // + // Push ... + if (pushAlerts) + { + PushAlert(message); + } +} +void SendAlert( + XSignal &signal, // the Signal Object which requred to Alert + bool asExecuted = true // determines Alert Signal as Executed Signal or not +) +{ + // + // Prepare Message ... + string message = asExecuted ? ExecutedSignalToString(signal) : SignalToString(signal); + + // + // Do Alerting ... + SendAlert(message); +} +// +// END Provided Functions ... +// diff --git a/XEU5-0/Libraries/x-saherelm.common.lib.mq5 b/XEU5-0/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..290dde9 --- /dev/null +++ b/XEU5-0/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,4429 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommon +// Description: provide all commonly used 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 + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// Include Models Library ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Detect is new Candle or not ... +bool IsNewCandle() +{ + // + bool result = false; + + // + static int barsOnChart = 0; + int currentBarsOnChart = Bars(_Symbol, _Period); + result = currentBarsOnChart > barsOnChart; + if (!result) + { + return result; + } + + // + barsOnChart = currentBarsOnChart; + result = true; + + // + return result; +} + +// +// Retrive Ask Price ... +double GetAsk() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_ASK); +} +double GetAsk( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_BID); +} +double GetBid( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_BID); + + // + return result; +} + +// +// Calculate and Retrieve Spread Price ... +double GetSpread() +{ + // + double ask = GetAsk(); + double bid = GetBid(); + double result = MathAbs(ask - bid); + + // + return result; +} +double GetSpread( + string symbol // selected symbol for calculations +) +{ + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Get Points ... +double GetPoints() +{ + return _Point; +} +double GetPoints( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + return result; +} + +// +// Get Digits ... +int GetDigits() +{ + return _Digits; +} +int GetDigits( + string symbol // selected symbol for calculations +) +{ + // + int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Get Signal Entry ... +double GetEntry( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice() +{ + // + double result = _Point; + if (_Digits == 3 || _Digits == 5) + { + result *= 10; + } + + // + return result; +} +double GetPipPrice( + string symbol // selected symbol for calculations +) +{ + // + double symbolPoint = GetPoints(symbol); + int symbolDigits = GetDigits(symbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + int pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + double pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + int pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + double pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(); + double pipPrice = GetPipPrice(); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PriceToPips( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(symbol); + double pipPrice = GetPipPrice(symbol); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Get a Candle Body ... +double GetCandleBody( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.open - candle.close); + + // + return result; +} + +// +// Get a Candle Range ... +double GetCandleRange( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.high - candle.low); + + // + return result; +} + +// +// Get a Candle Shadow ... +double GetCandleShadow( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + double result = MathAbs(range - body); + + // + return result; +} + +// +// Retrieve Applied Price at Specific Candle ... +double GetAppliedPrice( + XOHCL &candle, // specified candle + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + switch (source) + { + // + // Open ... + case PRICE_OPEN: + result = candle.open; + break; + + // + // High ... + case PRICE_HIGH: + result = candle.high; + break; + + // + // Low ... + case PRICE_LOW: + result = candle.low; + break; + + // + // Median ((High + Low) / 2) ... + case PRICE_MEDIAN: + result = (candle.high + candle.low) / 2; + break; + + // + // Typical ((High + Low + Close)/3) ... + case PRICE_TYPICAL: + result = (candle.high + candle.low + candle.close) / 3; + break; + + // + // Weighted ((High + Low + Close + Close)/4) ... + case PRICE_WEIGHTED: + result = (candle.high + candle.low + (candle.close * 2)) / 4; + break; + + // + // Close ... + default: + case PRICE_CLOSE: + result = candle.close; + break; + } + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + XOHCL candle = GetCandle(bar_index); + result = GetAppliedPrice(candle, source); + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + double result = 0; + + // + ENUM_APPLIED_PRICE mAppliedTo = To(mode); + result = GetAppliedPrice( + bar_index, + mAppliedTo); + + // + return result; +} + +// +// Converts ... +ENUM_APPLIED_PRICE To( + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + ENUM_APPLIED_PRICE result = PRICE_CLOSE; + + // + switch (mode) + { + // + // High ... + case MODE_HIGH: + result = PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve a Candel Data ... +XOHCL GetCandle(int bar_index) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + double close = iClose(_Symbol, _Period, bar_index); + double low = iLow(_Symbol, _Period, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, mPeriod, bar_index); + double high = iHigh(_Symbol, mPeriod, bar_index); + double close = iClose(_Symbol, mPeriod, bar_index); + double low = iLow(_Symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(symbol, mPeriod, bar_index); + double high = iHigh(symbol, mPeriod, bar_index); + double close = iClose(symbol, mPeriod, bar_index); + double low = iLow(symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} + +// +// Retrieve a candle index in current timeframe inside another timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(_Symbol, _Period, bar_index); + result = iBarShift(_Symbol, destPeriod, barTime); + + // + return result; +} + +// +// Retrieve a symbol candle index in source time frame inside dest timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + string symbol, // Specify desired Symbol + ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(symbol, sourcePeriod, bar_index); + result = iBarShift(symbol, destPeriod, barTime); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBullishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open < candle.close; + + // + return result; +} +bool IsBullishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} +bool IsBullishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBearishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open > candle.close; + + // + return result; +} +bool IsBearishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} +bool IsBearishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} + +// +// Check Candle Body Bigger Than it's Shadow ... +bool HasStrongBody(XOHCL &candle) +{ + // + double bodySize = MathAbs(candle.open - candle.close); + double shadowSize = MathAbs(candle.high - candle.low) - bodySize; + + // + bool result = bodySize > (shadowSize * 1.5); + + // + return result; +} + +// +// Determines a cnadle is Swing High +// or Swing Low order block ... +ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(bar_index + 1); + candles[1] = GetCandle(bar_index + 2); + candles[2] = GetCandle(bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(mPeriod, bar_index + 1); + candles[1] = GetCandle(mPeriod, bar_index + 2); + candles[2] = GetCandle(mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); + candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); + candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} + +// +// Retrieve Market Highest High ... +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Retrieve Market Lowest Low ... +double GetLowestLow( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} + +// +// Check first Cross Over second at bar_index ... +bool IsCrossOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + !(first[bar_index + 1] > second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Over second at bar_index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + first[bar_index + 1] > second[bar_index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at bar_index ... +bool IsCrossUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + !(first[bar_index + 1] < second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Under second at bar_index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + first[bar_index + 1] < second[bar_index + 1]; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + int from, // In Past Index ... + int to, // In Past Index ... + double &buffer[]) +{ + // + double result = 0; + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Get Max Value of Specific Loopback of a Buffer ... +double GetMaxValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min Value of Specific Loopback of a Buffer ... +double GetMinValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +bool IsInPeak( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue > lastValue + // + && + // + ( + firstValue > q1Value && + firstValue > halfValue) + // + ; + + // + return result; +} + +// +bool IsInVale( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue < lastValue + // + && + // + ( + firstValue < q1Value && + firstValue < halfValue) + // + ; + + // + return result; +} + +// +// Check Sharp Happens or not ... +bool IsSharpChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check InCreased Sharp Happens or not ... +bool IsSharpIncreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check Decreased Sharp Happens or not ... +bool IsSharpDecreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + !isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Validate Struct ... +bool IsValid(XSignal &model, ulong magicNumber) +{ + // + bool result = false; + + // + // Validate Signal Type ... + result = model.type != X_SIGNAL_UNKNOWN; + if (!result) + { + return result; + } + + // + // Check Symbol ... + result = StringLen(model.symbol) == 0 ? true : model.symbol == _Symbol; + if (!result) + { + return result; + } + + // + // Check magic number ... + result = model.magicNumber <= 0 ? true : model.magicNumber == magicNumber; + if (!result) + { + return result; + } + + // + // Check Entry ... + result = model.entry > 0; + if (!result) + { + return result; + } + + // + // Check SL ... + result = model.sl == 0 ? true : model.type == X_SIGNAL_LONG ? model.sl < model.entry + : model.sl > model.entry; + if (!result) + { + return result; + } + + // + // Check TP ... + result = model.tp == 0 ? true : model.type == X_SIGNAL_LONG ? model.tp > model.entry + : model.tp < model.entry; + if (!result) + { + return result; + } + + // + // Check Volume ... + result = model.volume > 0; + if (!result) + { + return result; + } + + // + // Check Time ... + result = model.time > 0; + if (!result) + { + return result; + } + + // + return result; +} + +// +void CleanBuffer(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(ulong &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(double &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(XSignal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(XDeal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(XOrder &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +bool GetLastItem( + double &item, // Holds Result + double &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} +bool GetLastItem( + datetime &item, // Holds Result + datetime &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} + +// +void Add( + int item, // item want to add + int &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + ulong item, // item want to add + ulong &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + string item, // item want to add + string &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + double item, // item want to add + double &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOHCL &item, // item want to add + XOHCL &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + datetime &item, // item want to add + datetime &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XSignal &item, // item want to add + XSignal &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XDeal &item, // item want to add + XDeal &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOrder &item, // item want to add + XOrder &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Converts a Buffer to String Representation ... +string ToString( + const int &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const double &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const string &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const datetime &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} + +// +// Check a Signal is Long or not ... +bool IsLong(ENUM_X_SIGNAL_TYPE type) +{ + return type == X_SIGNAL_LONG; +} +bool IsLong(XSignal &signal) +{ + // + bool result = IsLong(signal.type); + + // + return result; +} + +// +// Check a Signal is Short or not ... +bool IsShort(ENUM_X_SIGNAL_TYPE type) +{ + return type == X_SIGNAL_SHORT; +} +bool IsShort(XSignal &signal) +{ + // + bool result = IsShort(signal.type); + + // + return result; +} + +// +// Retrieve a Signal Type String Value ... +string GetSignalType(ENUM_X_SIGNAL_TYPE type) +{ + // + string result = ""; + + // + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + result = type == X_SIGNAL_LONG ? "Long" : "Short"; + + // + return result; +} +string GetSignalType(XSignal &signal) +{ + // + string result = ""; + + // + result = GetSignalType(signal.type); + + // + return result; +} +ENUM_X_SIGNAL_TYPE GetSignalType(string typeStr) +{ + // + ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; + + // + if (typeStr == GetSignalType(X_SIGNAL_LONG)) + { + result = X_SIGNAL_LONG; + } + else if (typeStr == GetSignalType(X_SIGNAL_SHORT)) + { + result = X_SIGNAL_SHORT; + } + + // + return result; +} + +// +// Retrieve Signal Execution String ... +string GetSignalExecutionError(int error) +{ + // + string result = ""; + + // + switch (error) + { + // + case X_TRADER_INVALID_SIGNAL_ERROR: + result = "Invalid Signal ..."; + break; + + // + case X_TRADER_NOT_ENOUGH_EQUITY_ERROR: + result = "Not Enough Equity for Trade ..."; + break; + + // + case X_TRADER_NOT_ENOUGH_BALANCE_ERROR: + result = "Not Enough Balance for Trade ..."; + break; + + // + case X_TRADER_NOT_ENOUGH_MARIGIN_ERROR: + result = "Not Enough Marigin For Trade ..."; + break; + + // + case X_TRADER_MAX_TRADES_REACHED_ERROR: + result = "Max Allowed Trade Reached ..."; + break; + + // + case X_TRADER_UNKNOWN_ERROR: + default: + result = "Unknown Issue ..."; + break; + } + + // + return result; +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double volume, // desired volume to normalize + string symbol = NULL, // Specified Symbol for Normalization + int mLength = 2 // Length of Digits +) +{ + // + double result = volume; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Normalize Digits ... + int digits = GetDigits(symbol); + mLength = + mLength == 0 || mLength > digits + ? digits + : MathMin(mLength, digits); + + // + // Normalize Volume ... + result = NormalizeDouble(result, mLength); + + // + double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double price, // desired Price for normalization + string symbol = NULL // Specified Symbol for Normalization +) +{ + // + double result = 0; + + // + // Mormalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + int digits = GetDigits(symbol); + result = NormalizeDouble(price, digits); + + // + return result; +} + +// +// Error Descriptions Functions ... +// + +// +// Retrieve Specified Error Code Description ... +string GetErrorDescription(int err_code) +{ + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; +} + +// +// Retrieve Specified Error Code Description ... +string GetTradeServerReturnCodeDescription(int return_code) +{ + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; +} + +// +// Check Expert Running in Testing Mode or not ... +bool IsRunningOnTestMode() +{ + // + bool result = false; + + // + // check programm mode ... + result = MQL5InfoInteger(MQL5_TESTING); + + // + return result; +} + +// +// Date Time Manipulation Functions ... +// + +// +// Representation of Time Struct ... +// struct MqlDateTime +// { +// int year; // Year +// int mon; // Month +// int day; // Day +// int hour; // Hour +// int min; // Minutes +// int sec; // Seconds +// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) +// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) +// }; + +// +// Converts Time to Seconds ... +ulong TimeToSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = (ulong)time; + + // + return result; +} +ulong TimeToSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToSeconds(dTime); + + // + return result; +} + +// +// Converts Seconds To Time ... +datetime SecondsToTime( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime result = (datetime)seconds; + + // + return result; +} +MqlDateTime SecondsToStruct( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime dTime = SecondsToTime(seconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Converts Time to MilliSeconds ... +ulong TimeToMilliSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = TimeToSeconds(time) * 1000; + + // + return result; +} +ulong TimeToMilliSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToMilliSeconds(dTime); + + // + return result; +} + +// +// Converts MillisSeconds to Time ... +datetime MilliSecondsToTiem( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + ulong seconds = milliSeconds / 1000; + + // + datetime result = SecondsToTime(seconds); + + // + return result; +} +MqlDateTime MilliSecondsToStruct( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + datetime dTime = MilliSecondsToTiem(milliSeconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Retrieve DateTime Structure ... +MqlDateTime GetCurrentTime() +{ + // + MqlDateTime result = {}; + + // + TimeCurrent(result); + + // + return result; +} + +// +// Retrieve Current Time as Seconds ... +ulong GetCurrentTimeAsSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Current Time as MilliSeconds ... +ulong GetCurrentTimeAsMilliSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +datetime GetCandleTime( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Validate and Normalize Args ... + + // + // Normalize Symbol ... + symbol = StringLen(symbol) == 0 + ? _Symbol + : symbol; + + // + // Normalize Period ... + period = period == NULL + ? _Period + : period; + + // + // Retrieve Bar Time ... + datetime result = iTime( + symbol, + period, + bar_index); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsMilliSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve a Candle Time Structure ... +MqlDateTime GetCandleTimeStruct( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + MqlDateTime result = {}; + + // + // Retrieve Bar Time ... + datetime barTime = GetCandleTime( + symbol, + period, + bar_index); + + // + // Convert to Structure ... + TimeToStruct(barTime, result); + + // + return result; +} + +// +// +// + +// +// Holds Month ... +static int xMonth = -1; + +// +// Holds Day Of Week ... +static int xDayOfWeek = -1; +static int xForWeekDay = -1; + +// +// Holds Day ... +static int xDay = -1; + +// +// Holds Hour ... +static int xHour = -1; + +// +// Reset Timing Variables ... +void ResetTiming() +{ + // + xHour = -1; + xDay = -1; + xDayOfWeek = -1; + xMonth = -1; +} + +// +// Detecting New Houre ... +bool IsNewHour() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.hour != xHour; + if (result) + { + xHour = timeStruct.hour; + } + + // + return result; +} + +// +// Detecting New Day ... +bool IsNewDay() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.day_of_year != xDay; + if (result) + { + xDay = timeStruct.day_of_year; + } + + // + return result; +} + +// +// Detecting New Week ... +bool IsNewWeek() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Week ... + // Since Week Starts From Monday in Forex World ... + // we Calculate Start of Week by 1-Monday ... + result = + xDayOfWeek == -1 && + xForWeekDay == -1 + ? true + : timeStruct.day_of_week == 1 && + timeStruct.day_of_year > xForWeekDay; + + // + xForWeekDay = timeStruct.day_of_year; + xDayOfWeek = timeStruct.day_of_week; + + // + return result; +} + +// +// Detecting End Of Week ... +bool IsWeekEnd() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check WeekEnd ... + // Since Week Starts From Monday in Forex World ... + // we Calculate End of Week by 5-Friday ... + result = + xDayOfWeek != -1 && + timeStruct.day_of_week == 5 && + timeStruct.hour == 23 && + timeStruct.min == 59 && + timeStruct.sec == 59; + + // + return result; +} + +// +// Detecting New Month ... +bool IsNewMonth() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.mon != xMonth; + if (result) + { + xMonth = timeStruct.mon; + } + + // + return result; +} + +// +// Find Farest Time Frame ... +ENUM_TIMEFRAMES GetFarestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + case PERIOD_M30: + result = PERIOD_H4; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + result = PERIOD_H12; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Medium Time Frame ... +ENUM_TIMEFRAMES GetMediestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H1; + break; + + // + case PERIOD_M30: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Nearest Time Frame ... +ENUM_TIMEFRAMES GetNearestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M5; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_M30: + result = PERIOD_H1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Get Specific Time Frame Start Candle Time ... +datetime GetPeriodStartTime( + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + datetime mTime = NULL // Specified Bar Time ... +) +{ + // + // Normalize Arg ... + + // + if ( + mSymbol == NULL || + StringLen(mSymbol) == 0) + { + mSymbol = _Symbol; + } + + // + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if ( + mTime < 0 || + mTime == NULL) + { + mTime = TimeCurrent(); + } + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false); + + // + datetime result = iTime( + mSymbol, + mPeriod, + barIndex); + + // + return result; +} + +// +// END Provided Functions ... +// diff --git a/XEU5-0/Libraries/x-saherelm.draw.lib.mq5 b/XEU5-0/Libraries/x-saherelm.draw.lib.mq5 new file mode 100644 index 0000000..ece98c8 --- /dev/null +++ b/XEU5-0/Libraries/x-saherelm.draw.lib.mq5 @@ -0,0 +1,2345 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Draw Library +// -------------------------------------- +// Name: XDraw +// Description: provides Draw abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// Include Logger Library ... +#include "x-saherelm.log.lib.mq5" +#include "x-saherelm.common.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string drawPrefix = "X-OBJ"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// DeInitial Library if required ... +void OnDeinitDrawLibrary() +{ + RemoveDraws(); +} + +// +void DrawSignalShape( + XSignal &signal, // Specify Signal to Draw + color longColor = clrAqua, // Long Signals Color + color shortColor = clrFuchsia, // Short Signal Color + color entryColor = clrGold // Signal Entry Price Color +) +{ + // + // Draw Signal Info : + // - Draw Entry Price Line; + // - Draw SL; + // - Draw TP; + // - Risk Free; + + // + bool isLong = signal.type == X_SIGNAL_LONG; + + // + color tpColor = longColor; + color slColor = shortColor; + + // + string name = "T(" + (string)signal.ticket + ")" + "_" + "TY(" + EnumToString(signal.type) + ")"; + + // + string tpName = "TP_" + name; + if (IsDrawExists(tpName)) + { + RemoveDraw(tpName); + } + + // + string slName = "SL_" + name; + if (IsDrawExists(slName)) + { + RemoveDraw(slName); + } + + // + string riskFreeName = "RF_" + name; + if (IsDrawExists(riskFreeName)) + { + RemoveDraw(riskFreeName); + } + + // + string entryName = "Entry_" + name; + if (IsDrawExists(entryName)) + { + RemoveDraw(entryName); + } + + // + string vlName = "Time_" + name; + if (IsDrawExists(vlName)) + { + RemoveDraw(vlName); + } + + // + int signalBarIndex = iBarShift( + signal.symbol, + _Period, + signal.time); + + // + datetime time1 = iTime( + signal.symbol, + _Period, + signalBarIndex + 1); + datetime time2 = iTime( + signal.symbol, + _Period, + signalBarIndex - 1); + + // + // Entry ... + bool isTrendLineDrawn = DrawTrendLine( + 0, + entryName, + 0, + time1, + signal.entry, + time2, + signal.entry, + entryColor); + + // + // TP ... + bool isTPDrawn = false; + if (signal.tp > 0) + { + // + isTPDrawn = DrawTrendLine( + 0, + tpName, + 0, + time1, + signal.tp, + time2, + signal.tp, + tpColor, + STYLE_SOLID, + 1, + false, + true); + } + + // + // RISKFREE ... + bool isRFDrawn = false; + if (signal.riskFreeStep > 0) + { + // + double firstStepPrice = isLong ? signal.entry + PipsToPrice(signal.riskFreeStep) + : signal.entry - PipsToPrice(signal.riskFreeStep); + + // + isRFDrawn = DrawTrendLine( + 0, + riskFreeName, + 0, + time1, + firstStepPrice, + time2, + firstStepPrice, + tpColor, + STYLE_DOT, + 1, + false, + true); + } + + // + // SL ... + bool isSLDrawn = false; + if (signal.sl > 0) + { + // + isSLDrawn = DrawTrendLine( + 0, + slName, + 0, + time1, + signal.sl, + time2, + signal.sl, + slColor, + STYLE_SOLID, + 1, + false, + true); + } + + // + // Draw a Vertical Line ... + bool isVerticalLineDrawn = DrawVerticalLine( + 0, + vlName, + 0, + signal.time, + slColor); +} + +// +// remove drawn objects ... +void RemoveDraws( + string tag = NULL, + int chartId = -1, + int subWindow = -1) +{ + // + // Normalize Args ... + // + if (tag == NULL) + { + tag = drawPrefix; + } + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, tag) >= 0) + { + ObjectDelete(chartId, on); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + +// +bool RemoveDraw( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + string objName = ""; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, name) >= 0) + { + // + objName = on; + break; + } + } + + // + if (StringLen(objName) > 0) + { + result = ObjectDelete(chartId, objName); + } + + // + return result; +} + +// +// Check Object Exists ... +bool IsDrawExists( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + result = StringFind(on, name) >= 0; + if (result) + { + break; + } + } + + // + return result; +} +// +// END Provided Functions ... +// + +// +// START Regular Draws ... +// + +// +// START Arrow Functions ... +// +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = 252, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create an arrow ... + if (!ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete an arrow ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change the arrow code ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) + { + // + string message = + __FUNCTION__ + + ": failed to change the arrow code! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change anchor type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) + { + // + string message = + __FUNCTION__ + + ": failed to change anchor type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Arrow Functions ... +// + +// +// START Horizontal Line Functions ... +// +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the price is not set, set it at the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a horizontal line ... + if (!ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) +{ + // + // if the line price is not set, move it to the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move a horizontal line ... + if (!ObjectMove(chartID, name, 0, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a horizontal line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} +// +// END Horizontal Line Functions ... +// + +// +// START Vertical Line Functions ... +// +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int sub_window = 0, // subwindow index + datetime time = 0, // line time + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the line time is not set, draw it via the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a vertical line ... + if (!ObjectCreate(chartID, objName, OBJ_VLINE, sub_window, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) +{ + // + // if line time is not set, move the line to the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the vertical line ... + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the vertical line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END Vertical Line Functions ... +// + +// +// START RectangleLabel Functions ... +// +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color back_clr = clrWhiteSmoke, // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + //--- create a rectangle label + if (!ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, back_clr); + + // + // set border type ... + ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the label by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // move the rectangle label ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) + { + // + string message = + __FUNCTION__ + + ": failed to move X coordinate of the label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) + { + // + string message = + __FUNCTION__ + + ": failed to move Y coordinate of the label! Error code = " + + (string)GetLastError(); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the label ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change label size ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's width! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's height! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change border type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) + { + // + string message = + __FUNCTION__ + + ": failed to change the border type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} +// +// END RectangleLabel Functions ... +// + +// +// START TrendLine Funcions ... +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a trend line by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move trend line's anchor point ... + if (!ObjectMove(chartID, name, pointindex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a trend line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) + { + price2 = price1; + } +} +// +// END TrendLine Functions ... +// + +// +// START Text Functions ... +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + //--- create Text object + if (!ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set the text ... + ObjectSetString(chartID, objName, OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, objName, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the object by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + //--- if point position is not set, move it to the current bar having Bid price + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point .. + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change object text ... + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Text Functions ... +// + +// +// START Fibonacchi Functions ... +// +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + bool result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + objName); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // check array sizes ... + if ( + levels != ArraySize(colors) || + levels != ArraySize(styles) || + levels != ArraySize(widths) || + levels != ArraySize(widths)) + { + // + string message = + __FUNCTION__ + + ": array length does not correspond to the number of levels, error!"; + + // + LogMessage(message); + + // + return (false); + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for (int i = 0; i < levels; i++) + { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return (true); +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, pointIndex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) + { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) + { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time2, 10, temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) + { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} +// +// END Fibonacci Functions ... +// + +// +// START Event Functions ... +// + +// +// Create an Event ... +bool EventCreate( + const long chartID = 0, // chart's ID + const string name = "Event", // object name + const int subWindow = 0, // subwindow index + const string text = "Content", // event text + datetime time = 0, // anchor point time + const color clr = clrRed, // color + const int width = 1, // point width when highlighted + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + if (!time) + { + time = TimeCurrent(); + } + + // + ResetLastError(); + + // + if (!ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set event text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set anchor point width if the object is highlighted + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving event by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution + return (true); +} + +// +// Change Event object text +bool EventTextChange( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + const string text = "Content" // text +) +{ + // + // reset the error value + ResetLastError(); + + // + // change object text + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Move Event object +bool EventMove( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + datetime time = 0 // time +) +{ + // + // if time is not set, move event to the last bar + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // move the object + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Delete Event object +bool EventDelete( + const long chartID = 0, // chart's ID + const string name = "Event" // event name +) +{ + // + // reset the error value + ResetLastError(); + + // + // delete the object + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// END Event Functions ... +// + +// +// END Regular Draws ... +// + +// +// START Chart Style Drawers ... +// +// +// Apply Styles On Chart ... +void ApplyChartStyle( + int chartId = -1, // chart's ID + ENUM_CHART_MODE mode = CHART_CANDLES, // chart's mode + bool showBidLine = true, // show bid line + bool showAskLine = true, // show ask line + bool showGrid = false, // show grids on chart + bool showVolumes = false, // show volumes + bool showTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool autoScroll = true, // chart autoscroll + bool quickNavigation = true, // chart quick navigation state + color foreGroundColor = clrWhite, // chart's foreground color + color backGroundColor = clrBlack, // chart's background color + color upColor = clrGreen, // Up Color + color downColor = clrRed, // Down Color + color bullishColor = clrGreen, // Bullish color + color bearishColor = clrRed, // Bearish color + color gridColor = clrGray, // grid color + color bidLineColor = clrGray, // bid line color + color askLineColor = clrRed, // ask line color + color lineColor = clrLime, // line mode and doji candlestick color + color stopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color volumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (chartId == -1) + { + chartId = 0; + } + + // + ChartSetInteger(chartId, CHART_MODE, mode); + ChartSetInteger(chartId, CHART_SHOW_BID_LINE, showBidLine); + ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, showAskLine); + ChartSetInteger(chartId, CHART_SHOW_GRID, showGrid); + ChartSetInteger(chartId, CHART_SHOW_VOLUMES, showVolumes); + ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, showTradeLevels); + ChartSetInteger(chartId, CHART_AUTOSCROLL, autoScroll); + ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, quickNavigation); + ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, foreGroundColor); + ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, backGroundColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_UP, upColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, downColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, bullishColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, bearishColor); + ChartSetInteger(chartId, CHART_COLOR_GRID, gridColor); + ChartSetInteger(chartId, CHART_COLOR_BID, bidLineColor); + ChartSetInteger(chartId, CHART_COLOR_ASK, askLineColor); + ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, stopColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, lineColor); + ChartSetInteger(chartId, CHART_COLOR_VOLUME, volumesColor); +} +// +// END Chart Style Drawers ... +// \ No newline at end of file diff --git a/XEU5-0/Libraries/x-saherelm.http.lib.mq5 b/XEU5-0/Libraries/x-saherelm.http.lib.mq5 new file mode 100644 index 0000000..97f7ac0 --- /dev/null +++ b/XEU5-0/Libraries/x-saherelm.http.lib.mq5 @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Http Library +// ------------------------------------------ +// Name: XHttp +// Description: provide http communication +// abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Model Definition ... +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; +// +// END Model Definition ... +// + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitHttpLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitHttpLibrary() +{ +} + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// +// Send Global Request ... +int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) +{ + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) { + return result; + } + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders + ); + + // + return result; +} + +// +// Get Request ... +int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} + +// +// Post Request ... +int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} +// +// END Provided Functions ... +// diff --git a/XEU5-0/Libraries/x-saherelm.log.lib.mq5 b/XEU5-0/Libraries/x-saherelm.log.lib.mq5 new file mode 100644 index 0000000..70f1bda --- /dev/null +++ b/XEU5-0/Libraries/x-saherelm.log.lib.mq5 @@ -0,0 +1,261 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Logger Library +// --------------------------------------- +// Name: XLogger +// Description: provides Logging abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Logging"; +input bool enableLogging = true; // Enable Logging +// +// END Inputs ... +// + +// +// Including Models ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string logTag = "X-Logger"; // LogTag +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Logging a Message ... +void LogMessage(string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, " > ", message); +} +void LogMessage(string tag, string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(tag, " > ", message); +} + +// +// Logging an Array ... +void LogArray(int &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(double &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(string &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} + +// +// Convert a Signal to String Message ... +string SignalToString(const XSignal &signal) +{ + // + string result = "\n"; + + // + result += "Signal: " + "\n"; + result += "id: " + (string)signal.id + "\n"; + result += "symbol: " + signal.symbol + "\n"; + result += "type: " + EnumToString(signal.type) + "\n"; + result += "magicNumber: " + (string)signal.magicNumber + "\n"; + result += "ticket: " + (string)signal.ticket + "\n"; + result += "entry: " + (string)signal.entry + "\n"; + result += "tp: " + (string)signal.tp + "\n"; + result += "sl: " + (string)signal.sl + "\n"; + result += "riskFreeStep: " + (string)signal.riskFreeStep + "\n"; + result += "riskFreeRate: " + (string)signal.riskFreeRate + "\n"; + result += "profit: " + (string)signal.profit + "\n"; + result += "time: " + (string)signal.time + "\n"; + result += "volume: " + (string)signal.volume + "\n"; + result += "comment: " + signal.comment + "\n"; + + // + return result; +} + +// +// Convert an Executed Signal to String Message ... +string ExecutedSignalToString(const XSignal &signal) +{ + // + string result = ""; + + // + result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal Executed provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment; + + // + return result; +} + +// +// Logging Signal ... +void LogSignal(const XSignal &signal) +{ + // + string message = SignalToString(signal); + + // + LogMessage(message); +} + +// +// Log Signal Execution ... +void LogExecutedSignal(const XSignal &signal) +{ + // + string message = ExecutedSignalToString(signal); + + // + LogMessage(message); +} + +// +// Convert a Deal to String ... +string DealToString(const XDeal &deal) +{ + // + string result = "\n"; + + // + result += "Deal:" + "\n"; + result += " " + "\n"; + result += "time: " + (string)deal.time + "\n"; + result += "ticket: " + (string)deal.ticket + "\n"; + result += "order: " + (string)deal.order + "\n"; + result += "positionId: " + (string)deal.positionId + "\n"; + result += "type: " + EnumToString(deal.type) + "\n"; + result += "entry: " + EnumToString(deal.entry) + "\n"; + result += "reason: " + EnumToString(deal.reason) + "\n"; + result += "symbol: " + deal.symbol + "\n"; + result += "price: " + (string)deal.price + "\n"; + result += "profit: " + (string)deal.profit + "\n"; + result += "swap: " + (string)deal.swap + "\n"; + result += "commission: " + (string)deal.commission + "\n"; + result += "volume: " + (string)deal.volume + "\n"; + result += "comment: " + deal.comment + "\n"; + + // + return result; +} + +// +// Log Specific Deal ... +void LogDeal(const XDeal &deal) +{ + // + string message = DealToString(deal); + + // + LogMessage(message); +} + +// +// Convert an Order to String ... +string OrderToString(const XOrder &order) +{ + // + string result = "\n"; + + // + result += "Order: " + "\n"; + result += "magic: " + (string)order.magic + "\n"; + result += "positionId: " + (string)order.positionId + "\n"; + result += "symbol: " + (string)order.symbol + "\n"; + result += "ticket: " + (string)order.ticket + "\n"; + result += "timeSetup: " + (string)order.timeSetup + "\n"; + result += "timeDone: " + (string)order.timeDone + "\n"; + result += "timeExpiration: " + (string)order.timeExpiration + "\n"; + result += "priceOpen: " + (string)order.priceOpen + "\n"; + result += "priceCurrent: " + (string)order.priceCurrent + "\n"; + result += "priceStopLimit: " + (string)order.priceStopLimit + "\n"; + result += "stopLoss: " + (string)order.stopLoss + "\n"; + result += "takeProfit: " + (string)order.takeProfit + "\n"; + result += "volumeInitial: " + (string)order.volumeInitial + "\n"; + result += "volumeCurrent: " + (string)order.volumeCurrent + "\n"; + result += "comment: " + order.comment + "\n"; + result += "type: " + EnumToString(order.type) + "\n"; + result += "state: " + EnumToString(order.state) + "\n"; + result += "typeFilling: " + EnumToString(order.typeFilling) + "\n"; + result += "typeTime: " + EnumToString(order.typeTime) + "\n"; + result += "reason: " + EnumToString(order.reason) + "\n"; + + // + return result; +} + +// +// Log Specific Order ... +void LogOrder(const XOrder &order) +{ + // + string message = OrderToString(order); + + // + LogMessage(message); +} + +// +// END Provided Functions ... +// diff --git a/XEU5-0/Libraries/x-saherelm.models.lib.mq5 b/XEU5-0/Libraries/x-saherelm.models.lib.mq5 new file mode 100644 index 0000000..b98ae3e --- /dev/null +++ b/XEU5-0/Libraries/x-saherelm.models.lib.mq5 @@ -0,0 +1,438 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Models Library +// --------------------------------------- +// Name: XModels +// Description: provides all required models ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// How To Calculate Static Volume ... +enum ENUM_STATIC_VOLUME_METHODS +{ + // + // Based On Deposit ... + X_STATIC_VOLUME_BASED_ON_DEPOSIT, + // + // Based On Balance ... + X_STATIC_VOLUME_BASED_ON_BALANCE, +}; + +// +// START Model Definitions ... +// +// +// OHCL Candel Model ... +enum ENUM_X_PRICE +{ + X_PRICE_HIGH, + X_PRICE_OPEN, + X_PRICE_CLOSE, + X_PRICE_LOW +}; + +// +// Describe an Specific Candle ... +struct XOHCL +{ + double high; + double open; + double close; + double low; +}; + +// +// Swing Types Enum ... +enum ENUM_X_SWING_TYPE +{ + X_NO_SWING = 0, + X_SWING_HIGH = 1, + X_SWING_LOW = -1, +}; + +// +// XTrader Execution Signal Result ... +enum ENUM_EXECUTION_SIGNAL_RESULT +{ + // + X_TRADER_UNKNOWN_ERROR, + X_TRADER_SUCCEED_EXECUTION, + X_TRADER_INVALID_SIGNAL_ERROR, + X_TRADER_NOT_ENOUGH_EQUITY_ERROR, + X_TRADER_MAX_TRADES_REACHED_ERROR, + X_TRADER_NOT_ENOUGH_BALANCE_ERROR, + X_TRADER_NOT_ENOUGH_MARIGIN_ERROR + // +}; + +// +// Signal Types ... +enum ENUM_X_SIGNAL_TYPE +{ + X_SIGNAL_LONG, + X_SIGNAL_SHORT, + X_SIGNAL_UNKNOWN, +}; + +// +// Signal Structure ... +struct XSignal +{ + // + // Identifier ... + ulong id; + + // + // Which Symbol used for Signal ... + string symbol; + + // + // Which Type of operations ... + ENUM_X_SIGNAL_TYPE type; + + // + // Magic Number ... + ulong magicNumber; + + // + // Ticket ... + ulong ticket; + + // + // Entry/Open Price ... + double entry; + + // + // TP ... + double tp; + + // + // SL ... + double sl; + + // + // Make Risk Free Trade on this Value if provided ... + double riskFreeStep; + + // + // a Multiplier for determines how much trade volume exit on risk free time ... + double riskFreeRate; + + // + // Trade Profit ... + double profit; + + // + // Time of Operation ... + datetime time; + + // + // Volume ... + double volume; + + // + // Comment ... + string comment; +}; + +// +// Signal Additional Info ... +struct XProvidedSignal +{ + // + // Suggested TP ... + double tp; + + // + // Suggested SL ... + double sl; + + // + // Signallers ... + string signallers[]; +}; + +// +// Model Specific Deal ... +struct XDeal +{ + // + // the ID of the Expert Advisor, that executed the deal ... + ulong magic; + + // + // the ID of position, in which the deal was involved ... + ulong positionId; + + // + // Ticket ... + ulong ticket; + + // + // the name of the deal symbol ... + string symbol; + + // + // order by which the deal is executed ... + ulong order; + + // + // the time of deal execution ... + datetime time; + + // + // Deal price ... + double price; + + // + // the financial result of the deal (in deposit currency) ... + double profit; + + // + // the amount of swap when position is closed ... + double swap; + + // + // the amount of commission of the deal ... + double commission; + + // + // the volume of deal ... + double volume; + + // + // the deal comment ... + string comment; + + // + // the deal type ... + // ------------------------------------------------------------------ + // DEAL_TYPE_BUY => Buy ... + // DEAL_TYPE_SELL => Sell ... + // DEAL_TYPE_BUY_CANCELED => Canceled buy deal ... + // There can be a situation when a previously executed buy deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ... + // + // DEAL_TYPE_SELL_CANCELED => Canceled sell deal ... + // There can be a situation when a previously executed sell deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation + // + // DEAL_TYPE_BALANCE => Balance ... + // DEAL_TYPE_CREDIT => Credit ... + // DEAL_TYPE_CHARGE => Additional charge ... + // DEAL_TYPE_CORRECTION => Correction ... + // DEAL_TAX => Tax charges ... + // DEAL_TYPE_BONUS => Bonus ... + // DEAL_TYPE_INTEREST => Interest rate ... + // DEAL_DIVIDEND => Dividend operations... + // DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ... + // DEAL_TYPE_COMMISSION => Additional commission ... + // DEAL_TYPE_COMMISSION_DAILY => Daily commission ... + // DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ... + // DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ... + // DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission + ENUM_DEAL_TYPE type; + + // + // the deal direction ... + // ---------------------------------- + // DEAL_ENTRY_IN => Entry in ... + // DEAL_ENTRY_OUT => Entry out ... + // DEAL_ENTRY_INOUT => Reverse ... + // DEAL_ENTRY_OUT_BY => Close a position by an opposite one ... + ENUM_DEAL_ENTRY entry; + + // + // deal reson ... + // --------------------- + // DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ... + // DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ... + // DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ... + // DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ... + // DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ... + // DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ... + // DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ... + // DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ... + // DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ... + // DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ... + ENUM_DEAL_REASON reason; +}; + +// +// Model Specific Order ... +struct XOrder +{ + // + // the ID of expert that placed the order ... + ulong magic; + + // + // the ID of position ... + ulong positionId; + + // + // the name of order symbol ... + string symbol; + + // + // the ticket of an order, previously selected for access ... + ulong ticket; + + // + // the time of order placement ... + datetime timeSetup; + + // + // the time of order execution or cancellation ... + datetime timeDone; + + // + // the order expiration time ... + datetime timeExpiration; + + // + // the order price ... + double priceOpen; + + // + // the current price by order symbol ... + double priceCurrent; + + // + // the price of a pending order ... + double priceStopLimit; + + // + // the order's Stop Loss ... + double stopLoss; + + // + // the order's Take Profit ... + double takeProfit; + + // + // the initial volume of order ... + double volumeInitial; + + // + // the unfilled volume of order ... + double volumeCurrent; + + // + // the order comment ... + string comment; + + // + // the order type ... + // -------------------- + // ORDER_TYPE_BUY => Market Buy order ... + // ORDER_TYPE_SELL => Market Sell order ... + // ORDER_TYPE_BUY_LIMIT => Buy Limit pending order ... + // ORDER_TYPE_SELL_LIMIT => Sell Limit pending order ... + // ORDER_TYPE_BUY_STOP => Buy Stop pending order ... + // ORDER_TYPE_SELL_STOP => Sell Stop pending order ... + // ORDER_TYPE_BUY_STOP_LIMIT => Upon reaching the order price, a pending Buy Limit order is placed at the StopLimit price ... + // ORDER_TYPE_SELL_STOP_LIMIT => Upon reaching the order price, a pending Sell Limit order is placed at the StopLimit price ... + // ORDER_TYPE_CLOSE_BY => Order to close a position by an opposite one ... + ENUM_ORDER_TYPE type; + + // + // the order state ... + // -------------------------- + // ORDER_STATE_STARTED => Order checked, but not yet accepted by broker ... + // ORDER_STATE_PLACED => Order accepted ... + // ORDER_STATE_CANCELED => Order canceled by client ... + // ORDER_STATE_PARTIAL => Order partially executed ... + // ORDER_STATE_FILLED => Order fully executed ... + // ORDER_STATE_REJECTED => Order rejected ... + // ORDER_STATE_EXPIRED => Order expired ... + // ORDER_STATE_REQUEST_ADD => Order is being registered (placing to the trading system) + // ORDER_STATE_REQUEST_MODIFY => Order is being modified (changing its parameters) ... + // ORDER_STATE_REQUEST_CANCEL => Order is being deleted (deleting from the trading system) ... + ENUM_ORDER_STATE state; + + // + // the order filling type ... + // ---------------------------- + // ORDER_FILLING_FOK => Fill or Kill + // An order can be executed in the specified volume only. + // If the necessary amount of a financial instrument is currently unavailable in the market, + // the order will not be executed. + // The desired volume can be made up of several available offers. + // The possibility of using FOK orders is determined at the trade server. + // ORDER_FILLING_IOC => Immediate or Cancel + // A trader agrees to execute a deal with the volume maximally available in the market within that indicated in the order. + // If the request cannot be filled completely, an order with the available volume will be executed, + // and the remaining volume will be canceled. + // The possibility of using IOC orders is determined at the trade server. + // ORDER_FILLING_BOC => Passive (Book or Cancel) + // The BoC order assumes that the order can only be placed in the Depth of Market and cannot be immediately executed. + // If the order can be executed immediately when placed, then it is canceled. + // In fact, the BOC policy guarantees that the price of the placed order will be worse than + // the current market. BoC orders are used to implement passive trading, + // so that the order is not executed immediately when placed and does not affect current liquidity. + // Only limit and stop limit orders are supported (ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT, ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT). + // ORDER_FILLING_RETURN => Return + // In case of partial filling, an order with remaining volume is not canceled but processed further. + // Return orders are not allowed in the Market Execution + // mode (market execution — SYMBOL_TRADE_EXECUTION_MARKET). + ENUM_ORDER_TYPE_FILLING typeFilling; + + // + // the type of order at the time of the expiration ... + // -------------------------------------------------------- + // ORDER_TIME_GTC => Good till cancel order ... + // ORDER_TIME_DAY => Good till current trade day order ... + // ORDER_TIME_SPECIFIED => Good till expired order ... + // ORDER_TIME_SPECIFIED_DAY => The order will be effective till 23:59:59 of the specified day. + // If this time is outside a trading session, the order expires in the nearest trading time ... + ENUM_ORDER_TYPE_TIME typeTime; + + // + // The reason for order placing ... + // -------------------------------------- + // ORDER_REASON_SL => The order was placed as a result of Stop Loss activation ... + // ORDER_REASON_TP => The order was placed as a result of Take Profit activation ... + // ORDER_REASON_SO => The order was placed as a result of the Stop Out event ... + // ORDER_REASON_WEB => The order was placed from a web platform ... + // ORDER_REASON_CLIENT => The order was placed from a desktop terminal ... + // ORDER_REASON_MOBILE => The order was placed from a mobile application ... + // ORDER_REASON_EXPERT => The order was placed from an MQL5-program, i.e. by an Expert Advisor or a script ... + ENUM_ORDER_REASON reason; +}; +// +// END Provided Functions ... +// diff --git a/XEU5-0/Providers/.gitkeep b/XEU5-0/Providers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 b/XEU5-0/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 new file mode 100644 index 0000000..b45d4fd --- /dev/null +++ b/XEU5-0/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 @@ -0,0 +1,9201 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XEU5 Signal Provider Indicators Library +// ---------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Define Enums ... +// + +// +enum ENUM_XEU5_SIGNAL_PROVIDERS +{ + // + // XSP Expert Support Mechanism ... + XSP, + // + // XTD ... + XTD, + // + // XTAM ... + XTAM, + // + // XSI ... + XSI, + // + // XSTFI ... + XSTFI, + // + // XOBDLH ... + XOBDLH, + // + // XCHMACC ... + XCHMACC, + // + // XCHMACMN ... + XCHMACMN, + // + // XCHMACMX ... + XCHMACMX, +}; + +// +// Represent Market Conditions ... +struct XEU5MarketConditions +{ + // + // XTM ... + bool isXTMPeak; + bool isXTMVale; + bool isXTMBullish; + bool isXTMBearish; + bool isXTMNeutural; + bool isXTMEndBullish; + bool isXTMEndBearish; + bool isXTMStartBullish; + bool isXTMStartBearish; + bool isXTMEndBullishByNeutural; + bool isXTMEndBearishByNeutural; + bool isXTMStartBullishAfterNeutural; + bool isXTMStartBearishAfterNeutural; + + // + // XAMA ... + bool isXAMAPeak; + bool isXAMAVale; + bool isXAMABullish; + bool isXAMABearish; + bool isXAMANeutural; + bool isXAMAEndBullish; + bool isXAMAEndBearish; + bool isXAMAStartBullish; + bool isXAMAStartBearish; + bool isXAMAEndBullishByNeutural; + bool isXAMAEndBearishByNeutural; + bool isXAMAStartBullishAfterNeutural; + bool isXAMAStartBearishAfterNeutural; + + // + // XLH ... + bool isXLHHHIncreased; + bool isXLHHHDecreased; + bool isXLHLLIncreased; + bool isXLHLLDecreased; + bool isXLHLowAttachedLL; + bool isXLHHighAttachedHH; + bool isXLHHHSameInLength; + bool isXLHLLSameInLength; + bool isXLHPriceOverSignal; + bool isXLHPriceUnderSignal; + bool isXLHPriceInSignalRange; + bool isXLHPriceCrossedOverSignal; + bool isXLHPriceCrossedUnderSignal; + + // + // XTD ... + bool isXTDSignalPeak; + bool isXTDSignalVale; + bool isXTDBullishPeak; + bool isXTDBullishVale; + bool isXTDBearishPeak; + bool isXTDBearishVale; + bool isXTDBullOverBear; + bool isXTDBullUnderBear; + bool isXTDSignalOverBear; + bool isXTDSignalUnderBear; + bool isXTDBullCrossedOverBear; + bool isXTDBullCrossedUnderBear; + bool isXTDSignalCrossedOverBear; + bool isXTDSignalCrossedUnderBear; + + // + // XFI ... + bool isXFIPeak; + bool isXFIVale; + bool isXFICrossedOverZero; + bool isXFIOverZero; + bool isXFICrossedUnderZero; + bool isXFIUnderZero; + + // + // XTS ... + bool isXTSAllSame; + bool isXTSCurrentMin; + bool isXTSCurrentMax; + bool isXTSCurrentOverFarest; + bool isXTSCurrentOverNearest; + bool isXTSCurrentOverMediest; + bool isXTSCurrentUnderFarest; + bool isXTSCurrentUnderNearest; + bool isXTSCurrentUnderMediest; + bool isXTSCurrentCrossedOverFarest; + bool isXTSCurrentCrossedOverNearest; + bool isXTSCurrentCrossedOverMediest; + bool isXTSCurrentCrossedUnderFarest; + bool isXTSCurrentCrossedUnderNearest; + bool isXTSCurrentCrossedUnderMediest; + + // + // XRSI ... + bool isXRSIPeak; + bool isXRSIVale; + bool isXRSICrossedOverLongExit; + bool isXRSICrossedOverLongEntry; + bool isXRSICrossedUnderShortExit; + bool isXRSICrossedUnderShortEntry; + + // + // XOBD ... + bool isXOBDSwingLow; + bool isXOBDSwingHigh; + + // + // XCHLH ... + // + bool isXCHLHSameHHs; + bool isXCHLHSameLLs; + // + bool isXCHLHSCMCHHSame; + bool isXCHLHSCMCLLSame; + // + bool isXCHLHSCLCHHSame; + bool isXCHLHSCLCLLSame; + // + bool isXCHLHMCLCHHSame; + bool isXCHLHMCLCLLSame; + // + bool isXCHLHMCOnTopOfLC; + bool isXCHLHMCInBottomOfLC; + + // + // XCHMA ... + // + bool isXCHMASCOverMax; + bool isXCHMASCOverMin; + bool isXCHMASCUnderMax; + bool isXCHMASCUnderMin; + // + bool isXCHMASCCrossedOverMax; + bool isXCHMASCCrossedUnderMax; + bool isXCHMASCCrossedOverMin; + bool isXCHMASCCrossedUnderMin; + // + bool isXCHMASCPeak; + bool isXCHMASCVale; + bool isXCHMASCTrendsUp; + bool isXCHMASCTrendsDown; + bool isXCHMASCFastOverSlow; + bool isXCHMASCFastUnderSlow; + bool isXCHMASCFastCrossedOverSlow; + bool isXCHMASCFastCrossedUnderSlow; + // + bool isXCHMAMCPeak; + bool isXCHMAMCVale; + bool isXCHMAMCTrendsUp; + bool isXCHMAMCTrendsDown; + bool isXCHMAMCFastOverSlow; + bool isXCHMAMCFastUnderSlow; + bool isXCHMAMCFastCrossedOverSlow; + bool isXCHMAMCFastCrossedUnderSlow; + // + bool isXCHMALCPeak; + bool isXCHMALCVale; + bool isXCHMALCTrendsUp; + bool isXCHMALCTrendsDown; + bool isXCHMALCFastOverSlow; + bool isXCHMALCFastUnderSlow; + bool isXCHMALCFastCrossedOverSlow; + bool isXCHMALCFastCrossedUnderSlow; +}; + +// +// END Define Enums ... +// + +// +// Include Provider Inputs ... +#include "x-saherelm.xeu5.provider.inputs.lib.mq5" + +// +// Signallers ... +input group "XEU5 Signallers"; + +// +// XTD ... +input group "XEU5 XTD Signaller"; +input bool xEU5XTDEnableSignaller = true; // Enable Signaller +// input bool xEU5XTDEnableTPSL = false; // Enable TP/SL +input bool xEU5XTDAllowLongSignals = true; // Enable Long Signals +input bool xEU5XTDAllowShortSignals = true; // Enable Short Signals + +// +// XTAM ... +input group "XEU5 XTAM Signaller"; +input bool xEU5XTAMEnableSignaller = true; // Enable Signaller +// input bool xEU5XTAMEnableTPSL = false; // Enable TP/SL +input bool xEU5XTAMAllowLongSignals = true; // Enable Long Signals +input bool xEU5XTAMAllowShortSignals = true; // Enable Short Signals + +// +// XSI ... +input group "XEU5 XSI Signaller"; +input bool xEU5XSIEnableSignaller = true; // Enable Signaller +// input bool xEU5SIXEnableTPSL = false; // Enable TP/SL +input bool xEU5XSIAllowLongSignals = true; // Enable Long Signals +input bool xEU5XSIAllowShortSignals = true; // Enable Short Signals + +// +// XSTFI ... +input group "XEU5 XSTFI Signaller"; +input bool xEU5XSTFIEnableSignaller = true; // Enable Signaller +// input bool xEU5XSTFIEnableTPSL = false; // Enable TP/SL +input bool xEU5XSTFIAllowLongSignals = true; // Enable Long Signals +input bool xEU5XSTFIAllowShortSignals = true; // Enable Short Signals + +// +// XOBDLH ... +input group "XEU5 XOBDLH Signaller"; +input bool xEU5XOBDLHEnableSignaller = true; // Enable Signaller +// input bool xEU5XOBDLHEnableTPSL = false; // Enable TP/SL +input bool xEU5XOBDLHAllowLongSignals = true; // Enable Long Signals +input bool xEU5XOBDLHAllowShortSignals = true; // Enable Short Signals + +// +// XCHMACC ... +input group "XEU5 XCHMACC Signaller"; +input bool xEU5XCHMACCEnableSignaller = true; // Enable Signaller +// input bool xEU5XCHMACCEnableTPSL = false; // Enable TP/SL +input bool xEU5XCHMACCAllowLongSignals = true; // Enable Long Signals +input bool xEU5XCHMACCAllowShortSignals = true; // Enable Short Signals + +// +// XCHMACMX ... +input group "XEU5 XCHMACMX Signaller"; +input bool xEU5XCHMACMXEnableSignaller = true; // Enable Signaller +// input bool xEU5XCHMACMXEnableTPSL = false; // Enable TP/SL +input bool xEU5XCHMACMXAllowLongSignals = true; // Enable Long Signals +input bool xEU5XCHMACMXAllowShortSignals = true; // Enable Short Signals + +// +// XCHMACMN ... +input group "XEU5 XCHMACMN Signaller"; +input bool xEU5XCHMACMNEnableSignaller = true; // Enable Signaller +// input bool xEU5XCHMACMNEnableTPSL = false; // Enable TP/SL +input bool xEU5XCHMACMNAllowLongSignals = true; // Enable Long Signals +input bool xEU5XCHMACMNAllowShortSignals = true; // Enable Short Signals + +// +// Imports all Indicators Helper here ... +// input group "XEU5 Provider Indicators"; + +// +#include "../Helpers/x-saherelm.xtm.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xama.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xlh.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xts.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xobd.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5" + +// +bool xEU5IsTestMode = true; +int xEU5MaxLengthOfInputs = 0; +int xEU5CalculatedBars = 0; + +// +// Signaller Variables ... +// +// XTD ... +bool xEU5MXTDEnableSignaller = xEU5XTDEnableSignaller; +// bool xEU5MXTDEnableTPSL = xEU5XTDEnableTPSL; +bool xEU5MXTDAllowLongSignals = xEU5XTDAllowLongSignals; +bool xEU5MXTDAllowShortSignals = xEU5XTDAllowShortSignals; + +// +// XTAM ... +bool xEU5MXTAMEnableSignaller = xEU5XTAMEnableSignaller; +// bool xEU5MXTAMEnableTPSL = xEU5XTAMEnableTPSL; +bool xEU5MXTAMAllowLongSignals = xEU5XTAMAllowLongSignals; +bool xEU5MXTAMAllowShortSignals = xEU5XTAMAllowShortSignals; + +// +// XSI ... +bool xEU5MXSIEnableSignaller = xEU5XSIEnableSignaller; +// bool xEU5MSIXEnableTPSL = xEU5SIXEnableTPSL; +bool xEU5MXSIAllowLongSignals = xEU5XSIAllowLongSignals; +bool xEU5MXSIAllowShortSignals = xEU5XSIAllowShortSignals; + +// +// XSTFI ... +bool xEU5MXSTFIEnableSignaller = xEU5XSTFIEnableSignaller; +// bool xEU5MXSTFIEnableTPSL = xEU5XSTFIEnableTPSL; +bool xEU5MXSTFIAllowLongSignals = xEU5XSTFIAllowLongSignals; +bool xEU5MXSTFIAllowShortSignals = xEU5XSTFIAllowShortSignals; + +// +// XOBDLH ... +bool xEU5MXOBDLHEnableSignaller = xEU5XOBDLHEnableSignaller; +// bool xEU5MXOBDLHEnableTPSL = xEU5XOBDLHEnableTPSL; +bool xEU5MXOBDLHAllowLongSignals = xEU5XOBDLHAllowLongSignals; +bool xEU5MXOBDLHAllowShortSignals = xEU5XOBDLHAllowShortSignals; + +// +// XCHMACC ... +bool xEU5MXCHMACCEnableSignaller = xEU5XCHMACCEnableSignaller; +// bool xEU5MXCHMACCEnableTPSL = xEU5XCHMACCEnableTPSL; +bool xEU5MXCHMACCAllowLongSignals = xEU5XCHMACCAllowLongSignals; +bool xEU5MXCHMACCAllowShortSignals = xEU5XCHMACCAllowShortSignals; + +// +// XCHMAMX ... +bool xEU5MXCHMACMXEnableSignaller = xEU5XCHMACMXEnableSignaller; +// bool xEU5MXCHMACMXEnableTPSL = xEU5XCHMACMXEnableTPSL; +bool xEU5MXCHMACMXAllowLongSignals = xEU5XCHMACMXAllowLongSignals; +bool xEU5MXCHMACMXAllowShortSignals = xEU5XCHMACMXAllowShortSignals; + +// +// XCHMAMN ... +bool xEU5MXCHMACMNEnableSignaller = xEU5XCHMACMNEnableSignaller; +// bool xEU5MXCHMACMNEnableTPSL = xEU5XCHMACMNEnableTPSL; +bool xEU5MXCHMACMNAllowLongSignals = xEU5XCHMACMNAllowLongSignals; +bool xEU5MXCHMACMNAllowShortSignals = xEU5XCHMACMNAllowShortSignals; + +// +// Funded Next Resolve Guards ... +bool isXEU5OnFundedNext = true; + +// +// Here we Define some Global Market Variables to Analyse MArket Conditions +// using them at each time ... +XEU5MarketConditions xEU5Conditions = {}; + +// +// Validate Indicators Inputs ... +bool XEU5ValidateIndicatorsInputs() +{ + // + bool result = false; + + // + // XTM ... + result = XTMValidateInputs(); + if (!result) + { + return result; + } + + // + // XAMA ... + result = XAMAValidateInputs(); + if (!result) + { + return result; + } + + // + // XTD ... + result = XTDValidateInputs(); + if (!result) + { + return result; + } + + // + // XFI ... + result = XFIValidateInputs(); + if (!result) + { + return result; + } + + // + // XTS ... + result = XTSValidateInputs(); + if (!result) + { + return result; + } + + // + // XOBD ... + result = XOBDValidateInputs(); + if (!result) + { + return result; + } + + // + // XLH ... + result = XLHValidateInputs(); + if (!result) + { + return result; + } + + // + // XRSI ... + result = XRSIValidateInputs(); + if (!result) + { + return result; + } + + // + // XCHLH ... + result = XCHLHValidateInputs(); + if (!result) + { + return result; + } + + // + // XCHMA ... + result = XCHMAValidateInputs(); + if (!result) + { + return result; + } + + // + result = true; + + // + return result; +} + +// +// Init Indicators ... +bool XEU5InitIndicators() +{ + // + bool result = false; + + // + // Make it Enable when we need to Log Market Conditions ... + // xEU5IsTestMode = false; // IsRunningOnTestMode(); + + // + // Check and Calculate Max Length in Inputs ... + // + + // + // XTM ... + xEU5MaxLengthOfInputs = MathMax( + xTMMaPeriod, + xEU5NumberOfItemsPerTick); + + // + // XAMA ... + xEU5MaxLengthOfInputs = MathMax( + xAMALength, + xEU5NumberOfItemsPerTick); + xEU5MaxLengthOfInputs = MathMax( + xAMAFastEMA, + xEU5NumberOfItemsPerTick); + xEU5MaxLengthOfInputs = MathMax( + xAMASlowEMA, + xEU5NumberOfItemsPerTick); + + // + // XLH ... + xEU5MaxLengthOfInputs = MathMax( + xLHLength, + xEU5NumberOfItemsPerTick); + + // + // XTD ... + xEU5MaxLengthOfInputs = MathMax( + xTDLength, + xEU5MaxLengthOfInputs); + + // + // XFI ... + xEU5MaxLengthOfInputs = MathMax( + xFILength, + xEU5MaxLengthOfInputs); + + // + // XRSI ... + xEU5MaxLengthOfInputs = MathMax( + xRSILength, + xEU5MaxLengthOfInputs); + + // + // XOBD ... + xEU5MaxLengthOfInputs = MathMax( + xOBDLength, + xEU5MaxLengthOfInputs); + + // + // XCHLH ... + xEU5MaxLengthOfInputs = MathMax( + xCHLHLcLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHLHMcLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHLHScLength, + xEU5MaxLengthOfInputs); + + // + // XCHMA ... + xEU5MaxLengthOfInputs = MathMax( + xCHMAScFastLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMAScSlowLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMAMcFastLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMAMcSlowLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMALcFastLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMALcSlowLength, + xEU5MaxLengthOfInputs); + + // + // Validate Indicators Inputs before Initialization ... + result = XEU5ValidateIndicatorsInputs(); + if (!result) + { + return result; + } + + // + // Validate Signallers ... + + // + // XTD ... + bool isXTDEnable = + xEU5XTDEnableSignaller && + (xEU5XTDAllowLongSignals || + xEU5XTDAllowShortSignals); + + // + // XTAM ... + bool isXTAMEnable = + xEU5XTAMEnableSignaller && + (xEU5XTAMAllowLongSignals || + xEU5XTAMAllowShortSignals); + + // + // XSI ... + bool isXSIEnable = + xEU5XSIEnableSignaller && + (xEU5XSIAllowLongSignals || + xEU5XSIAllowShortSignals); + + // + // XSTFI ... + bool isXSTFIEnable = + xEU5XSTFIEnableSignaller && + (xEU5XSTFIAllowLongSignals || + xEU5XSTFIAllowShortSignals); + + // + // XOBDLH ... + bool isXOBDLHEnable = + xEU5XOBDLHEnableSignaller && + (xEU5XOBDLHAllowLongSignals || + xEU5XOBDLHAllowShortSignals); + + // + // XCHMACC ... + bool isXCHMACCEnable = + xEU5XCHMACCEnableSignaller && + (xEU5XCHMACCAllowLongSignals || + xEU5XCHMACCAllowShortSignals); + + // + // XCHMACMX ... + bool isXCHMACMXEnable = + xEU5XCHMACMXEnableSignaller && + (xEU5XCHMACMXAllowLongSignals || + xEU5XCHMACMXAllowShortSignals); + + // + // XCHMACMN ... + bool isXCHMACMNEnable = + xEU5XCHMACMNEnableSignaller && + (xEU5XCHMACMNAllowLongSignals || + xEU5XCHMACMNAllowShortSignals); + + // + bool hasSignaller = + // + isXTDEnable || + isXTAMEnable || + isXSIEnable || + isXSTFIEnable || + isXOBDLHEnable || + isXCHMACCEnable || + isXCHMACMXEnable || + isXCHMACMNEnable + // + ; + result = hasSignaller; + if (!result) + { + // + LogMessage("XEU5 doesn't enable any Signaller ..."); + + // + return result; + } + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Init ... + result = XTMInitHandlers(); + if (!result) + { + return result; + } + + // + // XAMA Init ... + result = XAMAInitHandlers(); + if (!result) + { + return result; + } + + // + // XLH Init ... + result = XLHInitHandlers(); + if (!result) + { + return result; + } + + // + // XTD Init ... + result = XTDInitHandlers(); + if (!result) + { + return result; + } + + // + // XFI Init ... + result = XFIInitHandlers(); + if (!result) + { + return result; + } + + // + // XTS Init ... + result = XTSInitHandlers(); + if (!result) + { + return result; + } + + // + // XRSI Init ... + result = XRSIInitHandlers(); + if (!result) + { + return result; + } + + // + // XOBD Init ... + result = XOBDInitHandlers(); + if (!result) + { + return result; + } + + // + // XCLH Init ... + result = XCHLHInitHandlers(); + if (!result) + { + return result; + } + + // + // XCHMA Init ... + result = XCHMAInitHandlers(); + if (!result) + { + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XEU5ReleaseIndicators() +{ + // + // Release Handlers ... + XTMReleaseHandlers(); + XAMAReleaseHandlers(); + XLHReleaseHandlers(); + XTDReleaseHandlers(); + XFIReleaseHandlers(); + XTSReleaseHandlers(); + XRSIReleaseHandlers(); + XOBDReleaseHandlers(); + XCHMAReleaseHandlers(); + XCHLHReleaseHandlers(); +} + +// +// Handle Reading Buffers ... +void XEU5HandleReadingBuffers() +{ + // + // Reading Calculated Bars for a Simple Handler ... + xEU5CalculatedBars = BarsCalculated(xTMHandler); + + // + // Read Indicators Buffers ... + XTMReadBuffers(xEU5NumberOfItemsPerTick); + XAMAReadBuffers(xEU5NumberOfItemsPerTick); + XLHReadBuffers(xEU5NumberOfItemsPerTick); + XTDReadBuffers(xEU5NumberOfItemsPerTick); + XFIReadBuffers(xEU5NumberOfItemsPerTick); + XTSReadBuffers(xEU5NumberOfItemsPerTick); + XRSIReadBuffers(xEU5NumberOfItemsPerTick); + XOBDReadBuffers(xEU5NumberOfItemsPerTick); + XCHMAReadBuffers(xEU5NumberOfItemsPerTick); + XCHLHReadBuffers(xEU5NumberOfItemsPerTick); + + // + XEU5ReadConditions(); +} + +// +// +// START Combination Functions ... +// +// + +// +// Can Open Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XEU5CanOpenLongTrade( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + info.tp = 0; + info.sl = 0; + ArrayResize( + info.signallers, + 0); + + // + bool hasSignal = XEU5HasLongSignal(info); + + // + result = + // + hasSignal + // + ; + + // + if (result) + { + XEU5ClearConditions(); + } + + // + return result; +} + +// +// Can Close Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XEU5CanCloseLongTrade() +{ + // + bool result = false; + + // + return result; +} + +// +// Can Open Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XEU5CanOpenShortTrade( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + info.tp = 0; + info.sl = 0; + ArrayResize( + info.signallers, + 0); + + // + bool hasSignal = XEU5HasShortSignal(info); + + // + result = + // + hasSignal + // + ; + + // + if (result) + { + XEU5ClearConditions(); + } + + // + return result; +} + +// +// Can Close Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XEU5CanCloseShortTrade() +{ + // + bool result = false; + + // + return result; +} + +// +// +// END Combination Functions ... +// +// + +// +// +// START Combination Signaling ... +// +// + +// +// Read All Globally Required Conditions ... +void XEU5ReadConditions() +{ + // + XEU5ClearConditions(); + + // + xEU5Conditions = XEU5GenerateMarketConditions(1); +} + +// +// Cleanup Conditions ... +void XEU5ClearConditions() +{ + // + XEU5MarketConditions mConditions = {}; + + // + xEU5Conditions = mConditions; +} + +// +// Generate Merket Conditions for Specified Bar Index ... +XEU5MarketConditions XEU5GenerateMarketConditions( + int bar_index = 1 // Specified Bar Index ... +) +{ + // + XEU5MarketConditions mConditions = {}; + + // + // XTM ... + mConditions.isXTMPeak = XTMIsPeak(bar_index); + mConditions.isXTMVale = XTMIsVale(bar_index); + mConditions.isXTMBullish = XTMIsBullish(bar_index); + mConditions.isXTMBearish = XTMIsBearish(bar_index); + mConditions.isXTMNeutural = XTMIsNeutural(bar_index); + mConditions.isXTMEndBullish = XTMIsEndBullish(bar_index); + mConditions.isXTMEndBearish = XTMIsEndBearish(bar_index); + mConditions.isXTMStartBullish = XTMIsStartBullish(bar_index); + mConditions.isXTMStartBearish = XTMIsStartBearish(bar_index); + mConditions.isXTMEndBullishByNeutural = XTMIsEndBullishByNeutural(bar_index); + mConditions.isXTMEndBearishByNeutural = XTMIsEndBearishByNeutural(bar_index); + mConditions.isXTMStartBullishAfterNeutural = XTMIsStartBullishAfterNeutural(bar_index); + mConditions.isXTMStartBearishAfterNeutural = XTMIsStartBearishAfterNeutural(bar_index); + + // + // XAMA ... + mConditions.isXAMAPeak = XAMAIsPeak(bar_index); + mConditions.isXAMAVale = XAMAIsVale(bar_index); + mConditions.isXAMABullish = XAMAIsBullish(bar_index); + mConditions.isXAMABearish = XAMAIsBearish(bar_index); + mConditions.isXAMANeutural = XAMAIsNeutural(bar_index); + mConditions.isXAMAEndBullish = XAMAIsEndBullish(bar_index); + mConditions.isXAMAEndBearish = XAMAIsEndBearish(bar_index); + mConditions.isXAMAStartBullish = XAMAIsStartBullish(bar_index); + mConditions.isXAMAStartBearish = XAMAIsStartBearish(bar_index); + mConditions.isXAMAEndBullishByNeutural = XAMAIsEndBullishByNeutural(bar_index); + mConditions.isXAMAEndBearishByNeutural = XAMAIsEndBearishByNeutural(bar_index); + mConditions.isXAMAStartBullishAfterNeutural = XAMAIsStartBullishAfterNeutural(bar_index); + mConditions.isXAMAStartBearishAfterNeutural = XAMAIsStartBearishAfterNeutural(bar_index); + + // + // XLH ... + mConditions.isXLHHHIncreased = XLHIsHHIncreased(bar_index); + mConditions.isXLHHHDecreased = XLHIsHHDecreased(bar_index); + mConditions.isXLHLLIncreased = XLHIsLLIncreased(bar_index); + mConditions.isXLHLLDecreased = XLHIsLLDecreased(bar_index); + mConditions.isXLHLowAttachedLL = XLHIsLowAttachedLL(bar_index); + mConditions.isXLHHighAttachedHH = XLHIsHighAttachedHH(bar_index); + mConditions.isXLHHHSameInLength = XLHIsHHSameInLength(bar_index); + mConditions.isXLHLLSameInLength = XLHIsLLSameInLength(bar_index); + mConditions.isXLHPriceOverSignal = XLHIsPriceOverSignal(bar_index); + mConditions.isXLHPriceUnderSignal = XLHIsPriceUnderSignal(bar_index); + mConditions.isXLHPriceInSignalRange = XLHIsPriceInSignalRange(bar_index); + mConditions.isXLHPriceCrossedOverSignal = XLHIsPriceCrossedOverSignal(bar_index); + mConditions.isXLHPriceCrossedUnderSignal = XLHIsPriceCrossedUnderSignal(bar_index); + + // + // XTD ... + mConditions.isXTDSignalPeak = XTDIsSignalPeak(bar_index); + mConditions.isXTDSignalVale = XTDIsSignalVale(bar_index); + mConditions.isXTDBullishPeak = XTDIsBullishPeak(bar_index); + mConditions.isXTDBullishVale = XTDIsBullishVale(bar_index); + mConditions.isXTDBearishPeak = XTDIsBearishPeak(bar_index); + mConditions.isXTDBearishVale = XTDIsBearishVale(bar_index); + mConditions.isXTDBullOverBear = XTDIsBullOverBear(bar_index); + mConditions.isXTDBullUnderBear = XTDIsBullUnderBear(bar_index); + mConditions.isXTDSignalOverBear = XTDIsSignalOverBear(bar_index); + mConditions.isXTDSignalUnderBear = XTDIsSignalUnderBear(bar_index); + mConditions.isXTDBullCrossedOverBear = XTDIsBullCrossedOverBear(bar_index); + mConditions.isXTDBullCrossedUnderBear = XTDIsBullCrossedUnderBear(bar_index); + mConditions.isXTDSignalCrossedOverBear = XTDIsSignalCrossedOverBear(bar_index); + mConditions.isXTDSignalCrossedUnderBear = XTDIsSignalCrossedUnderBear(bar_index); + + // + // XFI ... + mConditions.isXFIPeak = XFIIsPeak(bar_index); + mConditions.isXFIVale = XFIIsVale(bar_index); + mConditions.isXFIOverZero = XFIIsOverZero(bar_index); + mConditions.isXFIUnderZero = XFIIsUnderZero(bar_index); + mConditions.isXFICrossedOverZero = XFIIsCrossedOverZero(bar_index); + mConditions.isXFICrossedUnderZero = XFIIsCrossedUnderZero(bar_index); + + // + // XTS ... + mConditions.isXTSAllSame = XTSIsAllSame(bar_index); + mConditions.isXTSCurrentMin = XTSIsCurrentMin(bar_index); + mConditions.isXTSCurrentMax = XTSIsCurrentMax(bar_index); + mConditions.isXTSCurrentOverFarest = XTSIsCurrentOverFarest(bar_index); + mConditions.isXTSCurrentOverNearest = XTSIsCurrentOverNearest(bar_index); + mConditions.isXTSCurrentOverMediest = XTSIsCurrentOverMediest(bar_index); + mConditions.isXTSCurrentUnderFarest = XTSIsCurrentUnderFarest(bar_index); + mConditions.isXTSCurrentUnderNearest = XTSIsCurrentUnderNearest(bar_index); + mConditions.isXTSCurrentUnderMediest = XTSIsCurrentUnderMediest(bar_index); + mConditions.isXTSCurrentCrossedOverFarest = XTSIsCurrentCrossedOverFarest(bar_index); + mConditions.isXTSCurrentCrossedOverNearest = XTSIsCurrentCrossedOverNearest(bar_index); + mConditions.isXTSCurrentCrossedOverMediest = XTSIsCurrentCrossedOverMediest(bar_index); + mConditions.isXTSCurrentCrossedUnderFarest = XTSIsCurrentCrossedUnderFarest(bar_index); + mConditions.isXTSCurrentCrossedUnderNearest = XTSIsCurrentCrossedUnderNearest(bar_index); + mConditions.isXTSCurrentCrossedUnderMediest = XTSIsCurrentCrossedUnderMediest(bar_index); + + // + // XRSI ... + mConditions.isXRSIPeak = XRSIIsPeak(bar_index); + mConditions.isXRSIVale = XRSIIsVale(bar_index); + mConditions.isXRSICrossedOverLongExit = XRSIIsCrossedOverLongExit(bar_index); + mConditions.isXRSICrossedOverLongEntry = XRSIIsCrossedOverLongEntry(bar_index); + mConditions.isXRSICrossedUnderShortExit = XRSIIsCrossedUnderShortExit(bar_index); + mConditions.isXRSICrossedUnderShortEntry = XRSIIsCrossedUnderShortEntry(bar_index); + + // + // XOBD ... + mConditions.isXOBDSwingLow = XOBDIsSwingLow(bar_index); + mConditions.isXOBDSwingHigh = XOBDIsSwingHigh(bar_index); + + // + // XCHLH ... + // + mConditions.isXCHLHSameHHs = XCHLHIsSameHHs(bar_index); + mConditions.isXCHLHSameLLs = XCHLHIsSameLLs(bar_index); + // + mConditions.isXCHLHSCMCHHSame = XCHLHIsMCSCHasSameHH(bar_index); + mConditions.isXCHLHSCMCLLSame = XCHLHIsMCSCHasSameLL(bar_index); + // + mConditions.isXCHLHSCLCHHSame = XCHLHIsLCSCHasSameHH(bar_index); + mConditions.isXCHLHSCLCLLSame = XCHLHIsLCSCHasSameLL(bar_index); + // + mConditions.isXCHLHMCLCHHSame = XCHLHIsLCMCHasSameHH(bar_index); + mConditions.isXCHLHMCLCLLSame = XCHLHIsLCMCHasSameLL(bar_index); + // + mConditions.isXCHLHMCOnTopOfLC = XCHLHIsMCOnTopOfLC(bar_index); + mConditions.isXCHLHMCInBottomOfLC = XCHLHIsMCInBottomOfLC(bar_index); + + // + // XCHMA ... + // + mConditions.isXCHMASCOverMax = XCHMAIsSCOverMax(bar_index); + mConditions.isXCHMASCOverMin = XCHMAIsSCOverMin(bar_index); + mConditions.isXCHMASCUnderMax = XCHMAIsSCUnderMax(bar_index); + mConditions.isXCHMASCUnderMin = XCHMAIsSCUnderMin(bar_index); + // + mConditions.isXCHMASCCrossedOverMax = XCHMAIsSCCrossedOverMax(bar_index); + mConditions.isXCHMASCCrossedUnderMax = XCHMAIsSCCrossedUnderMax(bar_index); + mConditions.isXCHMASCCrossedOverMin = XCHMAIsSCCrossedOverMin(bar_index); + mConditions.isXCHMASCCrossedUnderMin = XCHMAIsSCCrossedUnderMin(bar_index); + // + mConditions.isXCHMASCPeak = XCHMAIsSCPeak(bar_index); + mConditions.isXCHMASCVale = XCHMAIsSCVale(bar_index); + mConditions.isXCHMASCTrendsUp = XCHMAIsSCTrendsUp(bar_index); + mConditions.isXCHMASCTrendsDown = XCHMAIsSCTrendsDown(bar_index); + mConditions.isXCHMASCFastOverSlow = XCHMAIsSCFastOverSlow(bar_index); + mConditions.isXCHMASCFastUnderSlow = XCHMAIsSCFastUnderSlow(bar_index); + mConditions.isXCHMASCFastCrossedOverSlow = XCHMAIsSCFastCrossedOverSlow(bar_index); + mConditions.isXCHMASCFastCrossedUnderSlow = XCHMAIsSCFastCrossedUnderSlow(bar_index); + // + mConditions.isXCHMAMCPeak = XCHMAIsMCPeak(bar_index); + mConditions.isXCHMAMCVale = XCHMAIsMCVale(bar_index); + mConditions.isXCHMAMCTrendsUp = XCHMAIsMCTrendsUp(bar_index); + mConditions.isXCHMAMCTrendsDown = XCHMAIsMCTrendsDown(bar_index); + mConditions.isXCHMAMCFastOverSlow = XCHMAIsMCFastOverSlow(bar_index); + mConditions.isXCHMAMCFastUnderSlow = XCHMAIsMCFastUnderSlow(bar_index); + mConditions.isXCHMAMCFastCrossedOverSlow = XCHMAIsMCFastCrossedOverSlow(bar_index); + mConditions.isXCHMAMCFastCrossedUnderSlow = XCHMAIsMCFastCrossedUnderSlow(bar_index); + // + mConditions.isXCHMALCPeak = XCHMAIsLCPeak(bar_index); + mConditions.isXCHMALCVale = XCHMAIsLCVale(bar_index); + mConditions.isXCHMALCTrendsUp = XCHMAIsLCTrendsUp(bar_index); + mConditions.isXCHMALCTrendsDown = XCHMAIsLCTrendsDown(bar_index); + mConditions.isXCHMALCFastOverSlow = XCHMAIsLCFastOverSlow(bar_index); + mConditions.isXCHMALCFastUnderSlow = XCHMAIsLCFastUnderSlow(bar_index); + mConditions.isXCHMALCFastCrossedOverSlow = XCHMAIsLCFastCrossedOverSlow(bar_index); + mConditions.isXCHMALCFastCrossedUnderSlow = XCHMAIsLCFastCrossedUnderSlow(bar_index); + + // + return mConditions; +} + +// +// Check Market Conditions by Combination of Power of All tools for LONGs ... +bool XEU5HasLongSignal( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // XTD ... + bool isXTDHasSignal = XEU5XTDHasLongSignal(); + if (isXTDHasSignal) + { + // + Add( + EnumToString(XTD), + info.signallers); + } + + // + // XTAM ... + bool isXTAMHasSignal = XEU5XTAMHasLongSignal(); + if (isXTAMHasSignal) + { + // + Add( + EnumToString(XTAM), + info.signallers); + } + + // + // XSI ... + bool isXSIHasSignal = XEU5XSIHasLongSignal(); + if (isXSIHasSignal) + { + // + Add( + EnumToString(XSI), + info.signallers); + } + + // + // XSTFI ... + bool isXSTFIHasSignal = XEU5XSTFIHasLongSignal(); + if (isXSTFIHasSignal) + { + // + Add( + EnumToString(XSTFI), + info.signallers); + } + + // + // XOBD XLH ... + bool isXOBDLHHasSignal = XEU5XOBDLHHasLongSignal(); + if (isXOBDLHHasSignal) + { + // + Add( + EnumToString(XOBDLH), + info.signallers); + } + + // + // XCHMA Cycles Cross ... + bool isXCHMACCHasSignal = XEU5XCHMACCHasLongSignal(); + if (isXCHMACCHasSignal) + { + // + Add( + EnumToString(XCHMACC), + info.signallers); + } + + // + // XCHMA Cycles Min ... + bool isXCHMACMNHasSignal = XEU5XCHMACMNHasLongSignal(); + if (isXCHMACMNHasSignal) + { + // + Add( + EnumToString(XCHMACMN), + info.signallers); + } + + // + // XCHMA Cycles Max + bool isXCHMACMXHasSignal = XEU5XCHMACMXHasLongSignal(); + if (isXCHMACMXHasSignal) + { + // + Add( + EnumToString(XCHMACMX), + info.signallers); + } + + // + result = + // + isXTDHasSignal + // + || + // + isXTAMHasSignal + // + || + // + isXSIHasSignal + // + || + // + isXSTFIHasSignal + // + || + // + isXOBDLHHasSignal + // + || + // + isXCHMACCHasSignal + // + || + // + isXCHMACMNHasSignal + // + || + // + isXCHMACMXHasSignal + // + ; + + // + if (result) + { + // + // Only Log Signals Time Market Conditions if is in Testing Mode ... + if (xEU5IsTestMode) + { + // + string message = XEU5GetConditionsString(xEU5Conditions, "\n"); + + // + LogMessage( + "Long Signal Provided by: \n" + + info.signallers[ArraySize(info.signallers) - 1] + "\n" + + "Pusher: " + (string)ArraySize(info.signallers) + "\n" + + "Market Conditions: " + message); + } + } + + // + return result; +} + +// +// Check Market Conditions by Combination of Power of All tools for SHORTs ... +bool XEU5HasShortSignal( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // XTD ... + bool isXTDHasSignal = XEU5XTDHasShortSignal(); + if (isXTDHasSignal) + { + // + Add( + EnumToString(XTD), + info.signallers); + } + + // + // XTAM ... + bool isXTAMHasSignal = XEU5XTAMHasShortSignal(); + if (isXTAMHasSignal) + { + // + Add( + EnumToString(XTAM), + info.signallers); + } + + // + // XSI ... + bool isXSIHasSignal = XEU5XSIHasShortSignal(); + if (isXSIHasSignal) + { + // + Add( + EnumToString(XSI), + info.signallers); + } + + // + // XSTFI ... + bool isXSTFIHasSignal = XEU5XSTFIHasShortSignal(); + if (isXSTFIHasSignal) + { + // + Add( + EnumToString(XSTFI), + info.signallers); + } + + // + // XOBD XLH ... + bool isXOBDLHHasSignal = XEU5XOBDLHHasShortSignal(); + if (isXOBDLHHasSignal) + { + // + Add( + EnumToString(XOBDLH), + info.signallers); + } + + // + // XCHMA Cycles Cross ... + bool isXCHMACCHasSignal = XEU5XCHMACCHasShortSignal(); + if (isXCHMACCHasSignal) + { + // + Add( + EnumToString(XCHMACC), + info.signallers); + } + + // + // XCHMA Cycles Min ... + bool isXCHMACMNHasSignal = XEU5XCHMACMNHasShortSignal(); + if (isXCHMACMNHasSignal) + { + // + Add( + EnumToString(XCHMACMN), + info.signallers); + } + + // + // XCHMA Cycles Max + bool isXCHMACMXHasSignal = XEU5XCHMACMXHasShortSignal(); + if (isXCHMACMXHasSignal) + { + // + Add( + EnumToString(XCHMACMX), + info.signallers); + } + + // + result = + // + isXTDHasSignal + // + || + // + isXTAMHasSignal + // + || + // + isXSIHasSignal + // + || + // + isXSTFIHasSignal + // + || + // + isXOBDLHHasSignal + // + || + // + isXCHMACCHasSignal + // + || + // + isXCHMACMNHasSignal + // + || + // + isXCHMACMXHasSignal + // + ; + + // + if (result) + { + // + // Only Log Signals Time Market Conditions if is in Testing Mode ... + if (xEU5IsTestMode) + { + // + string message = XEU5GetConditionsString(xEU5Conditions, "\n"); + + // + LogMessage( + "Short Signal Provided by: \n" + + info.signallers[ArraySize(info.signallers) - 1] + "\n" + + "Pusher: " + (string)ArraySize(info.signallers) + "\n" + + "Market Conditions: " + message); + } + } + + // + return result; +} + +// +// +// END Combination Signaling ... +// +// + +// +// START Signal Providers ... +// + +// +// Disbale All Signallers Longs ... +void XEU5DisableLongSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + xEU5MXTDAllowLongSignals = false; + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + xEU5MXTAMAllowLongSignals = false; + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + xEU5MXSIAllowLongSignals = false; + } + + // + // XSTFI ... + if (xEU5MXSTFIEnableSignaller) + { + xEU5MXSTFIAllowLongSignals = false; + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + xEU5MXOBDLHAllowLongSignals = false; + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + xEU5MXCHMACCAllowLongSignals = false; + } + + // + // XCHMAMX ... + if (xEU5MXCHMACMXEnableSignaller) + { + xEU5MXCHMACMXAllowLongSignals = false; + } + + // + // XCHMAMN ... + if (xEU5MXCHMACMNEnableSignaller) + { + xEU5MXCHMACMNAllowLongSignals = false; + } +} + +// +// Enable All Signallers Longs ... +// Only if they are Configured as Enable at Settings ... +void XEU5EnableLongSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + xEU5MXTDAllowLongSignals = + xEU5XTDAllowLongSignals + ? true + : xEU5MXTDAllowLongSignals; + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + xEU5MXTAMAllowLongSignals = + xEU5XTAMAllowLongSignals + ? true + : xEU5MXTAMAllowLongSignals; + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + xEU5MXSIAllowLongSignals = + xEU5XSIAllowLongSignals + ? true + : xEU5MXSIAllowLongSignals; + } + + // + // XSTFI ... + if (xEU5MXSTFIEnableSignaller) + { + xEU5MXSTFIAllowLongSignals = + xEU5XSTFIAllowLongSignals + ? true + : xEU5MXSTFIAllowLongSignals; + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + xEU5MXOBDLHAllowLongSignals = + xEU5XOBDLHAllowLongSignals + ? true + : xEU5MXOBDLHAllowLongSignals; + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + xEU5MXCHMACCAllowLongSignals = + xEU5XCHMACCAllowLongSignals + ? true + : xEU5MXCHMACCAllowLongSignals; + } + + // + // XCHMAMX ... + if (xEU5MXCHMACMXEnableSignaller) + { + xEU5MXCHMACMXAllowLongSignals = + xEU5XCHMACMXAllowLongSignals + ? true + : xEU5MXCHMACMXAllowLongSignals; + } + + // + // XCHMAMN ... + if (xEU5MXCHMACMNEnableSignaller) + { + xEU5MXCHMACMNAllowLongSignals = + xEU5XCHMACMNAllowLongSignals + ? true + : xEU5MXCHMACMNAllowLongSignals; + } +} + +// +// Disable All Signallers Shorts ... +void XEUDisableShortSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + xEU5MXTDAllowShortSignals = false; + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + xEU5MXTAMAllowShortSignals = false; + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + xEU5MXSIAllowShortSignals = false; + } + + // + // XSTFI ... + if (xEU5MXSTFIEnableSignaller) + { + xEU5MXSTFIAllowShortSignals = false; + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + xEU5MXOBDLHAllowShortSignals = false; + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + xEU5MXCHMACCAllowShortSignals = false; + } + + // + // XCHMAMX ... + if (xEU5MXCHMACMXEnableSignaller) + { + xEU5MXCHMACMXAllowShortSignals = false; + } + + // + // XCHMAMN ... + if (xEU5MXCHMACMNEnableSignaller) + { + xEU5MXCHMACMNAllowShortSignals = false; + } +} + +// +// Enable All Signallers Shorts ... +// Only if they are Configured as Enable at Settings ... +void XEUEnableShortSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + xEU5MXTDAllowShortSignals = + xEU5XTDAllowShortSignals + ? true + : xEU5MXTDAllowShortSignals; + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + xEU5MXTAMAllowShortSignals = + xEU5XTAMAllowShortSignals + ? true + : xEU5MXTAMAllowShortSignals; + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + xEU5MXSIAllowShortSignals = + xEU5XSIAllowShortSignals + ? true + : xEU5MXSIAllowShortSignals; + } + + // + // XSTFI ... + if (xEU5MXSTFIEnableSignaller) + { + xEU5MXSTFIAllowShortSignals = + xEU5XSTFIAllowShortSignals + ? true + : xEU5MXSTFIAllowShortSignals; + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + xEU5MXOBDLHAllowShortSignals = + xEU5XOBDLHAllowShortSignals + ? true + : xEU5MXOBDLHAllowShortSignals; + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + xEU5MXCHMACCAllowShortSignals = + xEU5XCHMACCAllowShortSignals + ? true + : xEU5MXCHMACCAllowShortSignals; + } + + // + // XCHMAMX ... + if (xEU5MXCHMACMXEnableSignaller) + { + xEU5MXCHMACMXAllowShortSignals = + xEU5XCHMACMXAllowShortSignals + ? true + : xEU5MXCHMACMXAllowShortSignals; + } + + // + // XCHMAMN ... + if (xEU5MXCHMACMNEnableSignaller) + { + xEU5MXCHMACMNAllowShortSignals = + xEU5XCHMACMNAllowShortSignals + ? true + : xEU5MXCHMACMNAllowShortSignals; + } +} + +// +// XTD Long Signal Checking ... +bool XEU5XTDHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTDEnableSignaller || + !xEU5MXTDAllowLongSignals) + { + return result; + } + + // + result = + // + xEU5Conditions.isXTDSignalCrossedOverBear && + // + !xEU5Conditions.isXLHHighAttachedHH && + !xEU5Conditions.isXLHPriceInSignalRange && + // + !xEU5Conditions.isXCHMAMCPeak && + !xEU5Conditions.isXCHMALCPeak && + !xEU5Conditions.isXCHMAMCFastUnderSlow && + !xEU5Conditions.isXCHMALCFastUnderSlow && + !xEU5Conditions.isXCHMAMCFastCrossedUnderSlow && + !xEU5Conditions.isXCHMALCFastCrossedUnderSlow + // + && + // + !( + // + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXLHPriceOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBearishVale && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXTDSignalCrossedOverBear && + xEU5Conditions.isXCHMASCFastCrossedUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXTDSignalCrossedOverBear && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XTD Short Signal Checking ... +bool XEU5XTDHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTDEnableSignaller || + !xEU5MXTDAllowShortSignals) + { + return result; + } + + // + result = + // + xEU5Conditions.isXTDSignalCrossedUnderBear + // + && + // + !xEU5Conditions.isXLHLowAttachedLL && + !xEU5Conditions.isXLHPriceInSignalRange && + // + !xEU5Conditions.isXCHMAMCVale && + !xEU5Conditions.isXCHMALCVale && + !xEU5Conditions.isXCHMAMCFastOverSlow && + !xEU5Conditions.isXCHMALCFastOverSlow && + !xEU5Conditions.isXCHMAMCFastCrossedOverSlow && + !xEU5Conditions.isXCHMALCFastCrossedOverSlow + // + && + // + !( + // + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + !( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin + // + ) + // + && + !( + // + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXTDSignalCrossedUnderBear + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBearish && + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXTDSignalCrossedUnderBear && + xEU5Conditions.isXLHPriceCrossedUnderSignal && + xEU5Conditions.isXCHMASCFastCrossedUnderSlow + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XTAM Long Signal Checking ... +bool XEU5XTAMHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTAMEnableSignaller || + !xEU5MXTAMAllowLongSignals) + { + return result; + } + + // + result = + // + xAMAMaBuffer[1] > xTMMaBuffer[1] && + xAMAMaBuffer[2] > xTMMaBuffer[2] + // + && + // + xEU5Conditions.isXAMABullish + // + && + // + xEU5Conditions.isXTMBullish + // + && + // + xEU5Conditions.isXLHLLSameInLength + // + && + // + xEU5Conditions.isXFIOverZero + // + && + // + xEU5Conditions.isXTSCurrentMax + // + && + // + xEU5Conditions.isXTSCurrentOverFarest + // + && + // + xEU5Conditions.isXCHMASCUnderMax + // + && + // + !xEU5Conditions.isXOBDSwingLow + // + && + // + !xEU5Conditions.isXTDSignalCrossedUnderBear + // + && + // + !( + // + ( + // + ( + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow) + // + && + // + ( + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow) + + ) + // + || + // + ( + // + ( + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow) + // + && + // + ( + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow) + // + && + // + ( + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + ) + // + ) + // + && + // + ( + // + ( + xEU5Conditions.isXCHMASCFastOverSlow + ? !xEU5Conditions.isXCHMASCTrendsDown + : true) + // + || + // + ( + xEU5Conditions.isXCHMAMCFastOverSlow + ? !xEU5Conditions.isXCHMAMCTrendsDown + : true) + // + || + // + ( + xEU5Conditions.isXCHMALCFastOverSlow + ? !xEU5Conditions.isXCHMALCTrendsDown + : true) + // + ) + // + && + // + ( + // + (xEU5Conditions.isXLHHHSameInLength || + xEU5Conditions.isXLHLLSameInLength) + ? !( + xEU5Conditions.isXLHPriceInSignalRange || + xEU5Conditions.isXLHPriceUnderSignal) + : true + // + ) + // + && + // + ( + // + xEU5Conditions.isXTSCurrentMax || + xEU5Conditions.isXFICrossedOverZero || + (xEU5Conditions.isXTSCurrentOverNearest || + xEU5Conditions.isXTSCurrentCrossedOverNearest) || + (xEU5Conditions.isXTSCurrentOverMediest || + xEU5Conditions.isXTSCurrentCrossedOverMediest) + ? (!xEU5Conditions.isXLHPriceOverSignal && + !xEU5Conditions.isXLHPriceUnderSignal && + !xEU5Conditions.isXLHPriceInSignalRange && + !xEU5Conditions.isXLHPriceCrossedOverSignal && + !xEU5Conditions.isXLHPriceCrossedUnderSignal + ? !( + ( + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + ( + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXLHLLSameInLength) + // + ) + : true) && + (xEU5Conditions.isXLHPriceInSignalRange + ? !xEU5Conditions.isXLHHighAttachedHH + : true) && + (xEU5Conditions.isXLHPriceUnderSignal + ? !(xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXLHLLSameInLength) + : true) && + ((xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) + ? !( + // + ( + ( + xEU5Conditions.isXLHLLDecreased || + xEU5Conditions.isXLHHHDecreased || + xEU5Conditions.isXLHHHSameInLength || + xEU5Conditions.isXLHHighAttachedHH) && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + ( + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + ( + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXRSICrossedUnderShortEntry && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + ) + : true) + : true + // + ) + // + && + // + ( + // + xEU5Conditions.isXLHLLSameInLength && + (xEU5Conditions.isXTSCurrentOverNearest || + xEU5Conditions.isXTSCurrentOverMediest) + ? !(xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) + : true + // + ) + // + && + // + // False Positives ... + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXTSCurrentMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTMStartBullish && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXAMAStartBullish && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMASCCrossedUnderMax + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTSCurrentMax && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXLHLLSameInLength && + ( + // + xEU5Conditions.isXLHHHIncreased || + xEU5Conditions.isXLHHighAttachedHH + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMASCFastCrossedOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXTSCurrentOverFarest && + xEU5Conditions.isXTSCurrentOverMediest + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXTDBearishVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXTSCurrentMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXFICrossedOverZero && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXTSCurrentOverNearest && + xEU5Conditions.isXTSCurrentOverMediest && + xEU5Conditions.isXTDSignalCrossedOverBear && + xEU5Conditions.isXTSCurrentCrossedOverNearest && + xEU5Conditions.isXTSCurrentCrossedOverMediest + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTSCurrentMax && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXFICrossedOverZero && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXTDBullCrossedOverBear && + xEU5Conditions.isXLHPriceCrossedOverSignal && + xEU5Conditions.isXCHMAMCFastCrossedOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXRSICrossedOverLongExit + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + (xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXTDBullCrossedUnderBear) + // + || + // + ((xEU5Conditions.isXCHMASCFastUnderSlow || + xEU5Conditions.isXCHMASCFastCrossedUnderSlow) && + (xEU5Conditions.isXCHMAMCFastUnderSlow || + xEU5Conditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + (xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + ((xEU5Conditions.isXCHMAMCVale && + (xEU5Conditions.isXCHMAMCFastUnderSlow || + xEU5Conditions.isXCHMAMCFastCrossedUnderSlow)) && + (xEU5Conditions.isXCHMALCVale && + (xEU5Conditions.isXCHMALCFastUnderSlow || + xEU5Conditions.isXCHMALCFastCrossedUnderSlow)) + // + ) + // + || + // + (xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXTDSignalUnderBear) + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + ) + // + && + // + // Funded ... + !( + // + (xEU5Conditions.isXCHMALCPeak && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXLHPriceOverSignal && + (xEU5Conditions.isXCHMAMCFastUnderSlow || + xEU5Conditions.isXCHMAMCFastCrossedUnderSlow)) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XTAM Short Signal Checking ... +bool XEU5XTAMHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTAMEnableSignaller || + !xEU5MXTAMAllowShortSignals) + { + return result; + } + + // + result = + // + xAMAMaBuffer[1] < xTMMaBuffer[1] && + xAMAMaBuffer[2] < xTMMaBuffer[2] + // + && + // + xEU5Conditions.isXAMABearish + // + && + // + xEU5Conditions.isXTMBearish + // + && + // + xEU5Conditions.isXFIUnderZero + // + && + // + xEU5Conditions.isXTSCurrentMin + // + && + // + xEU5Conditions.isXTSCurrentUnderFarest + // + && + // + !xEU5Conditions.isXOBDSwingHigh + // + && + // + !( + // + xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale + // + ) + // + && + // + ( + // + ((xEU5Conditions.isXTSCurrentUnderNearest || + xEU5Conditions.isXTSCurrentCrossedUnderNearest) || + (xEU5Conditions.isXTSCurrentUnderMediest || + xEU5Conditions.isXTSCurrentCrossedUnderMediest)) + ? ( + // + ( + // + (xEU5Conditions.isXLHPriceUnderSignal || + xEU5Conditions.isXLHPriceInSignalRange || + xEU5Conditions.isXLHPriceCrossedUnderSignal) + ? !( + (xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHLHSCMCLLSame) + // + || + // + (xEU5Conditions.isXLHLLDecreased && + (xEU5Conditions.isXCHLHSCMCLLSame || + xEU5Conditions.isXCHLHMCLCHHSame)) + // + || + // + (xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXLHHHIncreased) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHSCMCHHSame) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHLHSameLLs || + xEU5Conditions.isXLHLowAttachedLL || + xEU5Conditions.isXLHHHSameInLength) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + // + ( + // + xEU5Conditions.isXLHHHSameInLength + // + || + // + (xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + (xEU5Conditions.isXLHHHDecreased || + xEU5Conditions.isXCHMALCPeak)) + // + || + // + (xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + (xEU5Conditions.isXCHMALCPeak || + xEU5Conditions.isXCHMASCFastOverSlow)) + // + || + // + (xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXTDBullCrossedUnderBear) + // + || + // + (xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + ) + // + ) + // + ) + : (xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) + ? ( + !( + xEU5Conditions.isXCHLHSameHHs + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHSCMCHHSame) + // + || + // + (xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXLHLLIncreased) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + (xEU5Conditions.isXLHHHSameInLength + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMALCFastOverSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + ( + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + ) + // + ) + // + || + // + ( + xEU5Conditions.isXLHLLSameInLength && + ( + // + (xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + )) + // + ) + // + ) + : ( + !xEU5Conditions.isXLHPriceOverSignal && + !xEU5Conditions.isXLHPriceUnderSignal && + !xEU5Conditions.isXLHPriceInSignalRange && + !xEU5Conditions.isXLHPriceCrossedOverSignal && + !xEU5Conditions.isXLHPriceCrossedUnderSignal) + ? !( + // + (xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + (xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow) + // + ) + : true) + // + ) + : true + // + ) + // + && + // + ( + // + ( + (xEU5Conditions.isXTDBullOverBear || + (xEU5Conditions.isXTDBullUnderBear || + xEU5Conditions.isXTDBullCrossedUnderBear)) && + (xEU5Conditions.isXTDSignalUnderBear || + xEU5Conditions.isXTDSignalCrossedUnderBear)) + ? !( + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXAMAVale) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + (xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXLHHHSameInLength) + // + || + // + (xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHPriceCrossedUnderSignal) + // + ) + : true + // + ) + // + && + // + ( + // + (xEU5Conditions.isXLHPriceUnderSignal || + xEU5Conditions.isXLHPriceCrossedUnderSignal) + ? !( + // + (xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXCHLHSameHHs) + // + || + // + ( + xEU5Conditions.isXLHHHSameInLength && + ( + // + (xEU5Conditions.isXLHLLSameInLength && + // + ( + (xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXLHLowAttachedLL) + // + || + // + (xEU5Conditions.isXCHMALCVale && + ( + // + xEU5Conditions.isXCHMAMCVale + // + || + // + xEU5Conditions.isXCHMASCFastOverSlow + // + ) + // + ) + // + || + // + xEU5Conditions.isXCHLHSameLLs + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHMCLCHHSame) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXRSICrossedOverLongExit && + xEU5Conditions.isXLHPriceCrossedUnderSignal) + // + ) + : xEU5Conditions.isXLHPriceInSignalRange + ? ( + // + ( + xEU5Conditions.isXLHHHSameInLength + ? !( + // + xEU5Conditions.isXCHLHSameLLs + // + || + // + (xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXTDSignalVale || + xEU5Conditions.isXLHLLSameInLength) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + // Funded ... + ( + // + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMALCPeak) + // + || + // + ((xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + : true + // + ) + // + ) + : (xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) + ? !( + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + ( + // + xEU5Conditions.isXLHLLSameInLength + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + ) + // + ) + // + ) + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHPriceInSignalRange && + xEU5Conditions.isXTSCurrentCrossedUnderFarest + // + ) + // + && + // + // False Positives ... + !( + ((xEU5Conditions.isXTSCurrentUnderNearest || + xEU5Conditions.isXTSCurrentCrossedUnderNearest) + // + || + // + (xEU5Conditions.isXTSCurrentUnderMediest || + xEU5Conditions.isXTSCurrentCrossedUnderMediest) + // + ) + // + ? (xEU5Conditions.isXLHPriceInSignalRange + ? ( + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + || + // + (xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + ( + // + xEU5Conditions.isXFICrossedUnderZero + // + || + // + (xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXLHHHDecreased || + // + ( + // + xEU5Conditions.isXCHMAMCFastOverSlow || + // + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) + // + || + // + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + || + // + (xEU5Conditions.isXTMBearish && + xEU5Conditions.isXAMABearish && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalCrossedUnderBear) + // + ) + // + || + // + (xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXTSCurrentCrossedUnderFarest && + xEU5Conditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + ) + // + ) + // + : (xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) + ? ( + // + (xEU5Conditions.isXLHHHSameInLength && + // + ( + // + xEU5Conditions.isXTMVale + // + || + // + xEU5Conditions.isXTDSignalCrossedUnderBear + // + || + // + (xEU5Conditions.isXCHLHMCLCHHSame && + (xEU5Conditions.isXCHMAMCPeak || + xEU5Conditions.isXCHMAMCFastOverSlow)) + // + || + // + (xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale) + // + || + // + (xEU5Conditions.isXCHMASCVale && + (xEU5Conditions.isXCHMALCVale || + xEU5Conditions.isXCHMASCFastOverSlow)) + // + || + // + (xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXLHLLIncreased) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + || + // + (!xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsDown && + !xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMASCCrossedUnderMax) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + ( + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHHHDecreased) + // + || + // + (xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + || + // + (xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + ) + // + : (xEU5Conditions.isXLHPriceUnderSignal || + xEU5Conditions.isXLHPriceCrossedUnderSignal) + ? ( + // + (xEU5Conditions.isXLHLLSameInLength && + ( + // + xEU5Conditions.isXCHLHSCMCHHSame + // + || + // + xEU5Conditions.isXCHMAMCFastOverSlow + // + || + // + xEU5Conditions.isXRSICrossedUnderShortExit + // + || + // + (xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale) + // + || + // + (xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + ((xEU5Conditions.isXCHMALCPeak || + xEU5Conditions.isXCHMAMCVale) && + xEU5Conditions.isXCHMALCFastOverSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin) + // + || + // + (xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHSCMCLLSame) + // + ) + // + // XLH Price False ... + : + // + // Funed ... + ( + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + ( + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXLHHHSameInLength) + // + || + // + ( + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + // Just Current XTS Min and Farest ... + : (xEU5Conditions.isXLHPriceInSignalRange + ? ( + // + (xEU5Conditions.isXLHHHSameInLength && + ( + // + xEU5Conditions.isXCHMASCFastOverSlow + // + || + // + (xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + ( + // + (xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalCrossedUnderBear && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + : (xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) + ? ( + // + ( + xEU5Conditions.isXLHLLSameInLength && + ( + // + xEU5Conditions.isXCHLHMCLCLLSame + // + || + // + xEU5Conditions.isXFICrossedUnderZero + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + )) + // + ) + // + : ( + xEU5Conditions.isXLHPriceUnderSignal || + xEU5Conditions.isXLHPriceCrossedUnderSignal) + ? ( + // + ( + // + (xEU5Conditions.isXLHHHSameInLength && + ( + // + (xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHSCMCLLSame) + // + || + // + (xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin) + // + || + // + (xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXFICrossedUnderZero) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + ( + // + (xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHLHMCOnTopOfLC) + // + || + // + ((xEU5Conditions.isXCHMALCPeak || + xEU5Conditions.isXCHMAMCVale) && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXTDBullOverBear) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + ) + // + ) + // + || + // + ( + (xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) && + ( + // + xEU5Conditions.isXLHHHDecreased + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale) + // + || + // + (xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXLHLowAttachedLL) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + ) + // + ) + // + // XLH Price Falses ... + : ( + // + (xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHLHSCMCHHSame) + // + || + // + (xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + ((xEU5Conditions.isXTMBearish || + xEU5Conditions.isXTMStartBearish) && + (xEU5Conditions.isXAMABearish || + xEU5Conditions.isXAMAStartBearish) && + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) && + xEU5Conditions.isXLHLLIncreased && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XSI Long Signal Checking ... +bool XEU5XSIHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXSIEnableSignaller || + !xEU5MXSIAllowLongSignals) + { + return result; + } + + // + result = + // + xEU5Conditions.isXRSICrossedOverLongEntry && + xRSIBuffer[3] < xRSILongEntryValue + // + && + // + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXCHMASCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMASCUnderMin + ? !( + // + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMASCFastUnderSlow + // + ) && + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCVale || + xEU5Conditions.isXCHMASCFastCrossedUnderSlow + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMAMCFastOverSlow + ? !xEU5Conditions.isXCHMAMCTrendsDown + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCPeak + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMASCUnderMin + ? !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXTDBearishVale && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength + // + ) + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXTMEndBearishByNeutural + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHSCLCLLSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXLHPriceInSignalRange && + xEU5Conditions.isXCHMASCFastCrossedOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHSCLCLLSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMASCFastCrossedOverSlow + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XSI Short Signal Checking ... +bool XEU5XSIHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXSIEnableSignaller || + !xEU5MXSIAllowShortSignals) + { + return result; + } + + // + result = + // + xEU5Conditions.isXRSICrossedUnderShortEntry && + xRSIBuffer[3] > xRSIShortEntryValue && + !xEU5Conditions.isXOBDSwingHigh + // + && + // + !( + // + ( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak + // + ) + // + || + // + ( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak + // + ) + // + || + // + ( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCPeak + // + ) + // + || + // + ( + // + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXTDSignalCrossedOverBear + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXCHMASCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXTDSignalOverBear + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHSCLCHHSame && + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXLHPriceInSignalRange + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBearish && + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHSCLCHHSame && + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXLHPriceInSignalRange && + xEU5Conditions.isXLHPriceCrossedUnderSignal && + xEU5Conditions.isXCHMASCFastCrossedUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXTDSignalCrossedOverBear + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXLHPriceCrossedUnderSignal && + xEU5Conditions.isXCHMASCFastCrossedUnderSlow + // + ) + // + && + // + !( + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXTDBullCrossedUnderBear && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + ((xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMABullish && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalOverBear) || + (xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal) || + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow))) + // + || + // + (xEU5Conditions.isXTSCurrentMax && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XSTFI Long Signal Checking ... +bool XEU5XSTFIHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXSTFIEnableSignaller || + !xEU5MXSTFIAllowLongSignals) + { + return result; + } + + // + result = + // + // Base Condition ... + XTSGetMinValue(1) == xTSFarestBuffer[1] && + (xEU5Conditions.isXTSCurrentOverFarest || + xEU5Conditions.isXTSCurrentCrossedOverFarest) && + (xTSCurrentBuffer[1] < xTSNearestBuffer[1] || + xTSCurrentBuffer[1] < xTSMediestBuffer[1]) && + !(xEU5Conditions.isXTSCurrentUnderNearest || + xEU5Conditions.isXTSCurrentCrossedUnderNearest) + // + && + // + // Check Market MA's ... + ( + // + ( + // + ( + // + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) + // + && + // + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + ) + // + && + // + ( + // + !(xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + && + // + !(xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + && + // + !(xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin) + // + ) + // + // End of Check MA's ... + ) + // + && + // + // Check XTS ... + ( + // + !( + // + (xEU5Conditions.isXTSCurrentUnderNearest && + xEU5Conditions.isXTSCurrentCrossedUnderNearest) + // + || + // + (xEU5Conditions.isXTSCurrentUnderMediest && + xEU5Conditions.isXTSCurrentCrossedUnderMediest) + // + ) + // + // End Of Check XTS ... + ) + // + && + // + // Check XLH ... + ( + // + // Based On Price ... + !( + // + // Signal Range ... + ( + // + xEU5Conditions.isXLHPriceInSignalRange && + ( + // + ((xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) && + ( + // + xEU5Conditions.isXCHMALCPeak + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + ( + // + (xEU5Conditions.isXTMStartBearish && + xEU5Conditions.isXAMAStartBearish && + xEU5Conditions.isXFICrossedOverZero) + // + || + // + (((xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow) || + xEU5Conditions.isXCHMALCPeak) && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastOverSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + // + ( + // + ((xEU5Conditions.isXCHMASCTrendsDown && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) && + (xEU5Conditions.isXCHMAMCTrendsDown && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow))) + // + || + // + (xEU5Conditions.isXAMABullish && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXOBDSwingHigh && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHLHMCLCHHSame) + // + ) + // + ) + // + || + // + ( + // + ((xEU5Conditions.isXCHMASCPeak || + xEU5Conditions.isXCHMAMCPeak) && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXFICrossedOverZero && + xEU5Conditions.isXTDSignalCrossedOverBear) + // + || + // + (xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXLHHHSameInLength) + // + || + // + (xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXTDBearishVale) + // + )) + // + ) + // + || + // + // Under Signal ... + ( + // + (xEU5Conditions.isXLHPriceUnderSignal || + xEU5Conditions.isXLHPriceCrossedUnderSignal) && + ( + // + (xEU5Conditions.isXLHHHSameInLength && + ( + // + ((xEU5Conditions.isXCHMAMCVale || + xEU5Conditions.isXCHMAMCPeak || + xEU5Conditions.isXFICrossedUnderZero) && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural) + // + || + // + (xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHLHMCLCHHSame) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + ( + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + // Funded ... + ( + // + (xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXTSCurrentOverFarest && + xEU5Conditions.isXTSCurrentUnderMediest) + // + || + // + (xEU5Conditions.isXCHMASCTrendsDown && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow))) + // + ) + // + ) + // + || + // + ((xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) && + ( + // + ((xEU5Conditions.isXCHMASCPeak || + xEU5Conditions.isXTDBearishVale || + xEU5Conditions.isXCHLHMCLCHHSame || + (xEU5Conditions.isXTMBearish && + xEU5Conditions.isXAMABearish) || + (xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow)) && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHLHMCLCHHSame && + (xEU5Conditions.isXFICrossedOverZero || + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXCHMAMCTrendsDown))) + // + || + // + (xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Over Signal ... + ( + // + (xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) && + ( + // + ((xEU5Conditions.isXCHMASCPeak || + xEU5Conditions.isXCHMAMCPeak) && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + // + ( + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXLHHHDecreased) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Price Nothing ... + ( + // + ( + !xEU5Conditions.isXLHPriceOverSignal && + !xEU5Conditions.isXLHPriceUnderSignal && + !xEU5Conditions.isXLHPriceInSignalRange && + !xEU5Conditions.isXLHPriceCrossedOverSignal && + !xEU5Conditions.isXLHPriceCrossedUnderSignal) && + ( + // + (xEU5Conditions.isXLHHHSameInLength && + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + ) + // + ) + // + ) + // + // End Based On Price Check ... + ) + // + // End Of Check XLH ... + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XSTFI Short Signal Checking ... +bool XEU5XSTFIHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXSTFIEnableSignaller || + !xEU5MXSTFIAllowShortSignals) + { + return result; + } + + // + result = + // + // Base Conditions ... + XTSGetMaxValue(1) == xTSFarestBuffer[1] && + (xEU5Conditions.isXTSCurrentUnderFarest || + xEU5Conditions.isXTSCurrentCrossedUnderFarest) && + (xTSCurrentBuffer[1] > xTSNearestBuffer[1] || + xTSCurrentBuffer[1] > xTSMediestBuffer[1]) && + !(xEU5Conditions.isXTSCurrentOverNearest || + xEU5Conditions.isXTSCurrentCrossedOverNearest) + // + && + // + // XOBD Check ... + !xEU5Conditions.isXOBDSwingHigh + // + && + // + // XCHMA Check ... + ( + // + !(xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + && + // + !(xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin) + // + && + // + !(xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + ) + // + && + // + // XLH Prices ... + ( + // + !( + // + // Signal Range ... + (xEU5Conditions.isXLHPriceInSignalRange && + // + ( + // + (xEU5Conditions.isXLHLLSameInLength && + // + ( + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural) + // + || + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXAMAVale && + xEU5Conditions.isXTMEndBearish) + // + || + // + (xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMAEndBullish && + xEU5Conditions.isXLHLLDecreased) + // + || + // + (xEU5Conditions.isXCHMASCTrendsUp && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + ((xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMALCVale) && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXCHLHMCLCLLSame) + // + || + // + (xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + ((xEU5Conditions.isXTMBullish || + xEU5Conditions.isXTMStartBullish) && + (xEU5Conditions.isXAMABullish || + xEU5Conditions.isXAMAStartBullish)) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + // + ( + // + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXAMAVale) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMABullish) + // + || + // + (xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXTDBearishVale) + // + || + // + // Funded ... + ( + // + ( + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXAMAEndBearish && + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXFICrossedUnderZero) + // + || + // + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCTrendsUp && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHLLIncreased) + // + || + // + ((xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + xEU5Conditions.isXCHMAMCPeak + // + || + // + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow) + // + || + // + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) && + // + ( + // + (xEU5Conditions.isXAMABullish && + xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXCHLHSCMCLLSame) + // + || + // + (xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTMEndBearish) + // + || + // + ((xEU5Conditions.isXCHMAMCPeak || + xEU5Conditions.isXCHMAMCVale) && + (xEU5Conditions.isXCHMALCPeak || + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow))) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + ((xEU5Conditions.isXTMStartBullish && + xEU5Conditions.isXAMAEndBearish) || + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow) || + (xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXTSCurrentOverMediest && + xEU5Conditions.isXTSCurrentUnderFarest && + xEU5Conditions.isXTSCurrentUnderNearest))) + // + || + // + // Funded ... + ( + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMABearish && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTMEndBearish && + xEU5Conditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + ) + // + || + ( + // + ((xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + // + ( + // + xEU5Conditions.isXCHMALCPeak + // + || + // + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow) + // + || + // + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMAEndBearish && + xEU5Conditions.isXCHLHSCMCLLSame) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTMEndBearish && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHLHSCMCHHSame) + // + ) + // + ) + // + || + // + ((xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow) && + ( + // + xEU5Conditions.isXCHMALCPeak + // + ) + // + ) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXTDBullCrossedOverBear) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHSameLLs) + // + ) + // + ) + // + ) + // + || + // + // Under Signal ... + ((xEU5Conditions.isXLHPriceUnderSignal || + xEU5Conditions.isXLHPriceCrossedUnderSignal) && + // + ( + // + (xEU5Conditions.isXLHLLSameInLength && + // + ( + // + (xEU5Conditions.isXTMBearish && + xEU5Conditions.isXAMABearish) + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXTDBearishVale) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + (xEU5Conditions.isXCHMALCVale || + xEU5Conditions.isXAMAVale || + xEU5Conditions.isXTMBullish || + xEU5Conditions.isXCHLHSCMCLLSame || + xEU5Conditions.isXFICrossedOverZero)) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXFICrossedUnderZero) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((xEU5Conditions.isXCHMALCPeak || + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + // + ( + // + (xEU5Conditions.isXCHMASCVale && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastOverSlow)) + // + || + // + (xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXCHLHSCMCLLSame) + // + || + // + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXAMAVale) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHLHSCMCHHSame && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + ((xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXCHLHSCMCLLSame && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXLHLLIncreased) + // + || + // + (xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHLHMCLCHHSame && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + ((xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) && + // + ( + // + xEU5Conditions.isXTDBearishVale + // + || + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + ((xEU5Conditions.isXTMVale || + xEU5Conditions.isXLHLLDecreased) && + xEU5Conditions.isXAMAVale) + // + || + ((xEU5Conditions.isXCHMASCVale || + xEU5Conditions.isXCHMALCVale) && + xEU5Conditions.isXCHMAMCVale) + // + || + // + (xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + ((xEU5Conditions.isXCHMALCPeak || + xEU5Conditions.isXFICrossedUnderZero || + xEU5Conditions.isXCHMAMCFastOverSlow) && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXFICrossedUnderZero) + // + ) + // + ) + // + || + // + ( + // + (xEU5Conditions.isXCHLHSCMCHHSame && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHLHSCMCLLSame) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHMAMCTrendsDown) + // + || + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXTMEndBearish && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) + // + || + // + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXAMAVale && + xEU5Conditions.isXLHLowAttachedLL) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHSCMCLLSame) + // + || + // + (xEU5Conditions.isXAMANeutural && + (xEU5Conditions.isXTMBullish || + xEU5Conditions.isXTMStartBullish)) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHLHSameLLs) + // + || + // + (xEU5Conditions.isXLHHHDecreased && + (xEU5Conditions.isXLHLLDecreased || + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural))) + // + || + // + (xEU5Conditions.isXTMBearish && + xEU5Conditions.isXAMABearish && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHMAMCFastUnderSlow) + // + || + // + ((xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow) && + ( + // + xEU5Conditions.isXCHMAMCVale + // + || + // + xEU5Conditions.isXCHMALCVale + // + || + // + xEU5Conditions.isXCHLHSameLLs + // + || + // + xEU5Conditions.isXFICrossedOverZero + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMABullish) + // + || + // + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) + // + ) + // + ) + // + || + // + ((xEU5Conditions.isXCHMASCVale || + xEU5Conditions.isXLHLowAttachedLL) && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXAMAStartBullish && + xEU5Conditions.isXRSICrossedOverLongEntry) + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHLHSCMCLLSame && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXTMEndBearish && + xEU5Conditions.isXAMAEndBearish && + xEU5Conditions.isXCHLHSCMCLLSame && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + || + // + // Over Signal ... + ((xEU5Conditions.isXLHPriceOverSignal || + xEU5Conditions.isXLHPriceCrossedOverSignal) && + // + ( + // + (xEU5Conditions.isXLHLLSameInLength && + // + ( + // + ((xEU5Conditions.isXCHMAMCVale || + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXCHMASCVale) || + (xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXLHPriceCrossedOverSignal)) && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale) + // + || + // + (xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXCHLHMCLCLLSame) + // + || + // + (xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMALCFastOverSlow) + // + || + // + (xEU5Conditions.isXAMABullish && + xEU5Conditions.isXCHLHSCMCHHSame) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) || + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + // Funded ... + ( + // + (xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXLHLLIncreased) + // + ) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + // + ( + // + (xEU5Conditions.isXTMVale && + xEU5Conditions.isXAMAVale) + // + || + // + (xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + ((xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMAMCPeak || + xEU5Conditions.isXAMANeutural || + xEU5Conditions.isXCHMALCVale || + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow))) + // + || + // + (xEU5Conditions.isXTMStartBullish && + xEU5Conditions.isXAMAStartBullish) + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCCrossedOverMax) + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + (xEU5Conditions.isXCHMALCVale && + (xEU5Conditions.isXCHMAMCVale || + xEU5Conditions.isXCHMASCFastOverSlow || + (xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXCHLHSCMCLLSame))) + // + || + // + (xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMABullish) + // + || + // + (xEU5Conditions.isXCHLHSCMCLLSame || + xEU5Conditions.isXFICrossedUnderZero) + // + || + // + (xEU5Conditions.isXOBDSwingLow && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (((xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural) || + (xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMALCVale)) && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + (xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow) + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + // Funded ... + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXLHLLIncreased) + // + || + // + (xEU5Conditions.isXCHMALCVale && + (xEU5Conditions.isXCHMAMCTrendsDown && + (xEU5Conditions.isXCHMAMCFastUnderSlow || + xEU5Conditions.isXCHMAMCFastCrossedUnderSlow))) + // + ) + // + ) + // + || + // + ((xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) && + ( + // + ((xEU5Conditions.isXCHMASCVale || + xEU5Conditions.isXCHMAMCPeak) && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMANeutural) + // + || + // + (xEU5Conditions.isXTMEndBullish && + xEU5Conditions.isXAMAEndBullish) + // + || + // + (xEU5Conditions.isXTMStartBullish && + xEU5Conditions.isXAMAStartBullish) + // + || + // + (xEU5Conditions.isXTMEndBearish && + xEU5Conditions.isXAMAEndBearish) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXAMANeutural) + // + || + // + ((xEU5Conditions.isXCHMAMCPeak || + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + ( + // + (xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMABullish && + xEU5Conditions.isXLHHighAttachedHH) + // + || + // + ((xEU5Conditions.isXCHMAMCPeak || + xEU5Conditions.isXCHMASCTrendsUp || + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) && + (xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + ((xEU5Conditions.isXCHMALCPeak || + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXTMEndBullish && + xEU5Conditions.isXAMAEndBullish && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXFICrossedUnderZero) + // + ) + // + ) + // + ) + // + || + // + // Price Empty Condition ... + ((!xEU5Conditions.isXLHPriceOverSignal && + !xEU5Conditions.isXLHPriceInSignalRange && + !xEU5Conditions.isXLHPriceUnderSignal && + !xEU5Conditions.isXLHPriceCrossedUnderSignal && + !xEU5Conditions.isXLHPriceCrossedOverSignal) && + // + ( + // + (xEU5Conditions.isXLHHHSameInLength && + // + ( + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXAMANeutural && + (xEU5Conditions.isXTMEndBearish || + xEU5Conditions.isXTMNeutural) && + xEU5Conditions.isXLHLLIncreased) + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXAMAEndBearish) + // + || + // + ((xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + // Funded ... + ( + // + (xEU5Conditions.isXCHMALCPeak && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + || + // + (xEU5Conditions.isXLHLLSameInLength && + // + ( + // + (xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak) + // + || + // + (xEU5Conditions.isXAMAEndBearish && + xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXTMStartBullish) + // + || + // + ((xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + ((xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHHHSameInLength) && + // + ( + // + (xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMABullish) + // + || + // + (xEU5Conditions.isXCHMAMCPeak && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXTMEndBearish && + xEU5Conditions.isXCHLHMCLCHHSame) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ); + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XOBDLH Long Signal Checking ... +bool XEU5XOBDLHHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXOBDLHEnableSignaller || + !xEU5MXOBDLHAllowLongSignals) + { + return result; + } + + // + double entry = GetEntry(X_SIGNAL_LONG); + XEU5MarketConditions conditions2 = XEU5GenerateMarketConditions(2); + + // + result = + // + conditions2.isXOBDSwingLow && + conditions2.isXLHLowAttachedLL && + xLHLLBuffer[1] >= xLHLLBuffer[2] && + // + ( + // + xEU5Conditions.isXLHPriceUnderSignal + ? entry < xLHSignalBuffer[1] + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCFastUnderSlow + ? !( + // + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMASCUnderMin + ? !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale + // + ) + : true + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + ? !xEU5Conditions.isXCHMASCTrendsUp + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXLHLLDecreased && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXTDBullCrossedOverBear + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XOBDLH Short Signal Checking ... +bool XEU5XOBDLHHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXOBDLHEnableSignaller || + !xEU5MXOBDLHAllowShortSignals) + { + return result; + } + + // + double entry = GetEntry(X_SIGNAL_SHORT); + XEU5MarketConditions conditions2 = XEU5GenerateMarketConditions(2); + + // + result = + // + conditions2.isXOBDSwingHigh && + conditions2.isXLHHighAttachedHH && + // + !( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMASCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + ( + // + ( + // + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) || + ( + // + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastCrossedOverSlow + // + ) + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceInSignalRange && + xEU5Conditions.isXCHMASCCrossedUnderMax + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMStartBullish && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHPriceOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXTDSignalOverBear && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + // Funded ... + !( + // + (xEU5Conditions.isXTMBullish && + xEU5Conditions.isXAMABullish && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXTDSignalOverBear) + // + || + // + (xEU5Conditions.isXTSCurrentMax && + (xEU5Conditions.isXTSCurrentOverFarest || + xEU5Conditions.isXTSCurrentCrossedOverFarest) && + (xEU5Conditions.isXTSCurrentOverNearest || + xEU5Conditions.isXTSCurrentCrossedOverNearest) && + (xEU5Conditions.isXTSCurrentOverMediest || + xEU5Conditions.isXTSCurrentCrossedOverMediest)) + // + || + // + (xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal) + // + || + // + (xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCUnderMax) + // + || + // + ((xEU5Conditions.isXCHMASCFastOverSlow || + xEU5Conditions.isXCHMASCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XCHMACC Long Signal Checking ... +bool XEU5XCHMACCHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACCEnableSignaller || + !xEU5MXCHMACCAllowLongSignals) + { + return result; + } + + // + // Required Data ... + double entry = GetEntry(X_SIGNAL_LONG); + double nearHH = GetHighestHigh(3, 1); + double nearLL = GetLowestLow(3, 1); + + // + bool isSharpChanged = IsSharpIncreasedChanged( + 5, + 1, + xTMMaBuffer); + + // + bool isCandleSharpChanged = IsSharpIncreasedChanged( + 5, + 1, + PRICE_CLOSE); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + + // + double xCHMANonSCMax3 = XCHMAGetCyclesMaxValue(3, cycles); + double xCHMANonSCMin3 = XCHMAGetCyclesMinValue(3, cycles); + + // + result = + // + xCHMAScFastBuffer[1] > xCHMAScSlowBuffer[1] && + xCHMAMcFastBuffer[1] > xCHMAMcSlowBuffer[1] && + xCHMALcFastBuffer[1] > xCHMALcSlowBuffer[1] && + // + xCHMAScFastBuffer[2] > xCHMAScSlowBuffer[2] && + xCHMAMcFastBuffer[2] > xCHMAMcSlowBuffer[2] && + xCHMALcFastBuffer[2] > xCHMALcSlowBuffer[2] && + // + !( + // + xCHMAScFastBuffer[3] > xCHMAScSlowBuffer[3] && + xCHMAMcFastBuffer[3] > xCHMAMcSlowBuffer[3] && + xCHMALcFastBuffer[3] > xCHMALcSlowBuffer[3] + // + ) + // + && + // + ( + // + XCHMAIsSCFastCrossedOverSlow(2) + ? XCHMAGetSCTrendPower(1) <= (XCHMAGetSCTrendPower(2) * 2) + : true + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMASCOverMax + ? XCHMAGetSCTrendPower(2) <= (xCHMANonSCMax2 - xCHMANonSCMin2) + : true + // + ) + // + && + // + !xEU5Conditions.isXCHMAMCTrendsDown + // + && + // + ( + // + xEU5Conditions.isXCHMASCCrossedOverMax || xEU5Conditions.isXLHPriceOverSignal + ? !isCandleSharpChanged + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak + // + ) + // + && + // + ( + // + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength + ? entry < nearHH + : true + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCFastOverSlow + ? !xEU5Conditions.isXCHMASCTrendsDown + : true) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XCHMACC Short Signal Checking ... +bool XEU5XCHMACCHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACCEnableSignaller || + !xEU5MXCHMACCAllowShortSignals) + { + return result; + } + + // + result = + // + xCHMAScFastBuffer[1] < xCHMAScSlowBuffer[1] && + xCHMAMcFastBuffer[1] < xCHMAMcSlowBuffer[1] && + xCHMALcFastBuffer[1] < xCHMALcSlowBuffer[1] && + // + xCHMAScFastBuffer[2] < xCHMAScSlowBuffer[2] && + xCHMAMcFastBuffer[2] < xCHMAMcSlowBuffer[2] && + xCHMALcFastBuffer[2] < xCHMALcSlowBuffer[2] && + // + !( + // + xCHMAScFastBuffer[3] < xCHMAScSlowBuffer[3] && + xCHMAMcFastBuffer[3] < xCHMAMcSlowBuffer[3] && + xCHMALcFastBuffer[3] < xCHMALcSlowBuffer[3] + // + ) + // + && + // + !( + // + ( + // + !xEU5Conditions.isXCHMASCTrendsUp && + !xEU5Conditions.isXCHMASCTrendsDown + // + ) + // + || + // + ( + // + !xEU5Conditions.isXCHMAMCTrendsUp && + !xEU5Conditions.isXCHMAMCTrendsDown + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameLLs && + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXLHPriceUnderSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXCHMALCFastUnderSlow && + ( + // + !xEU5Conditions.isXCHMALCTrendsUp && + !xEU5Conditions.isXCHMALCTrendsDown + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceInSignalRange + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXTMStartBullishAfterNeutural + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXTMEndBullishByNeutural && + xEU5Conditions.isXTDSignalCrossedUnderBear + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHHHIncreased && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceInSignalRange + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXTMEndBearishByNeutural + // + ) + // + && + // + !( + // + xEU5Conditions.isXTDSignalVale && + xEU5Conditions.isXTDBullishVale && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMASCCrossedUnderMin + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXTMEndBearishByNeutural + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXTDBullCrossedUnderBear + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXTMStartBullishAfterNeutural + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBearish && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceInSignalRange && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBearish && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCUnderMin && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + (xEU5Conditions.isXTMEndBearish && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceUnderSignal) + // + ) + // + && + // + // Funded ... + !( + // + (xEU5Conditions.isXTMVale && + (xEU5Conditions.isXTMBearish || + xEU5Conditions.isXTMStartBearish) && + xEU5Conditions.isXAMAVale && + xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHPriceUnderSignal) + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXFIOverZero && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXTDBullOverBear) + // + || + // + (xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XCHMACMN Long Signal Checking ... +bool XEU5XCHMACMNHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACMNEnableSignaller || + !xEU5MXCHMACMNAllowLongSignals) + { + return result; + } + + // + // Required Data ... + double entry = GetEntry(X_SIGNAL_LONG); + double nearHH = GetHighestHigh(3, 1); + double nearLL = GetLowestLow(3, 1); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + + // + result = + // + xEU5Conditions.isXCHMASCCrossedOverMin && + xCHMAScFastBuffer[2] < xCHMANonSCMin2 && + xCHMAScSlowBuffer[2] < xCHMANonSCMin2 && + // + ( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax + ? !( + // + XCHMAGetCycleMaxValue(1, X_XCHMA_CYCLE_MEDIUM) < XCHMAGetCycleMaxValue(1, X_XCHMA_CYCLE_LONG) && + XCHMAGetCycleMinValue(1, X_XCHMA_CYCLE_MEDIUM) > XCHMAGetCycleMinValue(1, X_XCHMA_CYCLE_LONG) + // + ) + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHHighAttachedHH + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + ? !xEU5Conditions.isXLHPriceInSignalRange + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXLHPriceOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown + // + ) + // + && + // + !( + // + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXRSICrossedOverLongExit + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTDBearishVale && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMASCFastCrossedOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceOverSignal && + xEU5Conditions.isXCHMASCCrossedOverMin && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCCrossedOverMin && + xEU5Conditions.isXLHPriceCrossedOverSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCOverMin && + (xEU5Conditions.isXCHLHMCLCHHSame || + xEU5Conditions.isXCHLHMCLCLLSame) && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMASCCrossedOverMin && + xEU5Conditions.isXCHMASCFastCrossedOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal && + (xEU5Conditions.isXCHMAMCVale && + (xEU5Conditions.isXCHMAMCFastUnderSlow || + xEU5Conditions.isXCHMAMCFastCrossedUnderSlow)) && + (xEU5Conditions.isXCHMALCVale && + (xEU5Conditions.isXCHMALCFastUnderSlow || + xEU5Conditions.isXCHMALCFastCrossedUnderSlow)) + // + ) + // + && + // + // Funded ... + !( + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXTSCurrentMax && + xEU5Conditions.isXAMAEndBearish && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHPriceUnderSignal) + // + || + // + (xEU5Conditions.isXCHMAMCVale && + (xEU5Conditions.isXCHMASCFastUnderSlow || + xEU5Conditions.isXCHMASCFastCrossedUnderSlow) && + (xEU5Conditions.isXCHMAMCFastUnderSlow || + xEU5Conditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + ( + // + xEU5Conditions.isXOBDSwingLow + // + || + // + (xEU5Conditions.isXTMNeutural && + xEU5Conditions.isXAMANeutural && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXTDBullCrossedOverBear) + // + || + // + (xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXLHPriceInSignalRange) + // + || + // + ((xEU5Conditions.isXCHMASCFastUnderSlow || + xEU5Conditions.isXCHMASCFastCrossedUnderSlow) && + (xEU5Conditions.isXCHMAMCFastUnderSlow || + xEU5Conditions.isXCHMAMCFastCrossedUnderSlow)) + // + ) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XCHMACMN Short Signal Checking ... +bool XEU5XCHMACMNHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACMNEnableSignaller || + !xEU5MXCHMACMNAllowShortSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + double xCHMANonSCMin3 = XCHMAGetCyclesMinValue(3, cycles); + + // + result = + // + xEU5Conditions.isXCHMASCCrossedUnderMin && + xCHMAScFastBuffer[2] > xCHMANonSCMin2 && + xCHMAScSlowBuffer[2] > xCHMANonSCMin2 + // + && + // + !( + // + ( + // + xEU5Conditions.isXCHMASCFastCrossedOverSlow || + ( + // + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMASCFastOverSlow + // + ) + // + ) && + ( + // + xEU5Conditions.isXCHMAMCFastCrossedOverSlow || + ( + // + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) + // + ) && + ( + // + xEU5Conditions.isXCHMALCFastCrossedOverSlow || + ( + // + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXCHMALCVale + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXCHMALCFastUnderSlow && + // + ( + // + ( + // + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastUnderSlow + // + ) || + ( + // + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBearish && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXTDBullCrossedUnderBear + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceInSignalRange + // + ) + // + && + // + !( + // + ( + // + xEU5Conditions.isXCHMASCVale || + xEU5Conditions.isXCHMAMCVale + // + ) + // + && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXTDSignalUnderBear && + ( + // + ( + // + xEU5Conditions.isXTMVale && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength + // + ) || + ( + // + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMALCVale && + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + // Funded ... + !( + // + (xEU5Conditions.isXAMAVale && + xEU5Conditions.isXCHMAMCVale && + xEU5Conditions.isXTDBullOverBear) + // + || + // + ((xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength) && + (xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XCHMACMX Long Signal Checking ... +bool XEU5XCHMACMXHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACMXEnableSignaller || + !xEU5MXCHMACMXAllowLongSignals) + { + return result; + } + + // + // Required Data ... + double entry = GetEntry(X_SIGNAL_LONG); + double nearHH = GetHighestHigh(3, 1); + double nearLL = GetLowestLow(3, 1); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + + // + result = + // + xEU5Conditions.isXCHMASCCrossedOverMax && + xCHMAScFastBuffer[2] < xCHMANonSCMax2 && + xCHMAScSlowBuffer[2] < xCHMANonSCMax2 && + MathAbs(xCHMANonSCMax2 - xCHMAScFastBuffer[2]) > MathAbs(xCHMAScFastBuffer[2] - xCHMAScSlowBuffer[2]) && + MathAbs(xCHMANonSCMax2 - xCHMAScSlowBuffer[2]) > MathAbs(xCHMAScFastBuffer[2] - xCHMAScSlowBuffer[2]) + // + && + // + !( + // + xEU5Conditions.isXLHPriceInSignalRange && + xEU5Conditions.isXLHHighAttachedHH + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + ( + // + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHMCOnTopOfLC && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXLHLLSameInLength + ? entry < nearHH + : true + // + ) + // + && + // + !( + // + xEU5Conditions.isXTMBullish && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXLHHighAttachedHH && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMASCCrossedOverMax && + xEU5Conditions.isXTDSignalCrossedOverBear + // + ) && + // + !( + // + (xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXLHHHDecreased && + xEU5Conditions.isXCHMASCOverMax && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow && + xEU5Conditions.isXCHMASCCrossedOverMax && + xEU5Conditions.isXLHPriceCrossedOverSignal) + // + || + // + (xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceOverSignal) + // + || + // + (xEU5Conditions.isXCHMASCPeak && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMALCTrendsDown) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// XCHMACMX Short Signal Checking ... +bool XEU5XCHMACMXHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACMXEnableSignaller || + !xEU5MXCHMACMXAllowShortSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax3 = XCHMAGetCyclesMaxValue(3, cycles); + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + + // + result = + // + xEU5Conditions.isXCHMASCCrossedUnderMax && + xCHMAScFastBuffer[2] > xCHMANonSCMax2 && + xCHMAScSlowBuffer[2] > xCHMANonSCMax2 + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMALCPeak + // + ) + // + && + // + !( + // + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXLHPriceInSignalRange && + // + ( + // + ( + // + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) || + ( + // + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXTDSignalUnderBear + // + ) + // + ) + // + ) + // + && + // + !( + // + ( + // + xEU5Conditions.isXCHMASCFastCrossedOverSlow || + ( + // + xEU5Conditions.isXCHMASCTrendsUp && + xEU5Conditions.isXCHMASCFastOverSlow + // + ) + // + ) && + ( + // + xEU5Conditions.isXCHMAMCFastCrossedOverSlow || + ( + // + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow + // + ) + // + ) && + ( + // + xEU5Conditions.isXCHMALCFastCrossedOverSlow || + ( + // + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + ) + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMin + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHLHSCMCLLSame && + xEU5Conditions.isXCHLHMCLCHHSame && + xEU5Conditions.isXLHLowAttachedLL + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHLHSameHHs && + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHMAMCTrendsUp && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXLHPriceInSignalRange + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXLHLLIncreased && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHPriceUnderSignal && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMAMCPeak && + xEU5Conditions.isXCHLHSCMCHHSame && + xEU5Conditions.isXCHLHMCLCLLSame && + xEU5Conditions.isXTDBullUnderBear && + xEU5Conditions.isXLHLLSameInLength && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMAMCFastUnderSlow && + xEU5Conditions.isXCHMALCFastUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXCHMALCTrendsUp && + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMASCFastOverSlow && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCCrossedUnderMax && + xEU5Conditions.isXLHPriceCrossedUnderSignal + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCCrossedUnderMax && + xEU5Conditions.isXTDSignalCrossedUnderBear && + xEU5Conditions.isXCHMASCFastCrossedUnderSlow + // + ) + // + && + // + !( + // + xEU5Conditions.isXCHMALCPeak && + xEU5Conditions.isXCHMASCOverMin && + xEU5Conditions.isXTDBullOverBear && + xEU5Conditions.isXCHMASCUnderMax && + xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXCHMASCTrendsDown && + xEU5Conditions.isXCHMAMCTrendsDown && + xEU5Conditions.isXCHMALCTrendsDown && + xEU5Conditions.isXTDSignalUnderBear && + xEU5Conditions.isXCHMAMCFastOverSlow && + xEU5Conditions.isXCHMALCFastOverSlow && + xEU5Conditions.isXCHMASCFastUnderSlow && + xEU5Conditions.isXCHMASCCrossedUnderMax + // + ) + // + && + // + !( + // + (xEU5Conditions.isXLHLowAttachedLL && + xEU5Conditions.isXLHHHSameInLength && + xEU5Conditions.isXLHPriceUnderSignal && + (xEU5Conditions.isXCHMAMCFastOverSlow || + xEU5Conditions.isXCHMAMCFastCrossedOverSlow) && + (xEU5Conditions.isXCHMALCFastOverSlow || + xEU5Conditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ; + + // + // Funded Next ... + if (isXEU5OnFundedNext && result) + { + // + result = + // + true + // + ; + } + + // + return result; +} + +// +// END Signal Providers ... +// + +// +// START Utilities ... +// + +// +// Converts Market Conditions to Specific String Representation ... +string XEU5GetConditionsString( + XEU5MarketConditions &condition, // Specify Conditiond + string separator = ",", // Specify Separator + bool ignoreFalses = true // Ignore False Conditions +) +{ + // + XEU5MarketConditions mConditions = {}; + + // + mConditions = condition; + + // + string result = "\n"; + + // + // XOBD ... + result += + "| XOBD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXOBDSwingLow)) + { + result += "isXOBDSwingLow: " + (string)mConditions.isXOBDSwingLow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXOBDSwingHigh)) + { + result += "isXOBDSwingHigh: " + (string)mConditions.isXOBDSwingHigh + separator; + } + + // + // Separator ... + result += separator; + + // + // XTM ... + result += + "| XTM |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMPeak)) + { + result += "isXTMPeak: " + (string)mConditions.isXTMPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMVale)) + { + result += "isXTMVale: " + (string)mConditions.isXTMVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBullish)) + { + result += "isXTMStartBullish: " + (string)mConditions.isXTMStartBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBullishAfterNeutural)) + { + result += "isXTMStartBullishAfterNeutural: " + (string)mConditions.isXTMStartBullishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMBullish)) + { + result += "isXTMBullish: " + (string)mConditions.isXTMBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBullish)) + { + result += "isXTMEndBullish: " + (string)mConditions.isXTMEndBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBullishByNeutural)) + { + result += "isXTMEndBullishByNeutural: " + (string)mConditions.isXTMEndBullishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBearish)) + { + result += "isXTMStartBearish: " + (string)mConditions.isXTMStartBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBearishAfterNeutural)) + { + result += "isXTMStartBearishAfterNeutural: " + (string)mConditions.isXTMStartBearishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMBearish)) + { + result += "isXTMBearish: " + (string)mConditions.isXTMBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBearish)) + { + result += "isXTMEndBearish: " + (string)mConditions.isXTMEndBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBearishByNeutural)) + { + result += "isXTMEndBearishByNeutural: " + (string)mConditions.isXTMEndBearishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMNeutural)) + { + result += "isXTMNeutural: " + (string)mConditions.isXTMNeutural + separator; + } + + // + // Separator ... + result += separator; + + // + // XAMA ... + result += + "| XAMA |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAPeak)) + { + result += "isXAMAPeak: " + (string)mConditions.isXAMAPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAVale)) + { + result += "isXAMAVale: " + (string)mConditions.isXAMAVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBullish)) + { + result += "isXAMAStartBullish: " + (string)mConditions.isXAMAStartBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBullishAfterNeutural)) + { + result += "isXAMAStartBullishAfterNeutural: " + (string)mConditions.isXAMAStartBullishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMABullish)) + { + result += "isXAMABullish: " + (string)mConditions.isXAMABullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBullish)) + { + result += "isXAMAEndBullish: " + (string)mConditions.isXAMAEndBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBullishByNeutural)) + { + result += "isXAMAEndBullishByNeutural: " + (string)mConditions.isXAMAEndBullishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBearish)) + { + result += "isXAMAStartBearish: " + (string)mConditions.isXAMAStartBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBearishAfterNeutural)) + { + result += "isXAMAStartBearishAfterNeutural: " + (string)mConditions.isXAMAStartBearishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMABearish)) + { + result += "isXAMABearish: " + (string)mConditions.isXAMABearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBearish)) + { + result += "isXAMAEndBearish: " + (string)mConditions.isXAMAEndBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBearishByNeutural)) + { + result += "isXAMAEndBearishByNeutural: " + (string)mConditions.isXAMAEndBearishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMANeutural)) + { + result += "isXAMANeutural: " + (string)mConditions.isXAMANeutural + separator; + } + + // + // Separator ... + result += separator; + + // + // XTD ... + result += + "| XTD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalPeak)) + { + result += "isXTDSignalPeak: " + (string)mConditions.isXTDSignalPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalVale)) + { + result += "isXTDSignalVale: " + (string)mConditions.isXTDSignalVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullishPeak)) + { + result += "isXTDBullishPeak: " + (string)mConditions.isXTDBullishPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullishVale)) + { + result += "isXTDBullishVale: " + (string)mConditions.isXTDBullishVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBearishPeak)) + { + result += "isXTDBearishPeak: " + (string)mConditions.isXTDBearishPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBearishVale)) + { + result += "isXTDBearishVale: " + (string)mConditions.isXTDBearishVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullOverBear)) + { + result += "isXTDBullOverBear: " + (string)mConditions.isXTDBullOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullUnderBear)) + { + result += "isXTDBullUnderBear: " + (string)mConditions.isXTDBullUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalOverBear)) + { + result += "isXTDSignalOverBear: " + (string)mConditions.isXTDSignalOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalUnderBear)) + { + result += "isXTDSignalUnderBear: " + (string)mConditions.isXTDSignalUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullCrossedOverBear)) + { + result += "isXTDBullCrossedOverBear: " + (string)mConditions.isXTDBullCrossedOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullCrossedUnderBear)) + { + result += "isXTDBullCrossedUnderBear: " + (string)mConditions.isXTDBullCrossedUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalCrossedOverBear)) + { + result += "isXTDSignalCrossedOverBear: " + (string)mConditions.isXTDSignalCrossedOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalCrossedUnderBear)) + { + result += "isXTDSignalCrossedUnderBear: " + (string)mConditions.isXTDSignalCrossedUnderBear + separator; + } + + // + // Separator ... + result += separator; + + // + // XFI ... + result += + "| XFI |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIPeak)) + { + result += "isXFIPeak: " + (string)mConditions.isXFIPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIVale)) + { + result += "isXFIVale: " + (string)mConditions.isXFIVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIOverZero)) + { + result += "isXFIOverZero: " + (string)mConditions.isXFIOverZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIUnderZero)) + { + result += "isXFIUnderZero: " + (string)mConditions.isXFIUnderZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFICrossedOverZero)) + { + result += "isXFICrossedOverZero: " + (string)mConditions.isXFICrossedOverZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFICrossedUnderZero)) + { + result += "isXFICrossedUnderZero: " + (string)mConditions.isXFICrossedUnderZero + separator; + } + + // + // Separator ... + result += separator; + + // + // XTS ... + result += + "| XTS |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSAllSame)) + { + result += "isXTSAllSame: " + (string)mConditions.isXTSAllSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentMin)) + { + result += "isXTSCurrentMin: " + (string)mConditions.isXTSCurrentMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentMax)) + { + result += "isXTSCurrentMax: " + (string)mConditions.isXTSCurrentMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverFarest)) + { + result += "isXTSCurrentOverFarest: " + (string)mConditions.isXTSCurrentOverFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverNearest)) + { + result += "isXTSCurrentOverNearest: " + (string)mConditions.isXTSCurrentOverNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverMediest)) + { + result += "isXTSCurrentOverMediest: " + (string)mConditions.isXTSCurrentOverMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderFarest)) + { + result += "isXTSCurrentUnderFarest: " + (string)mConditions.isXTSCurrentUnderFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderNearest)) + { + result += "isXTSCurrentUnderNearest: " + (string)mConditions.isXTSCurrentUnderNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderMediest)) + { + result += "isXTSCurrentUnderMediest: " + (string)mConditions.isXTSCurrentUnderMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverFarest)) + { + result += "isXTSCurrentCrossedOverFarest: " + (string)mConditions.isXTSCurrentCrossedOverFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverNearest)) + { + result += "isXTSCurrentCrossedOverNearest: " + (string)mConditions.isXTSCurrentCrossedOverNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverMediest)) + { + result += "isXTSCurrentCrossedOverMediest: " + (string)mConditions.isXTSCurrentCrossedOverMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderFarest)) + { + result += "isXTSCurrentCrossedUnderFarest: " + (string)mConditions.isXTSCurrentCrossedUnderFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderNearest)) + { + result += "isXTSCurrentCrossedUnderNearest: " + (string)mConditions.isXTSCurrentCrossedUnderNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderMediest)) + { + result += "isXTSCurrentCrossedUnderMediest: " + (string)mConditions.isXTSCurrentCrossedUnderMediest + separator; + } + + // + // Separator ... + result += separator; + + // + // XLH ... + result += + "| XLH |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHIncreased)) + { + result += "isXLHHHIncreased: " + (string)mConditions.isXLHHHIncreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHDecreased)) + { + result += "isXLHHHDecreased: " + (string)mConditions.isXLHHHDecreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLIncreased)) + { + result += "isXLHLLIncreased: " + (string)mConditions.isXLHLLIncreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLDecreased)) + { + result += "isXLHLLDecreased: " + (string)mConditions.isXLHLLDecreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHighAttachedHH)) + { + result += "isXLHHighAttachedHH: " + (string)mConditions.isXLHHighAttachedHH + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLowAttachedLL)) + { + result += "isXLHLowAttachedLL: " + (string)mConditions.isXLHLowAttachedLL + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHSameInLength)) + { + result += "isXLHHHSameInLength: " + (string)mConditions.isXLHHHSameInLength + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLSameInLength)) + { + result += "isXLHLLSameInLength: " + (string)mConditions.isXLHLLSameInLength + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceCrossedOverSignal)) + { + result += "isXLHPriceCrossedOverSignal: " + (string)mConditions.isXLHPriceCrossedOverSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceOverSignal)) + { + result += "isXLHPriceOverSignal: " + (string)mConditions.isXLHPriceOverSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceCrossedUnderSignal)) + { + result += "isXLHPriceCrossedUnderSignal: " + (string)mConditions.isXLHPriceCrossedUnderSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceUnderSignal)) + { + result += "isXLHPriceUnderSignal: " + (string)mConditions.isXLHPriceUnderSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceInSignalRange)) + { + result += "isXLHPriceInSignalRange: " + (string)mConditions.isXLHPriceInSignalRange + separator; + } + + // + // Separator ... + result += separator; + + // + // XRSI ... + result += + "| XRSI |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSIPeak)) + { + result += "isXRSIPeak: " + (string)mConditions.isXRSIPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSIVale)) + { + result += "isXRSIVale: " + (string)mConditions.isXRSIVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedOverLongExit)) + { + result += "isXRSICrossedOverLongExit: " + (string)mConditions.isXRSICrossedOverLongExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedOverLongEntry)) + { + result += "isXRSICrossedOverLongEntry: " + (string)mConditions.isXRSICrossedOverLongEntry + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedUnderShortExit)) + { + result += "isXRSICrossedUnderShortExit: " + (string)mConditions.isXRSICrossedUnderShortExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedUnderShortEntry)) + { + result += "isXRSICrossedUnderShortEntry: " + (string)mConditions.isXRSICrossedUnderShortEntry + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHLH ... + result += + "| XCHLH |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSameHHs)) + { + result += "isXCHLHSameHHs: " + (string)mConditions.isXCHLHSameHHs + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSameLLs)) + { + result += "isXCHLHSameLLs: " + (string)mConditions.isXCHLHSameLLs + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCMCHHSame)) + { + result += "isXCHLHSCMCHHSame: " + (string)mConditions.isXCHLHSCMCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCMCLLSame)) + { + result += "isXCHLHSCMCLLSame: " + (string)mConditions.isXCHLHSCMCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCLCHHSame)) + { + result += "isXCHLHSCLCHHSame: " + (string)mConditions.isXCHLHSCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCLCLLSame)) + { + result += "isXCHLHSCLCLLSame: " + (string)mConditions.isXCHLHSCLCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCLCHHSame)) + { + result += "isXCHLHMCLCHHSame: " + (string)mConditions.isXCHLHMCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCLCLLSame)) + { + result += "isXCHLHMCLCLLSame: " + (string)mConditions.isXCHLHMCLCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCOnTopOfLC)) + { + result += "isXCHLHMCOnTopOfLC: " + (string)mConditions.isXCHLHMCOnTopOfLC + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCInBottomOfLC)) + { + result += "isXCHLHMCInBottomOfLC: " + (string)mConditions.isXCHLHMCInBottomOfLC + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHMA ... + result += + "| XCHMA |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCOverMax)) + { + result += "isXCHMASCOverMax: " + (string)mConditions.isXCHMASCOverMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCOverMin)) + { + result += "isXCHMASCOverMin: " + (string)mConditions.isXCHMASCOverMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCUnderMax)) + { + result += "isXCHMASCUnderMax: " + (string)mConditions.isXCHMASCUnderMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCUnderMin)) + { + result += "isXCHMASCUnderMin: " + (string)mConditions.isXCHMASCUnderMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedOverMax)) + { + result += "isXCHMASCCrossedOverMax: " + (string)mConditions.isXCHMASCCrossedOverMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedUnderMax)) + { + result += "isXCHMASCCrossedUnderMax: " + (string)mConditions.isXCHMASCCrossedUnderMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedOverMin)) + { + result += "isXCHMASCCrossedOverMin: " + (string)mConditions.isXCHMASCCrossedOverMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedUnderMin)) + { + result += "isXCHMASCCrossedUnderMin: " + (string)mConditions.isXCHMASCCrossedUnderMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCPeak)) + { + result += "isXCHMASCPeak: " + (string)mConditions.isXCHMASCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCVale)) + { + result += "isXCHMASCVale: " + (string)mConditions.isXCHMASCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCTrendsUp)) + { + result += "isXCHMASCTrendsUp: " + (string)mConditions.isXCHMASCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCTrendsDown)) + { + result += "isXCHMASCTrendsDown: " + (string)mConditions.isXCHMASCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastOverSlow)) + { + result += "isXCHMASCFastOverSlow: " + (string)mConditions.isXCHMASCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastUnderSlow)) + { + result += "isXCHMASCFastUnderSlow: " + (string)mConditions.isXCHMASCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastCrossedOverSlow)) + { + result += "isXCHMASCFastCrossedOverSlow: " + (string)mConditions.isXCHMASCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastCrossedUnderSlow)) + { + result += "isXCHMASCFastCrossedUnderSlow: " + (string)mConditions.isXCHMASCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCPeak)) + { + result += "isXCHMAMCPeak: " + (string)mConditions.isXCHMAMCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCVale)) + { + result += "isXCHMAMCVale: " + (string)mConditions.isXCHMAMCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCTrendsUp)) + { + result += "isXCHMAMCTrendsUp: " + (string)mConditions.isXCHMAMCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCTrendsDown)) + { + result += "isXCHMAMCTrendsDown: " + (string)mConditions.isXCHMAMCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastOverSlow)) + { + result += "isXCHMAMCFastOverSlow: " + (string)mConditions.isXCHMAMCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastUnderSlow)) + { + result += "isXCHMAMCFastUnderSlow: " + (string)mConditions.isXCHMAMCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastCrossedOverSlow)) + { + result += "isXCHMAMCFastCrossedOverSlow: " + (string)mConditions.isXCHMAMCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastCrossedUnderSlow)) + { + result += "isXCHMAMCFastCrossedUnderSlow: " + (string)mConditions.isXCHMAMCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCPeak)) + { + result += "isXCHMALCPeak: " + (string)mConditions.isXCHMALCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCVale)) + { + result += "isXCHMALCVale: " + (string)mConditions.isXCHMALCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCTrendsUp)) + { + result += "isXCHMALCTrendsUp: " + (string)mConditions.isXCHMALCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCTrendsDown)) + { + result += "isXCHMALCTrendsDown: " + (string)mConditions.isXCHMALCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastOverSlow)) + { + result += "isXCHMALCFastOverSlow: " + (string)mConditions.isXCHMALCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastUnderSlow)) + { + result += "isXCHMALCFastUnderSlow: " + (string)mConditions.isXCHMALCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastCrossedOverSlow)) + { + result += "isXCHMALCFastCrossedOverSlow: " + (string)mConditions.isXCHMALCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastCrossedUnderSlow)) + { + result += "isXCHMALCFastCrossedUnderSlow: " + (string)mConditions.isXCHMALCFastCrossedUnderSlow + separator; + } + + // + // Separator ... + result += separator; + + // + return result; +} + +void Add( + ENUM_XEU5_SIGNAL_PROVIDERS item, + ENUM_XEU5_SIGNAL_PROVIDERS &items[]) +{ + // + ArrayResize( + items, + ArraySize(items) + 1); + + // + items[ArraySize(items) - 1] = item; +} +// +// START Utilities ... +// \ No newline at end of file diff --git a/XEU5-0/Providers/x-saherelm.xeu5.provider.inputs.lib.mq5 b/XEU5-0/Providers/x-saherelm.xeu5.provider.inputs.lib.mq5 new file mode 100644 index 0000000..b873b64 --- /dev/null +++ b/XEU5-0/Providers/x-saherelm.xeu5.provider.inputs.lib.mq5 @@ -0,0 +1,321 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XEU5 Signal Provider Library Inputs +// ----------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Include Logger ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Classes ... +#include "../Classes/x-saherelm.class.lib.mq5" + +// +// START Definitions ... +// + +// +// Cross Signals Methods ... +enum ENUM_XEU5_CROSS_SIGNAL_METHOD +{ + // + // Do Nothing and Ignore them ... + XEU5_CROSS_SIGNAL_DO_NOTHING, + // + // Accept all Cross Signals and Act Usually ... + XEU5_CROSS_SIGNAL_REGULAR, + // + // Accept all Cross Signals and for Directional Act Usually and for Indirectional Ac Important ... + XEU5_CROSS_SIGNAL_DIRECTION_REGULAR_INDIRECTION_IMPORTANT, + // + // Accept all Cross Signals and for Directional Act Important and for Indirectional Ac Usually ... + XEU5_CROSS_SIGNAL_DIRECTION_IMPORTANT_INDIRECTION_REGULAR, + // + // Accept Only Indirectional Signals and Act Usually ... + XEU5_CROSS_SIGNAL_INDIRECTION_REGULAR, + // + // Accept Only Directional Signals and Act Usually ... + XEU5_CROSS_SIGNAL_DIRECTION_REGULAR, + // + // Accept Only Indirectional Signals and Act Important ... + XEU5_CROSS_SIGNAL_INDIRECTION_IMPORTANT, + // + // Accept Only Directional Signals and Act Important ... + XEU5_CROSS_SIGNAL_DIRECTION_IMPORTANT, +}; + +// +// END Definitions ... +// + +// +input group "XEU5 Provider"; + +// +// Commonly Used Configurations ... +input group "XEU5 Common"; +// +// Provider ... +input bool xEU5EnableProvider = true; // Enable Provider +input int xEU5NumberOfItemsPerTick = 30; // Number Of items Readed In Each Tick +// +// Alerts ... +input bool xEU5EnableAlerts = true; // Enable Events Alert +input bool xEU5EnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEU5EnableDailyAlerts = false; // Send Alert on each new Day +input bool xEU5EnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEU5EnableMonthlyAlerts = true; // Send Alert on each new Month +// +// Reports ... +input bool xEU5EnableDailyReports = false; // Send Report on each new Day +input bool xEU5EnableWeeklyReports = false; // Send Report on each new Week +input bool xEU5EnableMonthlyReports = true; // Send Report on each new Month + +// +// Trader and Expert Specific Configurations ... +input group "XEU5 Trader"; +input int xEU5MagicNumber = 16940561; // Trader MagicNumber +input int xEU5Slippage = 10; // Trader Slippage + +// +// Trades Management Configurations ... +input group "XEU5 Trade Management"; +input bool xEU5AllowLongTrades = true; // Allow Long Trades +input bool xEU5AllowShortTrades = true; // Allow Short Trades + +// +// Risk Management Configurations ... +input group "XEU5 Risk Management"; +// +input bool xEU5UseVirtualTPSl = true; // Use Virtual TP SL +// +// Trade Count ... +input int xEU5MaxAllowedTrades = 4; // Max Allowed Trades at Same Time +input ENUM_XEU5_CROSS_SIGNAL_METHOD xEU5CrossSignalsMethod = XEU5_CROSS_SIGNAL_REGULAR; // Handle Cross Signals Method +// +// Max Allowed Trade Age ... +input int xEU5MaxAllowedTradeAge = 0; // Detect Long Time Trades +input ENUM_X_GUARD_ACTIONS xEU5OldTradesAction = X_GUARD_DO_NOTHING; // What to do with Old Trades +// +// Trade Volume Specific Configurations ... +input double xEU5StaticVolumeFactor = 0.00002; // Static Volume baesd on Balance +input ENUM_STATIC_VOLUME_METHODS xEU5StaticVolumeMethod = X_STATIC_VOLUME_BASED_ON_DEPOSIT; // How to Calculate Static Volume +input double xEU5VolumeMultiplier = 2.0; // Volume Increase Multiplier +input double xEU5ApplyVolumeMultiplierFactor = 0.002; // Apply Volume Multiplier Rate based on Balance +input double xEU5MaxSupportedVolumePerTradeFactor = 0.00008; // Max Supported Volume Per Trade Factor based on Balance +input double xEU5IncreasedMaxSupportedVolumeRate = 0.3; // Increase Max Supported Volume based on Balance +// +// Trade Profits ... +input double xEU5MinRewardInPips = 15; // Minimum Reward Per Trade in Pips +input double xEU5RiskFreeStepInPips = 4; // Make Trades Risk Free Steps in Pips +input double xEU5RiskFreeRate = 0.75; // Volume Multiplier for Risk Free Trades +// +// Guard Riskable Money and Profits ... +input double xEU5CriticalDrawDownFactor = 0.25; // Critical Allowed Drawdown Factor based on Balance +input ENUM_X_GUARD_ACTIONS xEU5CriticalGuardAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5; // Specify Guard Action on Critical Drawdown +input double xEU5MaxAllowedDrawDownFactor = 0.4; // Max Allowed Drawdown Factor based on Balance +input ENUM_X_GUARD_ACTIONS xEU5MaxAllowedGuardAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10; // Specify Guard Action on Max Allowed Drawdown +input int xEU5GuardStopoutFiredAfterTouches = 5; // Guard Stopout all Trades if Max Allowed Drawdown touched +// +// TODO: Complete this ... +// input ENUM_X_GUARD_SUPPORT_METHODS xEU5GuardSupportMethod = X_SUPPORT_DO_NOTHING; // How to Supprt Open Trades + +// +// Account Conditions for Trading ... +input double xEU5BalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades +input double xEU5FreeMarginFactorForOpenTrades = 0.8; // Minimum Free Margin for Open Trades + +// +// Validate Inputs before Initialization ... +bool XEU5ValidateInputs() +{ + // + bool result = false; + + // + // Implement Other Verifications ... + + // + // Check Trading Availability ... + bool isTradeAvailable = xEU5AllowLongTrades || xEU5AllowShortTrades; + if (!isTradeAvailable) + { + LogMessage("XEU5 => Warning: Trading disabled ..."); + } + + // + // Chekc Number of reading items per tick ... + result = xEU5NumberOfItemsPerTick >= 5; + if (!result) + { + // + LogMessage("XEU5 invalid Number of items Reading Per Tick ..."); + + // + return result; + } + + // + // Check Max Allowed Trades Count ... + result = isTradeAvailable && xEU5MaxAllowedTrades >= 1; + if (!result) + { + // + LogMessage("XEU5 Number of Trades not valid ..."); + + // + return result; + } + + // + // Check Free Margin ... + result = + isTradeAvailable && + xEU5FreeMarginFactorForOpenTrades > 0 && + xEU5FreeMarginFactorForOpenTrades < 1; + if (!result) + { + // + LogMessage("XEU5 Invalid Free Margin ..."); + + // + return result; + } + + // + // Check min Balance for Open Trades ... + result = + isTradeAvailable && + xEU5BalanceFactorForOpenTrades > 0 && + xEU5BalanceFactorForOpenTrades < 1; + if (!result) + { + // + LogMessage("XEU5 Invalid Min Balance for Open Trades ..."); + + // + return result; + } + + // + // Check Min Reward Per Trade ... + result = xEU5MinRewardInPips > 0; + if (!result) + { + // + LogMessage("XEU5 Invalid Min Reward Per Trade ..."); + + // + return result; + } + + // + // Check Trades Volume ... + result = xEU5StaticVolumeFactor > 0; + if (!result) + { + // + LogMessage("XEU5 Invalid Static Volume ..."); + + // + return result; + } + + // + // Check Volume Multiplier ... + result = xEU5VolumeMultiplier >= 0; + if (!result) + { + // + LogMessage("XEU5 Invalid Volume Multiplier ..."); + + // + return result; + } + + // + result = + xEU5CriticalDrawDownFactor == 0 || (xEU5CriticalDrawDownFactor > 0 && + xEU5CriticalDrawDownFactor < 1); + if (!result) + { + // + LogMessage("XEU5 Invalid Critical DrawDown Factor ..."); + + // + return result; + } + + // + result = + xEU5MaxAllowedDrawDownFactor == 0 || (xEU5MaxAllowedDrawDownFactor > 0 && + xEU5MaxAllowedDrawDownFactor < 1); + if (!result) + { + // + LogMessage("XEU5 Invalid Max Allowed DrawDown Factor ..."); + + // + return result; + } + + // + // Check Guard Actions ... + // + result = + xEU5CriticalDrawDownFactor > 0 && + xEU5CriticalDrawDownFactor < 1 && + xEU5MaxAllowedDrawDownFactor > 0 && + xEU5MaxAllowedDrawDownFactor < 1; + if (!result) + { + // + LogMessage("XEU5 For Critical Drawdown, you have to Specify Max Drawdown also ..."); + + // + return result; + } + + // + result = xEU5CriticalDrawDownFactor > 0 && xEU5CriticalDrawDownFactor < xEU5MaxAllowedDrawDownFactor; + if (!result) + { + // + LogMessage("XEU5 Critical Drawdown must Smaller than Max Drawdown ..."); + + // + return result; + } + + // + if (xEU5CriticalDrawDownFactor > 0 && xEU5CriticalGuardAction == X_GUARD_DO_NOTHING) + { + LogMessage("XEU5 IMPORTANT you Specified Critical Drawdown, but there is no any Guard Action ..."); + } + + // + if (xEU5MaxAllowedDrawDownFactor > 0 && xEU5MaxAllowedGuardAction == X_GUARD_DO_NOTHING) + { + LogMessage("XEU5 IMPORTANT you Specified Max Allowed Drawdown, but there is no any Guard Action ..."); + } + + // + result = true; + + // + return result; +} \ No newline at end of file diff --git a/XEU5-0/Providers/x-saherelm.xeu5.provider.lib.mq5 b/XEU5-0/Providers/x-saherelm.xeu5.provider.lib.mq5 new file mode 100644 index 0000000..4366410 --- /dev/null +++ b/XEU5-0/Providers/x-saherelm.xeu5.provider.lib.mq5 @@ -0,0 +1,1370 @@ +//////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XEU5 Signal Provider Library +// -------------------------------------------------------- +// Name: XEU5SignalProvider +// Description: XEU5 based signal provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +#define XEU5ProviderName "XEU5" + +// +// START Inputs ... +// + +#include "x-saherelm.xeu5.provider.inputs.lib.mq5"; + +// +// END Inputs ... +// + +// +// Include Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Include Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Alert Library ... +#include "../Libraries/x-saherelm.alert.lib.mq5" + +// +// Include Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Include Class Libraries ... +#include "../Classes/x-saherelm.class.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XCGuard *xEU5Guard; +XCTrade *xEU5Trader; +XCReporter *xEU5Reporter; +XCCollector *xEU5Collector; +XCAccountInfo *xEU5AccountInfo; +XCVolumeManager *xEU5VolumeManager; + +// +#include "x-saherelm.xeu5.provider.indicators.lib.mq5" + +// +// Controlling Variables ... +bool xEU5MEnableProvider = false; +bool xEU5MAllowLongTrades = false; +bool xEU5MAllowShortTrades = false; + +// +double xEU5Deposit = 0; +double xEU5Balance = 0; +double xEU5MinReward = 0; +double xEU5FreeMargin = 0; +double xEU5BalanceForOpenTrades = 0; +double xEU5FreeMarginForOpenTrades = 0; + +// +// Guard ... +double xEU5CriticalDrawDown = 0; +double xEU5MaxAllowedDrawDown = 0; + +// +double xEU5MaxDrawUp = 0; +double xEU5MaxDrawDown = 0; + +// +int NOT_ENOUGH_MONEY_ERROR = 4756; +const string XEU5_SUPPORT_ID = "SP"; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Initial Library if required ... +bool XEU5InitSignalProviderLibrary() +{ + // + bool result = false; + + // + if (!xEU5EnableProvider) + { + return result; + } + + // + // Controlling Variables ... + xEU5MEnableProvider = xEU5EnableProvider; + xEU5MAllowLongTrades = xEU5AllowLongTrades; + xEU5MAllowShortTrades = xEU5AllowShortTrades; + + // + // Validate Inputs ... + result = XEU5ValidateInputs(); + if (!result) + { + return result; + } + + // + // Init Indicators ... + result = XEU5InitIndicators(); + if (!result) + { + return result; + } + + // + xEU5Reporter = new XCReporter(); + xEU5Collector = new XCCollector(); + xEU5AccountInfo = new XCAccountInfo(); + + // + // Calculate Account Deposit ... + xEU5Deposit = xEU5AccountInfo.GetInitialBalance(); + + // + // Prepare Min Reward ... + if (xEU5MinRewardInPips > 0) + { + xEU5MinReward = PipsToPrice(xEU5MinRewardInPips); + } + + // + // Calculate Min Balance for Trades ... + if (xEU5BalanceFactorForOpenTrades > 0) + { + xEU5BalanceForOpenTrades = xEU5BalanceFactorForOpenTrades * xEU5Deposit; + } + + // + // Claculate Min Free Marging for Trades ... + if (xEU5FreeMarginFactorForOpenTrades > 0) + { + xEU5FreeMarginForOpenTrades = xEU5FreeMarginFactorForOpenTrades * xEU5Deposit; + } + + // + // Calculate Init Time Critical DrawDown Value ... + if (xEU5CriticalDrawDownFactor > 0) + { + xEU5CriticalDrawDown = xEU5CriticalDrawDownFactor * xEU5Deposit; + } + + // + // Calculate Init Time Max Allowed DrawDown Value ... + if (xEU5MaxAllowedDrawDownFactor > 0) + { + xEU5MaxAllowedDrawDown = xEU5MaxAllowedDrawDownFactor * xEU5Deposit; + } + + // + // Instant Volume Manager ... + xEU5VolumeManager = new XCVolumeManager( + xEU5StaticVolumeFactor, + xEU5StaticVolumeMethod, + xEU5VolumeMultiplier, + xEU5ApplyVolumeMultiplierFactor, + xEU5MaxSupportedVolumePerTradeFactor, + xEU5IncreasedMaxSupportedVolumeRate); + + // + // Make XCTrader instance ... + xEU5Trader = new XCTrade( + XEU5ProviderName, + _Symbol, + xEU5Slippage, + xEU5MagicNumber, + xEU5UseVirtualTPSl, + xEU5MaxAllowedTrades, + xEU5FreeMarginForOpenTrades, + xEU5BalanceForOpenTrades); + + // + // Instantiate Account Guard ... + xEU5Guard = new XCGuard( + // + // Old Trades ... + xEU5MaxAllowedTradeAge, + xEU5OldTradesAction, + // + // Critical DrawDown ... + xEU5CriticalDrawDownFactor, + xEU5CriticalGuardAction, + // + // Max Allowed DrawDown ... + xEU5MaxAllowedDrawDownFactor, + xEU5MaxAllowedGuardAction, + xEU5GuardStopoutFiredAfterTouches, + // + // xEU5GuardSupportMethod + X_SUPPORT_DO_NOTHING + // + ); + + // + // Reset Calculations Buffers and Variables ... + XEU5ResetCollectors(); + + // + XEU5UpdateReports(); + + // + result = true; + + // + // Logging State ... + XEU5IssueInitializationSucceedAlert(); + + // + return result; +} + +// +// DeInitial Library if required ... +void XEU5DeinitSignalProviderLibrary(const int reason) +{ + // + // Release Handlers ... + XEU5ReleaseIndicators(); + + // + // Logging State ... + XEU5IssueDeinitializationSucceedAlert(); +} + +// +// this is a Globally Function which do all of +// checkings and positions handling ... +void XEU5SignalProviderHandleTick() +{ + // + // Check Provider is Enable or Not ... + if (!xEU5MEnableProvider) + { + return; + } + + // + XEU5SignalProviderDoControlState(); + + // + // Reading Indicator Buffers ... + XEU5HandleReadingBuffers(); + if (xEU5CalculatedBars < xEU5MaxLengthOfInputs) + { + return; + } + + // + // Handle Open Trades ... + XEU5HandleOpenTrades(); + + // + // Handle Close Trades ... + XEU5HandleCloseTrades(); + + // + // DrawDown and DrawUp ... + XEU5HandleCalculateDrawDownUp(); +} + +// +// Do Control Checks here ... +void XEU5SignalProviderDoControlState() +{ + // + // Update account Balance ... + xEU5Balance = xEU5AccountInfo.GetBalance(); + xEU5FreeMargin = xEU5AccountInfo.GetFreeMargin(); + + // + // Check Provider is Enable or Not ... + if (!xEU5MEnableProvider) + { + return; + } + + // + // Protect Account by Guarding Maximum Drawdown ... + // TODO: add Guard Result here ... + string guardMessage = ""; + XGuardHandlerResult guardHandlerResult; + bool isGuarded = xEU5Guard.Guard( + guardHandlerResult, + guardMessage, + xEU5Trader, + _Period); + if (isGuarded) + { + // + // Criticals ... + int criticalsCount = ArraySize(guardHandlerResult.criticals); + if (criticalsCount > 0) + { + // + for (int i = 0; i < criticalsCount; i++) + { + // + XSignal iSignal = guardHandlerResult.criticals[i]; + + // + XEU5OnGuard( + iSignal, + X_GUARDED_CRITICAL, + guardMessage); + } + } + + // + // Maxes ... + int maxesCount = ArraySize(guardHandlerResult.maxes); + if (maxesCount > 0) + { + // + for (int i = 0; i < maxesCount; i++) + { + // + XSignal iSignal = guardHandlerResult.maxes[i]; + + // + XEU5OnGuard( + iSignal, + X_GUARDED_MAX, + guardMessage, + guardHandlerResult.isStopOut); + } + } + + // + // Olds ... + int oldsCount = ArraySize(guardHandlerResult.olds); + if (oldsCount > 0) + { + // + for (int i = 0; i < oldsCount; i++) + { + // + XSignal iSignal = guardHandlerResult.olds[i]; + + // + XEU5OnGuard( + iSignal, + X_GUARDED_OLD, + guardMessage); + } + } + } + + // + // Signal Protection ... + XSignal protectSupports[]; + bool isSupported = xEU5Guard.ProtectSignals( + protectSupports, + xEU5Trader); + if (isSupported) + { + // + LogMessage("Guard do Support Trdae ..."); + } + + // + // Handling Signals ... + XTraderHandlerResult signalHandlerResult; + xEU5Trader.HandleSignals( + signalHandlerResult, + false // Ignore Risk Free Trdaes + ); + + // + // Handle Sl Reports ... + int handledSLsCount = ArraySize(signalHandlerResult.sl); + if (handledSLsCount > 0) + { + // + for (int i = 0; i < handledSLsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.sl[i]; + XEU5OnSL(iSignal); + } + } + + // + // Handle TP Reports ... + int handledTPsCount = ArraySize(signalHandlerResult.tp); + if (handledTPsCount > 0) + { + // + for (int i = 0; i < handledTPsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.tp[i]; + XEU5OnTP(iSignal); + } + } + + // + // Handle RFs as TP Reports ... + int handledRFsCount = ArraySize(signalHandlerResult.rf); + if (handledRFsCount > 0) + { + // + for (int i = 0; i < handledRFsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.rf[i]; + XEU5OnRF(iSignal); + } + } +} + +// +// Handle Trades when OnTrade Event Hnadler Calls ... +void XEU5SignalProviderHandleTrade() +{ + // + // Check Provider Enabled ... + if (!xEU5MEnableProvider) + { + return; + } + + // + // Handle OnTrade Event ... + XOnTradeHandlerResult result = {}; + xEU5Trader.HandleOnTradeEvent( + result); + + // + // Detected TP or SL ... + if (result.hasNewDeal) + { + // + XDeal last = xEU5Trader.GetLastDeal(); + + // + if (last.reason == DEAL_REASON_SL) + { + xEU5Reporter.AddTradeSLInReports(); + } + else if (last.reason == DEAL_REASON_TP) + { + xEU5Reporter.AddTradeTPInReports(); + } + } +} + +// +// Handle Open Trades ... +void XEU5HandleOpenTrades() +{ + // + // Check Can Trade ... + bool canTrade = xEU5MAllowLongTrades || xEU5MAllowShortTrades; + if (!canTrade) + { + return; + } + + // + // Check Max Open Trades ... + int openSignals = xEU5Trader.Count(); + bool canOpenPositions = openSignals < xEU5MaxAllowedTrades; + if (!canOpenPositions) + { + return; + } + + // + // Check Signals Exists ... + XProvidedSignal longSignalInfo; + XProvidedSignal shortSignalInfo; + bool hasLongSignal = XEU5CanOpenLongTrade(longSignalInfo); + bool hasShortSignal = XEU5CanOpenShortTrade(shortSignalInfo); + if (!hasLongSignal && !hasShortSignal) + { + return; + } + + // + // Update Reports ... + XEU5UpdateReports(); + + // + // Open Long Trades ... + if ( + // + hasLongSignal && + xEU5MAllowLongTrades) + { + // + bool isOpened = XEU5OpenLongPosition(longSignalInfo); + } + + // + // Open Short Trades ... + if ( + // + hasShortSignal && + xEU5MAllowShortTrades) + { + // + bool isOpened = XEU5OpenShortPosition(shortSignalInfo); + } +} + +// +// Handle Close Trades ... +void XEU5HandleCloseTrades() +{ + // + // Force Close Long Trades ... + bool isClosedLongTrades = false; + bool canCloseLongTrades = XEU5CanCloseLongTrade(); + if (xEU5MAllowLongTrades && canCloseLongTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG; + + // + XSignal closed[]; + xEU5Trader.CloseSignals( + closed, + type); + + // + int closedTradesCount = ArraySize(closed); + isClosedLongTrades = closedTradesCount > 0; + if (isClosedLongTrades) + { + // + for (int i = 0; i < closedTradesCount; i++) + { + // + XSignal iSignal = closed[i]; + XEU5OnFC(iSignal); + } + } + } + + // + // Force Close Short Trades ... + bool isClosedShortTrades = false; + bool canCloseShortTrades = XEU5CanCloseShortTrade(); + if (xEU5MAllowShortTrades && canCloseShortTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT; + + // + XSignal closed[]; + xEU5Trader.CloseSignals( + closed, + type); + + // + int closedTradesCount = ArraySize(closed); + isClosedShortTrades = closedTradesCount > 0; + if (isClosedShortTrades) + { + // + for (int i = 0; i < closedTradesCount; i++) + { + // + XSignal iSignal = closed[i]; + XEU5OnFC(iSignal); + } + } + } +} + +// +// Open Long Position ... +bool XEU5OpenLongPosition( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double entry = GetEntry(_Symbol, X_SIGNAL_LONG); + double sl = info.sl > 0 ? info.sl : 0; + // entry - (200 * _Point); + // info.sl > 0 ? info.sl : 0; + double tp = info.tp > 0 ? info.tp : entry + xEU5MinReward; + double riskFreeRate = xEU5RiskFreeRate; + double riskFreeStep = xEU5RiskFreeStepInPips; + double volume = XEU5CalculateVolume(ArraySize(info.signallers)); + + // + XSignal signal = {}; + signal = xEU5Trader.GenerateSignal( + X_SIGNAL_LONG, + tp, + sl, + volume, + riskFreeStep, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xEU5MagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int signalsCount = xEU5Trader.Count(); + bool isCross = signalsCount >= 1; + if (isCross) + { + // + // Handle Cross Signals ... + XEU5HnadleCrossSignal(signal); + } + + // + // Retrieve Can Execute Signal or not ... + bool canExecuteSignal = + !isCross + // + || + // + ( + // + isCross && + xEU5CrossSignalsMethod != XEU5_CROSS_SIGNAL_DO_NOTHING + // + ); + if (!canExecuteSignal) + { + return result; + } + + // + // Execute Signal ... + ENUM_EXECUTION_SIGNAL_RESULT executionResult = xEU5Trader.ExecuteSignal( + signal, + false, // Ignore Number of Trades ... + true // Check Account Conditions ... + ); + result = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (result) + { + // + // Update Reports ... + string providers[]; + ArrayCopy( + providers, + info.signallers + ); + + // + XSignal tSignal = xEU5Trader.GetSignal(signal.ticket); + + // + XEU5OnSignal( + tSignal, + providers); + } + else + { + XEU5IssueSignalExecutionError(executionResult); + } + + // + return result; +} + +// +// Open Short Position ... +bool XEU5OpenShortPosition( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double entry = GetEntry(_Symbol, X_SIGNAL_SHORT); + double sl = info.sl > 0 ? info.sl : 0; + // entry + (200 * _Point); + // info.sl > 0 ? info.sl : 0; + double tp = info.tp > 0 ? info.tp : entry - xEU5MinReward; + double riskFreeRate = xEU5RiskFreeRate; + double riskFreeStep = xEU5RiskFreeStepInPips; + double volume = XEU5CalculateVolume(ArraySize(info.signallers)); + + // + XSignal signal = {}; + signal = xEU5Trader.GenerateSignal( + X_SIGNAL_SHORT, + tp, + sl, + volume, + riskFreeStep, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xEU5MagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int signalsCount = xEU5Trader.Count(); + bool isCross = signalsCount >= 1; + if (isCross) + { + // + // Handle Cross Signals ... + XEU5HnadleCrossSignal(signal); + } + + // + // Retrieve Can Execute Signal or not ... + bool canExecuteSignal = + !isCross + // + || + // + ( + // + isCross && + xEU5CrossSignalsMethod != XEU5_CROSS_SIGNAL_DO_NOTHING + // + ); + if (!canExecuteSignal) + { + return result; + } + + // + // Execute Signal ... + ENUM_EXECUTION_SIGNAL_RESULT executionResult = xEU5Trader.ExecuteSignal( + signal, + false, // Ignore Number of Trades ... + true // Check Account Conditions ... + ); + result = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (result) + { + string providers[]; + ArrayCopy( + providers, + info.signallers + ); + + // + XSignal tSignal = xEU5Trader.GetSignal(signal.ticket); + + // + XEU5OnSignal( + tSignal, + providers); + } + else + { + XEU5IssueSignalExecutionError(executionResult); + } + + // + return result; +} + +// +// Apply Cross Signal Actions ... +void XEU5HnadleCrossSignal( + XSignal &signal // Specified Signal ... +) +{ + // + // Check Cross Signal Handling Enabled ... + if (xEU5CrossSignalsMethod == XEU5_CROSS_SIGNAL_DO_NOTHING) + { + return; + } + + // + // First We have to Change Cross Signals Comment ... + string comment = xEU5Trader.GenerateSignalComment( + signal, + true); + + // + signal.comment = comment; + + // + // If Every thing is Regular, prevent any changes here ... + if (xEU5CrossSignalsMethod == XEU5_CROSS_SIGNAL_REGULAR) + { + return; + } + + // + // Retrieve Max in Drawdown Signal ... + XSignal maxInDDSignal = xEU5Trader.GetMaxInDrawdownSignal(); + + // + // Validate Signal ... + bool isValidSignal = + maxInDDSignal.ticket > 0 && + maxInDDSignal.symbol == signal.symbol && + IsValid(maxInDDSignal, xEU5MagicNumber); + if (!isValidSignal) + { + return; + } + + // + double volume = signal.volume; + bool isDirectional = maxInDDSignal.type == signal.type; + + // + // Prevent any changes on Regular Conditions ... + bool isRegular = + isDirectional + ? ( + // + xEU5CrossSignalsMethod == XEU5_CROSS_SIGNAL_DIRECTION_REGULAR || + xEU5CrossSignalsMethod == XEU5_CROSS_SIGNAL_DIRECTION_REGULAR_INDIRECTION_IMPORTANT + // + ) + : ( + // + xEU5CrossSignalsMethod == XEU5_CROSS_SIGNAL_INDIRECTION_REGULAR || + xEU5CrossSignalsMethod == XEU5_CROSS_SIGNAL_DIRECTION_IMPORTANT_INDIRECTION_REGULAR + // + ); + if (isRegular) + { + return; + } + + // + // Important Act needs to Multiply volume by 2 ... + volume *= 2; + + // + // Set Volume of signal ... + signal.volume = volume; +} + +// +// Calculate Usefull data ... +void XEU5HandleCalculateDrawDownUp() +{ + // + XSignal signals[]; + xEU5Trader.GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + double profit = 0; + double volume = 0; + XCollector collector = {}; + double maxAllowedVolume = xEU5VolumeManager.GetMaxAllowedVolume(); + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + profit += iSignal.profit; + + // + volume = + volume == 0 || + volume < iSignal.volume + ? iSignal.volume + : volume; + } + + // + if (profit < 0) + { + // + xEU5MaxDrawDown = + xEU5MaxDrawDown == 0 || + xEU5MaxDrawDown > MathAbs(profit) + ? MathAbs(profit) + : xEU5MaxDrawDown; + + // + // Update Buffers ... + datetime time = iTime(_Symbol, _Period, 0); + + // + // Calculate Max Allowed Drawdown ... + // + collector.time = time; + collector.volume = volume; + collector.maxDrawDown = xEU5MaxDrawDown; + collector.maxAllowedVolume = maxAllowedVolume; + collector.minBalanceForOpenTrade = xEU5Trader.GetMinBalanceForOpenTrades(); + } + else + { + // + xEU5MaxDrawUp = + xEU5MaxDrawUp == 0 || + xEU5MaxDrawUp < profit + ? profit + : xEU5MaxDrawUp; + } + + // + // Update Collector ... + xEU5Collector.Add(collector); + + // + // Update Reports ... + xEU5Reporter.UpdateMaxDrawUpInReports(xEU5MaxDrawUp); + xEU5Reporter.UpdateMaxDrawDownInReports(xEU5MaxDrawDown); + xEU5Reporter.UpdateMaxSameTimeTradesInReports(signalsCount); +} + +// +// START Event Handlers ... +// + +// +// Runs When a Signal Successfully Executed ... +void XEU5OnSignal( + XSignal &signal, // Specified Signal + string &providers[] // Signal Providers +) +{ + // + // Issue Propper Alert ... + XEU5IssueSignalExecutionAlert( + signal, + providers); + + // + // Add Signal To Supports on Guard ... + xEU5Guard.AddSupport(signal); + + // + // Update Reports ... + xEU5Reporter.AddSignalToReports( + signal, + providers); +} + +// +// Runs when a Position Got Take Profit ... +void XEU5OnTP( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueTPAlert(signal); + + // + // Remove Signal From Guard Protector ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeTPInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Got Stop Loss ... +void XEU5OnSL( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueSLAlert(signal); + + // + // Remove Signal From Guard Protector ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Risk Free ... +void XEU5OnRF( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueRFAlert(signal); + + // + // Remove Signal From Guard Protector ... + // since RiskFree Signals has SL ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Force Closed ... +void XEU5OnFC( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueFCAlert(signal); + + // + // Remove Signal From Guard Protector ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Guarded ... +void XEU5OnGuard( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason, // Reason of Guard Applied + string message, // Guard Returned Message + bool isStopOut = false // Specified StopOut Fired or not +) +{ + // + // Chekc StopOut ... + if (isStopOut) + { + // + LogMessage(message); + + // + xEU5MEnableProvider = false; + } + + // + // Issue Propper Alert ... + XEU5IssueGuardAlert(signal, reason, isStopOut); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// END Event Handlers ... +// + +// +// END Provided Functions ... +// + +// +// START Private Functions ... +// + +// +// START Volume Baseed Functions ... +// + +// +// Calculating Volume for Tradings ... +double XEU5CalculateVolume( + double forceMultiplier = 0 // some times we get more than one signal at the same time, here we increase volume using this ... +) +{ + // + // Check Open Trades ... + int openSignals = xEU5Trader.Count(); + + // + double result = xEU5VolumeManager.CalculateVolume( + openSignals, + _Symbol); + + // + result *= forceMultiplier; + + // + // Normalize Volume ... + result = NormalizeVolume(result, _Symbol, 2); + + // + return result; +} + +// +// END Volume Baseed Functions ... +// + +// +// START Report/Collect and Guard Functions ... +// + +// +// Update Report Info ... +void XEU5UpdateReports() +{ + // + double staticVolume = xEU5VolumeManager.GetStaticVolume(); + string staticVolumeCalculationMethod = EnumToString(xEU5StaticVolumeMethod); + double maxAllowedVolume = xEU5VolumeManager.GetMaxAllowedVolume(); + double volumeIncreaseMultiplier = xEU5VolumeManager.GetVolumeMultiplier(); + double balanceGowingToApplyMultiplier = xEU5VolumeManager.GetIncreaseMultiplierBalance(); + + double balanceGrowingToIncreaseMaxAllowedVolume = xEU5VolumeManager.GetIncreaseMaxAllowedVolumeBalance(); + + // + // Update Reports Volume Info ... + xEU5Reporter.UpdateReportsVolumeInfo( + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Calculate Max Allowed Drawdown ... + double minBalanceForTradeBasedOnBalance = xEU5Trader.GetMinBalanceForOpenTrades(); + xEU5Reporter.UpdateMinBalanceForOpenTradesInReports(minBalanceForTradeBasedOnBalance); +} + +// +// Reset XEU5 Info Buffers ... +void XEU5ResetCollectors() +{ + // + // Reset Calculations Buffers and Variables ... + xEU5MaxDrawUp = 0; + xEU5MaxDrawDown = 0; + + // + xEU5Trader.Reset(); + xEU5Reporter.Reset(); + xEU5Collector.Reset(); + xEU5VolumeManager.ResetForceVolumeMultiplier(); +} + +// +// END Report/Collect and Guard Functions ... +// + +// +// START Alert Functions ... +// + +// +// Send Alert ... +void XEU5IssueAlert(string message) +{ + // + // Validate Args ... + if (StringLen(message) <= 0) + { + return; + } + + // + if (xEU5EnableAlerts) + { + SendAlert(message); + } + else + { + LogMessage(message); + } +} + +// +// Send Take Profit Alert on Specific Signal ... +void XEU5IssueTPAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalTPComment(signal); + + // + XEU5IssueAlert(message); +} + +// +// Send Stop Loss Alert on Specific Signal ... +void XEU5IssueSLAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalSLComment(signal); + + // + XEU5IssueAlert(message); +} + +// +// Send Force Close Alert on Specific Signal ... +void XEU5IssueFCAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalForceCloseComment(signal); + + // + XEU5IssueAlert(message); +} + +// +// Send Risk Free Alert on Specific Signal ... +void XEU5IssueRFAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalRFComment(signal, 0); + + // + XEU5IssueAlert(message); +} + +// +// Send Guard Alert on Specific Signal ... +void XEU5IssueGuardAlert( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason, // Specified Guard Reason + bool isStopOut = false // Specified StopOut Fired or not +) +{ + // + string message = ""; + + // + message = xEU5Guard.GenerateGuardedSignalComment( + signal, + reason); + + // + XEU5IssueAlert(message); +} + +// +// Send Initialization Succeed Alert ... +void XEU5IssueInitializationSucceedAlert() +{ + // + string message = "Initializion of (" + XEU5ProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ..."; + XEU5IssueAlert(message); +} + +// +// Send De Initialization Succeed Alert ... +void XEU5IssueDeinitializationSucceedAlert() +{ + // + string message = "De Initializion of (" + XEU5ProviderName + " Provider" + ") Succeeded ..."; + XEU5IssueAlert(message); +} + +// +// Send Signal Successfully Execution Alert ... +void XEU5IssueSignalExecutionAlert( + XSignal &signal, // Specified Signal + string &providers[] // Signal Providers +) +{ + // + string message = xEU5Trader.ToString(signal); + + // + string providersMsg = ToString(providers); + if (StringLen(providersMsg) > 0) + { + message += ", Providers: " + providersMsg; + } + + // + XEU5IssueAlert(message); +} + +// +// Send Signal Execution Alert ... +void XEU5IssueSignalExecutionError(int error) +{ + // + string message = GetSignalExecutionError(error); + if (StringLen(message) == 0) + { + return; + } + + // + XEU5IssueAlert(message); +} + +// +// END Alert Functions ... +// + +// +// END Private Functions ... +// diff --git a/XEU5-0/Settings/.gitkeep b/XEU5-0/Settings/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Templates/.gitkeep b/XEU5-0/Templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5-0/Templates/FundedNext.XEU5.Guarded.Signals.txt b/XEU5-0/Templates/FundedNext.XEU5.Guarded.Signals.txt new file mode 100644 index 0000000..79c473c --- /dev/null +++ b/XEU5-0/Templates/FundedNext.XEU5.Guarded.Signals.txt @@ -0,0 +1,548 @@ +2020.02.06 20:35:00 XEU5EA > Long Signal Provided by: +2020.02.06 20:35:00 XTAM +2020.02.06 20:35:00 Pusher: 1 +2020.02.06 20:35:00 Market Conditions: +2020.02.06 20:35:00 | XOBD | +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XTM | +2020.02.06 20:35:00 isXTMBullish: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XAMA | +2020.02.06 20:35:00 isXAMABullish: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XTD | +2020.02.06 20:35:00 isXTDBullOverBear: true +2020.02.06 20:35:00 isXTDSignalOverBear: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XFI | +2020.02.06 20:35:00 isXFIOverZero: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XTS | +2020.02.06 20:35:00 isXTSCurrentMax: true +2020.02.06 20:35:00 isXTSCurrentOverFarest: true +2020.02.06 20:35:00 isXTSCurrentOverMediest: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XLH | +2020.02.06 20:35:00 isXLHLLSameInLength: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XRSI | +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XCHLH | +2020.02.06 20:35:00 isXCHLHMCLCLLSame: true +2020.02.06 20:35:00 isXCHLHMCOnTopOfLC: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 | XCHMA | +2020.02.06 20:35:00 isXCHMASCOverMin: true +2020.02.06 20:35:00 isXCHMASCUnderMax: true +2020.02.06 20:35:00 isXCHMASCUnderMin: true +2020.02.06 20:35:00 isXCHMASCTrendsUp: true +2020.02.06 20:35:00 isXCHMASCFastOverSlow: true +2020.02.06 20:35:00 isXCHMAMCVale: true +2020.02.06 20:35:00 isXCHMAMCTrendsDown: true +2020.02.06 20:35:00 isXCHMAMCFastUnderSlow: true +2020.02.06 20:35:00 isXCHMALCVale: true +2020.02.06 20:35:00 isXCHMALCTrendsUp: true +2020.02.06 20:35:00 isXCHMALCFastUnderSlow: true +2020.02.06 20:35:00 +2020.02.06 20:35:00 +2020.02.06 20:35:00 market buy 1.04 EURUSD tp: 1.10013 (1.09810 / 1.09813 / 1.09810) +2020.02.06 20:35:00 deal #785 buy 1.04 EURUSD at 1.09813 done (based on order #785) +2020.02.06 20:35:00 deal performed [#785 buy 1.04 EURUSD at 1.09813] +2020.02.06 20:35:00 order performed buy 1.04 at 1.09813 [#785 buy 1.04 EURUSD at 1.09813] +2020.02.06 20:35:00 XEU5EA > T(785)_TY(Long)_TP(1.10013)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XTAM + + +2020.04.29 02:05:00 XEU5EA > Short Signal Provided by: +2020.04.29 02:05:00 XSI +2020.04.29 02:05:00 Pusher: 1 +2020.04.29 02:05:00 Market Conditions: +2020.04.29 02:05:00 | XOBD | +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XTM | +2020.04.29 02:05:00 isXTMBullish: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XAMA | +2020.04.29 02:05:00 isXAMABullish: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XTD | +2020.04.29 02:05:00 isXTDBullOverBear: true +2020.04.29 02:05:00 isXTDSignalOverBear: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XFI | +2020.04.29 02:05:00 isXFIOverZero: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XTS | +2020.04.29 02:05:00 isXTSCurrentMax: true +2020.04.29 02:05:00 isXTSCurrentOverFarest: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XLH | +2020.04.29 02:05:00 isXLHLLSameInLength: true +2020.04.29 02:05:00 isXLHPriceOverSignal: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XRSI | +2020.04.29 02:05:00 isXRSICrossedUnderShortEntry: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XCHLH | +2020.04.29 02:05:00 isXCHLHSCMCHHSame: true +2020.04.29 02:05:00 isXCHLHMCOnTopOfLC: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 | XCHMA | +2020.04.29 02:05:00 isXCHMASCOverMax: true +2020.04.29 02:05:00 isXCHMASCOverMin: true +2020.04.29 02:05:00 isXCHMASCCrossedOverMax: true +2020.04.29 02:05:00 isXCHMASCPeak: true +2020.04.29 02:05:00 isXCHMASCTrendsUp: true +2020.04.29 02:05:00 isXCHMASCFastOverSlow: true +2020.04.29 02:05:00 isXCHMAMCTrendsDown: true +2020.04.29 02:05:00 isXCHMAMCFastUnderSlow: true +2020.04.29 02:05:00 isXCHMALCPeak: true +2020.04.29 02:05:00 isXCHMALCTrendsUp: true +2020.04.29 02:05:00 isXCHMALCFastOverSlow: true +2020.04.29 02:05:00 +2020.04.29 02:05:00 +2020.04.29 02:05:00 market sell 1.14 EURUSD tp: 1.08201 (1.08401 / 1.08451 / 1.08401) +2020.04.29 02:05:00 deal #975 sell 1.14 EURUSD at 1.08401 done (based on order #975) +2020.04.29 02:05:00 deal performed [#975 sell 1.14 EURUSD at 1.08401] +2020.04.29 02:05:00 order performed sell 1.14 at 1.08401 [#975 sell 1.14 EURUSD at 1.08401] +2020.04.29 02:05:00 XEU5EA > T(975)_TY(Short)_TP(1.08201)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XSI + + +2020.05.25 21:10:00 XEU5EA > Short Signal Provided by: +2020.05.25 21:10:00 XTAM +2020.05.25 21:10:00 Pusher: 1 +2020.05.25 21:10:00 Market Conditions: +2020.05.25 21:10:00 | XOBD | +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XTM | +2020.05.25 21:10:00 isXTMBearish: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XAMA | +2020.05.25 21:10:00 isXAMABearish: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XTD | +2020.05.25 21:10:00 isXTDSignalUnderBear: true +2020.05.25 21:10:00 isXTDBullCrossedUnderBear: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XFI | +2020.05.25 21:10:00 isXFIUnderZero: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XTS | +2020.05.25 21:10:00 isXTSCurrentMin: true +2020.05.25 21:10:00 isXTSCurrentUnderFarest: true +2020.05.25 21:10:00 isXTSCurrentUnderNearest: true +2020.05.25 21:10:00 isXTSCurrentUnderMediest: true +2020.05.25 21:10:00 isXTSCurrentCrossedUnderNearest: true +2020.05.25 21:10:00 isXTSCurrentCrossedUnderMediest: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XLH | +2020.05.25 21:10:00 isXLHHHSameInLength: true +2020.05.25 21:10:00 isXLHPriceCrossedOverSignal: true +2020.05.25 21:10:00 isXLHPriceOverSignal: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XRSI | +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XCHLH | +2020.05.25 21:10:00 isXCHLHMCOnTopOfLC: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 | XCHMA | +2020.05.25 21:10:00 isXCHMASCOverMin: true +2020.05.25 21:10:00 isXCHMASCUnderMax: true +2020.05.25 21:10:00 isXCHMASCTrendsUp: true +2020.05.25 21:10:00 isXCHMASCFastUnderSlow: true +2020.05.25 21:10:00 isXCHMAMCFastOverSlow: true +2020.05.25 21:10:00 isXCHMALCVale: true +2020.05.25 21:10:00 isXCHMALCTrendsDown: true +2020.05.25 21:10:00 isXCHMALCFastUnderSlow: true +2020.05.25 21:10:00 +2020.05.25 21:10:00 +2020.05.25 21:10:00 market sell 1.05 EURUSD tp: 1.08760 (1.08960 / 1.08966 / 1.08960) +2020.05.25 21:10:00 deal #1036 sell 1.05 EURUSD at 1.08960 done (based on order #1036) +2020.05.25 21:10:00 deal performed [#1036 sell 1.05 EURUSD at 1.08960] +2020.05.25 21:10:00 order performed sell 1.05 at 1.08960 [#1036 sell 1.05 EURUSD at 1.08960] +2020.05.25 21:10:00 XEU5EA > T(1036)_TY(Short)_TP(1.0876)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XTAM + + +2020.07.10 19:15:00 XEU5EA > Short Signal Provided by: +2020.07.10 19:15:00 XTAM +2020.07.10 19:15:00 Pusher: 1 +2020.07.10 19:15:00 Market Conditions: +2020.07.10 19:15:00 | XOBD | +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XTM | +2020.07.10 19:15:00 isXTMStartBearish: true +2020.07.10 19:15:00 isXTMStartBearishAfterNeutural: true +2020.07.10 19:15:00 isXTMBearish: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XAMA | +2020.07.10 19:15:00 isXAMAStartBearish: true +2020.07.10 19:15:00 isXAMAStartBearishAfterNeutural: true +2020.07.10 19:15:00 isXAMABearish: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XTD | +2020.07.10 19:15:00 isXTDBullOverBear: true +2020.07.10 19:15:00 isXTDSignalOverBear: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XFI | +2020.07.10 19:15:00 isXFIUnderZero: true +2020.07.10 19:15:00 isXFICrossedUnderZero: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XTS | +2020.07.10 19:15:00 isXTSCurrentMin: true +2020.07.10 19:15:00 isXTSCurrentUnderFarest: true +2020.07.10 19:15:00 isXTSCurrentUnderNearest: true +2020.07.10 19:15:00 isXTSCurrentUnderMediest: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XLH | +2020.07.10 19:15:00 isXLHHHSameInLength: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XRSI | +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XCHLH | +2020.07.10 19:15:00 isXCHLHMCLCHHSame: true +2020.07.10 19:15:00 isXCHLHMCOnTopOfLC: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 | XCHMA | +2020.07.10 19:15:00 isXCHMASCOverMax: true +2020.07.10 19:15:00 isXCHMASCOverMin: true +2020.07.10 19:15:00 isXCHMASCUnderMax: true +2020.07.10 19:15:00 isXCHMASCTrendsDown: true +2020.07.10 19:15:00 isXCHMASCFastOverSlow: true +2020.07.10 19:15:00 isXCHMAMCPeak: true +2020.07.10 19:15:00 isXCHMAMCTrendsDown: true +2020.07.10 19:15:00 isXCHMAMCFastOverSlow: true +2020.07.10 19:15:00 isXCHMALCPeak: true +2020.07.10 19:15:00 isXCHMALCTrendsDown: true +2020.07.10 19:15:00 isXCHMALCFastUnderSlow: true +2020.07.10 19:15:00 +2020.07.10 19:15:00 +2020.07.10 19:15:00 market sell 0.22 EURUSD tp: 1.12803 (1.13003 / 1.13007 / 1.13003) +2020.07.10 19:15:00 deal #1174 sell 0.22 EURUSD at 1.13003 done (based on order #1174) +2020.07.10 19:15:00 deal performed [#1174 sell 0.22 EURUSD at 1.13003] +2020.07.10 19:15:00 order performed sell 0.22 at 1.13003 [#1174 sell 0.22 EURUSD at 1.13003] +2020.07.10 19:15:00 XEU5EA > T(1174)_TY(Short)_TP(1.12803)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XTAM + + +2020.09.28 02:05:00 XEU5EA > Short Signal Provided by: +2020.09.28 02:05:00 XTAM +2020.09.28 02:05:00 Pusher: 1 +2020.09.28 02:05:00 Market Conditions: +2020.09.28 02:05:00 | XOBD | +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XTM | +2020.09.28 02:05:00 isXTMBearish: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XAMA | +2020.09.28 02:05:00 isXAMABearish: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XTD | +2020.09.28 02:05:00 isXTDBullUnderBear: true +2020.09.28 02:05:00 isXTDSignalUnderBear: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XFI | +2020.09.28 02:05:00 isXFIUnderZero: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XTS | +2020.09.28 02:05:00 isXTSCurrentMin: true +2020.09.28 02:05:00 isXTSCurrentUnderFarest: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XLH | +2020.09.28 02:05:00 isXLHHHSameInLength: true +2020.09.28 02:05:00 isXLHPriceUnderSignal: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XRSI | +2020.09.28 02:05:00 isXRSICrossedUnderShortExit: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XCHLH | +2020.09.28 02:05:00 isXCHLHSCMCLLSame: true +2020.09.28 02:05:00 isXCHLHMCOnTopOfLC: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 | XCHMA | +2020.09.28 02:05:00 isXCHMASCUnderMax: true +2020.09.28 02:05:00 isXCHMASCUnderMin: true +2020.09.28 02:05:00 isXCHMASCVale: true +2020.09.28 02:05:00 isXCHMASCTrendsUp: true +2020.09.28 02:05:00 isXCHMASCFastUnderSlow: true +2020.09.28 02:05:00 isXCHMAMCTrendsUp: true +2020.09.28 02:05:00 isXCHMAMCFastUnderSlow: true +2020.09.28 02:05:00 isXCHMALCVale: true +2020.09.28 02:05:00 isXCHMALCTrendsDown: true +2020.09.28 02:05:00 isXCHMALCFastUnderSlow: true +2020.09.28 02:05:00 +2020.09.28 02:05:00 +2020.09.28 02:05:00 market sell 0.36 EURUSD tp: 1.15989 (1.16189 / 1.16191 / 1.16189) +2020.09.28 02:05:00 deal #1364 sell 0.36 EURUSD at 1.16189 done (based on order #1364) +2020.09.28 02:05:00 deal performed [#1364 sell 0.36 EURUSD at 1.16189] +2020.09.28 02:05:00 order performed sell 0.36 at 1.16189 [#1364 sell 0.36 EURUSD at 1.16189] +2020.09.28 02:05:00 XEU5EA > T(1364)_TY(Short)_TP(1.15989)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XTAM + + +2021.03.04 05:20:00 XEU5EA > Long Signal Provided by: +2021.03.04 05:20:00 XTAM +2021.03.04 05:20:00 Pusher: 1 +2021.03.04 05:20:00 Market Conditions: +2021.03.04 05:20:00 | XOBD | +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XTM | +2021.03.04 05:20:00 isXTMStartBullish: true +2021.03.04 05:20:00 isXTMStartBullishAfterNeutural: true +2021.03.04 05:20:00 isXTMBullish: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XAMA | +2021.03.04 05:20:00 isXAMAStartBullish: true +2021.03.04 05:20:00 isXAMAStartBullishAfterNeutural: true +2021.03.04 05:20:00 isXAMABullish: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XTD | +2021.03.04 05:20:00 isXTDBearishVale: true +2021.03.04 05:20:00 isXTDBullOverBear: true +2021.03.04 05:20:00 isXTDSignalOverBear: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XFI | +2021.03.04 05:20:00 isXFIOverZero: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XTS | +2021.03.04 05:20:00 isXTSCurrentMax: true +2021.03.04 05:20:00 isXTSCurrentOverFarest: true +2021.03.04 05:20:00 isXTSCurrentOverMediest: true +2021.03.04 05:20:00 isXTSCurrentCrossedOverMediest: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XLH | +2021.03.04 05:20:00 isXLHLLSameInLength: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XRSI | +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XCHLH | +2021.03.04 05:20:00 isXCHLHMCOnTopOfLC: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 | XCHMA | +2021.03.04 05:20:00 isXCHMASCUnderMax: true +2021.03.04 05:20:00 isXCHMASCUnderMin: true +2021.03.04 05:20:00 isXCHMASCTrendsUp: true +2021.03.04 05:20:00 isXCHMASCFastOverSlow: true +2021.03.04 05:20:00 isXCHMAMCVale: true +2021.03.04 05:20:00 isXCHMAMCTrendsDown: true +2021.03.04 05:20:00 isXCHMAMCFastUnderSlow: true +2021.03.04 05:20:00 isXCHMALCVale: true +2021.03.04 05:20:00 isXCHMALCTrendsUp: true +2021.03.04 05:20:00 isXCHMALCFastUnderSlow: true +2021.03.04 05:20:00 +2021.03.04 05:20:00 +2021.03.04 05:20:00 market buy 0.4 EURUSD tp: 1.20764 (1.20563 / 1.20564 / 1.20563) +2021.03.04 05:20:00 deal #1558 buy 0.4 EURUSD at 1.20564 done (based on order #1558) +2021.03.04 05:20:00 deal performed [#1558 buy 0.4 EURUSD at 1.20564] +2021.03.04 05:20:00 order performed buy 0.4 at 1.20564 [#1558 buy 0.4 EURUSD at 1.20564] +2021.03.04 05:20:00 XEU5EA > T(1558)_TY(Long)_TP(1.20764)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XTAM + + +2021.05.17 07:40:00 XEU5EA > Short Signal Provided by: +2021.05.17 07:40:00 XOBDLH +2021.05.17 07:40:00 Pusher: 1 +2021.05.17 07:40:00 Market Conditions: +2021.05.17 07:40:00 | XOBD | +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XTM | +2021.05.17 07:40:00 isXTMBullish: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XAMA | +2021.05.17 07:40:00 isXAMABullish: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XTD | +2021.05.17 07:40:00 isXTDBullOverBear: true +2021.05.17 07:40:00 isXTDSignalOverBear: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XFI | +2021.05.17 07:40:00 isXFIOverZero: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XTS | +2021.05.17 07:40:00 isXTSCurrentMax: true +2021.05.17 07:40:00 isXTSCurrentOverFarest: true +2021.05.17 07:40:00 isXTSCurrentOverNearest: true +2021.05.17 07:40:00 isXTSCurrentOverMediest: true +2021.05.17 07:40:00 isXTSCurrentCrossedOverNearest: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XLH | +2021.05.17 07:40:00 isXLHHighAttachedHH: true +2021.05.17 07:40:00 isXLHLLSameInLength: true +2021.05.17 07:40:00 isXLHPriceOverSignal: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XRSI | +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XCHLH | +2021.05.17 07:40:00 isXCHLHSCMCHHSame: true +2021.05.17 07:40:00 isXCHLHMCOnTopOfLC: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 | XCHMA | +2021.05.17 07:40:00 isXCHMASCOverMax: true +2021.05.17 07:40:00 isXCHMASCOverMin: true +2021.05.17 07:40:00 isXCHMASCUnderMax: true +2021.05.17 07:40:00 isXCHMASCTrendsUp: true +2021.05.17 07:40:00 isXCHMASCFastOverSlow: true +2021.05.17 07:40:00 isXCHMAMCTrendsDown: true +2021.05.17 07:40:00 isXCHMAMCFastUnderSlow: true +2021.05.17 07:40:00 isXCHMALCPeak: true +2021.05.17 07:40:00 isXCHMALCTrendsDown: true +2021.05.17 07:40:00 isXCHMALCFastOverSlow: true +2021.05.17 07:40:00 +2021.05.17 07:40:00 +2021.05.17 07:40:00 market sell 0.16 EURUSD tp: 1.21210 (1.21410 / 1.21460 / 1.21410) +2021.05.17 07:40:00 deal #1701 sell 0.16 EURUSD at 1.21410 done (based on order #1701) +2021.05.17 07:40:00 deal performed [#1701 sell 0.16 EURUSD at 1.21410] +2021.05.17 07:40:00 order performed sell 0.16 at 1.21410 [#1701 sell 0.16 EURUSD at 1.21410] +2021.05.17 07:40:00 XEU5EA > T(1701)_TY(Short)_TP(1.2121)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XOBDLH + + +2021.05.17 22:05:00 XEU5EA > Short Signal Provided by: +2021.05.17 22:05:00 XTAM +2021.05.17 22:05:00 Pusher: 1 +2021.05.17 22:05:00 Market Conditions: +2021.05.17 22:05:00 | XOBD | +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XTM | +2021.05.17 22:05:00 isXTMVale: true +2021.05.17 22:05:00 isXTMBearish: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XAMA | +2021.05.17 22:05:00 isXAMABearish: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XTD | +2021.05.17 22:05:00 isXTDBullUnderBear: true +2021.05.17 22:05:00 isXTDSignalUnderBear: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XFI | +2021.05.17 22:05:00 isXFIUnderZero: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XTS | +2021.05.17 22:05:00 isXTSCurrentMin: true +2021.05.17 22:05:00 isXTSCurrentUnderFarest: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XLH | +2021.05.17 22:05:00 isXLHHHSameInLength: true +2021.05.17 22:05:00 isXLHPriceInSignalRange: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XRSI | +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XCHLH | +2021.05.17 22:05:00 isXCHLHMCOnTopOfLC: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 | XCHMA | +2021.05.17 22:05:00 isXCHMASCOverMin: true +2021.05.17 22:05:00 isXCHMASCUnderMax: true +2021.05.17 22:05:00 isXCHMASCCrossedUnderMax: true +2021.05.17 22:05:00 isXCHMASCVale: true +2021.05.17 22:05:00 isXCHMASCTrendsUp: true +2021.05.17 22:05:00 isXCHMASCFastUnderSlow: true +2021.05.17 22:05:00 isXCHMAMCTrendsDown: true +2021.05.17 22:05:00 isXCHMAMCFastOverSlow: true +2021.05.17 22:05:00 isXCHMALCPeak: true +2021.05.17 22:05:00 isXCHMALCTrendsDown: true +2021.05.17 22:05:00 isXCHMALCFastOverSlow: true +2021.05.17 22:05:00 +2021.05.17 22:05:00 +2021.05.17 22:05:00 market sell 0.16 EURUSD tp: 1.21306 (1.21506 / 1.21533 / 1.21506) +2021.05.17 22:05:00 deal #1706 sell 0.16 EURUSD at 1.21506 done (based on order #1706) +2021.05.17 22:05:00 deal performed [#1706 sell 0.16 EURUSD at 1.21506] +2021.05.17 22:05:00 order performed sell 0.16 at 1.21506 [#1706 sell 0.16 EURUSD at 1.21506] +2021.05.17 22:05:00 XEU5EA > T(1706)_TY(Short)_TP(1.21306)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XTAM + + +2021.08.16 23:10:00 XEU5EA > Long Signal Provided by: +2021.08.16 23:10:00 XTAM +2021.08.16 23:10:00 Pusher: 1 +2021.08.16 23:10:00 Market Conditions: +2021.08.16 23:10:00 | XOBD | +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XTM | +2021.08.16 23:10:00 isXTMBullish: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XAMA | +2021.08.16 23:10:00 isXAMABullish: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XTD | +2021.08.16 23:10:00 isXTDBullOverBear: true +2021.08.16 23:10:00 isXTDSignalCrossedOverBear: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XFI | +2021.08.16 23:10:00 isXFIOverZero: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XTS | +2021.08.16 23:10:00 isXTSCurrentMax: true +2021.08.16 23:10:00 isXTSCurrentOverFarest: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XLH | +2021.08.16 23:10:00 isXLHLLSameInLength: true +2021.08.16 23:10:00 isXLHPriceOverSignal: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XRSI | +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XCHLH | +2021.08.16 23:10:00 isXCHLHMCOnTopOfLC: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 | XCHMA | +2021.08.16 23:10:00 isXCHMASCOverMin: true +2021.08.16 23:10:00 isXCHMASCUnderMax: true +2021.08.16 23:10:00 isXCHMASCTrendsUp: true +2021.08.16 23:10:00 isXCHMASCFastOverSlow: true +2021.08.16 23:10:00 isXCHMAMCVale: true +2021.08.16 23:10:00 isXCHMAMCTrendsDown: true +2021.08.16 23:10:00 isXCHMAMCFastUnderSlow: true +2021.08.16 23:10:00 isXCHMALCPeak: true +2021.08.16 23:10:00 isXCHMALCTrendsDown: true +2021.08.16 23:10:00 isXCHMALCFastOverSlow: true +2021.08.16 23:10:00 +2021.08.16 23:10:00 +2021.08.16 23:10:00 market buy 0.42 EURUSD tp: 1.17985 (1.17780 / 1.17785 / 1.17780) +2021.08.16 23:10:00 deal #1924 buy 0.42 EURUSD at 1.17785 done (based on order #1924) +2021.08.16 23:10:00 deal performed [#1924 buy 0.42 EURUSD at 1.17785] +2021.08.16 23:10:00 order performed buy 0.42 at 1.17785 [#1924 buy 0.42 EURUSD at 1.17785] +2021.08.16 23:10:00 XEU5EA > T(1924)_TY(Long)_TP(1.17985)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XTAM + + +2023.06.08 02:05:00 XEU5EA > Short Signal Provided by: +2023.06.08 02:05:00 XCHMACC +2023.06.08 02:05:00 Pusher: 1 +2023.06.08 02:05:00 Market Conditions: +2023.06.08 02:05:00 | XOBD | +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XTM | +2023.06.08 02:05:00 isXTMNeutural: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XAMA | +2023.06.08 02:05:00 isXAMANeutural: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XTD | +2023.06.08 02:05:00 isXTDBullOverBear: true +2023.06.08 02:05:00 isXTDSignalUnderBear: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XFI | +2023.06.08 02:05:00 isXFIOverZero: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XTS | +2023.06.08 02:05:00 isXTSCurrentMax: true +2023.06.08 02:05:00 isXTSCurrentOverFarest: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XLH | +2023.06.08 02:05:00 isXLHHHSameInLength: true +2023.06.08 02:05:00 isXLHLLSameInLength: true +2023.06.08 02:05:00 isXLHPriceOverSignal: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XRSI | +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XCHLH | +2023.06.08 02:05:00 isXCHLHMCOnTopOfLC: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 | XCHMA | +2023.06.08 02:05:00 isXCHMASCUnderMax: true +2023.06.08 02:05:00 isXCHMASCUnderMin: true +2023.06.08 02:05:00 isXCHMASCTrendsUp: true +2023.06.08 02:05:00 isXCHMASCFastUnderSlow: true +2023.06.08 02:05:00 isXCHMAMCTrendsDown: true +2023.06.08 02:05:00 isXCHMAMCFastUnderSlow: true +2023.06.08 02:05:00 isXCHMALCTrendsDown: true +2023.06.08 02:05:00 isXCHMALCFastUnderSlow: true +2023.06.08 02:05:00 +2023.06.08 02:05:00 +2023.06.08 02:05:00 market sell 5.21 EURUSD tp: 1.06802 (1.07002 / 1.07003 / 1.07002) +2023.06.08 02:05:00 deal #3489 sell 5.21 EURUSD at 1.07002 done (based on order #3489) +2023.06.08 02:05:00 deal performed [#3489 sell 5.21 EURUSD at 1.07002] +2023.06.08 02:05:00 order performed sell 5.21 at 1.07002 [#3489 sell 5.21 EURUSD at 1.07002] +2023.06.08 02:05:00 XEU5EA > T(3489)_TY(Short)_TP(1.06802)_SL(0.0)_RFS(6.0)_RFR(0.6), Providers: XCHMACC diff --git a/XEU5/Classes/.gitkeep b/XEU5/Classes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Classes/x-saherelm.class.lib.mq5 b/XEU5/Classes/x-saherelm.class.lib.mq5 new file mode 100644 index 0000000..68f4847 --- /dev/null +++ b/XEU5/Classes/x-saherelm.class.lib.mq5 @@ -0,0 +1,10316 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XClass +// Description: provides all classes for use ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include +#include +#include +#include +#include +#include +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Constant Definitions ... +// + +static uchar _md5_PADDING[64] = + { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define _md5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define _md5_I(x, y, z) ((y) ^ ((x) | (~z))) +#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +#define _md5_FF(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define _md5_GG(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define _md5_HH(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define _md5_II(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +#define _md5_INIT_STATE_0 0x67452301 +#define _md5_INIT_STATE_1 0xefcdab89 +#define _md5_INIT_STATE_2 0x98badcfe +#define _md5_INIT_STATE_3 0x10325476 + +#define _md5_S11 7 +#define _md5_S12 12 +#define _md5_S13 17 +#define _md5_S14 22 + +#define _md5_S21 5 +#define _md5_S22 9 +#define _md5_S23 14 +#define _md5_S24 20 + +#define _md5_S31 4 +#define _md5_S32 11 +#define _md5_S33 16 +#define _md5_S34 23 + +#define _md5_S41 6 +#define _md5_S42 10 +#define _md5_S43 15 +#define _md5_S44 21 + +// +// END Constant Definitions ... +// + +// +// START Model Definitions ... +// + +// +string X_SIGNAL_TP = "TP"; +string X_SIGNAL_SL = "SL"; +string X_SIGNAL_TYPE = "TY"; +string X_SIGNAL_TICKET = "T"; +string X_SIGNAL_RISKFREE_STEP = "RFS"; +string X_SIGNAL_RISKFREE_RATE = "RFR"; + +// +// Model Signal Handler Result on XCTrade Class ... +struct XTraderHandlerResult +{ + // + // List Of Closed On SL Signals ... + XSignal sl[]; + + // + // List Of Closed On TP Signals ... + XSignal tp[]; + + // + // List Of Risk Free Signals ... + XSignal rf[]; +}; + +// +// Model OnTrade Event Handler Result on XCTrade Class ... +struct XOnTradeHandlerResult +{ + // + bool hasNewDeal; + int newDeals; + + // + bool hasNewOrder; + int newOrders; + + // + bool hasNewPosition; + int newPositions; + + // + bool hasNewHistoryOrder; + int newHistoryOrders; +}; + +// +// Model Guard Action Applied Signals ... +struct XGuardHandlerResult +{ + // + // Critical Guard ... + XSignal criticals[]; + + // + // Max Guard ... + XSignal maxes[]; + + // + // Old ... + XSignal olds[]; + + // + // Determines Stopout Action Cals or not ... + bool isStopOut; +}; + +// +// Define Volume States ... +struct XVolumeInfo +{ + // + // Current Available Static Volume ... + double staticVolume; + + // + // Static Volume Calculation Method ... + string staticVolumeCalculationMethod; + + // + // Current Maximum Appliable Volume ... + double maxAllowedVolume; + + // + // Static Volume Increase Multiplier ... + double volumeIncreaseMultiplier; + + // + // Multiply Volume Based On Balance Growing ... + double balanceGowingToApplyMultiplier; + + // + // Where to Increase MaxAllowed Volume ... + double balanceGrowingToIncreaseMaxAllowedVolume; +}; + +// +// Model a Simple Provider Status ... +struct XSignallerInfo +{ + // + // Provider Name ... + string name; + + // + // Number of Longs ... + int longs; + + // + // Number of Shorts ... + int shorts; +}; + +// +// Model Some of Usefull Signals and Market Data ... +struct XSummaryInfo +{ + // + // Define Max Signal Volume ... + double maxSignalVolume; + + // + // Max DrawDown ... + double maxDrawDown; + + // + // Max DrawUp ... + double maxDrawUp; + + // + // Max Number of Same Time Signals ... + int maxSameTimeSignals; + + // + // Number of Long Trades ... + int longSignals; + + // + // Number of Short Trades ... + int shortSignals; + + // + // Number of TPs Attached ... + int numberOfTPs; + + // + // Number of SLs Attached ... + int numberOfSLs; +}; + +// +// Model Account info ... +struct XAccountInfo +{ + // + // User Account ... + string user; + + // + // Name of Client ... + string name; + + // + // Trade Server Name ... + string server; + + // + // Broker Name ... + string broker; + + // + // Account Trade Mode ... + ENUM_ACCOUNT_TRADE_MODE mode; + + // + // Account Leverage ... + long leverage; + + // + // Currency ... + string currency; + + // + // Deposit ... + double deposit; + + // + // Balance ... + double balance; + + // + // Min Balance for Open Trades ... + double minBalanceForOpenTrades; +}; + +// +// this is a Model Which holds Reports for Specific Time Periods ... +struct XReport +{ + // + datetime start; + + // + datetime end; + + // + XAccountInfo accountInfo; + + // + XVolumeInfo volumeInfo; + + // + XSignallerInfo signallersInfo[]; + + // + XSummaryInfo summaryInfo; +}; + +// +// an Enumeration Object which determines Report Type ... +enum ENUM_XREPORT_TYPES +{ + // + // Main Report ... + XREPORT_MAIN, + // + // Daily Report ... + XREPORT_DAILY, + // + // Weekly Report ... + XREPORT_WEEKLY, + // + // Monthly Report ... + XREPORT_MONTHLY, +}; + +// +// a Signal Protection Structure ... +struct XProtectedSignal +{ + // + ulong ticket; + + // + datetime time[]; + + // + double profit[]; +}; + +// +// Represent Collector State Based on Time ... +struct XCollector +{ + // + // time in checking ... + datetime time; + + // + // Signal Volume ... + double volume; + + // + // Max DrawDown in Check Time ... + double maxDrawDown; + + // + // Max Allowed Volume in Check Time ... + double maxAllowedVolume; + + // + // Minimum required Balance for Opening Trades at Check Time ... + double minBalanceForOpenTrade; +}; + +// +// Cross Signals Methods ... +enum ENUM_X_CROSS_SIGNAL_METHOD +{ + // + // Do Nothing and Ignore them ... + X_CROSS_SIGNAL_DO_NOTHING, + // + // Accept all Cross Signals and Act Usually ... + X_CROSS_SIGNAL_REGULAR, + // + // Accept all Cross Signals and for Directional Act Usually and for Indirectional Ac Important ... + X_CROSS_SIGNAL_DIRECTION_REGULAR_INDIRECTION_IMPORTANT, + // + // Accept all Cross Signals and for Directional Act Important and for Indirectional Ac Usually ... + X_CROSS_SIGNAL_DIRECTION_IMPORTANT_INDIRECTION_REGULAR, + // + // Accept Only Indirectional Signals and Act Usually ... + X_CROSS_SIGNAL_INDIRECTION_REGULAR, + // + // Accept Only Directional Signals and Act Usually ... + X_CROSS_SIGNAL_DIRECTION_REGULAR, + // + // Accept Only Indirectional Signals and Act Important ... + X_CROSS_SIGNAL_INDIRECTION_IMPORTANT, + // + // Accept Only Directional Signals and Act Important ... + X_CROSS_SIGNAL_DIRECTION_IMPORTANT, +}; + +// +// the Action which Guard Handler Can Done when Attacked ... +enum ENUM_X_GUARD_ACTIONS +{ + // + // Do Nothing ... + X_GUARD_DO_NOTHING, + // + // Close All Open Positions ... + X_GUARD_CLOSE_ALL, + // + // Close Max In Drawdown Position ... + X_GUARD_CLOSE_MAX_IN_DD, + // + // Partial Close Max In Drawdown Position by 1% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1, + // + // Partial Close Max In Drawdown Position by 2% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2, + // + // Partial Close Max In Drawdown Position by 3% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3, + // + // Partial Close Max In Drawdown Position by 5% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5, + // + // Partial Close Max In Drawdown Position by 10% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10, + // + // Partial Close Max In Drawdown Position by 15% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15, + // + // Partial Close Max In Drawdown Position by 20% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20, + // + // Partial Close Max In Drawdown Position by 25% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25, + // + // Partial Close Max In Drawdown Position by 30% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30, + // + // Partial Close Max In Drawdown Position by 40% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40, + // + // Partial Close Max In Drawdown Position by 50% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50, + // + // Partial Close Max In Drawdown Position by 60% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60, + // + // Partial Close Max In Drawdown Position by 70% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70, + // + // Partial Close Max In Drawdown Position by 75% of Volume ... + X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75, +}; + +// +// Guard Reason ... +enum ENUM_X_GUARD_REASONS +{ + // + // Critical ... + X_GUARDED_CRITICAL, + // + // Max ... + X_GUARDED_MAX, + // + // Old ... + X_GUARDED_OLD +}; + +// +// All Suuported Support Positions Guard ... +enum ENUM_X_GUARD_SUPPORT_METHODS +{ + // + // Ignore Supporting ... + X_SUPPORT_DO_NOTHING, + // + // Full Both Side Support ... + X_SUPPORT_FULL, + // + // Indirectional Supports On Drawing Down ... + X_SUPPORT_IN_DRAWDOWN_INDIRECTIONAL, + // + // Directional Supports On Drawing Up ... + X_SUPPORT_IN_DRAWUP_DIRECTIONAL, +}; + +// +// END Model Definitions ... +// + +// +// START Overrides ... +// + +// +// XBase Class ... +class XCBase +{ + // + // Public ... +public: + // + // Protected ... +protected: + // + void AddItemToBuffer( + double item, // Specified Item + double &buffer[] // Specified Buffer + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; + } + void AddItemToBuffer( + datetime item, // Specified Item + datetime &buffer[] // Specified Buffer + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; + } + void AddItemToBuffer( + XSignal &item, + XSignal &buffer[]) + { + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; + } + void AddItemToBuffer( + XCollector &item, // Specified Item + XCollector &buffer[] // Specified Buffer + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; + } + void AddItemToBuffer( + XSignallerInfo &item, + XSignallerInfo &buffer[]) + { + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; + } + void AddItemToBuffer( + XProtectedSignal &item, // Item ... + XProtectedSignal &buffer[] // Buffer ... + ) + { + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + buffer[bufferSize] = item; + } + + // + void CleanBuffer(double &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XDeal &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XOrder &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XSignal &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XCollector &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XSignallerInfo &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + void CleanBuffer(XProtectedSignal &buffer[]) + { + // + ArrayFree(buffer); + ArrayResize(buffer, 0); + } + + // + void CopyBuffer( + const XSignallerInfo &source[], // Source Buffer ... + XSignallerInfo &dest[] // Dest Buffer ... + ) + { + // + CleanBuffer(dest); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < sourceCount; i++) + { + // + XSignallerInfo iInfo = source[i]; + + // + AddItemToBuffer( + iInfo, + dest); + } + } + void CopyBuffer( + XProtectedSignal &source[], // Source Buffer to Copy + XProtectedSignal &dest[] // Fill this buffer using source + ) + { + // + CleanBuffer(dest); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + XProtectedSignal iItem = source[i]; + + // + AddItemToBuffer( + iItem, + dest); + } + } + + // + // Private ... +private: +}; + +// +// XCTrade Base Class ... +class XSCTrade : public CTrade +{ +public: + // + // Modify Specific Position, by Specific Comment ... + bool PositionModify( + const string symbol, // Symbol + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!SelectPosition(symbol)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + bool PositionModify( + const ulong ticket, // Position Ticket + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.position = ticket; + m_request.symbol = PositionGetString(POSITION_SYMBOL); + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + + // + // Close Specific Position, by Specific Comment ... + bool PositionClose( + const string symbol, // Symbol + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + bool partial_close = false; + int retry_count = 10; + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + do + { + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specify Comment ... + m_request.comment = comment; + + // + // check volume + double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + if (m_request.volume > max_volume) + { + // + m_request.volume = max_volume; + partial_close = true; + } + else + { + partial_close = false; + } + + // + // hedging? just send order + if (IsHedging()) + { + return (OrderSend(m_request, m_result)); + } + + // + // order send + if (!OrderSend(m_request, m_result)) + { + // + if (--retry_count != 0) + { + continue; + } + + // + if (retcode == TRADE_RETCODE_DONE_PARTIAL) + { + m_result.retcode = retcode; + } + + // + return (false); + } + + // + //--- WARNING. If position volume exceeds the maximum volume allowed for deal, + //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, + //--- but partially. It is decreased by the maximum volume allowed for deal. + if (m_async_mode) + { + break; + } + + // + retcode = TRADE_RETCODE_DONE_PARTIAL; + if (partial_close) + { + Sleep(1000); + } + } while (partial_close); + + // + // succeed + return (true); + } + bool PositionClose( + const ulong ticket, // Position Ticket + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specify Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } + + // + // Partial Close Specific Position, by Specific Comment ... + bool PositionClosePartial( + const string symbol, // Symbol + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // hedging? just send order + return (OrderSend(m_request, m_result)); + } + bool PositionClosePartial( + const ulong ticket, // Position Ticket + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } +}; +// +// END Overrides ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// XCMD5 a library for Hashing ... +class XCMD5 : public XCBase +{ + // + // Public Provides ... +public: + // + // Protected Provides ... + + // + // Constructor ... + XCMD5(void) {} + + // + // Deconstructor ... + ~XCMD5(void) {} + + // + // Hash Specified Char Array ... + string Hash( + uchar &source[], // Specify Char Array to Hash + int length = 0 // Specify Length of Char Array which required to hash + ) + { + // + string result = ""; + + // + int sourceCount = ArraySize(source); + + // + // Validate Args ... + if ( + sourceCount <= 0 || + (sourceCount > 0 && length > sourceCount)) + { + return result; + } + + // + // Normalize Args ... + if (length == 0) + { + length = sourceCount; + } + + // + // Init MD5 ... + MD5Init(); + + // + // Update Buffer ... + MD5Update(source, length); + + // + // Calculate Result ... + result = MD5Final(); + + // + return result; + } + + // + // Hash Specified String ... + string Hash( + string source // Specified String + ) + { + // + string result = ""; + + // + // Converts String to Char Array ... + uchar bytes[]; + StringToCharArray( + source, + bytes, + 0, + StringLen(source)); + + // + result = Hash( + bytes, + ArraySize(bytes)); + + // + return result; + } + +protected: + // + // Private Provides ... +private: + // + uint m_lMD5[4]; + uint m_nCount[2]; + uchar m_lpszBuffer[64]; + + // + // Convert Byte to DWord ... + void ByteToDWord(int &out[], uint &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24; + } + } + + // + // Convert DWord to Byte ... + void DWordToByte(uchar &out[], int &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + // + out[j] = (uchar)(in[i] & 0xff); + out[j + 1] = (uchar)((in[i] >> 8) & 0xff); + out[j + 2] = (uchar)((in[i] >> 16) & 0xff); + out[j + 3] = (uchar)((in[i] >> 24) & 0xff); + } + } + + // + // Init MD5 Array ... + void MD5Init() + { + // + ArrayInitialize(m_lpszBuffer, 64); + + // + m_nCount[0] = m_nCount[1] = 0; + m_lMD5[0] = _md5_INIT_STATE_0; + m_lMD5[1] = _md5_INIT_STATE_1; + m_lMD5[2] = _md5_INIT_STATE_2; + m_lMD5[3] = _md5_INIT_STATE_3; + } + + // + // Update MD5 ... + void MD5Update(uchar &inBuf[], uint inLen) + { + // + int i, ii; + int mdi; + + // + uint in[16]; + int i0 = 0; + + // + mdi = (int)((m_nCount[0] >> 3) & 0x3F); + + // + if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0]) + { + m_nCount[1]++; + } + + // + m_nCount[0] += ((uint)inLen << 3); + m_nCount[1] += ((uint)inLen >> 29); + + // + while ((inLen--) > 0) + { + // + m_lpszBuffer[mdi++] = inBuf[i0++]; + if (mdi == 0x40) + { + // + for (i = 0, ii = 0; i < 16; i++, ii += 4) + { + in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]); + } + + // + Transform(m_lMD5, in); + + // + mdi = 0; + } + } + } + + // + // Finalize an MD5 Expression ... + string MD5Final() + { + // + uchar bits[8]; + int nIndex; + uint nPadLen; + const int nMD5Size = 16; + uchar lpszMD5[16]; + string temp; + string out = ""; + int i; + + // + DWordToByte(bits, m_nCount, 8); + nIndex = (int)((m_nCount[0] >> 3) & 0x3f); + nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); + MD5Update(_md5_PADDING, nPadLen); + MD5Update(bits, 8); + DWordToByte(lpszMD5, m_lMD5, nMD5Size); + + // + for (i = 0; i < nMD5Size; i++) + { + // + if (lpszMD5[i] == 0) + { + temp = "00"; + } + else if (lpszMD5[i] <= 15) + { + temp = StringFormat("0%x", lpszMD5[i]); + } + else + { + temp = StringFormat("%x", lpszMD5[i]); + } + + // + out += temp; + } + + // + lpszMD5[0] = '\0'; + + // + return (out); + } + + // + // Transform Buffers ... + void Transform(uint &buf[], uint &in[]) + { + // + uint a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + // + _md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478); + _md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756); + _md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB); + _md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE); + _md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF); + _md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A); + _md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613); + _md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501); + _md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8); + _md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF); + _md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1); + _md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE); + _md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122); + _md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193); + _md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E); + _md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821); + + // + _md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562); + _md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340); + _md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51); + _md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA); + _md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D); + _md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453); + _md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681); + _md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8); + _md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6); + _md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6); + _md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87); + _md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED); + _md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905); + _md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8); + _md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9); + _md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A); + + // + _md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942); + _md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681); + _md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122); + _md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C); + _md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44); + _md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9); + _md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60); + _md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70); + _md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6); + _md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA); + _md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085); + _md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05); + _md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039); + _md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5); + _md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8); + _md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665); + + // + _md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244); + _md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97); + _md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7); + _md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039); + _md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3); + _md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92); + _md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D); + _md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1); + _md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F); + _md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0); + _md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314); + _md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1); + _md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82); + _md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235); + _md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB); + _md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391); + + // + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; + } +}; + +// +// XSaherElm Account Info Class ... +class XCAccountInfo : public XCBase +{ + // + // Public properties ... +public: + // + // Constructro ... + void XCAccountInfo() + { + // + mAccountInfo = new CAccountInfo(); + + // + mInitialBalance = mAccountInfo.Balance(); + } + + // + // Deconstructor ... + void ~XCAccountInfo() + { + // + mInitialBalance = 0; + } + + // + // User Account ... + long GetUserAccount() + { + return mAccountInfo.Login(); + } + + // + // Account Leverage ... + long GetLeverage() + { + return mAccountInfo.Leverage(); + } + + // + // Get Trade Expert State ... + bool CanExpertTrade() + { + return mAccountInfo.TradeExpert(); + } + + // + // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... + // -------------------------- + // ACCOUNT_TRADE_MODE_DEMO + // ACCOUNT_TRADE_MODE_CONTEST + // ACCOUNT_TRADE_MODE_REAL + ENUM_ACCOUNT_TRADE_MODE GetTradeMode() + { + return mAccountInfo.TradeMode(); + } + + // + // Get Account Balance ... + double GetBalance() + { + return mAccountInfo.Balance(); + } + + // + // Get Initial Deposit Balance ... + double GetInitialBalance() + { + return mInitialBalance; + } + + // + // Get the amount of give Credit ... + double GetCredit() + { + return mAccountInfo.Credit(); + } + + // + // Get the amount of current Profit on account ... + double GetProfit() + { + return mAccountInfo.Profit(); + } + + // + // Get the amount of current Equity on account ... + double GetEquity() + { + return mAccountInfo.Equity(); + } + + // + // Get the amount of reserved Margin ... + double GetMargin() + { + return mAccountInfo.Margin(); + } + + // + // Get the amount of free Margin ... + double GetFreeMargin() + { + return mAccountInfo.FreeMargin(); + } + + // + // Get the Level of Margin ... + double GetMarginLevel() + { + return mAccountInfo.MarginLevel(); + } + + // + // Get the Level Of Margin for a Deposit ... + double GetMarginCall() + { + return mAccountInfo.MarginCall(); + } + + // + // Get the Level of Margin for Stop out ... + double GetMarginStopOut() + { + return mAccountInfo.MarginStopOut(); + } + + // + // Get the Client Name ... + string GetName() + { + return mAccountInfo.Name(); + } + + // + // Get the Trade Server Name ... + string GetServerName() + { + return mAccountInfo.Server(); + } + + // + // Get deposit Currency Name ... + string GetCurrency() + { + return mAccountInfo.Currency(); + } + + // + // Get the Company Name that serves an Account ... + string GetCompany() + { + return mAccountInfo.Company(); + } + + // + // Calculate Profits for the current account based on passed parameters ... + double CalculateTradeProfit( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry, // open price + double exit // close price + ) + { + // + double result = mAccountInfo.OrderProfitCheck( + symbol, + type, + volume, + entry, + exit); + + // + return result; + } + + // + // Calculate amount of margin which required for trade operation ... + double CalculateMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.MarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate amount of free margin left after trade operation ... + double CalculateFreeMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.FreeMarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate the Maximum possible volume of trade operation ... + double CalculateMaxVolume( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double entry, // open price + double percent = 100 // percent of available margin + ) + { + // + double result = mAccountInfo.MaxLotCheck( + symbol, + type, + entry, + percent); + + // + return result; + } + + // + // Protected properties ... +protected: + // + // Private properties ... +private: + // + // Initial Account Balance ... + double mInitialBalance; + + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// XSaherElm Report Info Class ... +class XCReporter : public XCBase +{ + // + // Public Provided ... +public: + // + // Constructro ... + void XCReporter() + { + // + mAccountInfo = new XCAccountInfo(); + + // + Reset(); + } + + // + // Deconstructor ... + void ~XCReporter() + { + } + + // + // Reset Specific Report ... + void Reset( + ENUM_XREPORT_TYPES type // Specify Report Type + ) + { + CleanReport(type); + } + + // + // Reset All Reports ... + void Reset() + { + // + CleanReport(XREPORT_MAIN); + CleanReport(XREPORT_MONTHLY); + CleanReport(XREPORT_WEEKLY); + CleanReport(XREPORT_DAILY); + } + + // + // Update Volume Info ... + void UpdateReportVolumeInfo( + ENUM_XREPORT_TYPES type, // Specified Report Type + // + double staticVolume, // Current Available Static Volume + string staticVolumeCalculationMethod, // Static Volume Calculation Method + double maxAllowedVolume, // Current Maximum Appliable Volume + double volumeIncreaseMultiplier, // Static Volume Increase Multiplier + double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing + double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume + ) + { + // + // Filling Account Info ... + FillReportAccountInfo(type); + + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + // + FillingVolumeInfo( + mMainReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + // + FillingVolumeInfo( + mMonthlyReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + // + FillingVolumeInfo( + mWeeklyReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + + // + // Daily ... + case XREPORT_DAILY: + // + FillingVolumeInfo( + mDailyReport, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + break; + } + } + + // + // Update Volume Info on All Reports ... + void UpdateReportsVolumeInfo( + double staticVolume, // Current Available Static Volume + string staticVolumeCalculationMethod, // Static Volume Calculation Method + double maxAllowedVolume, // Current Maximum Appliable Volume + double volumeIncreaseMultiplier, // Static Volume Increase Multiplier + double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing + double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume + ) + { + // + // Main ... + UpdateReportVolumeInfo( + XREPORT_MAIN, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Monthly ... + UpdateReportVolumeInfo( + XREPORT_MONTHLY, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Weekly ... + UpdateReportVolumeInfo( + XREPORT_WEEKLY, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Daily ... + UpdateReportVolumeInfo( + XREPORT_DAILY, + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + } + + // + // Add Specific Signal to Report ... + void AddSignalToReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + const XSignal &signal, // Specified Signal + const string &providers[] // Specified Signal Providers + ) + { + // + // + // Filling Account Info ... + FillReportAccountInfo(type); + + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + AddSignalToReport( + mMainReport, + signal, + providers); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + AddSignalToReport( + mMonthlyReport, + signal, + providers); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + AddSignalToReport( + mWeeklyReport, + signal, + providers); + break; + + // + // Daily ... + case XREPORT_DAILY: + AddSignalToReport( + mDailyReport, + signal, + providers); + break; + } + } + + // + // Add Specific Signal to All Reports ... + void AddSignalToReports( + const XSignal &signal, // Specified Signal + const string &providers[] // Specified Signal Providers + ) + { + // + // Main ... + AddSignalToReport( + XREPORT_MAIN, + signal, + providers); + + // + // Monthly ... + AddSignalToReport( + XREPORT_MONTHLY, + signal, + providers); + + // + // Weekly ... + AddSignalToReport( + XREPORT_WEEKLY, + signal, + providers); + + // + // Daily ... + AddSignalToReport( + XREPORT_DAILY, + signal, + providers); + } + + // + // Report a TP for Specific Report ... + void AddTradeTPInReport( + ENUM_XREPORT_TYPES type // Specified Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + AddTradeTPInReport(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + AddTradeTPInReport(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + AddTradeTPInReport(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + AddTradeTPInReport(mDailyReport); + break; + } + } + + // + // Report a TP for All Reports ... + void AddTradeTPInReports() + { + // + // Main ... + AddTradeTPInReport(XREPORT_MAIN); + + // + // Monthly ... + AddTradeTPInReport(XREPORT_MONTHLY); + + // + // Weekly ... + AddTradeTPInReport(XREPORT_WEEKLY); + + // + // Daily ... + AddTradeTPInReport(XREPORT_DAILY); + } + + // + // Report a SL for Specific Report ... + void AddTradeSLInReport( + ENUM_XREPORT_TYPES type // Specified Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + AddTradeSLInReport(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + AddTradeSLInReport(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + AddTradeSLInReport(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + AddTradeSLInReport(mDailyReport); + break; + } + } + + // + // Report a SL for All Reports ... + void AddTradeSLInReports() + { + // + // Main ... + AddTradeSLInReport(XREPORT_MAIN); + + // + // Monthly ... + AddTradeSLInReport(XREPORT_MONTHLY); + + // + // Weekly ... + AddTradeSLInReport(XREPORT_WEEKLY); + + // + // Daily ... + AddTradeSLInReport(XREPORT_DAILY); + } + + // + // Update Number of Same Time Trades in Specific Report ... + void UpdateMaxSameTimeTradesInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + int value // number of same time trades + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMaxSameTimeTradesInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMaxSameTimeTradesInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMaxSameTimeTradesInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMaxSameTimeTradesInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Number of Same Time Trades in All Report ... + void UpdateMaxSameTimeTradesInReports( + int value // number of same time trades + ) + { + // + // Main ... + UpdateMaxSameTimeTradesInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMaxSameTimeTradesInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMaxSameTimeTradesInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMaxSameTimeTradesInReport( + XREPORT_DAILY, + value); + } + + // + // Update Max DrawDown in Specific Report ... + void UpdateMaxDrawDownInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + double value // draw down value + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMaxDrawDownInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMaxDrawDownInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMaxDrawDownInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMaxDrawDownInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Max DrawDown in All Report ... + void UpdateMaxDrawDownInReports( + double value // draw down value + ) + { + // + // Main ... + UpdateMaxDrawDownInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMaxDrawDownInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMaxDrawDownInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMaxDrawDownInReport( + XREPORT_DAILY, + value); + } + + // + // Update Max DrawUp in Specific Report ... + void UpdateMaxDrawUpInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + double value // draw up value + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMaxDrawUpInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMaxDrawUpInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMaxDrawUpInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMaxDrawUpInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Max DrawUp in All Report ... + void UpdateMaxDrawUpInReports( + double value // draw up value + ) + { + // + // Main ... + UpdateMaxDrawUpInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMaxDrawUpInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMaxDrawUpInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMaxDrawUpInReport( + XREPORT_DAILY, + value); + } + + // + // Update Min Balance for Open Trades in Specific Report ... + void UpdateMinBalanceForOpenTradesInReport( + ENUM_XREPORT_TYPES type, // Specified Report Type + double value // min balance for open trades + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + UpdateMinBalanceForOpenTradesInReport( + mMainReport, + value); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + UpdateMinBalanceForOpenTradesInReport( + mMonthlyReport, + value); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + UpdateMinBalanceForOpenTradesInReport( + mWeeklyReport, + value); + break; + + // + // Daily ... + case XREPORT_DAILY: + UpdateMinBalanceForOpenTradesInReport( + mDailyReport, + value); + break; + } + } + + // + // Update Min Balance for Open Trades in All Report ... + void UpdateMinBalanceForOpenTradesInReports( + double value // min balance for open trades + ) + { + // + // Main ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_MAIN, + value); + + // + // Monthly ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_MONTHLY, + value); + + // + // Weekly ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_WEEKLY, + value); + + // + // Daily ... + UpdateMinBalanceForOpenTradesInReport( + XREPORT_DAILY, + value); + } + + // + // Gnerate Specific Type Of Report String Representation ... + string GenerateReportString( + ENUM_XREPORT_TYPES type, // Specified Report Type + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + result = GenerateReportString( + mMainReport, + separator); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + result = GenerateReportString( + mMonthlyReport, + separator); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + result = GenerateReportString( + mWeeklyReport, + separator); + break; + + // + // Daily ... + case XREPORT_DAILY: + result = GenerateReportString( + mDailyReport, + separator); + break; + } + + // + return result; + } + + // + // Protected Provided ... +protected: + // + // Private Provided ... +private: + // + // Account Info Instance ... + XCAccountInfo mAccountInfo; + + // + // Main Report ... + XReport mMainReport; + + // + // Monthly Report ... + XReport mMonthlyReport; + + // + // Weekly Report ... + XReport mWeeklyReport; + + // + // Daily Report ... + XReport mDailyReport; + + // + // Clean Specific Report ... + void CleanReport( + XReport &report // Specified Report + ) + { + // + datetime time = TimeCurrent(); + + // + // Reset Times ... + report.start = time; + report.end = -1; + + // + // Reset Account Info ... + FillReportAccountInfo(report); + + // + // Reset Summary Info ... + report.summaryInfo.maxDrawUp = 0; + report.summaryInfo.maxDrawDown = 0; + report.summaryInfo.longSignals = 0; + report.summaryInfo.numberOfTPs = 0; + report.summaryInfo.numberOfSLs = 0; + report.summaryInfo.shortSignals = 0; + report.summaryInfo.maxSignalVolume = 0; + report.summaryInfo.maxSameTimeSignals = 0; + + // + // Reset Volume Info ... + report.volumeInfo.staticVolume = 0; + report.volumeInfo.maxAllowedVolume = 0; + report.volumeInfo.volumeIncreaseMultiplier = 0; + report.volumeInfo.balanceGowingToApplyMultiplier = 0; + report.volumeInfo.staticVolumeCalculationMethod = NULL; + report.volumeInfo.balanceGrowingToIncreaseMaxAllowedVolume = 0; + + // + // Reset Signallers Info ... + CleanBuffer(report.signallersInfo); + } + void CleanReport( + ENUM_XREPORT_TYPES type // Specify Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + CleanReport(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + CleanReport(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + CleanReport(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + CleanReport(mDailyReport); + break; + } + } + + // + // Update Specific Reports End Time ... + void FillReportEndTime( + XReport &report // Specified Report + ) + { + // + datetime time = TimeCurrent(); + report.end = time; + } + + // + // Filleing Report Account Info ... + void FillReportAccountInfo( + XReport &report // Specified Report + ) + { + // + FillReportEndTime(report); + + // + report.accountInfo.user = (string)mAccountInfo.GetUserAccount(); + report.accountInfo.name = mAccountInfo.GetName(); + report.accountInfo.server = mAccountInfo.GetServerName(); + report.accountInfo.broker = mAccountInfo.GetCompany(); + report.accountInfo.mode = mAccountInfo.GetTradeMode(); + report.accountInfo.leverage = mAccountInfo.GetLeverage(); + report.accountInfo.currency = mAccountInfo.GetCurrency(); + report.accountInfo.deposit = mAccountInfo.GetInitialBalance(); + report.accountInfo.balance = mAccountInfo.GetBalance(); + } + void FillReportAccountInfo( + ENUM_XREPORT_TYPES type // Specify Report Type + ) + { + // + switch (type) + { + // + // Main ... + case XREPORT_MAIN: + FillReportAccountInfo(mMainReport); + break; + + // + // Monthly ... + case XREPORT_MONTHLY: + FillReportAccountInfo(mMonthlyReport); + break; + + // + // Weekly ... + case XREPORT_WEEKLY: + FillReportAccountInfo(mWeeklyReport); + break; + + // + // Daily ... + case XREPORT_DAILY: + FillReportAccountInfo(mDailyReport); + break; + } + } + + // + // Filling Volume Info ... + void FillingVolumeInfo( + XReport &report, // Specified Report + // + double staticVolume, // Current Available Static Volume + string staticVolumeCalculationMethod, // Static Volume Calculation Method + double maxAllowedVolume, // Current Maximum Appliable Volume + double volumeIncreaseMultiplier, // Static Volume Increase Multiplier + double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing + double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume + ) + { + // + FillReportEndTime(report); + + // + report.volumeInfo.staticVolume = staticVolume; + report.volumeInfo.maxAllowedVolume = maxAllowedVolume; + report.volumeInfo.volumeIncreaseMultiplier = volumeIncreaseMultiplier; + report.volumeInfo.staticVolumeCalculationMethod = staticVolumeCalculationMethod; + report.volumeInfo.balanceGowingToApplyMultiplier = balanceGowingToApplyMultiplier; + report.volumeInfo.balanceGrowingToIncreaseMaxAllowedVolume = balanceGrowingToIncreaseMaxAllowedVolume; + } + + // + // Add Signal to Report ... + void AddSignalToReport( + XReport &report, // Specified Report + const XSignal &signal, // Specified Signal + const string &providers[] // Specified Signal Providers + ) + { + // + FillReportEndTime(report); + + // + double volume = signal.volume; + bool isLong = signal.type == X_SIGNAL_LONG; + + // + // Update Longs and Shorts ... + if (isLong) + { + report.summaryInfo.longSignals++; + } + else + { + report.summaryInfo.shortSignals++; + } + + // + // Chack Max Volume ... + if (volume > report.summaryInfo.maxSignalVolume) + { + report.summaryInfo.maxSignalVolume = volume; + } + + // + // Update Signallers Info ... + for (int i = 0; i < ArraySize(providers); i++) + { + // + string iProvider = providers[i]; + + // + AddOrUpdateSignaller( + report, + iProvider, + signal); + } + } + + // + // Add or Update Signaller Info of Specific Report ... + void AddOrUpdateSignaller( + XReport &report, // Specified Report + const string provider, // Signal Provider name + const XSignal &signal // Specified Signal + ) + { + // + int providerIdx = -1; + int signallersInfoCount = 0; + bool isLong = signal.type == X_SIGNAL_LONG; + + // + // Prepare New One Provider ... + XSignallerInfo info = {}; + info.name = provider; + if (isLong) + { + info.longs = 1; + } + else + { + info.shorts = 1; + } + + // + // Find Provider idx if Exists ... + providerIdx = FindProviderInSignallersInfo( + provider, + report.signallersInfo); + + // + // Check IDX ... + if (providerIdx > -1) + { + // + // Update Exists ... + if (isLong) + { + report.signallersInfo[providerIdx].longs++; + } + else + { + report.signallersInfo[providerIdx].shorts++; + } + } + else + { + // + // Add New One ... + AddItemToBuffer( + info, + report.signallersInfo); + } + } + + // + // Add TP in Report ... + void AddTradeTPInReport( + XReport &report // Specified Report + ) + { + // + FillReportEndTime(report); + + // + report.summaryInfo.numberOfTPs++; + } + + // + // Add SL in Report ... + void AddTradeSLInReport( + XReport &report // Specified Report + ) + { + // + FillReportEndTime(report); + + // + report.summaryInfo.numberOfSLs++; + } + + // + // Update Number of Same Time Trades in Report ... + void UpdateMaxSameTimeTradesInReport( + XReport &report, // Specified Report + int value // number of same time trades + ) + { + // + // Validate Args ... + if (value <= report.summaryInfo.maxSameTimeSignals) + { + return; + } + + // + FillReportEndTime(report); + + // + report.summaryInfo.maxSameTimeSignals = value; + } + + // + // Update Number of Same Time Trades in Report ... + void UpdateMaxDrawUpInReport( + XReport &report, // Specified Report + double value // draw up value + ) + { + // + // Validate Args ... + if (value <= report.summaryInfo.maxDrawUp) + { + return; + } + + // + FillReportEndTime(report); + + // + report.summaryInfo.maxDrawUp = value; + } + + // + // Update Number of Same Time Trades in Report ... + void UpdateMaxDrawDownInReport( + XReport &report, // Specified Report + double value // draw down value + ) + { + // + // Validate Args ... + if (value <= report.summaryInfo.maxDrawDown) + { + return; + } + + // + FillReportEndTime(report); + + // + report.summaryInfo.maxDrawDown = value; + } + + // + // Update Min Balance for Open Trades Value in Report ... + void UpdateMinBalanceForOpenTradesInReport( + XReport &report, // Specified Report + double value // min balance for open trades + ) + { + // + // Validate Arg ... + if (value <= 0) + { + return; + } + + // + FillReportEndTime(report); + + // + report.accountInfo.minBalanceForOpenTrades = value; + } + + // + // Generate Specific Report String Representation ... + string GenerateReportString( + XReport &report, // Specified Report + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Start and End Date ... + result += "Start: " + (string)report.start + separator; + result += "End: " + (string)report.end + separator; + + // + // Account Info ... + string accountStr = GenerateAccountInfoReportString(report.accountInfo); + result += "Account: " + separator + accountStr + separator; + + // + // Summary Info ... + string summaryStr = GenerateSummaryInfoReportString(report.summaryInfo); + result += "Summary: " + separator + summaryStr + separator; + + // + // Volume Info ... + string volumeStr = GenerateVolumeInfoReportString(report.volumeInfo); + result += "Volume: " + separator + volumeStr + separator; + + // + // Signallers Info ... + string signallersStr = GenerateSignallersInfoReportString(report.signallersInfo); + result += "Signallers: " + separator + signallersStr + separator; + + // + return result; + } + + // + // Generate Account info String Representation ... + string GenerateAccountInfoReportString( + XAccountInfo &info, // Specified Account Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Generate Report ... + result += "user: " + info.user + separator; + result += "name: " + info.name + separator; + result += "server: " + info.server + separator; + result += "broker: " + info.broker + separator; + result += "mode: " + EnumToString(info.mode) + separator; + result += "leverage: " + (string)info.leverage + separator; + result += "currency: " + info.currency + separator; + result += "deposit: " + (string)info.deposit + separator; + result += "balance: " + (string)info.balance + separator; + result += "minBalanceForTrading: " + (string)info.minBalanceForOpenTrades + separator; + + // + return result; + } + + // + // Generate Summary info String Representation ... + string GenerateSummaryInfoReportString( + XSummaryInfo &info, // Specified Summary Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Generate Report ... + result += "longSignals: " + (string)info.longSignals + separator; + result += "shortSignals: " + (string)info.shortSignals + separator; + result += "numberOfTps: " + (string)info.numberOfTPs + separator; + result += "numberOfSLs: " + (string)info.numberOfSLs + separator; + result += "maxDrawUp: " + (string)info.maxDrawUp + separator; + result += "maxDrawDown: " + (string)info.maxDrawDown + separator; + result += "maxSignalVolume: " + (string)info.maxSignalVolume + separator; + result += "maxSameTimeSignals: " + (string)info.maxSameTimeSignals + separator; + + // + return result; + } + + // + // Generate Volume info String Representation ... + string GenerateVolumeInfoReportString( + XVolumeInfo &info, // Specified Volume Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Generate Report ... + result += "staticVolume: " + (string)info.staticVolume + separator; + result += "staticVolumeCalculationMethod: " + info.staticVolumeCalculationMethod + separator; + result += "maxAllowedVolume: " + (string)info.maxAllowedVolume + separator; + result += "volumeIncreaseMultiplier: " + (string)info.volumeIncreaseMultiplier + separator; + result += "balanceGowingToApplyMultiplier: " + (string)info.balanceGowingToApplyMultiplier + separator; + result += "balanceGrowingToIncreaseMaxAllowedVolume: " + (string)info.balanceGrowingToIncreaseMaxAllowedVolume + separator; + + // + return result; + } + + // + // Generate Signallers info String Representation ... + string GenerateSignallersInfoReportString( + XSignallerInfo &infos[], // Specified Signallers Info + string separator = "\n" // Separator + ) + { + // + string result = ""; + + // + // Validate Signallers Array Size ... + int signallersCount = ArraySize(infos); + if (signallersCount <= 0) + { + // + result += "EMPTY" + separator; + return result; + } + + // + // Generate Report ... + for (int i = 0; i < signallersCount; i++) + { + // + XSignallerInfo iSignaller = infos[i]; + + // + result += "name: " + iSignaller.name + separator; + result += "longs: " + (string)iSignaller.longs + separator; + result += "shorts: " + (string)iSignaller.shorts + separator; + + // + if (i < signallersCount - 1) + { + result += separator; + } + } + // + return result; + } + + // + // Find a Provider Index in SignallersInfo ... + int FindProviderInSignallersInfo( + string provider, // Specified Provider Name ... + XSignallerInfo &infoBuffer[] // Specified XSignallerInfo Buffer ... + ) + { + // + int result = -1; + + // + int bufferSize = ArraySize(infoBuffer); + if (bufferSize <= 0) + { + return result; + } + + // + // Loop through buffer to find provider index ... + for (int i = 0; i < bufferSize; i++) + { + // + XSignallerInfo iInfo = infoBuffer[i]; + + // + if (iInfo.name != provider) + { + continue; + } + + // + result = i; + } + + // + return result; + } +}; + +// +// a Class For Collectiong Info ... +class XCCollector : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCCollector() + { + Reset(); + } + + // + // Deconstructor ... + ~XCCollector() {} + + // + // Reset All Collectors ... + void Reset() + { + Clean(); + } + + // + // Count Data ... + int Count() + { + // + int result = 0; + + // + result = ArraySize(mTimes); + + // + return result; + } + + // + // TODO: Implement Business Logic here ... + + // + // Add Specific item to Collection ... + bool Add( + XCollector &item // Specified Info + ) + { + // + bool result = false; + + // + // Validate Args ... + result = IsValid( + item, + false); + if (!result) + { + return result; + } + + // + // Add Items Values to Buffers ... + // + AddItemToBuffer( + item.time, + mTimes); + + // + AddItemToBuffer( + item.volume, + mVolumes); + + // + AddItemToBuffer( + item.maxDrawDown, + mMaxDrawDowns); + + // + AddItemToBuffer( + item.maxAllowedVolume, + mMaxAllowedVolumes); + + // + AddItemToBuffer( + item.minBalanceForOpenTrade, + mMinBalanceForTradePrices); + + // + return result; + } + + // + // Retrieve Specific Item ... + bool Get( + XCollector &item, // Hold's Result + int index = 0 // Specified Index to Retrieve + ) + { + // + bool result = false; + + // + result = IsValidIndex(index); + if (!result) + { + return result; + } + + // + // Filling Item ... + item.time = mTimes[index]; + item.volume = mVolumes[index]; + item.maxDrawDown = mMaxDrawDowns[index]; + item.maxAllowedVolume = mMaxAllowedVolumes[index]; + item.minBalanceForOpenTrade = mMinBalanceForTradePrices[index]; + + // + return result; + } + XCollector Get( + int index = 0 // Specified Index to Retrieve + ) + { + // + XCollector result = {}; + + // + bool isValidIndex = IsValidIndex(index); + if (!isValidIndex) + { + return result; + } + + // + // Filling Item ... + result.time = mTimes[index]; + result.volume = mVolumes[index]; + result.maxDrawDown = mMaxDrawDowns[index]; + result.maxAllowedVolume = mMaxAllowedVolumes[index]; + result.minBalanceForOpenTrade = mMinBalanceForTradePrices[index]; + + // + return result; + } + bool Get( + XCollector &item, // Hold's Result + datetime time // Specified Index to Retrieve + ) + { + // + bool result = false; + + // + if (time <= 0) + { + return result; + } + + // + int timesCount = ArraySize(mTimes); + result = timesCount > 0; + if (!result) + { + return result; + } + + // + int index = -1; + for (int i = 0; i < timesCount; i++) + { + // + datetime iTime = mTimes[i]; + + // + if (iTime == time) + { + // + index = i; + break; + } + } + + // + result = index >= 0; + if (!result) + { + return result; + } + + // + result = Get( + item, + index); + + // + return result; + } + XCollector Get( + datetime time // Specified Index to Retrieve + ) + { + // + XCollector result = {}; + + // + if (time <= 0) + { + return result; + } + + // + int timesCount = ArraySize(mTimes); + if (timesCount <= 0) + { + return result; + } + + // + int index = -1; + for (int i = 0; i < timesCount; i++) + { + // + datetime iTime = mTimes[i]; + + // + if (iTime == time) + { + // + index = i; + break; + } + } + + // + if (index <= -1) + { + return result; + } + + // + result = Get( + index); + + // + return result; + } + + // + // Retrieve All ... + void GetAll( + XCollector &result[], // Hold's Result + bool reversal = false // Extract Direction + ) + { + // + CleanBuffer(result); + + // + int timesCount = ArraySize(mTimes); + if (timesCount <= 0) + { + return; + } + + // + if (!reversal) + { + // + for (int i = 0; i < timesCount; i++) + { + // + XCollector iCollector = Get(i); + + // + AddItemToBuffer( + iCollector, + result); + } + } + else + { + // + for (int i = timesCount - 1; i >= 0; i--) + { + // + XCollector iCollector = Get(i); + + // + AddItemToBuffer( + iCollector, + result); + } + } + } + + // + // Extract History ... + void Extract( + XCollector &result[], // Hold's Result + int start, // Start Index + int end // End Index + ) + { + // + CleanBuffer(result); + + // + // Validate Args ... + if ( + end < 0 || + start < 0 || + (start == 0 && end == 0) || + MathAbs(start - end == 0)) + { + return; + } + + // + // Validate Start and End Index ... + bool isValidEnd = IsValidIndex(end); + bool isValidStart = IsValidIndex(start); + if (!isValidEnd || !isValidStart) + { + return; + } + + // + bool direction = end > start; + if (direction) + { + // + for (int i = start; i < end - 1; i++) + { + // + XCollector iCollect = Get(i); + + // + AddItemToBuffer( + iCollect, + result); + } + } + else + { + // + for (int i = end - 1; i >= start; i--) + { + // + XCollector iCollect = Get(i); + + // + AddItemToBuffer( + iCollect, + result); + } + } + } + + // + // Validate an Item ... + bool IsValid( + XCollector &item, // Specified Info + bool ignoreTime = true // Ignore Times Checking ... + ) + { + // + bool result = false; + + // + // Check Each Items contains Correct Value ... + // + result = item.volume >= 0; + if (!result) + { + return result; + } + + // + result = item.maxDrawDown >= 0; + if (!result) + { + return result; + } + + // + result = item.maxAllowedVolume >= 0; + if (!result) + { + return result; + } + + // + result = item.minBalanceForOpenTrade >= 0; + if (!result) + { + return result; + } + + // + // Check Time has Proper Value ... + result = item.time > 0; + if (!result) + { + return result; + } + + // + // Check time bigger than last Time ... + int timesCount = ArraySize(mTimes); + if ( + !ignoreTime && + timesCount >= 0) + { + // + // Retrieve Last Added Times ... + datetime lastTime; + result = GetLastItem(lastTime, mTimes); + if (!result) + { + return result; + } + + // + // Compare Last Time by current Time ... + result = item.time > lastTime; + if (!result) + { + return result; + } + } + + // + return result; + } + + // + // Generate Logging String Representation ... + string GenerateString( + XCollector &item, // Specified Info + string separator = "\n" // Separator Character + ) + { + // + string result = ""; + + // + result += "time: " + (string)item.time + separator; + result += "volume: " + (string)item.volume + separator; + result += "maxDrawDown: " + (string)item.maxDrawDown + separator; + result += "maxAllowedVolume: " + (string)item.maxAllowedVolume + separator; + result += "minBalanceForOpenTrade: " + (string)item.minBalanceForOpenTrade + separator; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Max Draw Up touched till now ... + double mMaxDrawUp; + + // + // Max Draw Down touched till now ... + double mMaxDrawDown; + + // + // Last Time for Checks ... + datetime mTimes[]; + + // + // Volume at the Check Time ... + double mVolumes[]; + + // + // DrawDown for each Check ... + double mMaxDrawDowns[]; + + // + // Max Allowed Volume for each check ... + double mMaxAllowedVolumes[]; + + // + // Min Balance for Open Trades for Each Check ... + double mMinBalanceForTradePrices[]; + + // + // Reset ... + void Clean() + { + // + mMaxDrawUp = 0; + mMaxDrawDown = 0; + + // + CleanBuffer(mTimes); + CleanBuffer(mVolumes); + CleanBuffer(mMaxDrawDowns); + CleanBuffer(mMaxAllowedVolumes); + CleanBuffer(mMinBalanceForTradePrices); + } + + // + // Validate Index ... + bool IsValidIndex( + int index // Specified Index + ) + { + // + bool result = false; + + // + int bufferSize = ArraySize(mTimes); + if (bufferSize <= 0) + { + return result; + } + + // + result = index <= bufferSize - 1; + + // + return result; + } +}; + +// +// a Class for Managing Volumes ... +class XCVolumeManager : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCVolumeManager( + double staticVolumeRate, // Static Volume Calculation Mutiplier + ENUM_STATIC_VOLUME_METHODS volumeMethod = X_STATIC_VOLUME_BASED_ON_DEPOSIT, // How to Calculate Static Volume + double volumeMultiplier = 0, // Volume Multiplier + double volumeMultiplierAppliedRate = 0, // Apply Volume Multiplier when Balance Increased by this rate + double maxAllowedVolume = 0, // Max Allowed Volume + double increaseMaxAllowedVolumeRate = 0 // Increase Max Allowed Volumes when Balance Increased by this rate + ) + { + // + mAccountInfo = new XCAccountInfo(); + + // + ResetForceVolumeMultiplier(); + + // + mVolumeMethod = volumeMethod; + mStaticVoluemRate = staticVolumeRate; + mVolumeMultiplier = volumeMultiplier; + mMaxAllowedVolume = maxAllowedVolume; + mVolumeMultiplierAppliedRate = volumeMultiplierAppliedRate; + mIncreaseMaxAllowedVolumeRate = increaseMaxAllowedVolumeRate; + } + + // + // Deconstructor ... + ~XCVolumeManager(void) {} + + // + // Check Volume Multiplier ... + bool CanUseVolumeMultiplier() + { + // + bool result = false; + + // + result = + mVolumeMultiplier > 0 && + mVolumeMultiplierAppliedRate > 0; + + // + return result; + } + + // + // Check Max Volume ... + bool CanUseMaxVolume() + { + // + bool result = false; + + // + result = + mMaxAllowedVolume > 0; + + // + return result; + } + + // + // Calculate Volume for Position ... + double CalculateVolume( + int numberOfOpenPositions = 0, // Number Of Open Signals + string symbol = NULL // Specify Symbol + ) + { + // + double result = 0; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Static Volume ... + result = GetStaticVolume(); + + // + double multiplier = GetVolumeMultiplier(); + result *= multiplier; + + // + // Check Max Allowed Volume Exists ... + double maxAllowedVolume = GetMaxAllowedVolume(); + if (maxAllowedVolume > 0) + { + // + result = + result > maxAllowedVolume + ? maxAllowedVolume + : result; + } + + // + // Check Number of Open Positions ... + if (numberOfOpenPositions >= 0) + { + // + // Decrease Volume ... + result /= (1 + numberOfOpenPositions); + } + + // + // Apply Force Volume Multiplier ... + result *= mForceVolumeMultiplier; + + // + // Retrieve Symbol Volume Info ... + result = NormalizeVolume(result, symbol, 2); + + // + return result; + } + + // + // Calculate Volume Multiplier ... + double GetVolumeMultiplier() + { + // + double result = 1; + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + bool canUseVolumeMultiplier = CanUseVolumeMultiplier(); + if ( + balance < deposit || + !canUseVolumeMultiplier) + { + return result; + } + + // + // Apply Multiplier to Volume ... + double baseGrowBalance = deposit * mVolumeMultiplierAppliedRate; + double balanceGrows = balance - deposit; + if (balanceGrows < baseGrowBalance) + { + return result; + } + + // + double applyMultiplierTimes = balanceGrows / baseGrowBalance; + double roundedApplyMultiplierTimes = MathRound(applyMultiplierTimes); + + // + if (applyMultiplierTimes < roundedApplyMultiplierTimes) + { + applyMultiplierTimes -= (1 - (roundedApplyMultiplierTimes - applyMultiplierTimes)); + } + + // + // Calculate result ... + result = applyMultiplierTimes * mVolumeMultiplier; + + // + return result; + } + + // + // Retrieve Required Balance Grows for Increase Max Allowed Volume ... + double GetIncreaseMaxAllowedVolumeBalance() + { + // + double result = 0; + + // + if ( + mMaxAllowedVolume <= 0 || + mIncreaseMaxAllowedVolumeRate <= 0) + { + return result; + } + + // + result = mAccountInfo.GetInitialBalance() * mIncreaseMaxAllowedVolumeRate; + + // + return result; + } + + // + // Calculate Max Allowed Volume ... + double GetMaxAllowedVolume() + { + // + double result = 0; + + // + // Validate Args ... + result = + mMaxAllowedVolume <= 0 + ? 0 + : mMaxAllowedVolume; + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + bool canUseMaxAllowedVolume = CanUseMaxVolume(); + if ( + balance <= deposit || + !canUseMaxAllowedVolume || + mIncreaseMaxAllowedVolumeRate <= 0) + { + // + return result; + } + + // + // Apply Multiplier to Volume ... + double baseGrowBalance = GetIncreaseMaxAllowedVolumeBalance(); + double balanceGrows = balance - deposit; + if (balanceGrows < baseGrowBalance) + { + return result; + } + + // + double applyMultiplierTimes = balanceGrows / baseGrowBalance; + double roundedApplyMultiplierTimes = MathRound(applyMultiplierTimes); + + // + if (applyMultiplierTimes < roundedApplyMultiplierTimes) + { + applyMultiplierTimes -= (1 - (roundedApplyMultiplierTimes - applyMultiplierTimes)); + } + + // + result *= applyMultiplierTimes; + + // + return result; + } + + // + // Get Static Volume ... + double GetStaticVolume() + { + // + double result = 0; + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + + // + switch (mVolumeMethod) + { + // + case X_STATIC_VOLUME_BASED_ON_DEPOSIT: + result = mStaticVoluemRate * deposit; + break; + + // + case X_STATIC_VOLUME_BASED_ON_BALANCE: + result = mStaticVoluemRate * balance; + break; + } + + // + return result; + } + + // + // Reset Froce Volume Multiplier ... + void ResetForceVolumeMultiplier() + { + mForceVolumeMultiplier = 1; + } + + // + // Retrieve Current Force Volume Multiplier ... + double GetCurrentForceVolumeMultiplier() + { + return mForceVolumeMultiplier; + } + + // + // Retrieve Next Increase Multiplier Price ... + double GetIncreaseMultiplierBalance() + { + return mAccountInfo.GetInitialBalance() * mVolumeMultiplierAppliedRate; + } + + // + // Change Force Volume Multiplier ... + void ChangeForceVolumeMultiplier( + double rate // Change rate + ) + { + // + // Normalize rate ... + if (rate <= 1) + { + rate = 1; + } + + // + mForceVolumeMultiplier = rate; + } + + // + // Increase Force Volume Multiplier ... + void IncreaseForceVolumeMultiplier() + { + mForceVolumeMultiplier += 0.5; + } + + // + // Decrease Force Volume Multiplier ... + void DecreaseForceVolumeMultiplier() + { + // + if (mForceVolumeMultiplier <= 1) + { + return; + } + + // + mForceVolumeMultiplier -= 0.5; + } + + // + // Generate Current State Log String ... + string GenerateStateString( + string separator = "\n" // Log Separator ... + ) + { + // + string result = ""; + + // + // Normallize Separator ... + if (StringLen(separator) == 0) + { + separator = "\n"; + } + + // + result += "ForceVolumeMultiplier: " + (string)mForceVolumeMultiplier + separator; + // + result += "StaticVoluemRate: " + (string)mStaticVoluemRate + separator; + result += "StaticVoluem: " + (string)GetStaticVolume() + separator; + result += "VolumeMethod: " + EnumToString(mVolumeMethod) + separator; + // + result += "VolumeMultiplier: " + (string)mVolumeMultiplier + separator; + result += "VolumeMultiplierAppliedRate: " + (string)mVolumeMultiplierAppliedRate + separator; + // + result += "MaxAllowedVolume: " + (string)mMaxAllowedVolume + separator; + result += "IncreaseMaxAllowedVolumeRate: " + (string)mIncreaseMaxAllowedVolumeRate + separator; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // an Instance of Account Info for reading Balance and Deposit and etc ... + XCAccountInfo mAccountInfo; + + // + // Force Volume Rate Multiplier ... + double mForceVolumeMultiplier; + + // + // Static Volume Calculation Mutiplier ... + double mStaticVoluemRate; + + // + // How to Calculate Static Volume ... + ENUM_STATIC_VOLUME_METHODS mVolumeMethod; + + // + // Volume Multiplier ... + double mVolumeMultiplier; + + // + // Apply Volume Multiplier when Balance Increased by this rate ... + double mVolumeMultiplierAppliedRate; + + // + // Max Allowed Volume + double mMaxAllowedVolume; + + // + // Increase Max Allowed Volumes when Balance Increased by this rate + double mIncreaseMaxAllowedVolumeRate; +}; + +// +// a Class For Managing Signals Additional Data ... +class XCSignalManager : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCSignalManager(void) + { + CleanData(); + } + + // + // Deconstructor ... + ~XCSignalManager(void) {} + + // + void Reset() + { + CleanData(); + } + + // + // Retrieve All Signals ... + void GetAll( + XSignal &result[] // Hold's Result + ) + { + // + CleanBuffer(result); + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + AddItemToBuffer( + iSignal, + result); + } + } + + // + // Count Items ... + int Count() + { + return ArraySize(mSignals); + } + + // + // Retrieve Specific Signal by Ticket ... + XSignal Get( + ulong ticket // Signals Ticket ... + ) + { + // + XSignal result = {}; + + // + // Check Exists ... + bool isExists = IsExists(ticket); + if (!isExists) + { + return result; + } + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket == ticket) + { + // + result = iSignal; + break; + } + } + + // + return result; + } + + // + // Check Signal Exists or not ... + bool IsExists( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket == ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + bool IsExists( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket == signal.ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + + // + // Add Signal ... + bool Add( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Validate Args ... + if (signal.ticket <= 0) + { + return result; + } + + // + // Chekc Signal Exists ... + bool isExists = IsExists(signal); + if (isExists) + { + return result; + } + + // + AddItemToBuffer( + signal, + mSignals); + result = true; + + // + return result; + } + + // + // Update Specific Buffer ... + bool Update( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Validate Args ... + if (signal.ticket <= 0) + { + return result; + } + + // + // Chekc Signal Exists ... + bool isExists = IsExists(signal); + if (!isExists) + { + return result; + } + + // + // Remove Signal ... + Remove(signal); + + // + // Add new One ... + AddItemToBuffer( + signal, + mSignals); + + // + result = true; + + // + return result; + } + + // + // Remove Signal ... + bool Remove( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + // Check Signal Exists ... + bool isExists = IsExists(ticket); + if (!isExists) + { + return result; + } + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + XSignal signals[]; + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket != ticket) + { + AddItemToBuffer( + iSignal, + signals); + } + } + + // + // Now we have to Clean All Signals and Replace them by signals[] buffer ... + UpdateData(signals); + + // + result = true; + return result; + } + bool Remove( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Check Signal Exists ... + bool isExists = IsExists(signal); + if (!isExists) + { + return result; + } + + // + int signalsCount = ArraySize(mSignals); + if (signalsCount <= 0) + { + return result; + } + + // + XSignal signals[]; + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = mSignals[i]; + + // + if (iSignal.ticket != signal.ticket) + { + AddItemToBuffer( + iSignal, + signals); + } + } + + // + // Now we have to Clean All Signals and Replace them by signals[] buffer ... + UpdateData(signals); + + // + result = true; + return result; + } + + // + // Add Or Update ... + bool AddOrUpdate( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + // Validate Args ... + if (signal.ticket <= 0) + { + return result; + } + + // + // Chekc Signal Exists ... + bool isExists = IsExists(signal); + if (!isExists) + { + result = Add(signal); + } + else + { + result = Update(signal); + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Holds Signals ... + XSignal mSignals[]; + + // + // Clean All Exists Data ... + void CleanData() + { + CleanBuffer(mSignals); + } + + // + // Update Data ... + void UpdateData( + XSignal &source[] // a Buffer which needs to Replace ... + ) + { + // + CleanData(); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + XSignal iSignal = source[i]; + + // + AddItemToBuffer( + iSignal, + mSignals); + } + } +}; + +// +// XSaherElm Trade Class ... +class XCTrade : public XCBase +{ + // + // all public features ... +public: + // + // Constructor ... + void XCTrade( + string tag, // Specify a Tag for Trader instance + string symbol, // Specify Trader Symbol + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + bool useVirtualTPSL, // Use Virtual TP SL + int maxAllowedTrades, // Specify Max Allowed Trades + double minBallanceForOpenTrades, // Specify Minimum Balance for Open Trades + double minAllowedFreeMarginForOpenTrades, // Specify Minimum Free Marging for Open Trades + bool useSignalProtector = true // Specify Use Signal Protector or not + ) + { + // + mTag = tag; + mSymbol = symbol; + mSlippage = slippage; + mMagicNumber = magicNumber; + mUseVirtualTPSL = useVirtualTPSL; + mMaxAllowedTrades = maxAllowedTrades; + mMinBallanceForOpenTrades = minBallanceForOpenTrades; + mMinAllowedFreeMarginForOpenTrades = minAllowedFreeMarginForOpenTrades; + + // + mTrader = new XSCTrade(); + + // + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + mSignalManager = new XCSignalManager(); + + // + Reset(); + } + + // + // Deconstructor ... + void ~XCTrade() + { + } + + // + // START Configuring Class Functions ... + // + + // + // Reset all Variables ... + void Reset() + { + // + mSignalManager.Reset(); + + // + mDaysForRead = 1; + mScanStarted = false; + + // + // Reset On Trade Counter ... + ResetOnTradeContext(); + + // + // Init On Trade Context ... + InitOnTradeContext(); + } + + // + // END Configuring Class Functions ... + // + + // + // START Count ... + // + + // + // Count Open Positions ... + int Count() + { + // + int result = 0; + + // + int total = PositionsTotal(); + for (int i = 0; i < total; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + result++; + } + + // + return result; + } + + // + // Count Longs ... + int CountLongs() + { + int result = CountByType(X_SIGNAL_LONG); + return result; + } + + // + // Count Shorts ... + int CountShorts() + { + int result = CountByType(X_SIGNAL_SHORT); + return result; + } + + // + // Count Specific Type Of Positions ... + int CountByType(ENUM_POSITION_TYPE type) + { + // + int result = 0; + + // + int total = PositionsTotal(); + for (int i = 0; i < total; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + if (mPositionInfo.PositionType() != type) + { + continue; + } + + // + result++; + } + + // + return result; + } + + // + // Count By Type ... + int CountByType(ENUM_X_SIGNAL_TYPE type) + { + // + // Validate Args ... + ENUM_POSITION_TYPE mType = POSITION_TYPE_BUY; + if (type == X_SIGNAL_LONG) + { + mType = POSITION_TYPE_BUY; + } + else if (type == X_SIGNAL_SHORT) + { + mType = POSITION_TYPE_SELL; + } + + // + int result = CountByType(mType); + return result; + } + + // + // END Count ... + // + + // + // START Retrieve ... + // + + // + // Retrieve Specified Position by it's Ticket ... + XSignal GetSignal( + ulong ticket // Specified Ticket + ) + { + // + XSignal result = {}; + + // + result = PositionToSignal(ticket); + + // + return result; + } + + // + // Get Last Signal ... + XSignal GetLastSignal() + { + // + XSignal result = {}; + + // + XSignal signals[]; + GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + result = signals[0]; + + // + return result; + } + + // + // Retrieve Last Executed Signal ... + bool GetLastSignal(XSignal &signal) + { + // + bool result = false; + + // + XSignal signals[]; + GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + signal = signals[0]; + result = true; + + // + return result; + } + + // + // Retrieve All Positions ... + void GetSignals( + XSignal &result[] // Holds Result ... + ) + { + // + CleanBuffer(result); + + // + int totalPositions = PositionsTotal(); + for (int i = 0; i < totalPositions; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + if (mPositionInfo.Symbol() != mSymbol) + { + continue; + } + + // + // Position to Signal ... + XSignal signal = PositionToSignal(i); + Add( + signal, + result); + } + } + + // + // Retrieve Type Specific Signals ... + void GetSignals( + XSignal &result[], // Holds Result ... + ENUM_X_SIGNAL_TYPE type // Specified Sginal Type ... + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals(signals); + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = signalsCount - 1; i >= 0; i--) + { + // + XSignal iSignal = signals[i]; + + // + if (type == X_SIGNAL_UNKNOWN) + { + Add( + iSignal, + result); + } + else if (iSignal.type == type) + { + Add( + iSignal, + result); + } + } + } + + // + // Filter Signals By Searching Comments ... + void FilterSignals( + XSignal &result[], // Holds Result ... + const string query, // Search in Comment Qeury ... + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specified Sginal Type ... + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + + // + // Validate Args ... + if ( + StringLen(query) <= 0 || + signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + int queryPos = StringFind( + iSignal.comment, + query); + bool isContains = queryPos > -1; + if (!isContains) + { + continue; + } + + // + Add( + iSignal, + result); + } + } + + // + // Get All Trades Which Candle Passed after Open ... + void GetOldSignals( + XSignal &result[], // Holds Result + int life, // Max Candle Passed after Trades Open + ENUM_TIMEFRAMES period = NULL, // Calculate Candles based on time frame + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + // Normalize Period ... + if (period == NULL) + { + period = _Period; + } + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Current Time Frame Candle Index ... + int currentBarIndex = 0; + + // + // Loop through Positions ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + // Retrieve Trade Open Bar Index based on Current Period ... + int tradeOpenBarIndex = iBarShift( + mSymbol, + period, + iSignal.time); + + // + // Calculate Trade Life ... + int diff = MathAbs(currentBarIndex - tradeOpenBarIndex); + + // + bool isPassed = diff >= life; + if (isPassed) + { + // + Add( + iSignal, + result); + } + } + } + + // + // Get In Profit Signals ... + void GetInProfitSignals( + XSignal &result[], // Holds Result + double minProfit = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isPassed = minProfit <= 0 && iSignal.profit > 0 + ? true + : iSignal.profit >= minProfit; + if (isPassed) + { + Add( + iSignal, + result); + } + } + } + + // + // Get In Drawdown Signals ... + void GetInDrawdownSignals( + XSignal &result[], // Holds Result + double maxDrawDown = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isPassed = maxDrawDown <= 0 && iSignal.profit < 0 + ? true + : iSignal.profit >= (-1 * maxDrawDown); + if (isPassed) + { + Add( + iSignal, + result); + } + } + } + + // + // Retrieve Max In Draw Down Trade ... + XSignal GetMaxInDrawdownSignal( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + XSignal result = {}; + + // + XSignal signals[]; + GetInDrawdownSignals( + signals, + 0, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + result = + (result.ticket <= 0 && + result.profit == 0) || + result.profit > iSignal.profit + ? iSignal + : result; + } + + // + return result; + } + + // + // Calculate Profits Of all Open Signals ... + double GetSignalsProfit( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + double result = 0; + + // + XSignal signals[]; + GetSignals(signals, type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + result += iSignal.profit; + } + + // + return result; + } + + // + // END Retrieve ... + // + + // + // START Signal Execution Actions ... + // + + // + // Execute a Signal in Market ... + ENUM_EXECUTION_SIGNAL_RESULT ExecuteSignal( + XSignal &signal, // Specified Signal + bool ignoreNumberOfTraes = false, // Ignore Number of Trades + bool checkAccountConditions = true // Check Account Balance, Equity and Free Margin for Signal Execution + ) + { + // + ENUM_EXECUTION_SIGNAL_RESULT result = X_TRADER_UNKNOWN_ERROR; + + // + // Validate Signal ... + bool isValid = IsValidSignal(signal); + if (!isValid) + { + // + result = X_TRADER_INVALID_SIGNAL_ERROR; + return result; + } + + // + // Check Account Equity ... + bool isEquityPassed = !checkAccountConditions + ? true + : IsEquityReadyForTrade(); + if (!isEquityPassed) + { + // + result = X_TRADER_NOT_ENOUGH_EQUITY_ERROR; + return result; + } + + // + // Check Account Balance ... + bool isBalancePassed = !checkAccountConditions + ? true + : IsBalanceReadyForTrade(); + if (!isBalancePassed) + { + // + result = X_TRADER_NOT_ENOUGH_BALANCE_ERROR; + return result; + } + + // + // Check Account FreeMargin ... + bool isFreeMarginPassed = !checkAccountConditions + ? true + : IsFreeMarginReadyForTrade(); + if (!isFreeMarginPassed) + { + // + result = X_TRADER_NOT_ENOUGH_MARIGIN_ERROR; + return result; + } + + // + // Check Number of Open Trades ... + int openTradesCount = Count(); + bool isTradeCountPassed = ignoreNumberOfTraes + ? true + : openTradesCount < mMaxAllowedTrades; + if (!isTradeCountPassed) + { + // + result = X_TRADER_MAX_TRADES_REACHED_ERROR; + return result; + } + + // + bool isExecuted = + signal.type == X_SIGNAL_LONG + ? Buy( + signal.volume, + signal.entry, + mUseVirtualTPSL + ? 0 + : signal.sl, + mUseVirtualTPSL + ? 0 + : signal.tp, + signal.comment) + : signal.type == X_SIGNAL_SHORT + ? Sell( + signal.volume, + signal.entry, + mUseVirtualTPSL + ? 0 + : signal.sl, + mUseVirtualTPSL + ? 0 + : signal.tp, + signal.comment) + : false; + if (isExecuted) + { + // + ulong ticket = PositionGetTicket(PositionsTotal() - 1); + + // + signal.id = ticket; + signal.ticket = ticket; + + // + AddOrUpdateSignalInfo(signal); + + // + result = X_TRADER_SUCCEED_EXECUTION; + } + + // + return result; + } + + // + // This Function, Handling Following Works on Open Positions: + // - Close On SL if Reached ... + // - Close On TP if Reached ... + // - Make Risk Free Trades ... + bool HandleSignals( + XTraderHandlerResult &handlerResult, // Holds Result + bool ignoreRiskFree = false // Ignore Risk Free Trdaes + ) + { + // + bool result = false; + + // + // Cleanup Result ... + CleanBuffer(handlerResult.sl); + CleanBuffer(handlerResult.tp); + CleanBuffer(handlerResult.rf); + + // + // Reading Open Positions ... + XSignal signals[]; + GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + double deviation = mSlippage * GetPoints(mSymbol); + + // + // Loop ... + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isLong = iSignal.type == X_SIGNAL_LONG; + double entry = GetEntry(iSignal.symbol, iSignal.type); + double exit = GetExit(iSignal.symbol, iSignal.type); + double spread = GetSpread(iSignal.symbol); + double appliedTPPrice = + iSignal.tp > 0 + ? isLong + ? iSignal.tp - deviation + : iSignal.tp + deviation + : 0; + double appliedSLPrice = + iSignal.sl > 0 + ? isLong + ? iSignal.sl + deviation + : iSignal.sl - deviation + : 0; + + // + double usedPrice = exit; + + // + bool isSLTouched = + isLong + ? usedPrice <= appliedSLPrice + : usedPrice >= appliedSLPrice; + + // + bool isTPTouched = + isLong + ? usedPrice >= appliedTPPrice + : usedPrice <= appliedTPPrice; + + // + // Handle SL ... + if ( + // + iSignal.sl > 0 + // + && + // + isSLTouched + // + && + // + mUseVirtualTPSL) + { + // + string comment = GenerateSignalSLComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + AddItemToBuffer( + iSignal, + handlerResult.sl); + } + } + + // + // Handle TP ... + if ( + // + iSignal.tp > 0 + // + && + // + isTPTouched + // + && + // + mUseVirtualTPSL) + { + // + string comment = GenerateSignalTPComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + AddItemToBuffer( + iSignal, + handlerResult.tp); + } + } + + // + // Handle Risk Free ... + if ( + // + !ignoreRiskFree + // + && + // + iSignal.riskFreeStep > 0 + // + && + // + iSignal.riskFreeRate > 0 + // + ) + { + // + // Make Signals Risk Free Only if Signal In Profit ... + if (iSignal.profit <= 0) + { + continue; + } + + // + // Base Price is ENTRY, then Last Level, in each level SL is Last Level ... + // + // Calculate Risk Free Level/Multiplier ... + double level = 0; + double roundedLevel = 0; + double rStepPrice = PipsToPrice(iSignal.riskFreeStep); + double rBasePrice = + iSignal.sl > 0 && + iSignal.sl > iSignal.entry + ? iSignal.sl + : iSignal.entry; + + // + double exit = GetExit(iSignal.type); + + // + // Check Base Price for Signal reached with Exit Price ... + bool isExitPriceReachedBasePrice = + isLong + ? exit > rBasePrice + : exit < rBasePrice; + if (!isExitPriceReachedBasePrice) + { + continue; + } + + // + // Calculate Risk Free Step Multiplier ... + level = MathAbs(exit - rBasePrice) / rStepPrice; + + // + // Check Level Must Bigger than 1 ... + if (level < 1) + { + continue; + } + + // + // Normalize Level ... + roundedLevel = MathRound(level); + if (level < roundedLevel) + { + level -= (1 - (roundedLevel - level)); + } + else if (level > roundedLevel) + { + level -= (level - roundedLevel); + } + + // + // Generate Comment ... + string comment = GenerateSignalRFComment(iSignal, (int)level); + + // + // Calculate SL ... + double slDistance = spread; + double sl = + isLong + ? exit - slDistance + : exit + slDistance; + + // + // Increase TP One Level if Exists ... + double tp = iSignal.tp; + if (iSignal.tp > 0 && (isLong + ? iSignal.tp < rBasePrice + rStepPrice + : iSignal.tp > rBasePrice - rStepPrice)) + { + // + tp = + isLong + ? iSignal.tp + rStepPrice + : iSignal.tp - rStepPrice; + } + + // + double rVolume = NormalizeVolume((iSignal.volume * iSignal.riskFreeRate), iSignal.symbol); + + // + // Update Signal Volume ... + double volume = iSignal.volume - rVolume; + + // + bool isClosedPartial = + ClosePartial( + iSignal.ticket, + rVolume, + comment); + if (isClosedPartial) + { + // + bool isModified = true; + if (!mUseVirtualTPSL) + { + // + isModified = Modify( + iSignal.ticket, + sl, + tp, + comment); + } + + // + if (isModified) + { + // + // Try to Update Signal ... + XSignal s = mSignalManager.Get(iSignal.ticket); + + // + // Apply Changes on Signal ... + s.sl = sl; + s.tp = tp; + s.volume = volume; + + // + // Update Signal ... + bool isUpdated = false; + bool isRemoved = false; + if (volume == 0) + { + isRemoved = mSignalManager.Remove(s); + } + else if (volume > 0) + { + isUpdated = mSignalManager.AddOrUpdate(s); + } + if ( + isUpdated || + isRemoved) + { + // + AddItemToBuffer( + s, + handlerResult.rf); + } + } + } + else + { + mSignalManager.Remove(iSignal.ticket); + } + } + } + + // + result = + ArraySize(handlerResult.tp) > 0 || + ArraySize(handlerResult.sl) > 0 || + ArraySize(handlerResult.rf) > 0; + + // + return result; + } + + // + // Close All Trades ... + void CloseSignals( + XSignal &result[], // Holds Result + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalForceCloseComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // Close Pyramid Signals ... + void CloseInPyramidSignals( + XSignal &result[], // Holds Result + double pyramid = 0, // Close Pyramid Profit + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetSignals( + signals, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + double profit = 0; + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + profit += iSignal.profit; + } + + // + // Normalize Pyramid ... + if (pyramid < 0) + { + pyramid = 0; + } + + // + if (profit > pyramid) + { + CloseSignals(result); + } + } + + // + // Close All Trades Which Candle Passed after Open ... + void CloseOldSignals( + XSignal &result[], // Holds Result + int life, // Max Candle Passed after Trades Open + ENUM_TIMEFRAMES period = NULL, // Calculate Candles based on time frame + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetOldSignals( + signals, + life, + period, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalAgeComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // Close In Profit Signals ... + void CloseInProfitSignals( + XSignal &result[], // Holds Result + double minProfit = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetInProfitSignals( + signals, + minProfit, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalProfitComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // Close In Drawdown Signals ... + void CloseInDrawdownSignals( + XSignal &result[], // Holds Result + double maxDrawDown = 0, // Minimum Profit To Close Trades + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + GetInDrawdownSignals( + signals, + maxDrawDown, + type); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + string comment = GenerateSignalProfitComment(iSignal); + + // + bool isClosed = Close( + iSignal.ticket, + comment); + if (isClosed) + { + Add( + iSignal, + result); + } + } + } + + // + // END Signal Execution Actions ... + // + + // + // START Actions ... + // + + // + // Force Open a Buy/Long Position ... + bool Buy( + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + const string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.Buy( + volume, + mSymbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.BuyLimit( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.BuyStop( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Force Open a Sell/Short Position ... + bool Sell( + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + const string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.Sell( + volume, + mSymbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.SellLimit( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = "" // comment + ) + { + // + bool result = false; + + // + result = mTrader.SellStop( + volume, + price, + mSymbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Modify Position ... + bool Modify( + const ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0, // take profit + const string comment = "" // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + if (tp <= 0 && sl <= 0) + { + result = false; + return result; + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment); + if (result) + { + // + if (mSignalManager.IsExists(ticket)) + { + // + XSignal signal = GetSignal(ticket); + + // + mSignalManager.Update(signal); + } + } + + // + return result; + } + + // + // Close Position By Ticket ... + bool Close( + ulong ticket, // Position Ticket + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + // Try to Select Position ... + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + // Close Position By Specific Comment ... + result = mTrader.PositionClose( + ticket, + mSlippage, + comment); + if (result) + { + // + if (mSignalManager.IsExists(ticket)) + { + mSignalManager.Remove(ticket); + } + } + + // + return result; + } + + // + // Close Partial By Ticket ... + bool ClosePartial( + ulong ticket, // Position Ticket + double volume, // Volume Size for Partial Closing + string comment = "" // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + result = mTrader.PositionClosePartial( + ticket, + volume, + mSlippage, + comment); + if (result) + { + // + if (mSignalManager.IsExists(ticket)) + { + // + XSignal signal = GetSignal(ticket); + + // + mSignalManager.Update(signal); + } + } + + // + return result; + } + + // + // END Actions ... + // + + // + // START Account Related ... + // + + // + // Retrieve Minimum Balance For Open Trades ... + double GetMinBalanceForOpenTrades() + { + // + double result = mMinBallanceForOpenTrades; + + // + double balance = mAccountInfo.GetBalance(); + double deposit = mAccountInfo.GetInitialBalance(); + if (balance > deposit) + { + // + double rate = mMinBallanceForOpenTrades / deposit; + + // + double ratedBalance = balance * rate; + + // + result = MathMax(mMinBallanceForOpenTrades, ratedBalance); + } + + // + return result; + } + + // + // Check Account Has Minimum Balance For Trade ... + bool IsBalanceReadyForTrade() + { + // + bool result = false; + + // + double minBalance = GetMinBalanceForOpenTrades(); + result = mAccountInfo.GetBalance() >= minBalance; + + // + return result; + } + + // + // Check Free Margin Has Enough For Trade ... + bool IsFreeMarginReadyForTrade() + { + // + bool result = false; + + // + double freeMargin = mAccountInfo.GetFreeMargin(); + + // + result = freeMargin >= mMinAllowedFreeMarginForOpenTrades; + + // + return result; + } + + // + // Check Equity Has Enough For Trade ... + bool IsEquityReadyForTrade() + { + // + bool result = false; + + // + double equity = mAccountInfo.GetEquity(); + + // + result = equity >= mMinAllowedFreeMarginForOpenTrades; + + // + return result; + } + + // + // END Account Related ... + // + + // + // START Signal Related ... + // + + // + // Validate Signal ... + bool IsValidSignal( + XSignal &signal // Specified Signal for Execution + ) + { + // + bool result = false; + + // + // Validate Signal Type ... + result = signal.type != X_SIGNAL_UNKNOWN; + if (!result) + { + return result; + } + + // + // Check Symbol ... + result = StringLen(signal.symbol) == 0 ? true : signal.symbol == mSymbol; + if (!result) + { + return result; + } + + // + // Check magic number ... + result = signal.magicNumber <= 0 ? true : signal.magicNumber == mMagicNumber; + if (!result) + { + return result; + } + + // + // Check Entry ... + result = signal.entry > 0; + if (!result) + { + return result; + } + + // // + // // Check SL ... + // // For Fix RiskFree Issues Ignore this ... + // result = signal.sl == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.sl < signal.entry + // : signal.sl > signal.entry; + // if (!result) + // { + // return result; + // } + + // + // Check TP ... + result = signal.tp == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.tp > signal.entry + : signal.tp < signal.entry; + if (!result) + { + return result; + } + + // + // Check Volume ... + result = signal.volume > 0; + if (!result) + { + return result; + } + + // + // Check Time ... + result = signal.time > 0; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Get Signal InDirection (Reversal) Type ... + ENUM_X_SIGNAL_TYPE GetSignalIndirectionType( + XSignal &signal // Specified Signal + ) + { + // + ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; + + // + switch (signal.type) + { + // + case X_SIGNAL_LONG: + result = X_SIGNAL_SHORT; + break; + + // + case X_SIGNAL_SHORT: + result = X_SIGNAL_LONG; + break; + } + + // + return result; + } + + // + // Get Signal InDirection (Reversal) Type ... + ENUM_X_SIGNAL_TYPE GetIndirectionSignalType( + ENUM_X_SIGNAL_TYPE type // Specified Type + ) + { + // + ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; + + // + switch (type) + { + // + case X_SIGNAL_LONG: + result = X_SIGNAL_SHORT; + break; + + // + case X_SIGNAL_SHORT: + result = X_SIGNAL_LONG; + break; + } + + // + return result; + } + + // + // Calculate SignalAge ... + int GetSignalAge( + datetime time // Signal Execution Time + ) + { + // + int result = 0; + + // + // Validate Arg ... + if (time <= 0) + { + return result; + } + + // + int sIndex = iBarShift( + mSymbol, + _Period, + time); + + // + datetime cTime = iTime( + mSymbol, + _Period, + 0); + int cIndex = iBarShift( + mSymbol, + _Period, + cTime); + + // + result = MathAbs(cIndex - sIndex); + + // + return result; + } + int GetSignalAge( + datetime time, // Signal Execution Time + ENUM_TIMEFRAMES period // Specify Time Frame + ) + { + // + int result = 0; + + // + // Validate Arg ... + if (time <= 0) + { + return result; + } + + // + int sIndex = iBarShift( + mSymbol, + period, + time); + + // + datetime cTime = iTime( + mSymbol, + period, + 0); + int cIndex = iBarShift( + mSymbol, + _Period, + cTime); + + // + result = MathAbs(cIndex - sIndex); + + // + return result; + } + int GetSignalAge( + XSignal &signal // Specified Signal + ) + { + // + int result = 0; + + // + // Validate Arg ... + if ( + signal.time <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GetSignalAge(signal.time); + + // + return result; + } + int GetSignalAge( + XSignal &signal, // Specify Signal + ENUM_TIMEFRAMES period // Specify Time Frame + ) + { + // + int result = 0; + + // + // Validate Arg ... + if ( + signal.time <= 0 || + !IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GetSignalAge( + signal.time, + period); + + // + return result; + } + + // + // Prepare a Signall ... + XSignal GenerateSignal( + ENUM_X_SIGNAL_TYPE type, // Signal Type + double tp = 0, // Take Profit + double sl = 0, // Stop Loss + double volume = 0, // Volume + double riskFreeStep = 0, // Risk Free Step Price + double riskFreeRate = 0 // Risk Free Rate + ) + { + // + XSignal result = {}; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + // Check Signal Type ... + bool isLong = type == X_SIGNAL_LONG; + + // + // Retrieve entry Price ... + double entry = GetEntry(mSymbol, type); + double spread = GetSpread(mSymbol); + + // + result.tp = tp; + result.sl = sl; + result.type = type; + result.entry = entry; + result.symbol = mSymbol; + result.magicNumber = mMagicNumber; + result.riskFreeStep = riskFreeStep; + result.riskFreeRate = riskFreeRate; + result.time = iTime(mSymbol, _Period, 0); + result.volume = NormalizeVolume(volume, mSymbol); + + // + // Since we Use signal instance to Generate Comment, this must be at the end ... + result.comment = GenerateSignalComment(result); + + // + return result; + } + + // + // Convert a Signal to String Representation ... + string ToString( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + if (!IsValid(signal, mMagicNumber) || signal.ticket <= 0) + { + return result; + } + + // + // TICKET ... + // it is very importants since they hold position info ... + result += X_SIGNAL_TICKET + "(" + (string)signal.ticket + ")"; + + // + // TYPE ... + string typeStr = GetSignalType(signal.type); + result += "_" + X_SIGNAL_TYPE + "(" + typeStr + ")"; + + // + // TP ... + result += "_" + X_SIGNAL_TP + "(" + (string)signal.tp + ")"; + + // + // SL ... + result += "_" + X_SIGNAL_SL + "(" + (string)signal.sl + ")"; + + // + // RFS ... + result += "_" + X_SIGNAL_RISKFREE_STEP + "(" + (string)signal.riskFreeStep + ")"; + + // + // RFR ... + result += "_" + X_SIGNAL_RISKFREE_RATE + "(" + (string)signal.riskFreeRate + ")"; + + // + return result; + } + + // + // Generate Comments for Specific Signal ... + string GenerateSignalComment( + ENUM_X_SIGNAL_TYPE type, // Specify Kind Signal Type + double volume, // Signal Volume + bool isCrossSignal = false // Specify Signal Cross + ) + { + // + string result = ""; + + // + string typeStr = GetSignalType(type); + if ( + volume <= 0 || + StringLen(typeStr) == 0) + { + return result; + } + + // + volume = NormalizeVolume(volume, mSymbol); + + // + result = mTag + (!isCrossSignal ? "" : "_Cross_") + "_" + typeStr; + + // + return result; + } + string GenerateSignalComment( + XSignal &signal, // Specified Signal + bool isCrossSignal = false // Specify Signal Cross + ) + { + // + string result = GenerateSignalComment( + signal.type, + signal.volume, + isCrossSignal + // + ); + + // + return result; + } + + // + // Generate Signal RF TP Comment ... + string GenerateSignalRFComment( + XSignal &signal, // Specified Signal + int level // Which Step of RFS + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); + + // + string prefix = X_SIGNAL_RISKFREE_STEP + "(" + (string)signal.ticket + ")"; + // + result = + // + level > 0 + ? prefix + "_" + (string)level + ": " + (string)exit + : prefix + ": " + (string)exit; + // + ; + + // + return result; + } + + // + // Generate Signal TP Comment ... + string GenerateSignalTPComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); + + // + result = + // + X_SIGNAL_TP + "(" + (string)signal.ticket + "): " + (string)exit; + // + ; + + // + return result; + } + + // + // Generate Signal SL Comment ... + string GenerateSignalSLComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); + + // + result = + // + X_SIGNAL_SL + "(" + (string)signal.ticket + "): " + (string)exit; + // + ; + + // + return result; + } + + // + // Generate Signal Profit Comment ... + string GenerateSignalProfitComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + result = + // + "Profit(" + (string)signal.ticket + "): " + (string)signal.profit; + // + ; + + // + return result; + } + + // + // Generate Signal Force Close Comment ... + string GenerateSignalForceCloseComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + result = + // + "FC(" + (string)signal.ticket + "): " + (string)signal.profit; + // + ; + + // + return result; + } + + // + // Generate Signal Age Comment ... + string GenerateSignalAgeComment( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Signal and it's Ticket ... + if (!IsValidSignal(signal) || signal.ticket <= 0) + { + return result; + } + + // + int age = GetSignalAge(signal); + + // + result = + // + "(" + (string)signal.ticket + ") A: " + (string)age + ", P:" + (string)signal.profit; + // + ; + + // + return result; + } + + // + // Generate a Signal Object name for Draw Events On Chart ... + string GenerateSignalObjectName( + ulong ticket // Specify Ticket + ) + { + // + string result = ""; + + // + // Validate Arg ... + if (ticket <= 0) + { + return result; + } + + // + // TICKET ... + // it is very importants since they hold position info ... + result += "T(" + (string)ticket + ")"; + + // + return result; + } + string GenerateSignalObjectName( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + // Validate Arg ... + if (!IsValid(signal, mMagicNumber)) + { + return result; + } + + // + result = GenerateSignalObjectName(signal.ticket); + + // + return result; + } + + // + // Genrate a Signal Event Object Name ... + string GenerateSignalEventObjectName( + ulong ticket // Specify Ticket + ) + { + // + string result = ""; + + // + result = GenerateSignalObjectName(ticket) + "_Event"; + + // + return result; + } + string GenerateSignalEventObjectName( + XSignal &signal // Specified Signal + ) + { + // + string result = ""; + + // + result = GenerateSignalEventObjectName(signal.ticket); + + // + return result; + } + + // + // END Signal Related ... + // + + // + // START Deals ... + // + + // + // Count Deals ... + int DealsCount( + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + int result = 0; + + // + XDeal deals[]; + GetDeals( + deals, + start, + end); + result = ArraySize(deals); + + // + return result; + } + + // + // Retrieve All Deals ... + void GetDeals( + XDeal &result[], // Hold's Result + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + CleanBuffer(result); + + // + // Select History if Start and End date provided ... + if (start > -1) + { + // + // Normalize End date ... + if (end == -1) + { + end = TimeCurrent(); + } + + // + bool isSelect = HistorySelect(start, end); + if (!isSelect) + { + return; + } + } + + // + int total = HistoryDealsTotal(); + if (total <= 0) + { + return; + } + + // + // Loop ... + for (int i = total - 1; i >= 0; i--) + { + // + // Select by Index ... + bool isSelect = mDealInfo.SelectByIndex(i); + if (!isSelect) + { + continue; + } + + // + // Check Magic ... + ulong magic = mDealInfo.Magic(); + bool isMagicSame = magic == mMagicNumber; + if (!isMagicSame) + { + continue; + } + + // + // Check Symbol ... + string symbol = mDealInfo.Symbol(); + bool isSymbolSame = symbol == mSymbol; + if (!isSymbolSame) + { + continue; + } + + // + XDeal deal = ToXDealByIndex(i); + + // + Add( + deal, + result); + } + } + + // + // Retrieve Last Deal ... + XDeal GetLastDeal() + { + // + XDeal result = {}; + + // + XDeal deals[]; + GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount <= 0) + { + return result; + } + + // + result = deals[0]; + + // + return result; + } + + // + // END Deals ... + // + + // + // START Orders ... + // + + // + // Count Orders ... + int OrdersCount( + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + int result = 0; + + // + XOrder orders[]; + GetOrders( + orders, + start, + end); + result = ArraySize(orders); + + // + return result; + } + + // + // Retrieve Orders ... + void GetOrders( + XOrder &result[], // Hold's Result + datetime start = -1, // Start Date + datetime end = -1 // End Date + ) + { + // + CleanBuffer(result); + + // + // Select History if Start and End date provided ... + if (start > -1) + { + // + // Normalize End date ... + if (end == -1) + { + end = TimeCurrent(); + } + + // + bool isSelect = HistorySelect(start, end); + if (!isSelect) + { + return; + } + } + + // + int total = HistoryOrdersTotal(); + if (total <= 0) + { + return; + } + + // + // Loop ... + for (int i = total - 1; i >= 0; i--) + { + // + // Select by Index ... + bool isSelect = mOrderInfo.SelectByIndex(i); + if (!isSelect) + { + continue; + } + + // + // Check Magic ... + ulong magic = mOrderInfo.Magic(); + bool isMagicSame = magic == mMagicNumber; + if (!isMagicSame) + { + continue; + } + + // + // Check Symbol ... + string symbol = mOrderInfo.Symbol(); + bool isSymbolSame = symbol == mSymbol; + if (!isSymbolSame) + { + continue; + } + + // + XOrder order = ToXOrderByIndex(i); + + // + Add( + order, + result); + } + } + + // + // Retrieve Last Order ... + XOrder GetLastOrder() + { + // + XOrder result = {}; + + // + XOrder orders[]; + GetOrders(orders); + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + result = orders[0]; + + // + return result; + } + + // + // END Orders ... + // + + // + // START OnTrade Handlers ... + // + + // + // Handle OnTrade Event ... + void HandleOnTradeEvent( + XOnTradeHandlerResult &result // Hold's Result + ) + { + // + if (mScanStarted) + { + ProcessOnTradeContext(result); + } + else + { + InitOnTradeContext(); + } + } + + // + // END OnTrade Handlers ... + // + + // + // Retrieve Magic Number ... + ulong GetMagicNumber() + { + return mMagicNumber; + } + + // + // all protected features ... +protected: + // + // all private features ... +private: + // + // Specified Unique Tag ... + string mTag; + + // + // which Symbol ... + string mSymbol; + + // + // using deviation, it must be in Point ... + int mSlippage; + + // + // using magic number ... + ulong mMagicNumber; + + // + // Detect Using Virtual TP or SL ... + bool mUseVirtualTPSL; + + // + // Specify Max Allowed Trades + int mMaxAllowedTrades; + + // + // Minimum Free Marging for Open Trades + double mMinAllowedFreeMarginForOpenTrades; + + // + // Minimum Balance for Open Trades + double mMinBallanceForOpenTrades; + + // + // using CTrade instance ... + XSCTrade mTrader; + + // + // Deals Info ... + CDealInfo mDealInfo; + + // + // Order Info ... + COrderInfo mOrderInfo; + + // + // An Instance Of XCAccount Info for Handling Account Related Actions ... + XCAccountInfo mAccountInfo; + + // + // using PositionInfo instance ... + CPositionInfo mPositionInfo; + + // + // Signal Manager ... + XCSignalManager mSignalManager; + + // + // START OnTrade Handlers ... + // + + // + int mDaysForRead; + + // + // set the limits of the trade history on the global scope ... + + // + // // start date for trade history in cache ... + datetime mStartDate; + + // + // end date for trade history in cache ... + datetime mEndDate; + + // + // global OnTrade counters ... + + // + // number of active orders ... + int mOrdersCount; + + // + // number of open positions ... + int mPositionsCount; + + // + // number of deals in the trade history cache ... + int mDealsCount; + + // + // number of orders in the trade history cache ... + int mHistoryOrdersCount; + + // + // flag of counter relevance ... + bool mScanStarted; + + // + // Check Statrt Date In Trade History ... + void CheckStartDateInTradeHistory() + { + // + // initial interval, if we were to start working right now .. + datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + + // + // make sure that the start limit of the trade history has not gone + // more than 1 day over the intended date ... + if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) + { + // + // correct the start date of history to be loaded in the cache ... + mStartDate = currStart; + + // + // now reload the trade history for the updated interval ... + HistorySelect(mStartDate, mEndDate); + + // + // correct the deal and order counters in history for further comparison + mHistoryOrdersCount = HistoryOrdersTotal(); + mDealsCount = HistoryDealsTotal(); + } + } + + // + // Process On Trade Context ... + void ProcessOnTradeContext( + XOnTradeHandlerResult &result // Hold's Result + ) + { + // + mEndDate = TimeCurrent(); + + // + ResetLastError(); + + // + // download trading history from the specified interval to the program cache ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + // + LogMessage("Failed to Load OnTrade Context History ..."); + + // + return; + } + + // + // get the current values ... + int currOrders = OrdersTotal(); + int currPositions = PositionsTotal(); + int currDeals = HistoryDealsTotal(); + int currHistoryOrders = HistoryOrdersTotal(); + + // + // Orders ... + // check if the number of active orders has been changed ... + if (currOrders != mOrdersCount) + { + // + // number of active orders has been changed ... + result.hasNewOrder = true; + result.newOrders = currOrders - mOrdersCount; + + // + // update the value ... + mOrdersCount = currOrders; + } + + // + // Positions ... + // changes in the number of open positions ... + if (currPositions != mPositionsCount) + { + // + // number of open positions has been changed ... + result.hasNewPosition = true; + result.newPositions = currPositions - mPositionsCount; + + // + // update the value ... + mPositionsCount = currPositions; + } + + // + // Deals ... + // changes in the number of deals in the trade history cache ... + if (currDeals != mDealsCount) + { + // + // number of deals in the trade history cache has been changed ... + result.hasNewDeal = true; + result.newDeals = currDeals - mDealsCount; + + // + // update the value ... + mDealsCount = currDeals; + } + + // + // History Orders ... + // changes in the number of history orders in the trade history cache ... + if (currHistoryOrders != mHistoryOrdersCount) + { + // + // number of history orders in the trade history cache has been changed ... + result.hasNewHistoryOrder = true; + result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; + + // + // update the value ... + mHistoryOrdersCount = currHistoryOrders; + } + + // + // checking if it is necessary to change the limits of the trade history to be requested in cache ... + CheckStartDateInTradeHistory(); + } + + // + // Reset On Trade Scanner Context ... + void ResetOnTradeContext() + { + // + mEndDate = TimeCurrent(); + mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + } + + // + // Initial Context Of Trade Scanner ... + void InitOnTradeContext() + { + // + ResetLastError(); + + // + // load history ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + // + LogMessage("Failed to Load OnTrade Context History ..."); + + // + return; + } + + // + // get the current value ... + mOrdersCount = OrdersTotal(); + mPositionsCount = PositionsTotal(); + mDealsCount = HistoryDealsTotal(); + mHistoryOrdersCount = HistoryOrdersTotal(); + + // + mScanStarted = true; + } + + // + // END OnTrade Handlers ... + // + + // + // START Signal Private ... + // + + // + // Add Or Update Signal ... + void AddOrUpdateSignalInfo( + XSignal &signal // Specified Signal + ) + { + // + bool isExists = mSignalManager.IsExists(signal); + if (isExists) + { + mSignalManager.Remove(signal.ticket); + } + + // + bool isAddOrUpdated = mSignalManager.AddOrUpdate(signal); + if (isAddOrUpdated) + { + // + color longColor = clrAqua; + color shortColor = clrFuchsia; + + // + DrawSignalShape( + signal, + longColor, + shortColor); + } + } + + // + // Retrieve Signal String From Chart Event ... + XSignal RetrieveSignal( + ulong ticket // Specify Position Ticket + ) + { + // + XSignal result = {}; + + // + if (ticket <= 0) + { + return result; + } + + // + result = mSignalManager.Get(ticket); + + // + return result; + } + void RetrieveSignal( + XSignal &signal // Specified Signal + ) + { + + // + XSignal tSignal = mSignalManager.Get(signal.ticket); + + // + // Fill signal by tSignal Data ... + // since tese properties may change in signal manipulation times ... + signal.tp = tSignal.tp; + signal.sl = tSignal.sl; + signal.riskFreeStep = tSignal.riskFreeStep; + signal.riskFreeRate = tSignal.riskFreeRate; + } + + // + // Convert Position to Signal by Index ... + XSignal PositionToSignal(int index) + { + // + XSignal result = {}; + + // + if (!mPositionInfo.SelectByIndex(index)) + { + return result; + } + + // + ulong ticket = mPositionInfo.Ticket(); + result = PositionToSignal(ticket); + + // + return result; + } + + // + // Position To Signal by Ticket ... + XSignal PositionToSignal(ulong ticket) + { + // + XSignal result = {}; + + // + if (!mPositionInfo.SelectByTicket(ticket)) + { + return result; + } + + // + bool isExists = mSignalManager.IsExists(ticket); + if (isExists) + { + result = RetrieveSignal(ticket); + } + + // + // Ticket ... + result.ticket = mPositionInfo.Ticket(); + + // + // ID ... + result.id = mPositionInfo.Identifier(); + + // + // Symbol ... + result.symbol = mPositionInfo.Symbol(); + + // + // Type ... + ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType(); + ENUM_X_SIGNAL_TYPE type = pType == POSITION_TYPE_BUY ? X_SIGNAL_LONG : X_SIGNAL_SHORT; + result.type = type; + + // + // MagicNumber ... + result.magicNumber = mPositionInfo.Magic(); + + // + // Entry/Open Price ... + result.entry = mPositionInfo.PriceOpen(); + + // + // Take Profit ... + result.tp = result.tp <= 0 && mPositionInfo.TakeProfit() > 0 + ? mPositionInfo.TakeProfit() + : result.tp; + + // + // Stop Loss ... + result.sl = result.sl <= 0 && mPositionInfo.StopLoss() > 0 + ? mPositionInfo.StopLoss() + : result.sl; + + // + // Profit ... + result.profit = mPositionInfo.Profit(); + + // + // Time ... + result.time = mPositionInfo.Time(); + + // + // Volume ... + result.volume = mPositionInfo.Volume(); + + // + // Comment ... + result.comment = mPositionInfo.Comment(); + + // + return result; + } + + // + // Converts a Deal to XDeal by Index ... + XDeal ToXDealByIndex(int index) + { + // + XDeal result = {}; + + // + bool isSelect = mDealInfo.SelectByIndex(index); + if (!isSelect) + { + return result; + } + + // + // Read Deal Ticket ... + ulong ticket = mDealInfo.Ticket(); + result = ToXDealByTicket(ticket); + + // + return result; + } + + // + // Converts a Deal to XDeal by Ticket ... + XDeal ToXDealByTicket(ulong ticket) + { + // + XDeal result = {}; + + // + mDealInfo.Ticket(ticket); + + // + result.time = mDealInfo.Time(); + result.swap = mDealInfo.Swap(); + result.magic = mDealInfo.Magic(); + result.order = mDealInfo.Order(); + result.entry = mDealInfo.Entry(); + result.price = mDealInfo.Price(); + result.ticket = mDealInfo.Ticket(); + result.symbol = mDealInfo.Symbol(); + result.type = mDealInfo.DealType(); + result.profit = mDealInfo.Profit(); + result.volume = mDealInfo.Volume(); + result.comment = mDealInfo.Comment(); + result.positionId = mDealInfo.PositionId(); + result.commission = mDealInfo.Commission(); + result.reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( + ticket, + DEAL_REASON); + + // + return result; + } + + // + // Convert an Order to XOrder by Index ... + XOrder ToXOrderByIndex(int index) + { + // + XOrder result = {}; + + // + bool isSelect = mOrderInfo.SelectByIndex(index); + if (!isSelect) + { + return result; + } + + // + ulong ticket = mOrderInfo.Ticket(); + result = ToXOrderByTicket(ticket); + + // + return result; + } + + // + // Convert an Order to XOrder by Ticket ... + XOrder ToXOrderByTicket(ulong ticket) + { + // + XOrder result = {}; + + // + bool isSelect = mOrderInfo.Select(ticket); + if (!isSelect) + { + return result; + } + + // + result.state = mOrderInfo.State(); + result.magic = mOrderInfo.Magic(); + result.ticket = mOrderInfo.Ticket(); + result.symbol = mOrderInfo.Symbol(); + result.type = mOrderInfo.OrderType(); + result.comment = mOrderInfo.Comment(); + result.stopLoss = mOrderInfo.StopLoss(); + result.typeTime = mOrderInfo.TypeTime(); + result.timeDone = mOrderInfo.TimeDone(); + result.timeSetup = mOrderInfo.TimeSetup(); + result.positionId = mOrderInfo.PositionId(); + result.priceOpen = mOrderInfo.PriceOpen(); + result.takeProfit = mOrderInfo.TakeProfit(); + result.typeFilling = mOrderInfo.TypeFilling(); + result.priceCurrent = mOrderInfo.PriceCurrent(); + result.volumeInitial = mOrderInfo.VolumeInitial(); + result.volumeCurrent = mOrderInfo.VolumeCurrent(); + result.timeExpiration = mOrderInfo.TimeExpiration(); + result.priceStopLimit = mOrderInfo.PriceStopLimit(); + result.reason = (ENUM_ORDER_REASON)HistoryOrderGetInteger( + ticket, + ORDER_REASON); + + // + return result; + } + // + // END Signal Private ... + // +}; + +// +// a Class For Guard Account ... +class XCGuard : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCGuard( + int oldAge, // Age for Old Trades + ENUM_X_GUARD_ACTIONS oldGuardAction, // Guard Action for Too Old State + double criticalFactor, // Critical DrawDown Factor based On Balance + ENUM_X_GUARD_ACTIONS criticalAction, // Guard Action for Critical State + double maxFactor, // Max DrawDown Factor based on Balance + ENUM_X_GUARD_ACTIONS maxAction, // Guard Action for Max State + int GuardStopoutFiredAfterTouches, // Guard Stopout if Max State touched + ENUM_X_GUARD_SUPPORT_METHODS supportMethod // How to Support Signals + ) + { + // + mSupportPrefix = "SPT"; + mDirectional = "SPD"; + mInDirectional = "SPIND"; + + // + mOldAge = oldAge; + mOldGuardAction = oldGuardAction; + + // + mMaxFactor = maxFactor; + mMaxAction = maxAction; + mCriticalFactor = criticalFactor; + mCriticalAction = criticalAction; + mGuardStopoutFiredAfterTouches = GuardStopoutFiredAfterTouches; + + // + mSupportMethod = supportMethod; + + // + mAccountInfo = new XCAccountInfo(); + + // + double deposit = mAccountInfo.GetInitialBalance(); + + // + if ( + maxFactor > 0 && + maxFactor < 1) + { + mMaxValue = maxFactor * deposit; + } + + // + if ( + criticalFactor > 0 && + criticalFactor < 1) + { + mCriticalValue = criticalFactor * deposit; + } + + // + Reset(); + ResetMaxDrawDownTouches(); + } + + // + // Deconstructor ... + ~XCGuard() {} + + // + // Reset List ... + void Reset() + { + // + CleanBuffer(mGuardedSignals); + CleanBuffer(mSupportedSignals); + } + + // + // Reset Consecutive Max DrawDown Touches ... + void ResetMaxDrawDownTouches() + { + mOccuredconsecutiveMaxDraDownTouches = 0; + } + + // + // Calculate and Retrieve Critical DrawDown Value ... + double GetCriticalValue() + { + // + double result = mCriticalValue; + if (mCriticalFactor <= 0) + { + return result; + } + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + + // + if (balance > deposit) + { + // + double balanceBasedCriticalDrawDown = mCriticalFactor * balance; + + // + result = MathMax( + mCriticalValue, + balanceBasedCriticalDrawDown); + } + + // + return result; + } + + // + // Calculate and Retrieve Max Allowed DrawDown Value ... + double GetMaxValue() + { + // + double result = mMaxValue; + if (mMaxValue <= 0) + { + return result; + } + + // + double deposit = mAccountInfo.GetInitialBalance(); + double balance = mAccountInfo.GetBalance(); + + // + if (balance > deposit) + { + // + double balanceBasedMaxAllwedDrawDown = mMaxFactor * balance; + + // + result = MathMax( + mMaxValue, + balanceBasedMaxAllwedDrawDown); + } + + // + return result; + } + + // + // Guard Account Protection ... + bool Guard( + XGuardHandlerResult &guardResult, // Hold's Message + string &message, // Hold's Message + XCTrade &trader, // Specified Trader + ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages + ) + { + // + message = ""; + + // + // Clean Result of Guard ... + CleanBuffer(guardResult.olds); + CleanBuffer(guardResult.maxes); + CleanBuffer(guardResult.criticals); + + // + bool result = false; + + // + // So Important is to Guard DrawDowns ... + result = GuardDrawDown( + guardResult, + message, + trader); + if (result) + { + return result; + } + + // + // Then we have to Guard Old Trades ... + result = GuardOlds( + guardResult, + message, + trader); + + // + return result; + } + + // + // Handle Guard Old Trades ... + bool GuardOlds( + XGuardHandlerResult &guardResult, // Hold's Message + string &message, // Hold's Message + XCTrade &trader, // Specified Trader + ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages + ) + { + // + // Cleanup Message ... + message = ""; + + // + // Clean Result of Guard ... + CleanBuffer(guardResult.olds); + + // + bool result = false; + + // + // Validate Args ... + if ( + mOldAge <= 0 || + mOldGuardAction == X_GUARD_DO_NOTHING) + { + return result; + } + + // + // Normalize Args ... + if (period == NULL) + { + period = _Period; + } + + // + // Retrieve Old Trades ... + XSignal oldSignals[]; + trader.GetOldSignals( + oldSignals, + mOldAge, + period); + int oldSignalsCount = ArraySize(oldSignals); + if (oldSignalsCount <= 0) + { + return result; + } + + // + result = DoGuardAction( + guardResult, + message, + trader, + mOldGuardAction, + X_GUARDED_OLD, // Specify Guard Reason + period // Specified Running Time Frame for Signal Age Calculations + ); + + // + return result; + } + + // + // Hnadle Guard DrawDown ... + bool GuardDrawDown( + XGuardHandlerResult &guardResult, // Hold's Message + string &message, // Hold's Message + XCTrade &trader // Specified Trader + ) + { + // + message = ""; + + // + // Clean Result of Guard ... + CleanBuffer(guardResult.maxes); + CleanBuffer(guardResult.criticals); + + // + bool result = false; + + // + // Check State for Guard ... + bool isCriticalGuardEnabled = mCriticalFactor > 0; + bool isMaxGuardEnabled = mMaxFactor > 0; + bool isGuardEnabled = + isMaxGuardEnabled; + + // + if (!isGuardEnabled) + { + return result; + } + + // + double maxValue = GetMaxValue(); + double criticalValue = GetCriticalValue(); + + // + double profitSums = trader.GetSignalsProfit(); + + // + bool isMaxReached = + profitSums < 0 && + isMaxGuardEnabled && + MathAbs(profitSums) >= maxValue; + bool isCriticalReached = + profitSums < 0 && + isCriticalGuardEnabled && + MathAbs(profitSums) >= criticalValue; + + // + if (!isMaxReached && !isCriticalReached) + { + // + // Reset Consecutive Max DrawDown Touches ... + ResetMaxDrawDownTouches(); + + // + return result; + } + + // + // Check For Critical Guard ... + if (isCriticalReached && !isMaxReached) + { + // + result = DoGuardAction( + guardResult, + message, + trader, + mCriticalAction, + X_GUARDED_CRITICAL); + } + else if (isMaxReached) + { + // + result = DoGuardAction( + guardResult, + message, + trader, + mMaxAction, + X_GUARDED_MAX); + + // + // Handle Guard StopOut Action ... + mOccuredconsecutiveMaxDraDownTouches++; + if ( + mMaxAction != X_GUARD_DO_NOTHING && + mMaxAction != X_GUARD_CLOSE_ALL && + mGuardStopoutFiredAfterTouches > 0 && + mOccuredconsecutiveMaxDraDownTouches >= mGuardStopoutFiredAfterTouches) + { + // + XSignal closed[]; + trader.CloseSignals(closed); + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + // + XSignal iSignal = closed[i]; + + // + AddItemToBuffer( + iSignal, + guardResult.maxes); + } + + // + message = "Guard StopOut Action Closed (" + (string)closedCount + ") Signals and Release Account ..."; + + // + guardResult.isStopOut = true; + + // + result = true; + } + } + } + + // + return result; + } + + // + // Do Signal Protections and apply Support ... + bool ProtectSignals( + XSignal &mResult[], // Hold's Result + XCTrade &trader, // Specified Trader + int numberOfItemsCheck = 30 // Number of Items to check + ) + { + // + bool result = false; + + // + CleanBuffer(mResult); + + // + // Check Supports Enabled ... + result = IsSupportEnabled(); + if (!result) + { + return result; + } + + // + // Update Supports ... + XSignal signals[]; + trader.GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount > 0) + { + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isExists = IsSupportExists(iSignal.ticket); + if (isExists) + { + UpdateSupport(iSignal); + } + } + } + + // + // Count Supporteds ... + XProtectedSignal supporteds[]; + GetAllSupports(supporteds); + int supportedCount = ArraySize(supporteds); + result = supportedCount > 0; + if (!result) + { + return result; + } + + // + // Loop through ... + for (int i = 0; i < supportedCount; i++) + { + // + XProtectedSignal iP = supporteds[i]; + + // + bool canDoDirectional = CanDoDirectionalSupport( + trader, + iP.ticket, + numberOfItemsCheck); + bool canDoInDirectional = CanDoInDirectionalSupport( + trader, + iP.ticket, + numberOfItemsCheck); + + // + if ( + !canDoDirectional && + !canDoInDirectional) + { + continue; + } + + // + // Do Directional ... + if (canDoDirectional) + { + // + // Generate Propper Signal ... + XSignal sdSignal = GenerateDirectionalSupportSignal( + iP.ticket, + trader); + + // + ENUM_EXECUTION_SIGNAL_RESULT executionResult = trader.ExecuteSignal( + sdSignal, + true, + false); + bool isExecuted = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (isExecuted) + { + // + XSignal eSignal = trader.GetSignal(sdSignal.ticket); + + // + AddItemToBuffer( + eSignal, + mResult); + } + } + // + // Do Indirectional ... + else if (canDoInDirectional) + { + // + // Generate Propper Signal ... + XSignal sindSignal = GenerateDirectionalSupportSignal( + iP.ticket, + trader); + + // + ENUM_EXECUTION_SIGNAL_RESULT executionResult = trader.ExecuteSignal( + sindSignal, + true, + false); + bool isExecuted = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (isExecuted) + { + // + XSignal eSignal = trader.GetSignal(sindSignal.ticket); + + // + AddItemToBuffer( + eSignal, + mResult); + } + } + } + + // + result = ArraySize(mResult) > 0; + + // + return result; + } + + // + // Validate State ... + bool Validate() + { + // + bool result = false; + + // + result = + mMaxFactor > 0 && + (mCriticalFactor > 0 + ? mCriticalFactor < mMaxFactor + : true); + + // + return result; + } + + // + // START Guarded Signals Functions ... + // + + // + // Add new Protecte Signal ... + bool Add( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsExists(signal.ticket); + if (isExists) + { + return result; + } + + // + XProtectedSignal item; + + // + datetime time = TimeCurrent(); + + // + item.ticket = signal.ticket; + + // + AddItemToBuffer( + time, + item.time); + + // + AddItemToBuffer( + signal.profit, + item.profit); + + // + AddItemToBuffer( + item, + mGuardedSignals); + + // + return result; + } + + // + // Get All ... + void GetAll( + XProtectedSignal &result[] // Hold's Result + ) + { + // + CopyBuffer( + mGuardedSignals, + result); + } + + // + // Get ... + XProtectedSignal Get( + ulong ticket // Specified Signal Ticket + ) + { + // + XProtectedSignal result; + + // + bool isExists = IsExists(ticket); + if (!isExists) + { + return result; + } + + // + int protectedCounts = ArraySize(mGuardedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mGuardedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = iProtected; + break; + } + } + + // + return result; + } + + // + // Remove ... + bool Remove( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + result = IsExists(ticket); + if (!result) + { + return result; + } + + // + int protectedCounts = ArraySize(mGuardedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + XProtectedSignal cleared[]; + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mGuardedSignals[i]; + + // + if (iProtected.ticket != ticket) + { + AddItemToBuffer( + iProtected, + cleared); + } + } + + // + // Update Source by Cleared ... + CopyBuffer( + cleared, + mGuardedSignals); + + // + result = true; + + // + return result; + } + + // + // Update ... + bool Update( + ulong ticket, // Specified Signal Ticket + datetime time, // Specified Last Checked time + double profit // Specified Signal Profit + // XProtectedSignal &item // Specified which object to Update + ) + { + // + bool result = false; + + // + int protectedCounts = ArraySize(mGuardedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + result = IsExists(ticket); + if (!result) + { + return result; + } + + // + // Retrieve Struct ... + XProtectedSignal item = Get(ticket); + AddItemToBuffer( + time, + item.time); + AddItemToBuffer( + profit, + item.profit); + + // + result = Remove(ticket); + if (!result) + { + return result; + } + + // + AddItemToBuffer( + item, + mGuardedSignals); + result = true; + + // + return result; + } + bool Update( + XProtectedSignal &item // Specified Protected Item + ) + { + // + bool result = false; + + // + datetime time; + result = GetLastItem( + time, + item.time); + if (!result) + { + return result; + } + + // + double profit; + result = GetLastItem( + profit, + item.profit); + if (!result) + { + return result; + } + + // + result = Update( + item.ticket, time, profit); + + // + return result; + } + bool Update( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + ulong ticket = signal.ticket; + datetime time = TimeCurrent(); + double profit = signal.profit; + + // + result = Update( + ticket, + time, + profit); + + // + return result; + } + + // + // Add Or Update ... + bool AddOrUpdate( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsExists(signal.ticket); + if (!isExists) + { + result = Add(signal); + } + else + { + result = Update(signal); + } + + // + return result; + } + + // + // Check Exists ... + bool IsExists( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + int protectedCounts = ArraySize(mGuardedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mGuardedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + + // + // Count Protecteds ... + int Count() + { + // + int result = 0; + + // + result = ArraySize(mGuardedSignals); + + // + return result; + } + + // + // END Guarded Signals Functions ... + // + + // + // START Supported Signals Functions ... + // + + // + // Check can Handle Support Signals or not ... + bool IsSupportEnabled() + { + // + bool result = false; + + // + result = + mSupportMethod != X_SUPPORT_DO_NOTHING; + + // + return result; + } + + // + // Retrieve List Of Supported Signals ... + void GetSupportSignals( + XSignal &result[], // Hold's Result ... + XCTrade &trader // Specified Trader class Instance ... + ) + { + // + CleanBuffer(result); + + // + XSignal signals[]; + trader.GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + for (int i = -0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isSupport = IsSupport(iSignal.comment); + if (isSupport) + { + AddItemToBuffer( + iSignal, + result); + } + } + } + + // + // Retrieve List Of Specific Signals Supported Signals ... + void GetSignalSupports( + XSignal &result[], // Hold's Result ... + XCTrade &trader, // Specified Trader class Instance ... + ulong ticket // Specified Signal Ticket ... + ) + { + // + CleanBuffer(result); + + // + // Validate Args ... + if (ticket <= 0) + { + return; + } + + // + // Check Signal Exists using Trader ... + XSignal parentSignal = trader.GetSignal(ticket); + bool isValid = + parentSignal.ticket > 0 && + parentSignal.ticket == ticket && + StringLen(parentSignal.comment) > 0; + if (!isValid) + { + return; + } + + // + XSignal supportSignals[]; + GetSupportSignals( + supportSignals, + trader); + int supportSignalsCount = ArraySize(supportSignals); + if (supportSignalsCount <= 0) + { + return; + } + + // + for (int i = 0; i < supportSignalsCount; i++) + { + // + XSignal iSignal = supportSignals[i]; + + // + bool isBelongsToParent = IsBelongsToParent( + ticket, + iSignal.comment); + if (isBelongsToParent) + { + AddItemToBuffer( + iSignal, + result); + } + } + } + + // + // Check Specific Support Conditions for Opening Directional Support ... + bool CanDoDirectionalSupport( + XCTrade &trader, // Specified Trader class Instance ... + ulong ticket, // Specified Signal Ticket ... + int numberOfItemsCheck = 30 // Number of Items to check ... + ) + { + // + bool result = false; + + // + // Check Supports Enabled ... + result = IsSupportEnabled(); + if (!result) + { + return result; + } + + // + // Check Support Method Allows Directional ... + result = + mSupportMethod == X_SUPPORT_FULL || + mSupportMethod == X_SUPPORT_IN_DRAWUP_DIRECTIONAL; + if (!result) + { + return result; + } + + // + // Validate Ticket ... + result = ticket > 0; + if (!result) + { + return result; + } + + // + // Check Supports Count ... + int supportedCount = ArraySize(mSupportedSignals); + result = supportedCount > 0; + if (!result) + { + return result; + } + + // + // Check Ticket Exists in Supports ... + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + // Check signal Doesn't have any Support ... + XSignal supports[]; + GetSignalSupports( + supports, + trader, + ticket); + int supportsCount = ArraySize(supports); + result = supportsCount <= 0; + if (!result) + { + return result; + } + + // + // Retrieve Support Model ... + XProtectedSignal sInfo = GetSupport(ticket); + + // + // Validate Model ... + int sTimesCount = ArraySize(sInfo.time); + int sProfitsCount = ArraySize(sInfo.profit); + result = + sInfo.ticket == ticket && + sTimesCount == sProfitsCount && + sTimesCount >= numberOfItemsCheck && + sProfitsCount >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Validate Signal Age ... + XSignal sSignal = trader.GetSignal(ticket); + int sSignalAge = trader.GetSignalAge(sSignal.time); + result = sSignalAge >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Extrat Profits ... + double lastProfits[]; + for (int i = sProfitsCount - 1; i >= (sProfitsCount - numberOfItemsCheck); i++) + { + // + double iProfit = sInfo.profit[i]; + + // + AddItemToBuffer( + iProfit, + lastProfits); + } + + // + string logMsg = ToString(lastProfits); + LogMessage("" + (string)ticket + " lastProfits: \n" + logMsg); + + // + result = false; + + // + // Now implement Business Logics ... + + // + return result; + } + + // + // Check Specific Support Conditions for Opening InDirectional Support ... + bool CanDoInDirectionalSupport( + XCTrade &trader, // Specified Trader class Instance ... + ulong ticket, // Specified Signal Ticket ... + int numberOfItemsCheck = 30 // Number of Items to check ... + ) + { + // + bool result = false; + + // + // Check Supports Enabled ... + result = IsSupportEnabled(); + if (!result) + { + return result; + } + + // + // Check Support Method Allows Directional ... + result = + mSupportMethod == X_SUPPORT_FULL || + mSupportMethod == X_SUPPORT_IN_DRAWDOWN_INDIRECTIONAL; + if (!result) + { + return result; + } + + // + // Validate Ticket ... + result = ticket > 0; + if (!result) + { + return result; + } + + // + // Check Supports Count ... + int supportedCount = ArraySize(mSupportedSignals); + result = supportedCount > 0; + if (!result) + { + return result; + } + + // + // Check Ticket Exists in Supports ... + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + // Check signal Doesn't have any Support ... + XSignal supports[]; + GetSignalSupports( + supports, + trader, + ticket); + int supportsCount = ArraySize(supports); + result = supportsCount <= 0; + if (!result) + { + return result; + } + + // + // Retrieve Support Model ... + XProtectedSignal sInfo = GetSupport(ticket); + + // + // Validate Model ... + int sTimesCount = ArraySize(sInfo.time); + int sProfitsCount = ArraySize(sInfo.profit); + result = + sInfo.ticket == ticket && + sTimesCount == sProfitsCount && + sTimesCount >= numberOfItemsCheck && + sProfitsCount >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Validate Signal Age ... + XSignal sSignal = trader.GetSignal(ticket); + int sSignalAge = trader.GetSignalAge(sSignal.time); + result = sSignalAge >= numberOfItemsCheck; + if (!result) + { + return result; + } + + // + // Extrat Profits ... + double lastProfits[]; + for (int i = sProfitsCount - 1; i >= (sProfitsCount - numberOfItemsCheck); i++) + { + // + double iProfit = sInfo.profit[i]; + + // + AddItemToBuffer( + iProfit, + lastProfits); + } + + // + string logMsg = ToString(lastProfits); + LogMessage("" + (string)ticket + " lastProfits: \n" + logMsg); + + // + result = false; + + // + // Now implement Business Logics ... + + // + return result; + } + + // + // Generate Directional Support Signal for Parent Signal ... + XSignal GenerateDirectionalSupportSignal( + ulong ticket, // Specified Parent Signal Ticket ... + XCTrade &trader // Specified Trader Class ... + ) + { + // + XSignal result = {}; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + XSignal pSignal = trader.GetSignal(ticket); + bool isValidParent = + pSignal.ticket > 0 && + pSignal.ticket == ticket && + StringLen(pSignal.comment) > 0; + if (!isValidParent) + { + return result; + } + + // + ENUM_X_SIGNAL_TYPE type = pSignal.type; + bool isLong = IsLong(type); + + // + double entry = GetEntry( + pSignal.symbol, + type); + double exit = GetExit( + pSignal.symbol, + type); + + // + double reward = PipsToPrice( + pSignal.symbol, + 6); + double risk = PipsToPrice( + pSignal.symbol, + 1); + + // + double tp = + isLong + ? entry + reward + : entry - reward; + + // + double sl = + isLong + ? exit - risk + : exit + risk; + + // + double rfStep = 2; + double rfRate = 0.5; + + // + double volume = NormalizeVolume( + pSignal.volume / 2, + pSignal.symbol, + 2); + + // + // Generate Signal using Trader Class Instance ... + result = trader.GenerateSignal( + // + type, + tp, + sl, + volume, + rfStep, + rfRate + // + ); + + // + return result; + } + + // + // Generate InDirectional Support Signal for Parent Signal ... + XSignal GenerateInDirectionalSupportSignal( + ulong ticket, // Specified Parent Signal Ticket ... + XCTrade &trader // Specified Trader Class ... + ) + { + // + XSignal result = {}; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + XSignal pSignal = trader.GetSignal(ticket); + bool isValidParent = + pSignal.ticket > 0 && + pSignal.ticket == ticket && + StringLen(pSignal.comment) > 0; + if (!isValidParent) + { + return result; + } + + // + ENUM_X_SIGNAL_TYPE type = trader + .GetIndirectionSignalType(pSignal.type); + bool isLong = IsLong(type); + + // + double entry = GetEntry( + pSignal.symbol, + type); + double exit = GetExit( + pSignal.symbol, + type); + + // + double reward = PipsToPrice( + pSignal.symbol, + 6); + double risk = PipsToPrice( + pSignal.symbol, + 1); + + // + double tp = + isLong + ? entry + reward + : entry - reward; + + // + double sl = + isLong + ? exit - risk + : exit + risk; + + // + double rfStep = 2; + double rfRate = 0.5; + + // + double volume = NormalizeVolume( + pSignal.volume / 2, + pSignal.symbol, + 2); + + // + // Generate Signal using Trader Class Instance ... + result = trader.GenerateSignal( + // + type, + tp, + sl, + volume, + rfStep, + rfRate + // + ); + + // + return result; + } + + // + // Generate Specific Signals Support Signal Comment ... + string GenerateSupportSignalComment( + ulong ticket, // Specified Parent Signal Ticket + ENUM_X_SIGNAL_TYPE type, // Specified Support Signal Type + bool isInDirectional = false // Specified Support Signal Direction + ) + { + // + string result = ""; + + // + if (ticket <= 0) + { + return result; + } + + // + string typeString = GetSignalType(type); + string directionStr = GenerateSupportDirection(isInDirectional); + + // + result = + mSupportPrefix + "(" + (string)ticket + ")_" + + X_SIGNAL_TYPE + "(" + typeString + ")_" + + directionStr; + + // + return result; + } + + // + // Get Support Direction String Representation ... + string GenerateSupportDirection( + bool isInDirectional = false // Specified Support Signal Direction + ) + { + // + string result = ""; + + // + result = + isInDirectional + ? mInDirectional + : mDirectional; + + // + return result; + } + + // + // Check an String Is Directional Or not ... + bool IsDirectionalSupport( + string comment // Specified Comment ... + ) + { + // + bool result = false; + + // + result = IsSupport(comment); + if (!result) + { + return result; + } + + // + int sPos = StringFind( + comment, + mDirectional); + result = sPos >= 0; + + // + return result; + } + + // + // Check an String Is In Directional Or not ... + bool IsInDirectionalSupport( + string comment // Specified Comment ... + ) + { + // + bool result = false; + + // + result = IsSupport(comment); + if (!result) + { + return result; + } + + // + int sPos = StringFind( + comment, + mInDirectional); + result = sPos >= 0; + + // + return result; + } + + // + // Check an String Is Support or not ... + bool IsSupport( + string comment // Specified Comment ... + ) + { + // + bool result = false; + + // + int sPos = StringFind( + comment, + mSupportPrefix); + result = sPos >= 0; + + // + return result; + } + + // + // Extract Parent of Support Signal Ticket from a comment ... + ulong ExtractParentTicket( + string comment // Specified Comment ... + ) + { + // + ulong result = 0; + + // + bool isSupport = IsSupport(comment); + if (!isSupport) + { + return result; + } + + // + // TICKET ... + string ticketStr = ExtractString( + comment, + mSupportPrefix + "(", + ")"); + if (StringLen(ticketStr) > 0) + { + result = (ulong)ticketStr; + } + + // + return result; + } + + // + // Check a Comment belongs to Support Signal or not ... + bool IsBelongsToParent( + ulong ticket, // Specified Parent Signal Ticket + string comment // Specified Support Signal Comment + ) + { + // + bool result = false; + + // + // Validate Arg ... + if (ticket <= 0) + { + return result; + } + + // + result = IsSupport(comment); + if (!result) + { + return result; + } + + // + ulong spTicket = ExtractParentTicket(comment); + result = spTicket == ticket; + + // + return result; + } + + // + // Add new Protecte Signal ... + bool AddSupport( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsSupportExists(signal.ticket); + if (isExists) + { + return result; + } + + // + XProtectedSignal item; + + // + datetime time = TimeCurrent(); + + // + item.ticket = signal.ticket; + + // + AddItemToBuffer( + time, + item.time); + + // + AddItemToBuffer( + signal.profit, + item.profit); + + // + AddItemToBuffer( + item, + mSupportedSignals); + + // + return result; + } + + // + // Get All ... + void GetAllSupports( + XProtectedSignal &result[] // Hold's Result + ) + { + // + CopyBuffer( + mSupportedSignals, + result); + } + + // + // Get ... + XProtectedSignal GetSupport( + ulong ticket // Specified Signal Ticket + ) + { + // + XProtectedSignal result; + + // + bool isExists = IsSupportExists(ticket); + if (!isExists) + { + return result; + } + + // + int protectedCounts = ArraySize(mSupportedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mSupportedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = iProtected; + break; + } + } + + // + return result; + } + + // + // Remove ... + bool RemoveSupport( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + int protectedCounts = ArraySize(mSupportedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + XProtectedSignal cleared[]; + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mSupportedSignals[i]; + + // + if (iProtected.ticket != ticket) + { + AddItemToBuffer( + iProtected, + cleared); + } + } + + // + // Update Source by Cleared ... + CopyBuffer( + cleared, + mSupportedSignals); + + // + result = true; + + // + return result; + } + + // + // Update ... + bool UpdateSupport( + ulong ticket, // Specified Signal Ticket + datetime time, // Specified Last Checked time + double profit // Specified Signal Profit + ) + { + // + bool result = false; + + // + int protectedCounts = ArraySize(mSupportedSignals); + result = protectedCounts > 0; + if (!result) + { + return result; + } + + // + result = IsSupportExists(ticket); + if (!result) + { + return result; + } + + // + // Retrieve Struct ... + XProtectedSignal item = GetSupport(ticket); + AddItemToBuffer( + time, + item.time); + AddItemToBuffer( + profit, + item.profit); + + // + result = RemoveSupport(ticket); + if (!result) + { + return result; + } + + // + AddItemToBuffer( + item, + mSupportedSignals); + result = true; + + // + return result; + } + bool UpdateSupport( + XProtectedSignal &item // Specified Protected Item + ) + { + // + bool result = false; + + // + datetime time; + result = GetLastItem( + time, + item.time); + if (!result) + { + return result; + } + + // + double profit; + result = GetLastItem( + profit, + item.profit); + if (!result) + { + return result; + } + + // + result = UpdateSupport( + item.ticket, time, profit); + + // + return result; + } + bool UpdateSupport( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + ulong ticket = signal.ticket; + datetime time = TimeCurrent(); + double profit = signal.profit; + + // + result = UpdateSupport( + ticket, + time, + profit); + + // + return result; + } + + // + // Add Or Update ... + bool AddOrUpdateSupport( + XSignal &signal // Specified Signal + ) + { + // + bool result = false; + + // + bool isExists = IsSupportExists(signal.ticket); + if (!isExists) + { + result = Add(signal); + } + else + { + result = Update(signal); + } + + // + return result; + } + + // + // Check Exists ... + bool IsSupportExists( + ulong ticket // Specified Signal Ticket + ) + { + // + bool result = false; + + // + // Validate Args ... + if (ticket <= 0) + { + return result; + } + + // + int protectedCounts = ArraySize(mSupportedSignals); + if (protectedCounts <= 0) + { + return result; + } + + // + for (int i = 0; i < protectedCounts; i++) + { + // + XProtectedSignal iProtected = mSupportedSignals[i]; + + // + if (iProtected.ticket == ticket) + { + // + result = true; + break; + } + } + + // + return result; + } + + // + // Count Protecteds ... + int CountSupports() + { + // + int result = 0; + + // + result = ArraySize(mSupportedSignals); + + // + return result; + } + + // + // END Suppoprted Signals Functions ... + // + + // + // START Getter/Setter(s) ... + // + + // + int GetOldAge() + { + return mOldAge; + } + + // + bool SetOldAge(int value) + { + // + bool result = false; + + // + result = + value > 0 && + mOldAge != value; + if (!result) + { + return result; + } + + // + mOldAge = value; + + // + return result; + } + + // + ENUM_X_GUARD_ACTIONS GetOldGuardAction() + { + return mOldGuardAction; + } + + // + bool SetOldGuardAction(ENUM_X_GUARD_ACTIONS value) + { + // + bool result = false; + + // + result = value != mOldGuardAction; + if (!result) + { + return result; + } + + // + mOldGuardAction = value; + + // + return result; + } + + // + double GetCriticalFactor() + { + return mCriticalFactor; + } + + // + bool SetCriticalFactor(bool value) + { + // + bool result = false; + + // + result = + value > 0 && + value < 1 && + mCriticalFactor != value; + if (!result) + { + return result; + } + + // + mCriticalFactor = value; + + // + double deposit = mAccountInfo.GetInitialBalance(); + mCriticalValue = deposit * value; + + // + return result; + } + + // + ENUM_X_GUARD_ACTIONS GetCriticalAction() + { + return mCriticalAction; + } + + // + bool SetCriticalAction(ENUM_X_GUARD_ACTIONS value) + { + // + bool result = false; + + // + result = + value != mCriticalAction; + if (!result) + { + return result; + } + + // + mCriticalAction = value; + + // + return result; + } + + // + double GetMaxFactor() + { + return mMaxFactor; + } + + // + bool SetMaxFactor(bool value) + { + // + bool result = false; + + // + result = + value > 0 && + value < 1 && + mMaxFactor != value; + if (!result) + { + return result; + } + + // + mMaxFactor = value; + + // + double deposit = mAccountInfo.GetInitialBalance(); + mMaxValue = deposit * value; + + // + return result; + } + + // + ENUM_X_GUARD_ACTIONS GetMaxAction() + { + return mMaxAction; + } + + // + bool SetMaxAction(ENUM_X_GUARD_ACTIONS value) + { + // + bool result = false; + + // + result = + value != mMaxAction; + if (!result) + { + return result; + } + + // + mMaxAction = value; + + // + return result; + } + + // + ENUM_X_GUARD_SUPPORT_METHODS GetSupportMethod() + { + return mSupportMethod; + } + + // + bool SetSupportMethod(ENUM_X_GUARD_SUPPORT_METHODS value) + { + // + bool result = false; + + // + result = + value != mSupportMethod; + if (!result) + { + return result; + } + + // + mSupportMethod = value; + + // + return result; + } + + // + // END Getter/Setter(s) ... + // + + // + // Generate Signal Guard Attacked Message ... + string GenerateGuardedSignalComment( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason // Specified Guard Reason + ) + { + // + string result = ""; + + // + string reasonMessage = + ( + // + reason == X_GUARDED_OLD + ? "Because of Old Issue" + : reason == X_GUARDED_CRITICAL + ? "Because Of Crtical Drawdown Isuue" + : reason == X_GUARDED_MAX + ? "Because of Max Drawdown Issue" + : "" + // + ) + + " On Profit: " + (string)signal.profit; + + // + result += "Guard Attacked (" + (string)signal.ticket + "), " + reasonMessage + " ..."; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + string mSupportPrefix; + string mDirectional; + string mInDirectional; + + // + XProtectedSignal mGuardedSignals[]; + XProtectedSignal mSupportedSignals[]; + + // + int mOldAge; + ENUM_X_GUARD_ACTIONS mOldGuardAction; + + // + // Critical DrawDown Factor based On Balance ... + double mCriticalFactor; + double mCriticalValue; + + // + // Guard Action for Critical State ... + ENUM_X_GUARD_ACTIONS mCriticalAction; + + // + // Max DrawDown Factor based on Balance ... + double mMaxFactor; + double mMaxValue; + // + // Guard Stopout if Max State touched ... + int mOccuredconsecutiveMaxDraDownTouches; + int mGuardStopoutFiredAfterTouches; + + // + // Guard Action for Max State ... + ENUM_X_GUARD_ACTIONS mMaxAction; + + // + // How to Support Signals ... + ENUM_X_GUARD_SUPPORT_METHODS mSupportMethod; + + // + // Account Info Instance ... + XCAccountInfo mAccountInfo; + + // + // Get Volume Multiplier for Specified Guard Action ... + double GetGuardActionVolumeMultiplier( + ENUM_X_GUARD_ACTIONS action = X_GUARD_DO_NOTHING // Specified Action + ) + { + // + // Partial Close Max In Drawdown Trade ... + double result = 0.0; + if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1) + { + result = 0.01; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2) + { + result = 0.02; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3) + { + result = 0.03; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5) + { + result = 0.05; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10) + { + result = 0.10; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15) + { + result = 0.15; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20) + { + result = 0.20; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25) + { + result = 0.25; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30) + { + result = 0.30; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40) + { + result = 0.40; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50) + { + result = 0.50; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60) + { + result = 0.60; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70) + { + result = 0.70; + } + else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75) + { + result = 0.75; + } + + // + return result; + } + + // + // Do Specified Guard Action ... + bool DoGuardAction( + XGuardHandlerResult &guardResult, // Hold's Result ... + string &message, // Hold's Message ... + XCTrade &trader, // Specified Trader Class ... + ENUM_X_GUARD_ACTIONS action, // Specified Which Action to Do ... + ENUM_X_GUARD_REASONS reason, // Specified Guard Reason ... + ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages ... + ) + { + // + bool result = false; + + // + message = ""; + + // + string reasonString = + reason == X_GUARDED_OLD + ? "Because of Age Issue" + : "Because of DD " + ( + // + reason == X_GUARDED_CRITICAL ? "Critical" : "Max" + // + ) + + " Issue"; + + // + // Validate Args ... + if (action == X_GUARD_DO_NOTHING) + { + // + message = "Max Allowed Drawdown Reached, but nothing Happens ..."; + + // + return result; + } + + // + // Normalize Period ... + if (period == NULL) + { + period = _Period; + } + + // + // Close All Signals ... + XSignal closed[]; + XSignal maxInDDSignal; + + // + // Handle Perform Guard Action ... + switch (action) + { + // + // Close All ... + case X_GUARD_CLOSE_ALL: + { + // + trader.CloseSignals(closed); + int closedCount = ArraySize(closed); + result = closedCount > 0; + if (!result) + { + break; + } + + // + message = "Closed (" + (string)closedCount + ") Trades by Guard, " + reasonString + " ..."; + } + break; + + // + case X_GUARD_CLOSE_MAX_IN_DD: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70: + case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75: + { + // + // Retrieve Max In Drawdown Trade ... + maxInDDSignal = trader.GetMaxInDrawdownSignal(); + bool isValid = IsValid(maxInDDSignal, trader.GetMagicNumber()) && maxInDDSignal.ticket > 0; + if (!isValid) + { + break; + } + + // + // Close Max In Drawdown Trade ... + if (action == X_GUARD_CLOSE_MAX_IN_DD) + { + // + string comment = "Signal (" + (string)maxInDDSignal.ticket + ") Closed by Guard ..."; + result = trader.Close( + maxInDDSignal.ticket, + comment); + if (result) + { + message = comment; + } + + // + break; + } + + // + int signalAge = 0; + bool canGuard = true; + bool isGuardedBefore = false; + + // + // Do Some Additional Verifications if Guard for Olds Trades ... + if (reason == X_GUARDED_OLD) + { + // + // Retrieve Signal Age ... + signalAge = trader.GetSignalAge( + maxInDDSignal, + period); + + // + // Check Guarded Before Or Not ... + isGuardedBefore = IsExists(maxInDDSignal.ticket); + if (isGuardedBefore) + { + // + // Now We Have to Check Signal Age growse required times to apply Guard Action again ... + // First Calculate Guard Grow Step ... + int ageGrowStep = mOldAge / 10; + + // + XProtectedSignal guardItem = Get(maxInDDSignal.ticket); + datetime lastGuardTime = 0; + if (GetLastItem(lastGuardTime, guardItem.time)) + { + // + int lastGuardIndex = iBarShift( + maxInDDSignal.symbol, + period, + lastGuardTime); + + // + canGuard = + MathAbs(lastGuardIndex) >= ageGrowStep; + } + } + else + { + // + // Check Signal age ... + canGuard = signalAge >= mOldAge; + } + } + + // + // Prevent Moving Forward ... + if (!canGuard) + { + // + result = false; + break; + } + + // + // Partial Close Max In Drawdown Trade ... + double volumeRate = GetGuardActionVolumeMultiplier(action); + + // + double volume = NormalizeVolume( + maxInDDSignal.volume * volumeRate, + maxInDDSignal.symbol); + + // + string commentPrefix = "Signal (" + (string)maxInDDSignal.ticket + ") Partial Closed (" + (string)volumeRate + ") by Guard"; + string comment = commentPrefix + " ..."; + + // + result = trader.ClosePartial( + maxInDDSignal.ticket, + volume, + comment); + if (result) + { + // + reasonString = + reasonString + + (reason == X_GUARDED_OLD + ? " (" + (string)signalAge + ")" + : " (" + (string)maxInDDSignal.profit + ")"); + + // + // Update Guarded Signals ... + if (isGuardedBefore) + { + // + XSignal tSignal = trader.GetSignal(maxInDDSignal.ticket); + + // + if (tSignal.ticket > 0 && tSignal.volume > 0) + { + // + // Update In Guardeds ... + Update(tSignal); + } + else + { + // + // Remove From Guardeds ... + Remove(tSignal.ticket); + } + } + else if (reason == X_GUARDED_OLD) + { + // + // Added to Guardeds ... + Add(maxInDDSignal); + } + + // + message = commentPrefix + reasonString + " ..."; + } + } + break; + + // + // Nothing ... + // Default ... + default: + message = "Max Allowed Drawdown Reached ..."; + break; + } + + // + result = StringLen(message) > 0; + if (!result) + { + return result; + } + + // + if (result) + { + // + if (reason == X_GUARDED_OLD) + { + // + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + AddItemToBuffer( + closed[i], + guardResult.olds); + } + } + + // + if (maxInDDSignal.ticket > 0) + { + AddItemToBuffer( + maxInDDSignal, + guardResult.olds); + } + } + else if (reason == X_GUARDED_CRITICAL) + { + // + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + AddItemToBuffer( + closed[i], + guardResult.criticals); + } + } + + // + if (maxInDDSignal.ticket > 0) + { + AddItemToBuffer( + maxInDDSignal, + guardResult.criticals); + } + } + else if (reason == X_GUARDED_MAX) + { + // + int closedCount = ArraySize(closed); + if (closedCount > 0) + { + // + for (int i = 0; i < closedCount; i++) + { + AddItemToBuffer( + closed[i], + guardResult.maxes); + } + } + + // + if (maxInDDSignal.ticket > 0) + { + AddItemToBuffer( + maxInDDSignal, + guardResult.maxes); + } + } + } + + // + return result; + } +}; + +// +// END Global Definitions: Variables, Properties and etc ... +// diff --git a/XEU5/Classes/x-saherelm.nn.lib.mq5 b/XEU5/Classes/x-saherelm.nn.lib.mq5 new file mode 100644 index 0000000..8fa40f5 --- /dev/null +++ b/XEU5/Classes/x-saherelm.nn.lib.mq5 @@ -0,0 +1,258 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 NN Class Library +// ---------------------------------------- +// Name: XNNClass +// Description: provides all classes for implementing +// Neural Network ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Global Definitions: Variables, Properties and etc ... +// +class XCNNBase +{ + // + // Public Definitions ... +public: + // + // Constructor ... + void XCNNBase( + int nodes = 10, // Number of Input Nodes + double starterWeight = 0.5, // start weight for each input + double coEfficient = 0.1, // COEfficient Multiplier + double upperRange = 1, // Upper Normal Range Value + double lowerRange = -1, // Lower Normal Range Value + double learningRates = 0.1 // Back Propagation Learning Rate + ) { + // + mNodes = nodes; + mUpperRange = upperRange; + mLowerRange = lowerRange; + mCoEfficient = coEfficient; + mLearningRates = learningRates; + mStarterWeight = starterWeight; + + // + ReConstructWeights(); + } + + // + // Deconstructor ... + void ~XCNNBase() {} + + // + // Protected Definitions ... + void NormalizeInputs(double &inputs[], double &result[]) + { + // + ArrayFree(result); + ArrayResize(result, 1); + + // + // Validate inputs ... + if (ArraySize(inputs) != mNodes) + { + return; + } + + // + // Prepare Result ... + ArrayResize(result, mNodes); + + // + // Calculating min and max range value ... + double minRangeValue = inputs[ArrayMinimum(inputs)]; + double maxRangeValue = inputs[ArrayMaximum(inputs)]; + + // + // Loop through Inputs nd Normalize them ... + for (int i = 0; i < mNodes; i++) + { + // + double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange; + result[i] = normalValue; + } + } + + // + // Hyperbolic Tangent Activation Function ... + double TanHActivationFunction(double weightedInputs) + { + // + double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs)); + return result; + } + + // + // Calculate Weighted Inputs ... + double CalculateWeightedInputs( + double &inputs[], + bool applyCOEfficient = true) + { + // + double result = 0; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) + { + // + result = -1; + return result; + } + + // + for (int i = 0; i < mNodes; i++) + { + result += inputs[i] * mWeights[i]; + } + + // + // Multiply if required ... + if (applyCOEfficient) + { + result *= mCoEfficient; + } + + // + return result; + } + + // + // Calculate Hidden Layers ... + virtual double CalculateHiddenLayer(double &inputs[]) + { + // + // this is Default Activation Function which used ... + // you can override this by writing your own ... + double totalWeightedInputs = CalculateWeightedInputs(inputs); + double result = TanHActivationFunction(totalWeightedInputs); + + // + return result; + } + + // + // Calculate Output Layers ... + double CalculateOutputLayer(double &inputs[]) + { + // + double result = -1; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return result; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return result; + } + + // + double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs); + + // + result = 1 * hiddenLayerResult; + + // + return result; + } + + // + // Basck Propaggation Learning ... + void BackPropagation( + double &inputs[], + double &outputs, + double targetOutput + ) { + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return; + } + + // + double error = targetOutput - outputs; + double derivative = 1 - MathPow(outputs, 2); + + // + for (int i = 0; i < mNodes; i++) { + // + double gradient = error * derivative * inputs[i]; + mWeights[i] = mLearningRates * gradient; + } + } + +protected: + // + // Private Definitions ... +private: + // + // Number of Input Nodes ... + int mNodes; + + // + // Specify Upper range of Normal Values ... + double mUpperRange; + + // + // Specify Lower range of Normal Values ... + double mLowerRange; + + // + // Starter Weight for each input node ... + double mStarterWeight; + + // + // double Input Node Weights ... + double mWeights[]; + + // + // CoEfficient is a multiplyer for weighted inputs ... + double mCoEfficient; + + // + // Back Propagation Learning Rates ... + double mLearningRates; + + // + // ReConstruct Weights ... + void ReConstructWeights() { + // + ArrayFree(mWeights); + ArrayResize(mWeights, mNodes); + + // + for (int i = 0; i< mNodes; i++) { + mWeights[i] = mStarterWeight; + } + } +} +// +// END Global Definitions: Variables, Properties and etc ... +// diff --git a/XEU5/Classes/x-saherelm.provider.lib.mq5 b/XEU5/Classes/x-saherelm.provider.lib.mq5 new file mode 100644 index 0000000..1dbdcd3 --- /dev/null +++ b/XEU5/Classes/x-saherelm.provider.lib.mq5 @@ -0,0 +1,4430 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XProvider +// Description: provides all indicators based provider 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 + +// +// START Define Enums ... +// + +// +enum ENUM_X_SIGNAL_PROVIDERS +{ + // + // XSP Expert Support Mechanism ... + XSP, + // + // XTD ... + XTD, + // + // XTAM ... + XTAM, + // + // XSI ... + XSI, + // + // XTSFI ... + XTSFI, + // + // XOBDLH ... + XOBDLH, + // + // XCHMACC ... + XCHMACC, + // + // XCHMACMN ... + XCHMAMN, + // + // XCHMACMX ... + XCHMAMX, +}; + +// +// Represent Market Conditions ... +struct XMarketConditions +{ + // + // XTM ... + bool isXTMPeak; + bool isXTMVale; + bool isXTMBullish; + bool isXTMBearish; + bool isXTMNeutural; + bool isXTMEndBullish; + bool isXTMEndBearish; + bool isXTMStartBullish; + bool isXTMStartBearish; + bool isXTMEndBullishByNeutural; + bool isXTMEndBearishByNeutural; + bool isXTMStartBullishAfterNeutural; + bool isXTMStartBearishAfterNeutural; + + // + // XAMA ... + bool isXAMAPeak; + bool isXAMAVale; + bool isXAMABullish; + bool isXAMABearish; + bool isXAMANeutural; + bool isXAMAEndBullish; + bool isXAMAEndBearish; + bool isXAMAStartBullish; + bool isXAMAStartBearish; + bool isXAMAEndBullishByNeutural; + bool isXAMAEndBearishByNeutural; + bool isXAMAStartBullishAfterNeutural; + bool isXAMAStartBearishAfterNeutural; + + // + // XLH ... + bool isXLHHHIncreased; + bool isXLHHHDecreased; + bool isXLHLLIncreased; + bool isXLHLLDecreased; + bool isXLHLowAttachedLL; + bool isXLHHighAttachedHH; + bool isXLHHHSameInLength; + bool isXLHLLSameInLength; + bool isXLHPriceOverSignal; + bool isXLHPriceUnderSignal; + bool isXLHPriceInSignalRange; + bool isXLHPriceCrossedOverSignal; + bool isXLHPriceCrossedUnderSignal; + + // + // XTD ... + bool isXTDSignalPeak; + bool isXTDSignalVale; + bool isXTDBullishPeak; + bool isXTDBullishVale; + bool isXTDBearishPeak; + bool isXTDBearishVale; + bool isXTDBullOverBear; + bool isXTDBullUnderBear; + bool isXTDSignalOverBear; + bool isXTDSignalUnderBear; + bool isXTDBullCrossedOverBear; + bool isXTDBullCrossedUnderBear; + bool isXTDSignalCrossedOverBear; + bool isXTDSignalCrossedUnderBear; + + // + // XFI ... + bool isXFIPeak; + bool isXFIVale; + bool isXFICrossedOverZero; + bool isXFIOverZero; + bool isXFICrossedUnderZero; + bool isXFIUnderZero; + + // + // XTS ... + bool isXTSAllSame; + bool isXTSCurrentMin; + bool isXTSCurrentMax; + bool isXTSCurrentOverFarest; + bool isXTSCurrentOverNearest; + bool isXTSCurrentOverMediest; + bool isXTSCurrentUnderFarest; + bool isXTSCurrentUnderNearest; + bool isXTSCurrentUnderMediest; + bool isXTSCurrentCrossedOverFarest; + bool isXTSCurrentCrossedOverNearest; + bool isXTSCurrentCrossedOverMediest; + bool isXTSCurrentCrossedUnderFarest; + bool isXTSCurrentCrossedUnderNearest; + bool isXTSCurrentCrossedUnderMediest; + + // + // XRSI ... + bool isXRSIPeak; + bool isXRSIVale; + bool isXRSICrossedOverLongExit; + bool isXRSICrossedOverLongEntry; + bool isXRSICrossedUnderShortExit; + bool isXRSICrossedUnderShortEntry; + + // + // XOBD ... + bool isXOBDSwingLow; + bool isXOBDSwingHigh; + + // + // XCHLH ... + // + bool isXCHLHSameHHs; + bool isXCHLHSameLLs; + // + bool isXCHLHSCMCHHSame; + bool isXCHLHSCMCLLSame; + // + bool isXCHLHSCLCHHSame; + bool isXCHLHSCLCLLSame; + // + bool isXCHLHMCLCHHSame; + bool isXCHLHMCLCLLSame; + // + bool isXCHLHMCOnTopOfLC; + bool isXCHLHMCInBottomOfLC; + + // + // XCHMA ... + // + bool isXCHMASCOverMax; + bool isXCHMASCOverMin; + bool isXCHMASCUnderMax; + bool isXCHMASCUnderMin; + // + bool isXCHMASCCrossedOverMax; + bool isXCHMASCCrossedUnderMax; + bool isXCHMASCCrossedOverMin; + bool isXCHMASCCrossedUnderMin; + // + bool isXCHMASCPeak; + bool isXCHMASCVale; + bool isXCHMASCTrendsUp; + bool isXCHMASCTrendsDown; + bool isXCHMASCFastOverSlow; + bool isXCHMASCFastUnderSlow; + bool isXCHMASCFastCrossedOverSlow; + bool isXCHMASCFastCrossedUnderSlow; + // + bool isXCHMAMCPeak; + bool isXCHMAMCVale; + bool isXCHMAMCTrendsUp; + bool isXCHMAMCTrendsDown; + bool isXCHMAMCFastOverSlow; + bool isXCHMAMCFastUnderSlow; + bool isXCHMAMCFastCrossedOverSlow; + bool isXCHMAMCFastCrossedUnderSlow; + // + bool isXCHMALCPeak; + bool isXCHMALCVale; + bool isXCHMALCTrendsUp; + bool isXCHMALCTrendsDown; + bool isXCHMALCFastOverSlow; + bool isXCHMALCFastUnderSlow; + bool isXCHMALCFastCrossedOverSlow; + bool isXCHMALCFastCrossedUnderSlow; +}; + +// +// END Define Enums ... +// + +// +// START Includes Requirements ... +// + +// +// Includes Classes ... +#include "x-saherelm.class.lib.mq5" + +// +// Includes all Indicator's Helpers ... +#include "../Helpers/x-saherelm.xlh.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xtm.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xama.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xobd.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xts.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5" + +// +// END Includes Requirements ... +// + +// +class XCProvider : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCProvider( + // + // Common Requirements ... + string xSymbol, // Which Symbol is Used + ENUM_TIMEFRAMES xPeriod, // Which Period is Used + // + // Signallers Requirements ... + // + // XTD ... + bool xTDEnableSignaller, // Enable Signaller + bool xTDAllowLongSignals, // Allow Long Signals + bool xTDAllowShortSignals, // Allow Short Signals + // + // XTAM ... + bool xTAMEnableSignaller, // Enable Signaller + bool xTAMAllowLongSignals, // Allow Long Signals + bool xTAMAllowShortSignals, // Allow Short Signals + // + // XSI ... + bool xSIEnableSignaller, // Enable Signaller + bool xSIAllowLongSignals, // Allow Long Signals + bool xSIAllowShortSignals, // Allow Short Signals + // + // XTSFI ... + bool xTSFIEnableSignaller, // Enable Signaller + bool xTSFIAllowLongSignals, // Allow Long Signals + bool xTSFIAllowShortSignals, // Allow Short Signals + // + // XOBDLH ... + bool xOBDLHEnableSignaller, // Enable Signaller + bool xOBDLHAllowLongSignals, // Allow Long Signals + bool xOBDLHAllowShortSignals, // Allow Short Signals + // + // XCHMACC ... + bool xCHMACCEnableSignaller, // Enable Signaller + bool xCHMACCAllowLongSignals, // Allow Long Signals + bool xCHMACCAllowShortSignals, // Allow Short Signals + // + // XCHMAMX ... + bool xCHMACMXEnableSignaller, // Enable Signaller + bool xCHMACMXAllowLongSignals, // Allow Long Signals + bool xCHMACMXAllowShortSignals, // Allow Short Signals + // + // XCHMAMN ... + bool xCHMACMNEnableSignaller, // Enable Signaller + bool xCHMACMNAllowLongSignals, // Allow Long Signals + bool xCHMACMNAllowShortSignals // Allow Short Signals + // + ) + { + // + // XTD ... + mXTDEnableSignaller = xTDEnableSignaller; + mXTDAllowLongSignals = xTDAllowLongSignals; + mXTDAllowShortSignals = xTDAllowShortSignals; + + // + // XTAM ... + mXTAMEnableSignaller = xTAMEnableSignaller; + mXTAMAllowLongSignals = xTAMAllowLongSignals; + mXTAMAllowShortSignals = xTAMAllowShortSignals; + + // + // XSI ... + mXSIEnableSignaller = xSIEnableSignaller; + mXSIAllowLongSignals = xSIAllowLongSignals; + mXSIAllowShortSignals = xSIAllowShortSignals; + + // + // XTSFI ... + mXTSFIEnableSignaller = xTSFIEnableSignaller; + mXTSFIAllowLongSignals = xTSFIAllowLongSignals; + mXTSFIAllowShortSignals = xTSFIAllowShortSignals; + + // + // XOBDLH ... + mXOBDLHEnableSignaller = xOBDLHEnableSignaller; + mXOBDLHAllowLongSignals = xOBDLHAllowLongSignals; + mXOBDLHAllowShortSignals = xOBDLHAllowShortSignals; + + // + // XCHMACC ... + mXCHMACCEnableSignaller = xCHMACCEnableSignaller; + mXCHMACCAllowLongSignals = xCHMACCAllowLongSignals; + mXCHMACCAllowShortSignals = xCHMACCAllowShortSignals; + + // + // XCHMAMX ... + mXCHMAMXEnableSignaller = xCHMACMXEnableSignaller; + mXCHMAMXAllowLongSignals = xCHMACMXAllowLongSignals; + mXCHMAMXAllowShortSignals = xCHMACMXAllowShortSignals; + + // + // XCHMAMN ... + mXCHMAMNEnableSignaller = xCHMACMNEnableSignaller; + mXCHMAMNAllowLongSignals = xCHMACMNAllowLongSignals; + mXCHMAMNAllowShortSignals = xCHMACMNAllowShortSignals; + } + + // + // Deconstructor ... + ~XCProvider() {} + + // + // START Common Functions ... + // + + // + // Read All Globally Required Conditions ... + void ReadConditions() + { + // + ClearConditions(); + + // + mXConditions = GenerateMarketConditions(1); + } + + // + // Cleanup Conditions ... + void ClearConditions() + { + // + XMarketConditions mConditions = {}; + + // + mXConditions = mConditions; + } + + // + // Generate Merket Conditions for Specified Bar Index ... + XMarketConditions GenerateMarketConditions( + int bar_index = 1 // Specified Bar Index ... + ) + { + // + XMarketConditions mConditions = {}; + + // + // XTM ... + mConditions.isXTMPeak = XTMIsPeak(bar_index); + mConditions.isXTMVale = XTMIsVale(bar_index); + mConditions.isXTMBullish = XTMIsBullish(bar_index); + mConditions.isXTMBearish = XTMIsBearish(bar_index); + mConditions.isXTMNeutural = XTMIsNeutural(bar_index); + mConditions.isXTMEndBullish = XTMIsEndBullish(bar_index); + mConditions.isXTMEndBearish = XTMIsEndBearish(bar_index); + mConditions.isXTMStartBullish = XTMIsStartBullish(bar_index); + mConditions.isXTMStartBearish = XTMIsStartBearish(bar_index); + mConditions.isXTMEndBullishByNeutural = XTMIsEndBullishByNeutural(bar_index); + mConditions.isXTMEndBearishByNeutural = XTMIsEndBearishByNeutural(bar_index); + mConditions.isXTMStartBullishAfterNeutural = XTMIsStartBullishAfterNeutural(bar_index); + mConditions.isXTMStartBearishAfterNeutural = XTMIsStartBearishAfterNeutural(bar_index); + + // + // XAMA ... + mConditions.isXAMAPeak = XAMAIsPeak(bar_index); + mConditions.isXAMAVale = XAMAIsVale(bar_index); + mConditions.isXAMABullish = XAMAIsBullish(bar_index); + mConditions.isXAMABearish = XAMAIsBearish(bar_index); + mConditions.isXAMANeutural = XAMAIsNeutural(bar_index); + mConditions.isXAMAEndBullish = XAMAIsEndBullish(bar_index); + mConditions.isXAMAEndBearish = XAMAIsEndBearish(bar_index); + mConditions.isXAMAStartBullish = XAMAIsStartBullish(bar_index); + mConditions.isXAMAStartBearish = XAMAIsStartBearish(bar_index); + mConditions.isXAMAEndBullishByNeutural = XAMAIsEndBullishByNeutural(bar_index); + mConditions.isXAMAEndBearishByNeutural = XAMAIsEndBearishByNeutural(bar_index); + mConditions.isXAMAStartBullishAfterNeutural = XAMAIsStartBullishAfterNeutural(bar_index); + mConditions.isXAMAStartBearishAfterNeutural = XAMAIsStartBearishAfterNeutural(bar_index); + + // + // XLH ... + mConditions.isXLHHHIncreased = XLHIsHHIncreased(bar_index); + mConditions.isXLHHHDecreased = XLHIsHHDecreased(bar_index); + mConditions.isXLHLLIncreased = XLHIsLLIncreased(bar_index); + mConditions.isXLHLLDecreased = XLHIsLLDecreased(bar_index); + mConditions.isXLHLowAttachedLL = XLHIsLowAttachedLL(bar_index); + mConditions.isXLHHighAttachedHH = XLHIsHighAttachedHH(bar_index); + mConditions.isXLHHHSameInLength = XLHIsHHSameInLength(bar_index); + mConditions.isXLHLLSameInLength = XLHIsLLSameInLength(bar_index); + mConditions.isXLHPriceOverSignal = XLHIsPriceOverSignal(bar_index); + mConditions.isXLHPriceUnderSignal = XLHIsPriceUnderSignal(bar_index); + mConditions.isXLHPriceInSignalRange = XLHIsPriceInSignalRange(bar_index); + mConditions.isXLHPriceCrossedOverSignal = XLHIsPriceCrossedOverSignal(bar_index); + mConditions.isXLHPriceCrossedUnderSignal = XLHIsPriceCrossedUnderSignal(bar_index); + + // + // XTD ... + mConditions.isXTDSignalPeak = XTDIsSignalPeak(bar_index); + mConditions.isXTDSignalVale = XTDIsSignalVale(bar_index); + mConditions.isXTDBullishPeak = XTDIsBullishPeak(bar_index); + mConditions.isXTDBullishVale = XTDIsBullishVale(bar_index); + mConditions.isXTDBearishPeak = XTDIsBearishPeak(bar_index); + mConditions.isXTDBearishVale = XTDIsBearishVale(bar_index); + mConditions.isXTDBullOverBear = XTDIsBullOverBear(bar_index); + mConditions.isXTDBullUnderBear = XTDIsBullUnderBear(bar_index); + mConditions.isXTDSignalOverBear = XTDIsSignalOverBear(bar_index); + mConditions.isXTDSignalUnderBear = XTDIsSignalUnderBear(bar_index); + mConditions.isXTDBullCrossedOverBear = XTDIsBullCrossedOverBear(bar_index); + mConditions.isXTDBullCrossedUnderBear = XTDIsBullCrossedUnderBear(bar_index); + mConditions.isXTDSignalCrossedOverBear = XTDIsSignalCrossedOverBear(bar_index); + mConditions.isXTDSignalCrossedUnderBear = XTDIsSignalCrossedUnderBear(bar_index); + + // + // XFI ... + mConditions.isXFIPeak = XFIIsPeak(bar_index); + mConditions.isXFIVale = XFIIsVale(bar_index); + mConditions.isXFIOverZero = XFIIsOverZero(bar_index); + mConditions.isXFIUnderZero = XFIIsUnderZero(bar_index); + mConditions.isXFICrossedOverZero = XFIIsCrossedOverZero(bar_index); + mConditions.isXFICrossedUnderZero = XFIIsCrossedUnderZero(bar_index); + + // + // XTS ... + mConditions.isXTSAllSame = XTSIsAllSame(bar_index); + mConditions.isXTSCurrentMin = XTSIsCurrentMin(bar_index); + mConditions.isXTSCurrentMax = XTSIsCurrentMax(bar_index); + mConditions.isXTSCurrentOverFarest = XTSIsCurrentOverFarest(bar_index); + mConditions.isXTSCurrentOverNearest = XTSIsCurrentOverNearest(bar_index); + mConditions.isXTSCurrentOverMediest = XTSIsCurrentOverMediest(bar_index); + mConditions.isXTSCurrentUnderFarest = XTSIsCurrentUnderFarest(bar_index); + mConditions.isXTSCurrentUnderNearest = XTSIsCurrentUnderNearest(bar_index); + mConditions.isXTSCurrentUnderMediest = XTSIsCurrentUnderMediest(bar_index); + mConditions.isXTSCurrentCrossedOverFarest = XTSIsCurrentCrossedOverFarest(bar_index); + mConditions.isXTSCurrentCrossedOverNearest = XTSIsCurrentCrossedOverNearest(bar_index); + mConditions.isXTSCurrentCrossedOverMediest = XTSIsCurrentCrossedOverMediest(bar_index); + mConditions.isXTSCurrentCrossedUnderFarest = XTSIsCurrentCrossedUnderFarest(bar_index); + mConditions.isXTSCurrentCrossedUnderNearest = XTSIsCurrentCrossedUnderNearest(bar_index); + mConditions.isXTSCurrentCrossedUnderMediest = XTSIsCurrentCrossedUnderMediest(bar_index); + + // + // XRSI ... + mConditions.isXRSIPeak = XRSIIsPeak(bar_index); + mConditions.isXRSIVale = XRSIIsVale(bar_index); + mConditions.isXRSICrossedOverLongExit = XRSIIsCrossedOverLongExit(bar_index); + mConditions.isXRSICrossedOverLongEntry = XRSIIsCrossedOverLongEntry(bar_index); + mConditions.isXRSICrossedUnderShortExit = XRSIIsCrossedUnderShortExit(bar_index); + mConditions.isXRSICrossedUnderShortEntry = XRSIIsCrossedUnderShortEntry(bar_index); + + // + // XOBD ... + mConditions.isXOBDSwingLow = XOBDIsSwingLow(bar_index); + mConditions.isXOBDSwingHigh = XOBDIsSwingHigh(bar_index); + + // + // XCHLH ... + // + mConditions.isXCHLHSameHHs = XCHLHIsSameHHs(bar_index); + mConditions.isXCHLHSameLLs = XCHLHIsSameLLs(bar_index); + // + mConditions.isXCHLHSCMCHHSame = XCHLHIsMCSCHasSameHH(bar_index); + mConditions.isXCHLHSCMCLLSame = XCHLHIsMCSCHasSameLL(bar_index); + // + mConditions.isXCHLHSCLCHHSame = XCHLHIsLCSCHasSameHH(bar_index); + mConditions.isXCHLHSCLCLLSame = XCHLHIsLCSCHasSameLL(bar_index); + // + mConditions.isXCHLHMCLCHHSame = XCHLHIsLCMCHasSameHH(bar_index); + mConditions.isXCHLHMCLCLLSame = XCHLHIsLCMCHasSameLL(bar_index); + // + mConditions.isXCHLHMCOnTopOfLC = XCHLHIsMCOnTopOfLC(bar_index); + mConditions.isXCHLHMCInBottomOfLC = XCHLHIsMCInBottomOfLC(bar_index); + + // + // XCHMA ... + // + mConditions.isXCHMASCOverMax = XCHMAIsSCOverMax(bar_index); + mConditions.isXCHMASCOverMin = XCHMAIsSCOverMin(bar_index); + mConditions.isXCHMASCUnderMax = XCHMAIsSCUnderMax(bar_index); + mConditions.isXCHMASCUnderMin = XCHMAIsSCUnderMin(bar_index); + // + mConditions.isXCHMASCCrossedOverMax = XCHMAIsSCCrossedOverMax(bar_index); + mConditions.isXCHMASCCrossedUnderMax = XCHMAIsSCCrossedUnderMax(bar_index); + mConditions.isXCHMASCCrossedOverMin = XCHMAIsSCCrossedOverMin(bar_index); + mConditions.isXCHMASCCrossedUnderMin = XCHMAIsSCCrossedUnderMin(bar_index); + // + mConditions.isXCHMASCPeak = XCHMAIsSCPeak(bar_index); + mConditions.isXCHMASCVale = XCHMAIsSCVale(bar_index); + mConditions.isXCHMASCTrendsUp = XCHMAIsSCTrendsUp(bar_index); + mConditions.isXCHMASCTrendsDown = XCHMAIsSCTrendsDown(bar_index); + mConditions.isXCHMASCFastOverSlow = XCHMAIsSCFastOverSlow(bar_index); + mConditions.isXCHMASCFastUnderSlow = XCHMAIsSCFastUnderSlow(bar_index); + mConditions.isXCHMASCFastCrossedOverSlow = XCHMAIsSCFastCrossedOverSlow(bar_index); + mConditions.isXCHMASCFastCrossedUnderSlow = XCHMAIsSCFastCrossedUnderSlow(bar_index); + // + mConditions.isXCHMAMCPeak = XCHMAIsMCPeak(bar_index); + mConditions.isXCHMAMCVale = XCHMAIsMCVale(bar_index); + mConditions.isXCHMAMCTrendsUp = XCHMAIsMCTrendsUp(bar_index); + mConditions.isXCHMAMCTrendsDown = XCHMAIsMCTrendsDown(bar_index); + mConditions.isXCHMAMCFastOverSlow = XCHMAIsMCFastOverSlow(bar_index); + mConditions.isXCHMAMCFastUnderSlow = XCHMAIsMCFastUnderSlow(bar_index); + mConditions.isXCHMAMCFastCrossedOverSlow = XCHMAIsMCFastCrossedOverSlow(bar_index); + mConditions.isXCHMAMCFastCrossedUnderSlow = XCHMAIsMCFastCrossedUnderSlow(bar_index); + // + mConditions.isXCHMALCPeak = XCHMAIsLCPeak(bar_index); + mConditions.isXCHMALCVale = XCHMAIsLCVale(bar_index); + mConditions.isXCHMALCTrendsUp = XCHMAIsLCTrendsUp(bar_index); + mConditions.isXCHMALCTrendsDown = XCHMAIsLCTrendsDown(bar_index); + mConditions.isXCHMALCFastOverSlow = XCHMAIsLCFastOverSlow(bar_index); + mConditions.isXCHMALCFastUnderSlow = XCHMAIsLCFastUnderSlow(bar_index); + mConditions.isXCHMALCFastCrossedOverSlow = XCHMAIsLCFastCrossedOverSlow(bar_index); + mConditions.isXCHMALCFastCrossedUnderSlow = XCHMAIsLCFastCrossedUnderSlow(bar_index); + + // + return mConditions; + } + + // + // Access Last Readed Market Conditions ... + XMarketConditions GetLastMarketCondition() + { + // + XMarketConditions result = {}; + + // + result = mXConditions; + + // + return result; + } + + // + // Check Market Conditions is Ready for Long Signals or not ... + bool IsReadyForLong( + bool checkXCHMAMin = true, // Force Check XCHMA Min State + bool checkXCHMAMax = true, // Force Check XCHMA Max State + bool checkXCHMACycles = true, // Force Check XCHMA Cycles State + bool checkXCHMAPeaks = true, // Force Check XCHMA Peaks State + bool checkXCHMATrendPowers = true, // Force Check XCHMA Trend Powers + bool checkXOBD = true, // Force Check XOBD State + bool checkXTS = true // Force Check XTS State + ) + { + // + bool result = true; + + // + if (checkXCHMAMin) + { + // + result = + // + // XCHMA MIN ... + !( + // + (mXConditions.isXCHMASCOverMin || + mXConditions.isXCHMASCCrossedOverMin) && + (mXConditions.isXCHMASCUnderMin || + mXConditions.isXCHMASCCrossedUnderMin) + // + ); + } + + // + if (checkXCHMAMax && result) + { + // + result = + // + // XCHMA MAX ... + !( + // + (mXConditions.isXCHMASCOverMax || + mXConditions.isXCHMASCCrossedOverMax) && + (mXConditions.isXCHMASCUnderMax || + mXConditions.isXCHMASCCrossedUnderMax) + // + ) + // + ; + } + + // + if (checkXCHMACycles && result) + { + // + result = + // + // Check XCHMA Trend Bullish ... + ( + // + // All Cycles Bullish ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastOverSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastOverSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastOverSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + || + // + // Two Cycle Fully Bullish ... + ( + // + // SC and MC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastOverSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastOverSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + ) + // + || + // + // SC and LC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastOverSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastOverSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + || + // + // MC and LC ... + ( + // + // MC ... + (mXConditions.isXCHMAMCFastOverSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastOverSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMAPeaks && result) + { + // + result = + // + // XCHMA Check Peaks ... + !( + // + // All Cycles Peak ... + (mXConditions.isXCHMASCPeak && + mXConditions.isXCHMAMCPeak && + mXConditions.isXCHMALCPeak) + // + || + // + ( + // + // SC MC ... + (mXConditions.isXCHMASCPeak && + mXConditions.isXCHMAMCPeak) + // + || + // + // SC LC ... + (mXConditions.isXCHMASCPeak && + mXConditions.isXCHMALCPeak) + // + || + // + // MC LC ... + (mXConditions.isXCHMAMCPeak && + mXConditions.isXCHMALCPeak) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMATrendPowers && result) + { + // + result = + // + // XCHMA Check Trends Power ... + !( + // + // All Trends Down ... + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + // Twisted pairs ... + ( + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown) + // + || + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + (mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ; + } + + // + if (checkXOBD && result) + { + // + result = + // + // XOBD Check Swings ... + !mXConditions.isXOBDSwingLow + // + ; + } + + // + if (checkXTS && result) + { + result = + // + // XTS Check ... + !( + // + mXConditions.isXTSCurrentMin && + // + ( + // + // All Under ... + ( + (mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) && + (mXConditions.isXTSCurrentUnderMediest || + mXConditions.isXTSCurrentCrossedUnderMediest) && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest)) + // + || + // + // Pairs ... + ( + // + ((mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) && + (mXConditions.isXTSCurrentUnderMediest || + mXConditions.isXTSCurrentCrossedUnderMediest)) + // + || + // + ((mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest)) + // + || + // + ((mXConditions.isXTSCurrentUnderMediest || + mXConditions.isXTSCurrentCrossedUnderMediest) && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest)) + // + ) + // + ) + // + ) + // + ; + } + + // + return result; + } + + // + // Check Market Conditions is Ready for Short Signals or not ... + bool IsReadyForShort( + bool checkXCHMAMin = true, // Force Check XCHMA Min State + bool checkXCHMAMax = true, // Force Check XCHMA Max State + bool checkXCHMACycles = true, // Force Check XCHMA Cycles State + bool checkXCHMAVales = true, // Force Check XCHMA Vales State + bool checkXCHMATrendPowers = true, // Force Check XCHMA Trend Powers + bool checkXOBD = true, // Force Check XOBD State + bool checkXTS = true // Force Check XTS State + ) + { + // + bool result = true; + + // + if (checkXCHMAMin) + { + // + result = + // + // XCHMA MIN ... + !( + // + (mXConditions.isXCHMASCOverMin || + mXConditions.isXCHMASCCrossedOverMin) && + (mXConditions.isXCHMASCUnderMin || + mXConditions.isXCHMASCCrossedUnderMin) + // + ); + } + + // + if (checkXCHMAMax && result) + { + // + result = + // + // XCHMA MAX ... + !( + // + (mXConditions.isXCHMASCOverMax || + mXConditions.isXCHMASCCrossedOverMax) && + (mXConditions.isXCHMASCUnderMax || + mXConditions.isXCHMASCCrossedUnderMax) + // + ) + // + ; + } + + // + if (checkXCHMACycles && result) + { + // + result = + // + // Check XCHMA Trend Bullish ... + ( + // + // All Cycles Bullish ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastUnderSlow || + mXConditions.isXCHMASCFastCrossedUnderSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastUnderSlow || + mXConditions.isXCHMAMCFastCrossedUnderSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastUnderSlow || + mXConditions.isXCHMALCFastCrossedUnderSlow) + // + ) + // + || + // + // Two Cycle Fully Bullish ... + ( + // + // SC and MC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastUnderSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastUnderSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + ) + // + || + // + // SC and LC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastUnderSlow || + mXConditions.isXCHMASCFastCrossedUnderSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastUnderSlow || + mXConditions.isXCHMALCFastCrossedUnderSlow) + // + ) + // + || + // + // MC and LC ... + ( + // + // MC ... + (mXConditions.isXCHMAMCFastUnderSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastUnderSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMAVales && result) + { + // + result = + // + // XCHMA Check Vales ... + !( + // + // All Cycles Vale ... + (mXConditions.isXCHMASCVale && + mXConditions.isXCHMAMCVale && + mXConditions.isXCHMALCVale) + // + || + // + ( + // + // SC MC ... + (mXConditions.isXCHMASCVale && + mXConditions.isXCHMAMCVale) + // + || + // + // SC LC ... + (mXConditions.isXCHMASCVale && + mXConditions.isXCHMALCVale) + // + || + // + // MC LC ... + (mXConditions.isXCHMAMCVale && + mXConditions.isXCHMALCVale) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMATrendPowers && result) + { + // + result = + // + // XCHMA Check Trends Power ... + !( + // + // All Trends Down ... + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + // Twisted pairs ... + ( + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown) + // + || + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + (mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ; + } + + // + if (checkXOBD && result) + { + // + result = + // + // XOBD Check Swings ... + !mXConditions.isXOBDSwingHigh + // + ; + } + + // + if (checkXTS && result) + { + // + result = + // + // XTS Check ... + !( + // + mXConditions.isXTSCurrentMax && + // + ( + // + // All Over ... + ( + (mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) && + (mXConditions.isXTSCurrentOverMediest || + mXConditions.isXTSCurrentCrossedOverMediest) && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest)) + // + || + // + // Pairs ... + ( + // + ((mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) && + (mXConditions.isXTSCurrentOverMediest || + mXConditions.isXTSCurrentCrossedOverMediest)) + // + || + // + ((mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest)) + // + || + // + ((mXConditions.isXTSCurrentOverMediest || + mXConditions.isXTSCurrentCrossedOverMediest) && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest)) + // + ) + // + ) + // + ) + // + ; + } + + // + return result; + } + + // + // Converts Market Conditions to Specific String Representation ... + string GenerateConditionsString( + XMarketConditions &condition, // Specify Conditiond + string separator = "\n", // Specify Separator + bool ignoreFalses = true // Ignore False Conditions + ) + { + // + XMarketConditions mConditions = {}; + + // + mConditions = condition; + + // + string result = "\n"; + + // + // XOBD ... + result += + "| XOBD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXOBDSwingLow)) + { + result += "isXOBDSwingLow: " + (string)mConditions.isXOBDSwingLow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXOBDSwingHigh)) + { + result += "isXOBDSwingHigh: " + (string)mConditions.isXOBDSwingHigh + separator; + } + + // + // Separator ... + result += separator; + + // + // XTM ... + result += + "| XTM |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMPeak)) + { + result += "isXTMPeak: " + (string)mConditions.isXTMPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMVale)) + { + result += "isXTMVale: " + (string)mConditions.isXTMVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBullish)) + { + result += "isXTMStartBullish: " + (string)mConditions.isXTMStartBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBullishAfterNeutural)) + { + result += "isXTMStartBullishAfterNeutural: " + (string)mConditions.isXTMStartBullishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMBullish)) + { + result += "isXTMBullish: " + (string)mConditions.isXTMBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBullish)) + { + result += "isXTMEndBullish: " + (string)mConditions.isXTMEndBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBullishByNeutural)) + { + result += "isXTMEndBullishByNeutural: " + (string)mConditions.isXTMEndBullishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBearish)) + { + result += "isXTMStartBearish: " + (string)mConditions.isXTMStartBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBearishAfterNeutural)) + { + result += "isXTMStartBearishAfterNeutural: " + (string)mConditions.isXTMStartBearishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMBearish)) + { + result += "isXTMBearish: " + (string)mConditions.isXTMBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBearish)) + { + result += "isXTMEndBearish: " + (string)mConditions.isXTMEndBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBearishByNeutural)) + { + result += "isXTMEndBearishByNeutural: " + (string)mConditions.isXTMEndBearishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMNeutural)) + { + result += "isXTMNeutural: " + (string)mConditions.isXTMNeutural + separator; + } + + // + // Separator ... + result += separator; + + // + // XAMA ... + result += + "| XAMA |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAPeak)) + { + result += "isXAMAPeak: " + (string)mConditions.isXAMAPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAVale)) + { + result += "isXAMAVale: " + (string)mConditions.isXAMAVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBullish)) + { + result += "isXAMAStartBullish: " + (string)mConditions.isXAMAStartBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBullishAfterNeutural)) + { + result += "isXAMAStartBullishAfterNeutural: " + (string)mConditions.isXAMAStartBullishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMABullish)) + { + result += "isXAMABullish: " + (string)mConditions.isXAMABullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBullish)) + { + result += "isXAMAEndBullish: " + (string)mConditions.isXAMAEndBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBullishByNeutural)) + { + result += "isXAMAEndBullishByNeutural: " + (string)mConditions.isXAMAEndBullishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBearish)) + { + result += "isXAMAStartBearish: " + (string)mConditions.isXAMAStartBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBearishAfterNeutural)) + { + result += "isXAMAStartBearishAfterNeutural: " + (string)mConditions.isXAMAStartBearishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMABearish)) + { + result += "isXAMABearish: " + (string)mConditions.isXAMABearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBearish)) + { + result += "isXAMAEndBearish: " + (string)mConditions.isXAMAEndBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBearishByNeutural)) + { + result += "isXAMAEndBearishByNeutural: " + (string)mConditions.isXAMAEndBearishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMANeutural)) + { + result += "isXAMANeutural: " + (string)mConditions.isXAMANeutural + separator; + } + + // + // Separator ... + result += separator; + + // + // XTD ... + result += + "| XTD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalPeak)) + { + result += "isXTDSignalPeak: " + (string)mConditions.isXTDSignalPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalVale)) + { + result += "isXTDSignalVale: " + (string)mConditions.isXTDSignalVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullishPeak)) + { + result += "isXTDBullishPeak: " + (string)mConditions.isXTDBullishPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullishVale)) + { + result += "isXTDBullishVale: " + (string)mConditions.isXTDBullishVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBearishPeak)) + { + result += "isXTDBearishPeak: " + (string)mConditions.isXTDBearishPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBearishVale)) + { + result += "isXTDBearishVale: " + (string)mConditions.isXTDBearishVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullOverBear)) + { + result += "isXTDBullOverBear: " + (string)mConditions.isXTDBullOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullUnderBear)) + { + result += "isXTDBullUnderBear: " + (string)mConditions.isXTDBullUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalOverBear)) + { + result += "isXTDSignalOverBear: " + (string)mConditions.isXTDSignalOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalUnderBear)) + { + result += "isXTDSignalUnderBear: " + (string)mConditions.isXTDSignalUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullCrossedOverBear)) + { + result += "isXTDBullCrossedOverBear: " + (string)mConditions.isXTDBullCrossedOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullCrossedUnderBear)) + { + result += "isXTDBullCrossedUnderBear: " + (string)mConditions.isXTDBullCrossedUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalCrossedOverBear)) + { + result += "isXTDSignalCrossedOverBear: " + (string)mConditions.isXTDSignalCrossedOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalCrossedUnderBear)) + { + result += "isXTDSignalCrossedUnderBear: " + (string)mConditions.isXTDSignalCrossedUnderBear + separator; + } + + // + // Separator ... + result += separator; + + // + // XFI ... + result += + "| XFI |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIPeak)) + { + result += "isXFIPeak: " + (string)mConditions.isXFIPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIVale)) + { + result += "isXFIVale: " + (string)mConditions.isXFIVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIOverZero)) + { + result += "isXFIOverZero: " + (string)mConditions.isXFIOverZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIUnderZero)) + { + result += "isXFIUnderZero: " + (string)mConditions.isXFIUnderZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFICrossedOverZero)) + { + result += "isXFICrossedOverZero: " + (string)mConditions.isXFICrossedOverZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFICrossedUnderZero)) + { + result += "isXFICrossedUnderZero: " + (string)mConditions.isXFICrossedUnderZero + separator; + } + + // + // Separator ... + result += separator; + + // + // XTS ... + result += + "| XTS |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSAllSame)) + { + result += "isXTSAllSame: " + (string)mConditions.isXTSAllSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentMin)) + { + result += "isXTSCurrentMin: " + (string)mConditions.isXTSCurrentMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentMax)) + { + result += "isXTSCurrentMax: " + (string)mConditions.isXTSCurrentMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverFarest)) + { + result += "isXTSCurrentOverFarest: " + (string)mConditions.isXTSCurrentOverFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverNearest)) + { + result += "isXTSCurrentOverNearest: " + (string)mConditions.isXTSCurrentOverNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverMediest)) + { + result += "isXTSCurrentOverMediest: " + (string)mConditions.isXTSCurrentOverMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderFarest)) + { + result += "isXTSCurrentUnderFarest: " + (string)mConditions.isXTSCurrentUnderFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderNearest)) + { + result += "isXTSCurrentUnderNearest: " + (string)mConditions.isXTSCurrentUnderNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderMediest)) + { + result += "isXTSCurrentUnderMediest: " + (string)mConditions.isXTSCurrentUnderMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverFarest)) + { + result += "isXTSCurrentCrossedOverFarest: " + (string)mConditions.isXTSCurrentCrossedOverFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverNearest)) + { + result += "isXTSCurrentCrossedOverNearest: " + (string)mConditions.isXTSCurrentCrossedOverNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverMediest)) + { + result += "isXTSCurrentCrossedOverMediest: " + (string)mConditions.isXTSCurrentCrossedOverMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderFarest)) + { + result += "isXTSCurrentCrossedUnderFarest: " + (string)mConditions.isXTSCurrentCrossedUnderFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderNearest)) + { + result += "isXTSCurrentCrossedUnderNearest: " + (string)mConditions.isXTSCurrentCrossedUnderNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderMediest)) + { + result += "isXTSCurrentCrossedUnderMediest: " + (string)mConditions.isXTSCurrentCrossedUnderMediest + separator; + } + + // + // Separator ... + result += separator; + + // + // XLH ... + result += + "| XLH |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHIncreased)) + { + result += "isXLHHHIncreased: " + (string)mConditions.isXLHHHIncreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHDecreased)) + { + result += "isXLHHHDecreased: " + (string)mConditions.isXLHHHDecreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLIncreased)) + { + result += "isXLHLLIncreased: " + (string)mConditions.isXLHLLIncreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLDecreased)) + { + result += "isXLHLLDecreased: " + (string)mConditions.isXLHLLDecreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHighAttachedHH)) + { + result += "isXLHHighAttachedHH: " + (string)mConditions.isXLHHighAttachedHH + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLowAttachedLL)) + { + result += "isXLHLowAttachedLL: " + (string)mConditions.isXLHLowAttachedLL + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHSameInLength)) + { + result += "isXLHHHSameInLength: " + (string)mConditions.isXLHHHSameInLength + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLSameInLength)) + { + result += "isXLHLLSameInLength: " + (string)mConditions.isXLHLLSameInLength + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceCrossedOverSignal)) + { + result += "isXLHPriceCrossedOverSignal: " + (string)mConditions.isXLHPriceCrossedOverSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceOverSignal)) + { + result += "isXLHPriceOverSignal: " + (string)mConditions.isXLHPriceOverSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceCrossedUnderSignal)) + { + result += "isXLHPriceCrossedUnderSignal: " + (string)mConditions.isXLHPriceCrossedUnderSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceUnderSignal)) + { + result += "isXLHPriceUnderSignal: " + (string)mConditions.isXLHPriceUnderSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceInSignalRange)) + { + result += "isXLHPriceInSignalRange: " + (string)mConditions.isXLHPriceInSignalRange + separator; + } + + // + // Separator ... + result += separator; + + // + // XRSI ... + result += + "| XRSI |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSIPeak)) + { + result += "isXRSIPeak: " + (string)mConditions.isXRSIPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSIVale)) + { + result += "isXRSIVale: " + (string)mConditions.isXRSIVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedOverLongExit)) + { + result += "isXRSICrossedOverLongExit: " + (string)mConditions.isXRSICrossedOverLongExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedOverLongEntry)) + { + result += "isXRSICrossedOverLongEntry: " + (string)mConditions.isXRSICrossedOverLongEntry + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedUnderShortExit)) + { + result += "isXRSICrossedUnderShortExit: " + (string)mConditions.isXRSICrossedUnderShortExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedUnderShortEntry)) + { + result += "isXRSICrossedUnderShortEntry: " + (string)mConditions.isXRSICrossedUnderShortEntry + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHLH ... + result += + "| XCHLH |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSameHHs)) + { + result += "isXCHLHSameHHs: " + (string)mConditions.isXCHLHSameHHs + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSameLLs)) + { + result += "isXCHLHSameLLs: " + (string)mConditions.isXCHLHSameLLs + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCMCHHSame)) + { + result += "isXCHLHSCMCHHSame: " + (string)mConditions.isXCHLHSCMCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCMCLLSame)) + { + result += "isXCHLHSCMCLLSame: " + (string)mConditions.isXCHLHSCMCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCLCHHSame)) + { + result += "isXCHLHSCLCHHSame: " + (string)mConditions.isXCHLHSCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCLCLLSame)) + { + result += "isXCHLHSCLCLLSame: " + (string)mConditions.isXCHLHSCLCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCLCHHSame)) + { + result += "isXCHLHMCLCHHSame: " + (string)mConditions.isXCHLHMCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCLCLLSame)) + { + result += "isXCHLHMCLCLLSame: " + (string)mConditions.isXCHLHMCLCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCOnTopOfLC)) + { + result += "isXCHLHMCOnTopOfLC: " + (string)mConditions.isXCHLHMCOnTopOfLC + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCInBottomOfLC)) + { + result += "isXCHLHMCInBottomOfLC: " + (string)mConditions.isXCHLHMCInBottomOfLC + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHMA ... + result += + "| XCHMA |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCOverMax)) + { + result += "isXCHMASCOverMax: " + (string)mConditions.isXCHMASCOverMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCOverMin)) + { + result += "isXCHMASCOverMin: " + (string)mConditions.isXCHMASCOverMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCUnderMax)) + { + result += "isXCHMASCUnderMax: " + (string)mConditions.isXCHMASCUnderMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCUnderMin)) + { + result += "isXCHMASCUnderMin: " + (string)mConditions.isXCHMASCUnderMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedOverMax)) + { + result += "isXCHMASCCrossedOverMax: " + (string)mConditions.isXCHMASCCrossedOverMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedUnderMax)) + { + result += "isXCHMASCCrossedUnderMax: " + (string)mConditions.isXCHMASCCrossedUnderMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedOverMin)) + { + result += "isXCHMASCCrossedOverMin: " + (string)mConditions.isXCHMASCCrossedOverMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedUnderMin)) + { + result += "isXCHMASCCrossedUnderMin: " + (string)mConditions.isXCHMASCCrossedUnderMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCPeak)) + { + result += "isXCHMASCPeak: " + (string)mConditions.isXCHMASCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCVale)) + { + result += "isXCHMASCVale: " + (string)mConditions.isXCHMASCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCTrendsUp)) + { + result += "isXCHMASCTrendsUp: " + (string)mConditions.isXCHMASCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCTrendsDown)) + { + result += "isXCHMASCTrendsDown: " + (string)mConditions.isXCHMASCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastOverSlow)) + { + result += "isXCHMASCFastOverSlow: " + (string)mConditions.isXCHMASCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastUnderSlow)) + { + result += "isXCHMASCFastUnderSlow: " + (string)mConditions.isXCHMASCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastCrossedOverSlow)) + { + result += "isXCHMASCFastCrossedOverSlow: " + (string)mConditions.isXCHMASCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastCrossedUnderSlow)) + { + result += "isXCHMASCFastCrossedUnderSlow: " + (string)mConditions.isXCHMASCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCPeak)) + { + result += "isXCHMAMCPeak: " + (string)mConditions.isXCHMAMCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCVale)) + { + result += "isXCHMAMCVale: " + (string)mConditions.isXCHMAMCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCTrendsUp)) + { + result += "isXCHMAMCTrendsUp: " + (string)mConditions.isXCHMAMCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCTrendsDown)) + { + result += "isXCHMAMCTrendsDown: " + (string)mConditions.isXCHMAMCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastOverSlow)) + { + result += "isXCHMAMCFastOverSlow: " + (string)mConditions.isXCHMAMCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastUnderSlow)) + { + result += "isXCHMAMCFastUnderSlow: " + (string)mConditions.isXCHMAMCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastCrossedOverSlow)) + { + result += "isXCHMAMCFastCrossedOverSlow: " + (string)mConditions.isXCHMAMCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastCrossedUnderSlow)) + { + result += "isXCHMAMCFastCrossedUnderSlow: " + (string)mConditions.isXCHMAMCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCPeak)) + { + result += "isXCHMALCPeak: " + (string)mConditions.isXCHMALCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCVale)) + { + result += "isXCHMALCVale: " + (string)mConditions.isXCHMALCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCTrendsUp)) + { + result += "isXCHMALCTrendsUp: " + (string)mConditions.isXCHMALCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCTrendsDown)) + { + result += "isXCHMALCTrendsDown: " + (string)mConditions.isXCHMALCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastOverSlow)) + { + result += "isXCHMALCFastOverSlow: " + (string)mConditions.isXCHMALCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastUnderSlow)) + { + result += "isXCHMALCFastUnderSlow: " + (string)mConditions.isXCHMALCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastCrossedOverSlow)) + { + result += "isXCHMALCFastCrossedOverSlow: " + (string)mConditions.isXCHMALCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastCrossedUnderSlow)) + { + result += "isXCHMALCFastCrossedUnderSlow: " + (string)mConditions.isXCHMALCFastCrossedUnderSlow + separator; + } + + // + // Separator ... + result += separator; + + // + return result; + } + + // + // END Common Functions ... + // + + // + // START Actions Based On Signallers ... + // + + // + // START XTD Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXTDignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXTDEnableSignaller) + { + return result; + } + + // + result = true; + mXTDEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXTDSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXTDEnableSignaller) + { + return result; + } + + // + result = true; + mXTDEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXTDLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + mXTDAllowLongSignals) + { + return result; + } + + // + result = true; + mXTDAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXTDLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowLongSignals) + { + return result; + } + + // + result = true; + mXTDAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXTDShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + mXTDAllowShortSignals) + { + return result; + } + + // + result = true; + mXTDAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXTDShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowShortSignals) + { + return result; + } + + // + result = true; + mXTDAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XTDHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXTDSignalCrossedOverBear + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XTDHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXTDSignalCrossedUnderBear + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XTD Signaller ... + // + + // + // START XTAM Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXTAMignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXTAMEnableSignaller) + { + return result; + } + + // + result = true; + mXTAMEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXTAMSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXTAMEnableSignaller) + { + return result; + } + + // + result = true; + mXTAMEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXTAMLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + mXTAMAllowLongSignals) + { + return result; + } + + // + result = true; + mXTAMAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXTAMLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowLongSignals) + { + return result; + } + + // + result = true; + mXTAMAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXTAMShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + mXTAMAllowShortSignals) + { + return result; + } + + // + result = true; + mXTAMAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXTAMShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowShortSignals) + { + return result; + } + + // + result = true; + mXTAMAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XTAMHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + (xAMAMaBuffer[1] > xTMMaBuffer[1] && + xAMAMaBuffer[2] > xTMMaBuffer[2]) + // + && + // + !(xAMAMaBuffer[2] > xTMMaBuffer[2] && + xAMAMaBuffer[3] > xTMMaBuffer[3]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XTAMHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + (xAMAMaBuffer[1] < xTMMaBuffer[1] && + xAMAMaBuffer[2] < xTMMaBuffer[2]) + // + && + // + !(xAMAMaBuffer[2] < xTMMaBuffer[2] && + xAMAMaBuffer[3] < xTMMaBuffer[3]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XTAM Signaller ... + // + + // + // START XSI Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXSIignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXSIEnableSignaller) + { + return result; + } + + // + result = true; + mXSIEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXSISignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXSIEnableSignaller) + { + return result; + } + + // + result = true; + mXSIEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXSILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + mXSIAllowLongSignals) + { + return result; + } + + // + result = true; + mXSIAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXSILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowLongSignals) + { + return result; + } + + // + result = true; + mXSIAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXSIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + mXSIAllowShortSignals) + { + return result; + } + + // + result = true; + mXSIAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXSIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowShortSignals) + { + return result; + } + + // + result = true; + mXSIAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XSIHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXRSICrossedOverLongEntry && + xRSIBuffer[3] < xRSILongEntryValue + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + true, // XCHMA Cycles + true, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XSIHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXRSICrossedUnderShortEntry && + xRSIBuffer[3] > xRSIShortEntryValue + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + true, // XCHMA Min + true, // XCHMA Max + true, // XCHMA Cycles + true, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // END XSI Signaller ... + // + + // + // START XTSFI Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXTSFIignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXTSFIEnableSignaller) + { + return result; + } + + // + result = true; + mXTSFIEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXTSFISignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXTSFIEnableSignaller) + { + return result; + } + + // + result = true; + mXTSFIEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXTSFILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + mXTSFIAllowLongSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXTSFILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowLongSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXTSFIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + mXTSFIAllowShortSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXTSFIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowShortSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XTSFIHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + XTSGetMinValue(1) == xTSFarestBuffer[1] && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest) && + (xTSCurrentBuffer[1] < xTSNearestBuffer[1] || + xTSCurrentBuffer[1] < xTSMediestBuffer[1]) && + !(mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XTSFIHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + XTSGetMaxValue(1) == xTSFarestBuffer[1] && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest) && + (xTSCurrentBuffer[1] > xTSNearestBuffer[1] || + xTSCurrentBuffer[1] > xTSMediestBuffer[1]) && + !(mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XTSFI Signaller ... + // + + // + // START XOBDLH Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXOBDLHignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXOBDLHEnableSignaller) + { + return result; + } + + // + result = true; + mXOBDLHEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXOBDLHSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXOBDLHEnableSignaller) + { + return result; + } + + // + result = true; + mXOBDLHEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXOBDLHLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + mXOBDLHAllowLongSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXOBDLHLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowLongSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXOBDLHShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + mXOBDLHAllowShortSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXOBDLHShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowShortSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XOBDLHHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowLongSignals) + { + return result; + } + + // + XMarketConditions xConditions2 = GenerateMarketConditions(2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xConditions2.isXOBDSwingLow && + xConditions2.isXLHLowAttachedLL && + xLHLLBuffer[1] >= xLHLLBuffer[2] + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + false, // XOBD + false // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XOBDLHHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowShortSignals) + { + return result; + } + + // + XMarketConditions xConditions2 = GenerateMarketConditions(2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xConditions2.isXOBDSwingHigh && + xConditions2.isXLHHighAttachedHH && + xLHHHBuffer[1] <= xLHHHBuffer[2] + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + false, // XOBD + false // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // END XOBDLH Signaller ... + // + + // + // START XCHMACC Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXCHMACCignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXCHMACCEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMACCEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXCHMACCSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXCHMACCEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMACCEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXCHMACCLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + mXCHMACCAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXCHMACCLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXCHMACCShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + mXCHMACCAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXCHMACCShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XCHMACCHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xCHMAScFastBuffer[1] > xCHMAScSlowBuffer[1] && + xCHMAMcFastBuffer[1] > xCHMAMcSlowBuffer[1] && + xCHMALcFastBuffer[1] > xCHMALcSlowBuffer[1] && + // + xCHMAScFastBuffer[2] > xCHMAScSlowBuffer[2] && + xCHMAMcFastBuffer[2] > xCHMAMcSlowBuffer[2] && + xCHMALcFastBuffer[2] > xCHMALcSlowBuffer[2] && + // + !( + // + xCHMAScFastBuffer[3] > xCHMAScSlowBuffer[3] && + xCHMAMcFastBuffer[3] > xCHMAMcSlowBuffer[3] && + xCHMALcFastBuffer[3] > xCHMALcSlowBuffer[3] + // + ) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XCHMACCHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xCHMAScFastBuffer[1] < xCHMAScSlowBuffer[1] && + xCHMAMcFastBuffer[1] < xCHMAMcSlowBuffer[1] && + xCHMALcFastBuffer[1] < xCHMALcSlowBuffer[1] && + // + xCHMAScFastBuffer[2] < xCHMAScSlowBuffer[2] && + xCHMAMcFastBuffer[2] < xCHMAMcSlowBuffer[2] && + xCHMALcFastBuffer[2] < xCHMALcSlowBuffer[2] && + // + !( + // + xCHMAScFastBuffer[3] < xCHMAScSlowBuffer[3] && + xCHMAMcFastBuffer[3] < xCHMAMcSlowBuffer[3] && + xCHMALcFastBuffer[3] < xCHMALcSlowBuffer[3] + // + ) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XCHMACC Signaller ... + // + + // + // START XCHMAMX Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXCHMAMXignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXCHMAMXEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMXEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXCHMAMXSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXCHMAMXEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMXEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXCHMAMXLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + mXCHMAMXAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXCHMAMXLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXCHMAMXShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + mXCHMAMXAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXCHMAMXShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XCHMAMXHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowLongSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedOverMax && + xCHMAScFastBuffer[2] < xCHMANonSCMax2 && + xCHMAScSlowBuffer[2] < xCHMANonSCMax2 && + MathAbs(xCHMANonSCMax2 - xCHMAScFastBuffer[2]) > MathAbs(xCHMAScFastBuffer[2] - xCHMAScSlowBuffer[2]) && + MathAbs(xCHMANonSCMax2 - xCHMAScSlowBuffer[2]) > MathAbs(xCHMAScFastBuffer[2] - xCHMAScSlowBuffer[2]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XCHMAMXHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowShortSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedUnderMax && + xCHMAScFastBuffer[2] > xCHMANonSCMax2 && + xCHMAScSlowBuffer[2] > xCHMANonSCMax2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + // + return result; + } + + // + // END XCHMAMX Signaller ... + // + + // + // START XCHMAMN Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXCHMAMNignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXCHMAMNEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMNEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXCHMAMNSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXCHMAMNEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMNEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXCHMAMNLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + mXCHMAMNAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXCHMAMNLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXCHMAMNShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + mXCHMAMNAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXCHMAMNShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XCHMAMNHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowLongSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedOverMin && + xCHMAScFastBuffer[2] < xCHMANonSCMin2 && + xCHMAScSlowBuffer[2] < xCHMANonSCMin2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XCHMAMNHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowShortSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedUnderMin && + xCHMAScFastBuffer[2] > xCHMANonSCMin2 && + xCHMAScSlowBuffer[2] > xCHMANonSCMin2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + // + return result; + } + + // + // END XCHMAMN Signaller ... + // + + // + // END Actions Based On Signallers ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // XTD ... + bool mXTDEnableSignaller; + bool mXTDAllowLongSignals; + bool mXTDAllowShortSignals; + + // + // XTAM ... + bool mXTAMEnableSignaller; + bool mXTAMAllowLongSignals; + bool mXTAMAllowShortSignals; + + // + // XSI ... + bool mXSIEnableSignaller; + bool mXSIAllowLongSignals; + bool mXSIAllowShortSignals; + + // + // XTSFI ... + bool mXTSFIEnableSignaller; + bool mXTSFIAllowLongSignals; + bool mXTSFIAllowShortSignals; + + // + // XOBDLH ... + bool mXOBDLHEnableSignaller; + bool mXOBDLHAllowLongSignals; + bool mXOBDLHAllowShortSignals; + + // + // XCHMACC ... + bool mXCHMACCEnableSignaller; + bool mXCHMACCAllowLongSignals; + bool mXCHMACCAllowShortSignals; + + // + // XCHMAMX ... + bool mXCHMAMXEnableSignaller; + bool mXCHMAMXAllowLongSignals; + bool mXCHMAMXAllowShortSignals; + + // + // XCHMAMN ... + bool mXCHMAMNEnableSignaller; + bool mXCHMAMNAllowLongSignals; + bool mXCHMAMNAllowShortSignals; + + // + // Here we Define some Global Market Variables to Analyse MArket Conditions + // using them at each time ... + XMarketConditions mXConditions; +}; \ No newline at end of file diff --git a/XEU5/Documents/.gitkeep b/XEU5/Documents/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Documents/Reports/.gitkeep b/XEU5/Documents/Reports/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Documents/Settings/.gitkeep b/XEU5/Documents/Settings/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Experts/.gitkeep b/XEU5/Experts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Experts/x-saherelm.xeu5.ea.mq5 b/XEU5/Experts/x-saherelm.xeu5.ea.mq5 new file mode 100644 index 0000000..58c5bda --- /dev/null +++ b/XEU5/Experts/x-saherelm.xeu5.ea.mq5 @@ -0,0 +1,347 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: XAUUSD +// Description: this is an expert controller +// advisors which provides a mechanism for use them ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XEU5 EA" +#property strict + +// +// START Inputs ... +// + +input group "Commons"; + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Alert Library ... +#include "../Libraries/x-saherelm.alert.lib.mq5" + +// +// Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// XEU5 Signal Provider ... +#include "../Providers/x-saherelm.xeu5.provider.lib.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +bool isXEU5NewHour; +bool isXEU5NewDay; +bool isXEU5NewWeek; +bool isXEU5NewMonth; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = "XEU5EA"; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Apply default Chart Style for EA ... + ApplyChartStyle(); + + // + // Reset Timings ... + ResetTiming(); + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize XEU5 Provider ... + if (!XEU5InitSignalProviderLibrary()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Initialize XEU5 Provider ... + XEU5DeinitSignalProviderLibrary(reason); + + // + // De Init XDraw Library ... + // OnDeinitDrawLibrary(); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Handle Monthly Alert ... + bool isFirstMonth = xMonth == -1; + isXEU5NewMonth = IsNewMonth(); + bool canMonthlyAlert = + isXEU5NewMonth && + xEU5EnableAlerts && + xEU5EnableMonthlyAlerts; + bool canMonthlyReport = + !isFirstMonth && + canMonthlyAlert && + xEU5EnableMonthlyReports; + if (canMonthlyAlert) + { + // + string message = "New Month ..."; + + // + // Prepare Monthly Report ... + if (canMonthlyReport) + { + // + string report = xEU5Reporter.GenerateReportString(XREPORT_MONTHLY); + + // + message = "Last Month Report:\n" + report; + } + + // + // Reset Report ... + xEU5Reporter.Reset(XREPORT_MONTHLY); + + // + SendAlert(message); + } + + // + // Handle Weekly Alert ... + bool isFirstWeek = xDayOfWeek == -1; + isXEU5NewWeek = IsNewWeek(); + bool canWeeklyAlert = + isXEU5NewWeek && + xEU5EnableAlerts && + xEU5EnableWeeklyAlerts; + bool canWeeklyReport = + !isFirstWeek && + canWeeklyAlert && + xEU5EnableWeeklyReports; + if (canWeeklyAlert) + { + // + string message = "New Week ..."; + + // + // Prepare Weekly Report ... + if (canWeeklyReport) + { + // + string report = xEU5Reporter.GenerateReportString(XREPORT_WEEKLY); + + // + message = "Last Week Report:\n" + report; + } + + // + // Reset Report ... + xEU5Reporter.Reset(XREPORT_WEEKLY); + + // + SendAlert(message); + } + + // + // Handle Daily Alert ... + bool isFirstDay = xDay == -1; + isXEU5NewDay = IsNewDay(); + bool canDailyAlert = + isXEU5NewDay && + xEU5EnableAlerts && + xEU5EnableDailyAlerts; + bool canDailyReport = + !isFirstDay && + canDailyAlert && + xEU5EnableDailyReports; + if (canDailyAlert) + { + // + string message = "New Day ..."; + + // + // Prepare Daily Report ... + if (canDailyReport) + { + // + string report = xEU5Reporter.GenerateReportString(XREPORT_DAILY); + + // + message = "Last Week Report:\n" + report; + } + + // + // Reset Report ... + xEU5Reporter.Reset(XREPORT_DAILY); + + // + SendAlert(message); + } + + // + // Handle Hourly Alert ... + bool isFirstHour = xHour == -1; + isXEU5NewHour = IsNewHour(); + bool canHourlyAlert = + isXEU5NewHour && + xEU5EnableAlerts && + xEU5EnableHourlyAlerts; + if (canHourlyAlert) + { + // + string message = "New Hour ..."; + + // + SendAlert(message); + } + + + // + // Prevent Going Forward if user Disable it ... + if (xEU5EnableProvider) + { + // + // Handle Processing on XEU5 Signal Provider ... + XEU5SignalProviderDoControlState(); + } + + // + if (!IsNewCandle()) + { + return; + } + + // + // Prevent Going Forward if user Disable it ... + if (xEU5EnableProvider) + { + // + // Handle Processing on XEU5 Signal Provider ... + XEU5SignalProviderHandleTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + + // + // Prevent Going Forward if user Disable it ... + if (xEU5EnableProvider) + { + // + // Handle Processing Trades on XEU5 Signal Provider ... + XEU5SignalProviderHandleTrade(); + } +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + + // + // Validate XEU5 Provider Inputs ... + result = XEU5ValidateInputs(); + if (!result) + { + return false; + } + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// END Functions ... +// diff --git a/XEU5/Helpers/.gitkeep b/XEU5/Helpers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 new file mode 100644 index 0000000..f565e41 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 @@ -0,0 +1,607 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAMA Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 1, + X_XAMA_BEARISH = -1, + X_XAMA_NEUTURAL = 0, +}; + +// +// XAMA Indicator Buffer Lines ... +enum ENUM_X_XAMA_BUFFER_LINES +{ + X_XAMA_MA_LINE = 0, + X_XAMA_MC_COLOR_LINE = 1, + X_XAMA_STATE_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XAMA Indicator"; + +// +// input int xAMALength = 18; // Market Length +// input int xAMAFastEMA = 2; // Fast EMA Period +// input int xAMASlowEMA = 30; // Slow EMA Period +// input int xAMAShift = 0; // Shift +// input ENUM_APPLIED_PRICE xAMAAppliedTo = PRICE_CLOSE; // Applied To + +// +// Configurations ... +int xAMALength = 18; // Market Length +int xAMAFastEMA = 2; // Fast EMA Period +int xAMASlowEMA = 30; // Slow EMA Period +int xAMAShift = 0; // Shift +ENUM_APPLIED_PRICE xAMAAppliedTo = PRICE_CLOSE; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xAMAHandler = INVALID_HANDLE; +double xAMAMaBuffer[]; +double xAMAStateBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XAMAValidateInputs() +{ + // + bool result = false; + + // + result = + xAMALength > 2 && + xAMAFastEMA < xAMALength && + xAMAFastEMA < xAMASlowEMA && + xAMAShift >= 0; + + // + if (!result) + { + // + LogMessage("XAMA Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XAMAInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Indicator Handlers ... + ResetLastError(); + + // + // XAMA Handler ... + ArraySetAsSeries(xAMAMaBuffer, true); + ArraySetAsSeries(xAMAStateBuffer, true); + xAMAHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xama.indicator", + // + // Inputs ... + xAMALength, + xAMAFastEMA, + xAMASlowEMA, + xAMAShift, + xAMAAppliedTo + // + ); + if (xAMAHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XAMA Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XAMAReleaseHandlers() +{ + IndicatorRelease(xAMAHandler); +} + +// +// Handle Reading Buffers ... +void XAMAReadBuffers( + int xAMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XAMA Ma Buffer ... + CopyBuffer( + xAMAHandler, + X_XAMA_MA_LINE, + 0, + xAMAItemsPerTick, + xAMAMaBuffer); + + // + // XAMA State Buffer ... + CopyBuffer( + xAMAHandler, + X_XAMA_STATE_LINE, + 0, + xAMAItemsPerTick, + xAMAStateBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XAMA Custom Functions ... +// + +// +// Check SC is Peak ... +bool XAMAIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xAMAMaBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XAMAIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xAMAMaBuffer + // + ); + + // + return result; +} + +// +// Check TM Crossed Up ... +bool XAMAIsStartBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] != X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Up After Neutural State ... +bool XAMAIsStartBullishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Up State ... +bool XAMAIsBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State ... +bool XAMAIsEndBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] != X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State By Neutural ... +bool XAMAIsEndBullishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down ... +bool XAMAIsStartBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] != X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down After Neutural State ... +bool XAMAIsStartBearishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Down State ... +bool XAMAIsBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State ... +bool XAMAIsEndBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] != X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State By Neutural ... +bool XAMAIsEndBearishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM In Neutural State ... +bool XAMAIsNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XAMAIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xAMAMaBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XAMA Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..d7071b4 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 @@ -0,0 +1,1032 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHLH Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// Cycles Enumeration ... +enum ENUM_X_XCHLH_CYCLES +{ + X_XCHLH_CYCLE_LONG, + X_XCHLH_CYCLE_MEDIUM, + X_XCHLH_CYCLE_SHORT, +}; + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// XCHLH Buffer Lines ... +enum ENUM_X_XCHLH_BUFFER_LINES +{ + X_XCHLH_LC_HH_LINE = 0, + X_XCHLH_LC_LL_LINE = 1, + X_XCHLH_MC_HH_LINE = 2, + X_XCHLH_MC_LL_LINE = 3, + X_XCHLH_SC_HH_LINE = 4, + X_XCHLH_SC_LL_LINE = 5, + X_XCHLH_SIGNAL_T_LINE = 6, + X_XCHLH_SIGNAL_B_LINE = 7, + X_XCHLH_HOT_STATE_LINE = 8, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// // +// input group "XCHLH Oscillator"; + +// // +// // Common ... +// input group "XCHLH Hot Areas"; +// input bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol +// input uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code +// input color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color +// input uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code +// input color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// // +// // LC Inputs ... +// input group "XCHLH Long Cycle"; +// input group "XCHLH LC Market"; +// input int xCHLHLcLength = 288; // Length +// input double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH LC Style"; +// input int xCHLHLcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHLcHHColor = clrAqua; // Highest High Color +// input color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color +// input group "XCHLH LC Drawings"; +// input bool xCHLHLcDrawHH = true; // Draw Highest High +// input bool xCHLHLcDrawLL = true; // Draw Lowest Low + +// // +// // MC Inputs ... +// input group "XCHLH Medium Cycle"; +// input group "XCHLH MC Market"; +// input int xCHLHMcLength = 72; // Length +// input double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH MC Style"; +// input int xCHLHMcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHMcHHColor = clrLime; // Highest High Color +// input color xCHLHMcLLColor = clrRed; // Lowest Low Color +// input group "XCHLH MC Drawings"; +// input bool xCHLHMcDrawHH = true; // Draw Highest High +// input bool xCHLHMcDrawLL = true; // Draw Lowest Low + +// // +// // SC Inputs ... +// input group "XCHLH Short Cycle"; +// input group "XCHLH SC Market"; +// input int xCHLHScLength = 7; // Length +// input double xCHLHScThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH SC Style"; +// input int xCHLHScDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHScHHColor = clrLightBlue; // Highest High Color +// input color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color +// input group "XCHLH SC Drawings"; +// input bool xCHLHScDrawHH = true; // Draw Highest High +// input bool xCHLHScDrawLL = true; // Draw Lowest Low + +// +// Configurations ... +// +// Common ... +bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol +uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code +color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color +uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code +color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +int xCHLHLcLength = 288; // Length +double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHLcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style +color xCHLHLcHHColor = clrAqua; // Highest High Color +color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color +bool xCHLHLcDrawHH = true; // Draw Highest High +bool xCHLHLcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +int xCHLHMcLength = 72; // Length +double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHMcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style +color xCHLHMcHHColor = clrLime; // Highest High Color +color xCHLHMcLLColor = clrRed; // Lowest Low Color +bool xCHLHMcDrawHH = true; // Draw Highest High +bool xCHLHMcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +int xCHLHScLength = 7; // Length +double xCHLHScThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHScDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style +color xCHLHScHHColor = clrLightBlue; // Highest High Color +color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color +bool xCHLHScDrawHH = true; // Draw Highest High +bool xCHLHScDrawLL = true; // Draw Lowest Low + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHLHHandler = INVALID_HANDLE; +double xCHLHLcHHBuffer[]; +double xCHLHLcLLBuffer[]; +double xCHLHMcHHBuffer[]; +double xCHLHMcLLBuffer[]; +double xCHLHScHHBuffer[]; +double xCHLHScLLBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XCHLHValidateInputs() +{ + // + bool result = false; + + // + result = + xCHLHScLength >= 2 && + xCHLHMcLength > xCHLHScLength && + xCHLHLcLength > xCHLHMcLength; + + // + if (!result) + { + // + LogMessage("XCHLH Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XCHLHInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHLH Handler ... + ArraySetAsSeries(xCHLHLcHHBuffer, true); + ArraySetAsSeries(xCHLHLcLLBuffer, true); + ArraySetAsSeries(xCHLHMcHHBuffer, true); + ArraySetAsSeries(xCHLHMcLLBuffer, true); + ArraySetAsSeries(xCHLHScHHBuffer, true); + ArraySetAsSeries(xCHLHScLLBuffer, true); + xCHLHHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchlh.oscillator", + // + // Inputs ... + // + // Commons ... + "", + xCHLHDrawHotAreas, + xCHLHHotHHArrowCode, + xCHLHHotHHArrowColor, + xCHLHHotLLArrowCode, + xCHLHHotLLArrowColor, + // + // LC ... + "", + "", + xCHLHLcLength, + xCHLHLcThresholdInPips, + xCHLHLcHHMode, + xCHLHLcLLMode, + "", + xCHLHLcDrawWidth, + xCHLHLcDrawType, + xCHLHLcDrawStyle, + xCHLHLcHHColor, + xCHLHLcLLColor, + "", + xCHLHLcDrawHH, + xCHLHLcDrawLL, + // + // MC ... + "", + "", + xCHLHMcLength, + xCHLHMcThresholdInPips, + xCHLHMcHHMode, + xCHLHMcLLMode, + "", + xCHLHMcDrawWidth, + xCHLHMcDrawType, + xCHLHMcDrawStyle, + xCHLHMcHHColor, + xCHLHMcLLColor, + "", + xCHLHMcDrawHH, + xCHLHMcDrawLL, + // + // SC ... + "", + "", + xCHLHScLength, + xCHLHScThresholdInPips, + xCHLHScHHMode, + xCHLHScLLMode, + "", + xCHLHScDrawWidth, + xCHLHScDrawType, + xCHLHScDrawStyle, + xCHLHScHHColor, + xCHLHScLLColor, + "", + xCHLHScDrawHH, + xCHLHScDrawLL); + if (xCHLHHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHLH Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHLHReleaseHandlers() +{ + IndicatorRelease(xCHLHHandler); +} + +// +// Handle Reading Buffers ... +void XCHLHReadBuffers( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHLH LC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcHHBuffer); + + // + // XCHLH LC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcLLBuffer); + + // + // XCHLH MC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcHHBuffer); + + // + // XCHLH MC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcLLBuffer); + + // + // XCHLH SC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScHHBuffer); + + // + // XCHLH SC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScLLBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XCHLH Custom Functions ... +// + +// +// Check LC and MC has Same HH ... +bool XCHLHIsLCMCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and MC has Same LL ... +bool XCHLHIsLCMCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and SC has Same HH ... +bool XCHLHIsLCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check LC and SC has Same LL ... +bool XCHLHIsLCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same HH ... +bool XCHLHIsMCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same LL ... +bool XCHLHIsMCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check Is Same Highest Highs ... +bool XCHLHIsSameHHs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check Is Same Lowest Lows ... +bool XCHLHIsSameLLs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check Medium Cycle is On Top of Long Cycle's Mid ... +bool XCHLHIsMCOnTopOfLC( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + ENUM_X_XCHLH_CYCLES sCycle = X_XCHLH_CYCLE_MEDIUM; + ENUM_X_XCHLH_CYCLES dCycle = X_XCHLH_CYCLE_LONG; + + // + result = + // + XCHLHCheckCycleIsOnTopOfAnother( + bar_index, + sCycle, + dCycle) + // + ; + + // + return result; +} + +// +// Check Medium Cycle is In Bottom of Long Cycle's Mid ... +bool XCHLHIsMCInBottomOfLC( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + ENUM_X_XCHLH_CYCLES sCycle = X_XCHLH_CYCLE_MEDIUM; + ENUM_X_XCHLH_CYCLES dCycle = X_XCHLH_CYCLE_LONG; + + // + result = + // + XCHLHCheckCycleIsInBottomOfAnother( + bar_index, + sCycle, + dCycle) + // + ; + + // + return result; +} + +// +// Check and Validate Buffer Sizes ... +bool XCHLHIsValidBufferSizes( + int size // Specified Min Size +) +{ + // + bool result = false; + + // + result = + // + ArraySize(xCHLHLcHHBuffer) > size && + ArraySize(xCHLHLcLLBuffer) > size && + // + ArraySize(xCHLHMcHHBuffer) > size && + ArraySize(xCHLHMcLLBuffer) > size && + // + ArraySize(xCHLHScHHBuffer) > size && + ArraySize(xCHLHScLLBuffer) > size; + + // + return result; +} + +// +// Get Cycle Middle Value ... +double XCHLHGetCycleMid( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Cycle Max Value ... + double iMax = XCHLHGetCycleMax( + bar_index, + cycle); + + // + // Retrieve Cycle Min Value ... + double iMin = XCHLHGetCycleMin( + bar_index, + cycle); + + // + result = (iMax - iMin) / 2; + + // + return result; +} + +// +// Get Cycle Max Value ... +double XCHLHGetCycleMax( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + // Long Cycle ... + case X_XCHLH_CYCLE_LONG: + result = xCHLHLcHHBuffer[1]; + break; + + // + // Medium Cycle ... + case X_XCHLH_CYCLE_MEDIUM: + result = xCHLHMcHHBuffer[1]; + break; + + // + // Short Cycle ... + case X_XCHLH_CYCLE_SHORT: + result = xCHLHScHHBuffer[1]; + break; + } + + // + return result; +} + +// +// Get Specified Cycles Max Value ... +double XCHLHGetCyclesMax( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES &cycles[] // Specified Cycle ... +) +{ + // + bool result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + ArraySize(cycles) <= 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycles); i++) + { + // + ENUM_X_XCHLH_CYCLES iCycle = cycles[i]; + + // + double iValue = XCHLHGetCycleMax( + bar_index, + iCycle); + + // + result = result == 0 || result < iValue ? iValue : result; + } + + // + return result; +} + +// +// Get Cycle Min Value ... +double XCHLHGetCycleMin( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + // Long Cycle ... + case X_XCHLH_CYCLE_LONG: + result = xCHLHLcLLBuffer[1]; + break; + + // + // Medium Cycle ... + case X_XCHLH_CYCLE_MEDIUM: + result = xCHLHMcLLBuffer[1]; + break; + + // + // Short Cycle ... + case X_XCHLH_CYCLE_SHORT: + result = xCHLHScLLBuffer[1]; + break; + } + + // + return result; +} + +// +// Get Specified Cycles Min Value ... +double XCHLHGetCyclesMin( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES &cycles[] // Specified Cycle ... +) +{ + // + bool result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + ArraySize(cycles) <= 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycles); i++) + { + // + ENUM_X_XCHLH_CYCLES iCycle = cycles[i]; + + // + double iValue = XCHLHGetCycleMin( + bar_index, + iCycle); + + // + result = result == 0 || result > iValue ? iValue : result; + } + + // + return result; +} + +// +// Check a Cycle is On Top of Another Cycle's Mid ... +bool XCHLHCheckCycleIsOnTopOfAnother( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES sourceCycle, // Specified Source Cycle which Checks ... + ENUM_X_XCHLH_CYCLES destCycle // Specified Dest Cycle which source Checked based on it ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Min Value of Source Cycle ... + double iMin = XCHLHGetCycleMin( + bar_index, + sourceCycle); + + // + // Retrieve Mid Value of Dest Cycle ... + double iMid = XCHLHGetCycleMid( + bar_index, + destCycle); + + // + // Generate Result ... + result = + // + iMin >= iMid + // + ; + + // + return result; +} + +// +// Check a Cycle is Under Bottom of Another Cycle's Mid ... +bool XCHLHCheckCycleIsInBottomOfAnother( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES sourceCycle, // Specified Source Cycle which Checks ... + ENUM_X_XCHLH_CYCLES destCycle // Specified Dest Cycle which source Checked based on it ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Max Value of Source Cycle ... + double iMax = XCHLHGetCycleMax( + bar_index, + sourceCycle); + + // + // Retrieve Mid Value of Dest Cycle ... + double iMid = XCHLHGetCycleMid( + bar_index, + destCycle); + + // + // Generate Result ... + result = + // + iMax <= iMid + // + ; + + // + return result; +} + +// +// END XCHLH Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..e84d762 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 @@ -0,0 +1,2229 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHMA Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XCHMA Cycles ... +enum ENUM_XCHMA_CYCLES +{ + X_XCHMA_CYCLE_LONG, + X_XCHMA_CYCLE_MEDIUM, + X_XCHMA_CYCLE_SHORT, +}; + +// +// XCHMA Oscillator Hot State Presentation ... +enum ENUM_XCHMA_HOT_STATES +{ + X_XCHMA_HOT_BULLISH = 1, + X_XCHMA_HOT_NEUTURAL = 0, + X_XCHMA_HOT_BEARISH = -1, +}; + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; + +// +// XCHMA Oscillator Buffer Lines ... +enum ENUM_X_XCHMA_BUFFER_LINES +{ + X_XCHMA_LC_FAST_LINE = 0, + X_XCHMA_LC_SLOW_LINE = 1, + X_XCHMA_LC_STATE_LINE = 6, + X_XCHMA_MC_FAST_LINE = 2, + X_XCHMA_MC_SLOW_LINE = 3, + X_XCHMA_MC_STATE_LINE = 7, + X_XCHMA_SC_FAST_LINE = 4, + X_XCHMA_SC_SLOW_LINE = 5, + X_XCHMA_SC_STATE_LINE = 8, + X_XCHMA_HOT_STATE_LINE = 9, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XCHMA Oscillator"; + +// // +// // Commons ... +// input group "XCHMA Hot Areas"; +// input bool xCHMADrawHotAreas = false; // Draw Hot Areas Symbol; +// input uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code; +// input color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color; +// input uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code; +// input color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color; + +// // +// // LC Inputs ... +// input group "XCHMA Long Cycle"; +// input group "XCHMA LC Market"; +// input int xCHMALcFastLength = 288; // Fast Length +// input int xCHMALcSlowLength = 576; // Slow Length +// input ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA LC Style"; +// input int xCHMALcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHMALcFastColor = clrAqua; // Fast Color +// input color xCHMALcSlowColor = clrFuchsia; // Slow Color +// input group "XCHMA LC Drawings"; +// input bool xCHMALcDrawFast = true; // Draw Fast +// input bool xCHMALcDrawSlow = true; // Draw Slow +// input bool xCHMALcDrawCrosses = false; // Draw Cross Lines + +// // +// // MC Inputs ... +// input group "XCHMA Medium Cycle"; +// input group "XCHMA MC Market"; +// input int xCHMAMcFastLength = 72; // Fast Length +// input int xCHMAMcSlowLength = 144; // Slow Length +// input ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA MC Style"; +// input int xCHMAMcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHMAMcFastColor = clrLime; // Fast Color +// input color xCHMAMcSlowColor = clrRed; // Slow Color +// input group "XCHMA MC Drawings"; +// input bool xCHMAMcDrawFast = true; // Draw Fast +// input bool xCHMAMcDrawSlow = true; // Draw Slow +// input bool xCHMAMcDrawCrosses = false; // Draw Cross Lines + +// // +// // SC Inputs ... +// input group "XCHMA Short Cycle"; +// input group "XCHMA SC Market"; +// input int xCHMAScFastLength = 7; // Fast Length +// input int xCHMAScSlowLength = 14; // Slow Length +// input ENUM_MA_METHOD xCHMAScMethod = MODE_SMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA SC Style"; +// input int xCHMAScDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style +// input color xCHMAScFastColor = clrLightBlue; // Fast Color +// input color xCHMAScSlowColor = clrLightSalmon; // Slow Color +// input group "XCHMA SC Drawings"; +// input bool xCHMAScDrawFast = true; // Draw Fast +// input bool xCHMAScDrawSlow = true; // Draw Slow +// input bool xCHMAScDrawCrosses = false; // Draw Cross Lines + +// +// Configurations ... +// +// Commons ... +bool xCHMADrawHotAreas = false; // Draw Hot Areas Symbol; +uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code; +color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color; +uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code; +color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color; + +// +// LC Inputs ... +int xCHMALcFastLength = 288; // Fast Length +int xCHMALcSlowLength = 576; // Slow Length +ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To +int xCHMALcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style +color xCHMALcFastColor = clrAqua; // Fast Color +color xCHMALcSlowColor = clrFuchsia; // Slow Color +bool xCHMALcDrawFast = true; // Draw Fast +bool xCHMALcDrawSlow = true; // Draw Slow +bool xCHMALcDrawCrosses = false; // Draw Cross Lines + +// +// MC Inputs ... +int xCHMAMcFastLength = 72; // Fast Length +int xCHMAMcSlowLength = 144; // Slow Length +ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To +int xCHMAMcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style +color xCHMAMcFastColor = clrLime; // Fast Color +color xCHMAMcSlowColor = clrRed; // Slow Color +bool xCHMAMcDrawFast = true; // Draw Fast +bool xCHMAMcDrawSlow = true; // Draw Slow +bool xCHMAMcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +int xCHMAScFastLength = 7; // Fast Length +int xCHMAScSlowLength = 14; // Slow Length +ENUM_MA_METHOD xCHMAScMethod = MODE_SMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To +int xCHMAScDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style +color xCHMAScFastColor = clrLightBlue; // Fast Color +color xCHMAScSlowColor = clrLightSalmon; // Slow Color +bool xCHMAScDrawFast = true; // Draw Fast +bool xCHMAScDrawSlow = true; // Draw Slow +bool xCHMAScDrawCrosses = false; // Draw Cross Lines + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHMAHandler = INVALID_HANDLE; +double xCHMALcFastBuffer[]; +double xCHMALcSlowBuffer[]; +double xCHMAMcFastBuffer[]; +double xCHMAMcSlowBuffer[]; +double xCHMAScFastBuffer[]; +double xCHMAScSlowBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XCHMAValidateInputs() +{ + // + bool result = false; + + // + result = + xCHMAScFastLength >= 2 && + xCHMAScSlowLength > xCHMAScFastLength && + xCHMAMcFastLength > xCHMAScSlowLength && + xCHMAMcSlowLength > xCHMAMcFastLength && + xCHMALcFastLength > xCHMAMcSlowLength && + xCHMALcSlowLength > xCHMALcFastLength; + + // + if (!result) + { + // + LogMessage("XCHMA Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XCHMAInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHMA Handler ... + ArraySetAsSeries(xCHMALcFastBuffer, true); + ArraySetAsSeries(xCHMALcSlowBuffer, true); + ArraySetAsSeries(xCHMAMcFastBuffer, true); + ArraySetAsSeries(xCHMAMcSlowBuffer, true); + ArraySetAsSeries(xCHMAScFastBuffer, true); + ArraySetAsSeries(xCHMAScSlowBuffer, true); + xCHMAHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchma.oscillator", + // + // Inputs ... + "", + xCHMADrawHotAreas, + xCHMAHotBullishArrowCode, + xCHMAHotBullishArrowColor, + xCHMAHotBearishArrowCode, + xCHMAHotBearishArrowColor, + // + // Long Cycle ... + "", + "", + xCHMALcFastLength, + xCHMALcSlowLength, + xCHMALcMethod, + xCHMALcAppliedTo, + "", + xCHMALcDrawWidth, + xCHMALcDrawType, + xCHMALcDrawStyle, + xCHMALcFastColor, + xCHMALcSlowColor, + "", + xCHMALcDrawFast, + xCHMALcDrawSlow, + xCHMALcDrawCrosses, + // + // Medium Cycle ... + "", + "", + xCHMAMcFastLength, + xCHMAMcSlowLength, + xCHMAMcMethod, + xCHMAMcAppliedTo, + "", + xCHMAMcDrawWidth, + xCHMAMcDrawType, + xCHMAMcDrawStyle, + xCHMAMcFastColor, + xCHMAMcSlowColor, + "", + xCHMAMcDrawFast, + xCHMAMcDrawSlow, + xCHMAMcDrawCrosses, + // + // Short Cycle ... + "", + "", + xCHMAScFastLength, + xCHMAScSlowLength, + xCHMAScMethod, + xCHMAScAppliedTo, + "", + xCHMAScDrawWidth, + xCHMAScDrawType, + xCHMAScDrawStyle, + xCHMAScFastColor, + xCHMAScSlowColor, + "", + xCHMAScDrawFast, + xCHMAScDrawSlow, + xCHMAScDrawCrosses); + if (xCHMAHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHMA Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHMAReleaseHandlers() +{ + IndicatorRelease(xCHMAHandler); +} + +// +// Handle Reading Buffers ... +void XCHMAReadBuffers( + int xCHMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHMA Long Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcSlowBuffer); + + // + // XCHMA Medium Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcSlowBuffer); + + // + // XCHMA Short Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScSlowBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XCHMA Custom Functions ... +// + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMax( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // SC Fast ... + result = MathMax( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMax( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMax( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMax( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMax( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMax( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMin( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = xCHMAScFastBuffer[bar_index]; + + // + // SC Fast ... + result = MathMin( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMin( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMin( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMin( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMin( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMin( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Short Cycle Over Max Of Cycle Channels ... +bool XCHMAIsSCOverMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 > nonOfShortCycleMax1 + // + ; + + // + return result; +} + +// +// Short Cycle Under Max Of Cycle Channels ... +bool XCHMAIsSCUnderMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 < nonOfShortCycleMax1 + // + ; + + // + return result; +} + +// +// Short Cycle Over Min Of Cycle Channels ... +bool XCHMAIsSCOverMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 > nonOfShortCycleMin1 + // + ; + + // + return result; +} + +// +// Short Cycle Under Min Of Cycle Channels ... +bool XCHMAIsSCUnderMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 < nonOfShortCycleMin1 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Over Max Of Cycle Channels ... +bool XCHMAIsSCCrossedOverMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMin2 = XCHMAGetCycleMinValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + double nonOfShortCycleMax2 = XCHMAGetCyclesMaxValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 > nonOfShortCycleMax1 && + shortCycleMin2 <= nonOfShortCycleMax2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Under Max Of Cycle Channels ... +bool XCHMAIsSCCrossedUnderMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMax2 = XCHMAGetCycleMaxValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + double nonOfShortCycleMax2 = XCHMAGetCyclesMaxValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 < nonOfShortCycleMax1 && + shortCycleMax2 >= nonOfShortCycleMax2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Over Min Of Cycle Channels ... +bool XCHMAIsSCCrossedOverMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMin2 = XCHMAGetCycleMinValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + double nonOfShortCycleMin2 = XCHMAGetCyclesMinValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 > nonOfShortCycleMin1 && + shortCycleMin2 <= nonOfShortCycleMin2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Under Min Of Cycle Channels ... +bool XCHMAIsSCCrossedUnderMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMax2 = XCHMAGetCycleMaxValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + double nonOfShortCycleMin2 = XCHMAGetCyclesMinValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 < nonOfShortCycleMin1 && + shortCycleMax2 >= nonOfShortCycleMin2 + // + ; + + // + return result; +} + +// +// Long Cycle ... +// + +// +// Check LC is Peak ... +bool XCHMAIsLCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMALcSlowBuffer + // + ); + + // + return result; +} + +// +// Check LC is Vale ... +bool XCHMAIsLCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMALcSlowBuffer + // + ); + + // + return result; +} + +// +// Check LC Fast Crossed Over Slow ... +bool XCHMAIsLCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Over Slow ... +bool XCHMAIsLCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Crossed Under Slow ... +bool XCHMAIsLCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Under Slow ... +bool XCHMAIsLCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get Trend Power ... +double XCHMAGetLCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMALcFastBuffer[bar_index] - xCHMALcSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsLCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetLCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetLCTrendPower(i + 1); + double iTrend = XCHMAGetLCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsLCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetLCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetLCTrendPower(i + 1); + double iTrend = XCHMAGetLCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Medium Cycle ... +// + +// +// Check MC is Peak ... +bool XCHMAIsMCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMAMcSlowBuffer + // + ); + + // + return result; +} + +// +// Check MC is Vale ... +bool XCHMAIsMCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMAMcSlowBuffer + // + ); + + // + return result; +} + +// +// Check MC Fast Crossed Over Slow ... +bool XCHMAIsMCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Over Slow ... +bool XCHMAIsMCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Crossed Under Slow ... +bool XCHMAIsMCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Under Slow ... +bool XCHMAIsMCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get Trend Power ... +double XCHMAGetMCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMAMcFastBuffer[bar_index] - xCHMAMcSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsMCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetMCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetMCTrendPower(i + 1); + double iTrend = XCHMAGetMCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsMCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetMCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetMCTrendPower(i + 1); + double iTrend = XCHMAGetMCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Short Cycle ... +// + +// +// Check SC is Peak ... +bool XCHMAIsSCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMAScSlowBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XCHMAIsSCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMAScSlowBuffer + // + ); + + // + return result; +} + +// +// Check SC Fast Crossed Over Slow ... +bool XCHMAIsSCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Over Slow ... +bool XCHMAIsSCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Crossed Under Slow ... +bool XCHMAIsSCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Under Slow ... +bool XCHMAIsSCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get SC Trend Power ... +double XCHMAGetSCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMAScFastBuffer[bar_index] - xCHMAScSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check SC Trends Up ... +bool XCHMAIsSCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetSCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetSCTrendPower(i + 1); + double iTrend = XCHMAGetSCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check SC Trends Down ... +bool XCHMAIsSCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetSCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetSCTrendPower(i + 1); + double iTrend = XCHMAGetSCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Utility Functions ... +// + +// +// Check a Cycle is Over of Another ... +bool XCHMAIsCycleOverAnother( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES sourceCycle, // Specified Cycle ... + ENUM_XCHMA_CYCLES destCycle // Specified Cycle ... +) +{ + // + bool result = false; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceMinValue = XCHMAGetCycleMinValue(bar_index, sourceCycle); + double destMaxValue = XCHMAGetCycleMaxValue(bar_index, destCycle); + + // + result = + // + sourceMinValue > destMaxValue + // + ; + + // + return result; +} + +// +// Check a Cycle is Under of Another ... +bool XCHMAIsCycleUnderAnother( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES sourceCycle, // Specified Cycle ... + ENUM_XCHMA_CYCLES destCycle // Specified Cycle ... +) +{ + // + bool result = false; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceMaxValue = XCHMAGetCycleMaxValue(bar_index, sourceCycle); + double destMinValue = XCHMAGetCycleMinValue(bar_index, destCycle); + + // + result = + // + sourceMaxValue < destMinValue + // + ; + + // + return result; +} + +// +// Get Cycle Min Value ... +double XCHMAGetCycleMinValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = MathMin( + xCHMALcFastBuffer[bar_index], + xCHMALcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = MathMin( + xCHMAMcFastBuffer[bar_index], + xCHMAMcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = MathMin( + xCHMAScFastBuffer[bar_index], + xCHMAScSlowBuffer[bar_index]); + break; + } + + // + return result; +} + +// +// Get Cycles Min Value ... +double XCHMAGetCyclesMinValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES &cycle[] // Specified Cycles ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + // + bar_index <= 0 || + ArraySize(cycle) <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1) + // + ) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycle); i++) + { + // + ENUM_XCHMA_CYCLES iCycle = cycle[i]; + double iValue = XCHMAGetCycleMinValue( + bar_index, + iCycle); + + // + result = result == 0 || result > iValue ? iValue : result; + } + + // + return result; +} + +// +// Get Cycle Max Value ... +double XCHMAGetCycleMaxValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = MathMax( + xCHMALcFastBuffer[bar_index], + xCHMALcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = MathMax( + xCHMAMcFastBuffer[bar_index], + xCHMAMcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = MathMax( + xCHMAScFastBuffer[bar_index], + xCHMAScSlowBuffer[bar_index]); + break; + } + + // + return result; +} + +// +// Get Cycles Max Value ... +double XCHMAGetCyclesMaxValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES &cycle[] // Specified Cycles ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + // + bar_index <= 0 || + ArraySize(cycle) <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1) + // + ) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycle); i++) + { + // + ENUM_XCHMA_CYCLES iCycle = cycle[i]; + double iValue = XCHMAGetCycleMaxValue( + bar_index, + iCycle); + + // + result = result == 0 || result < iValue ? iValue : result; + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XCHMAIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xCHMALcFastBuffer) < size || + ArraySize(xCHMALcSlowBuffer) < size || + // + ArraySize(xCHMAMcFastBuffer) < size || + ArraySize(xCHMAMcSlowBuffer) < size || + // + ArraySize(xCHMAScFastBuffer) < size || + ArraySize(xCHMAScSlowBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Add Specified Object to it's correspond Buffer ... +void Add( + ENUM_XCHMA_CYCLES item, + ENUM_XCHMA_CYCLES &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// END XCHMA Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..19d3417 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 @@ -0,0 +1,358 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XFI Oscillator"; + +// // +// input int xFILength = 18; // Market Length +// input ENUM_MA_METHOD xFIMethod = MODE_SMA; // MA Method +// input ENUM_APPLIED_VOLUME xFIAppliedTo = VOLUME_TICK; // Applied To + +// +// Configurations ... +int xFILength = 18; // Market Length +ENUM_MA_METHOD xFIMethod = MODE_SMA; // MA Method +ENUM_APPLIED_VOLUME xFIAppliedTo = VOLUME_TICK; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xFIHandler = INVALID_HANDLE; +double xFIBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XFIValidateInputs() +{ + // + bool result = false; + + // + result = xFILength > 2; + + // + if (!result) + { + // + LogMessage("XFI Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XFIInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XFI Handler ... + ArraySetAsSeries(xFIBuffer, true); + xFIHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xfi.oscillator", + // + // Inputs ... + xFILength, + xFIMethod, + xFIAppliedTo + // + ); + if (xFIHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XFI Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XFIReleaseHandlers() +{ + IndicatorRelease(xFIHandler); +} + +// +// Handle Reading Buffers ... +void XFIReadBuffers( + int xFIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XFI Signal ... + CopyBuffer( + xFIHandler, + 0, + 0, + xFIItemsPerTick, + xFIBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XFI Custom Functions ... +// + +// +// Check SC is Peak ... +bool XFIIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XFIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xFIBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XFIIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XFIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xFIBuffer + // + ); + + // + return result; +} + +// +// Detect XFI Crossed Over Zero ... +bool XFIIsCrossedOverZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] > 0 && + xFIBuffer[bar_index + 1] <= 0; + + // + return result; +} + +// +// Detect XFI Over Zero ... +bool XFIIsOverZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] > 0; + + // + return result; +} + +// +// Detect XFI Crossed Under Zero ... +bool XFIIsCrossedUnderZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] < 0 && + xFIBuffer[bar_index + 1] >= 0; + + // + return result; +} + +// +// Detect XFI Under Zero ... +bool XFIIsUnderZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] < 0; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XFIIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xFIBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XFI Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 new file mode 100644 index 0000000..e6a92f6 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 @@ -0,0 +1,668 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XLH Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XLH Indicator Buffer Lines ... +enum ENUM_X_XLH_BUFFER_LINES +{ + X_XLH_HH_LINE = 0, + X_XLH_LL_LINE = 1, + X_XLH_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XLH Indicator"; + +// input int xLHLength = 72; // Length +// input ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method + +// +// Configurations ... +int xLHLength = 72; // Length +ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +// +int xLHHandler = INVALID_HANDLE; + +// +double xLHHHBuffer[]; +double xLHLLBuffer[]; +double xLHSignalBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XLHValidateInputs() +{ + // + bool result = false; + + // + result = xLHLength >= 2; + + // + if (!result) + { + // + LogMessage("XLH Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XLHInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XLH Handler ... + ArraySetAsSeries(xLHHHBuffer, true); + ArraySetAsSeries(xLHLLBuffer, true); + ArraySetAsSeries(xLHSignalBuffer, true); + + // + xLHHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xlh.indicator", + // + // Inputs ... + xLHLength, + xLHHHMode, + xLHLLMode + // + ); + if (xLHHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XLH Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XLHReleaseHandlers() +{ + IndicatorRelease(xLHHandler); +} + +// +// Handle Reading Buffers ... +void XLHReadBuffers( + int xLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // HH Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_HH_LINE, + 0, + xLHItemsPerTick, + xLHHHBuffer + // + ); + + // + // LL Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_LL_LINE, + 0, + xLHItemsPerTick, + xLHLLBuffer + // + ); + + // + // Signal Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_SIGNAL_LINE, + 0, + xLHItemsPerTick, + xLHSignalBuffer + // + ); +} + +// +// END Handler Funcions ... +// + +// +// START XLH Custom Functions ... +// + +// +// TODO: What we have to Implement ... +// - [] + +// +// Check Candle High is HH ... +bool XLHIsHighAttachedHH( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle = GetCandle(bar_index); + + // + result = + // + candle.high == xLHHHBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Candle Low is LL ... +bool XLHIsLowAttachedLL( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle = GetCandle(bar_index); + + // + result = + // + candle.low == xLHLLBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Jumping Up Signal ... +bool XLHIsPriceCrossedOverSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + XOHCL candle2 = GetCandle(bar_index + 1); + + // + result = + // + candle1.low > xLHSignalBuffer[bar_index] && + candle2.low < xLHSignalBuffer[bar_index + 1] + // + ; + + // + return result; +} + +// +// Check Price Over Signal ... +bool XLHIsPriceOverSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.low > xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Jumping Down Signal ... +bool XLHIsPriceCrossedUnderSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + XOHCL candle2 = GetCandle(bar_index + 1); + + // + result = + // + candle1.high < xLHSignalBuffer[bar_index] && + candle2.high > xLHSignalBuffer[bar_index + 1] + // + ; + + // + return result; +} + +// +// Check Price Down Signal ... +bool XLHIsPriceUnderSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.high < xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Ranging Signal ... +bool XLHIsPriceInSignalRange( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.high > xLHSignalBuffer[bar_index] && + candle1.low < xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check HH Increased ... +bool XLHIsHHIncreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xLHHHBuffer + // + ); + + // + return result; +} + +// +// Check HH Decreased ... +bool XLHIsHHDecreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xLHHHBuffer + // + ); + + // + return result; +} + +// +// Check LL Increased ... +bool XLHIsLLIncreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xLHLLBuffer + // + ); + + // + return result; +} + +// +// Check LL Decreased ... +bool XLHIsLLDecreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xLHLLBuffer + // + ); + + // + return result; +} + +// +// Check HH Same in Length ... +bool XLHIsHHSameInLength( + int bar_index, // Specified Index ... + int length = 5 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + double value1 = xLHHHBuffer[bar_index]; + + // + // Loop ... + result = true; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iValue = xLHHHBuffer[i]; + if (iValue != value1) + { + // + result = false; + + // + break; + } + } + + // + return result; +} + +// +// Check LL Same in Length ... +bool XLHIsLLSameInLength( + int bar_index, // Specified Index ... + int length = 5 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + double value1 = xLHLLBuffer[bar_index]; + + // + // Loop ... + result = true; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iValue = xLHLLBuffer[i]; + if (iValue != value1) + { + // + result = false; + + // + break; + } + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XLHIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xLHHHBuffer) < size || + ArraySize(xLHLLBuffer) < size || + ArraySize(xLHSignalBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XLH Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 new file mode 100644 index 0000000..f90f15b --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 @@ -0,0 +1,249 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XOBD Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XOBD Indicator"; + +// input int xOBDLength = 5; // Swing Length +// input uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code +// input color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color +// input uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code +// input color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color + +// +// Configurations ... +int xOBDLength = 5; // Swing Length +uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code +color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color +uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code +color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +// +int xOBDHandler = INVALID_HANDLE; + +// +double xOBDBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XOBDValidateInputs() +{ + // + bool result = false; + + // + result = xOBDLength >= 2; + + // + if (!result) + { + // + LogMessage("XOBD Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XOBDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XOBD Handler ... + ArraySetAsSeries(xOBDBuffer, true); + + // + xOBDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xobd.indicator", + // + // Inputs ... + xOBDLength, + xOBDSwingHighArrowCode, + xOBDSwingHighArrowColor, + xOBDSwingLowArrowCode, + xOBDSwingLowArrowColor + // + ); + if (xOBDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XOBD Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XOBDReleaseHandlers() +{ + IndicatorRelease(xOBDHandler); +} + +// +// Handle Reading Buffers ... +void XOBDReadBuffers( + int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // OBD Buffer ... + CopyBuffer( + xOBDHandler, + 0, + 0, + xOBDItemsPerTick, + xOBDBuffer + // + ); +} + +// +// END Handler Funcions ... +// + +// +// START XOBD Custom Functions ... +// + +// +// Check is Swing Low Occured or not ... +bool XOBDIsSwingLow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = xOBDBuffer[bar_index] == X_SWING_LOW; + + // + return result; +} + +// +// Check is Swing High Occured or not ... +bool XOBDIsSwingHigh( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = xOBDBuffer[bar_index] == X_SWING_HIGH; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XOBDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xOBDBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XOBD Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..e6971b7 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 @@ -0,0 +1,433 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XRSI Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XRSI Oscillator Buffer Lines ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XRSI Oscillator"; + +// // +// input group "XRSI Market"; +// input int xRSILength = 18; // Market Length +// input ENUM_APPLIED_PRICE xRSIAppliedTo = PRICE_OPEN; // Applied To + +// // +// input group "XRSI Short Entry"; +// input double xRSIShortEntryValue = 70; // Short Entry Level +// input color xRSIShortEntryColor = clrRed; // Short Entry Level Color +// input ENUM_LINE_STYLE xRSIShortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// // +// input group "XRSI Short Exit"; +// input double xRSIShortExitValue = 40; // Short Exit Level +// input color xRSIShortExitColor = clrRed; // Short Exit Level Color +// input ENUM_LINE_STYLE xRSIShortExitLineStyle = STYLE_DOT; // Short Exit Style + +// // +// input group "XRSI Long Entry"; +// input double xRSILongEntryValue = 30; // Long Entry Level +// input color xRSILongEntryColor = clrRed; // Long Entry Level Color +// input ENUM_LINE_STYLE xRSILongEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// // +// input group "XRSI Long Exit"; +// input double xRSILongExitValue = 60; // Long Exit Level +// input color xRSILongExitColor = clrRed; // Long Exit Level Color +// input ENUM_LINE_STYLE xRSILongExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// Configurations ... +int xRSILength = 18; // Market Length +ENUM_APPLIED_PRICE xRSIAppliedTo = PRICE_OPEN; // Applied To + +// +double xRSIShortEntryValue = 70; // Short Entry Level +color xRSIShortEntryColor = clrRed; // Short Entry Level Color +ENUM_LINE_STYLE xRSIShortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// +double xRSIShortExitValue = 40; // Short Exit Level +color xRSIShortExitColor = clrRed; // Short Exit Level Color +ENUM_LINE_STYLE xRSIShortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +double xRSILongEntryValue = 30; // Long Entry Level +color xRSILongEntryColor = clrRed; // Long Entry Level Color +ENUM_LINE_STYLE xRSILongEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// +double xRSILongExitValue = 60; // Long Exit Level +color xRSILongExitColor = clrRed; // Long Exit Level Color +ENUM_LINE_STYLE xRSILongExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xRSIHandler = INVALID_HANDLE; +double xRSIBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XRSIValidateInputs() +{ + // + bool result = false; + + // + result = + xRSILongEntryValue < xRSILongExitValue && + xRSIShortEntryValue > xRSIShortExitValue && + xRSIShortEntryValue > xRSILongExitValue && + xRSIShortExitValue < xRSILongExitValue; + + // + if (!result) + { + // + LogMessage("XRSI Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XRSIInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XRSI Handler ... + ArraySetAsSeries(xRSIBuffer, true); + xRSIHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xrsi.oscillator", + // + // Inputs ... + // + // Market ... + "", + xRSILength, + xRSIAppliedTo, + // + // Short Entry ... + "", + xRSIShortEntryValue, + xRSIShortEntryColor, + xRSIShortEntryLineStyle, + // + // Short Exit ... + "", + xRSIShortExitValue, + xRSIShortExitColor, + xRSIShortExitLineStyle, + // + // Long Entry ... + "", + xRSILongEntryValue, + xRSILongEntryColor, + xRSILongEntryLineStyle, + // + // Long Exit ... + "", + xRSILongExitValue, + xRSILongExitColor, + xRSILongExitLineStyle + // + ); + if (xRSIHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XRSI Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XRSIReleaseHandlers() +{ + IndicatorRelease(xRSIHandler); +} + +// +// Handle Reading Buffers ... +void XRSIReadBuffers( + int xRSIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XRSI Signal ... + CopyBuffer( + xRSIHandler, + 0, + 0, + xRSIItemsPerTick, + xRSIBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XRSI Custom Functions ... +// + +// +// Check SC is Peak ... +bool XRSIIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xRSIBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XRSIIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xRSIBuffer + // + ); + + // + return result; +} + +// +// RSI Value GO Up from Long Entry ... +bool XRSIIsCrossedOverLongEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongEntryValue && + xRSIBuffer[bar_index + 2] <= xRSILongEntryValue; + + // + return result; +} + +// +// RSI Value GO Up from Long Exit ... +bool XRSIIsCrossedOverLongExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongExitValue && + xRSIBuffer[bar_index + 2] <= xRSILongExitValue; + + // + return result; +} + +// +// RSI Value Go Down Short Entry ... +bool XRSIIsCrossedUnderShortEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortEntryValue && + xRSIBuffer[bar_index + 2] >= xRSIShortEntryValue; + + // + return result; +} + +// +// RSI Value Go Down Short Exit ... +bool XRSIIsCrossedUnderShortExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortExitValue && + xRSIBuffer[bar_index + 2] >= xRSIShortExitValue; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XRSIIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xRSIBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XRSI Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..6286228 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 @@ -0,0 +1,931 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTD Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; + +// +// XTD Oscillator Buffer Lines ... +enum ENUM_X_XTD_BUFFER_LINES +{ + X_XTD_BULLISH_POWER_LINE = 0, + X_XTD_BEARISH_POWER_LINE = 1, + X_XTD_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XTD Oscillator"; + +// input int xTDLength = 18; // Market Length +// input bool xTDDrawCrosses = false; // Draw Cross Arrows +// input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code +// input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color +// input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code +// input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color + +// +// Configurations ... +int xTDLength = 18; // Market Length +bool xTDDrawCrosses = false; // Draw Cross Arrows +uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code +color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color +uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code +color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTDHandler = INVALID_HANDLE; +double xTDBullishBuffer[]; +double xTDBearishBuffer[]; +double xTDSignalBuffer[]; +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTDValidateInputs() +{ + // + bool result = false; + + // + result = xTDLength >= 2; + + // + if (!result) + { + // + LogMessage("XTD Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XTDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTD Handler ... + ArraySetAsSeries(xTDBullishBuffer, true); + ArraySetAsSeries(xTDBearishBuffer, true); + ArraySetAsSeries(xTDSignalBuffer, true); + xTDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtd.oscillator", + // + // Inputs ... + xTDLength, + xTDDrawCrosses, + xTDBullishArrowCode, + xTDBullishArrowColor, + xTDBearishArrowCode, + xTDBearishArrowColor); + if (xTDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTD Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XTDReleaseHandlers() +{ + IndicatorRelease(xTDHandler); +} + +// +// Handle Reading Buffers ... +void XTDReadBuffers( + int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BULLISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBullishBuffer); + + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BEARISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBearishBuffer); + + // + // XTD Signal Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_SIGNAL_LINE, + 0, + xTDItemsPerTick, + xTDSignalBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTD Custom Functions ... +// + +// +// Check Signal Vale ... +bool XTDIsSignalVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDSignalBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsSignalPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDSignalBuffer + // + ); + + // + return result; +} + +// +// Check Signal Vale ... +bool XTDIsBullishVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDBullishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsBullishPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDBullishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Vale ... +bool XTDIsBearishVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDBearishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsBearishPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDBearishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... + +// +// Check Bullish Crossed Over Bearish ... +bool XTDIsBullCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Over Bearish ... +bool XTDIsBullOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Crossed Under Bearish ... +bool XTDIsBullCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Under Bearish ... +bool XTDIsBullUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Over Bearish ... +bool XTDIsSignalCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Over Bearish ... +bool XTDIsSignalOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Under Bearish ... +bool XTDIsSignalCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Under Bearish ... +bool XTDIsSignalUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDSignalBuffer) < size) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Count Signal Crossed Over Bear ... +int XTDCountSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Signal Crossed Under Bear ... +int XTDCountSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Over Bear ... +int XTDCountBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Under Bear ... +int XTDCountBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Over Bear ... +int XTDFindLastSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Onder Bear ... +int XTDFindLastSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Over Bear ... +int XTDFindLastBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Under Bear ... +int XTDFindLastBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// END XTD Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 new file mode 100644 index 0000000..a871ed4 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 @@ -0,0 +1,598 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTM Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; + +// +// XTM Indicator Buffer Lines ... +enum ENUM_X_XTM_BUFFER_LINES +{ + X_XTM_MA_LINE = 0, + X_XTM_MC_COLOR_LINE = 1, + X_XTM_STATE_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XTM Indicator"; + +// input int xTMMaPeriod = 18; // Period +// input int xTMMaShift = 0; // Shift +// input ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method +// input ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_OPEN; // Applied To + +// +// Configurations ... +int xTMMaPeriod = 18; // Period +int xTMMaShift = 0; // Shift +ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method +ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_OPEN; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTMHandler = INVALID_HANDLE; +double xTMMaBuffer[]; +double xTMStateBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTMValidateInputs() +{ + // + bool result = false; + + // + result = xTMMaPeriod >= 2; + + // + if (!result) + { + // + LogMessage("XTM Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XTMInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Handler ... + ArraySetAsSeries(xTMMaBuffer, true); + ArraySetAsSeries(xTMStateBuffer, true); + xTMHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtm.indicator", + // + // Inputs ... + xTMMaPeriod, + xTMMaShift, + xTMMaMethod, + xTMMaAppliedTo); + if (xTMHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTM Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XTMReleaseHandlers() +{ + IndicatorRelease(xTMHandler); +} + +// +// Handle Reading Buffers ... +void XTMReadBuffers( + int xTMItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // Ma Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_MA_LINE, + 0, + xTMItemsPerTick, + xTMMaBuffer); + + // + // State Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_STATE_LINE, + 0, + xTMItemsPerTick, + xTMStateBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTM Custom Functions ... +// + +// +// Find Peak based On this Indicator ... +bool XTMIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTMMaBuffer + // + ); + + // + return result; +} + +// +// Find Vale based On this Indicator ... +bool XTMIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTMMaBuffer + // + ); + + // + return result; +} + +// +// Check TM Crossed Up ... +bool XTMIsStartBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] != X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Up After Neutural State ... +bool XTMIsStartBullishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Up State ... +bool XTMIsBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State ... +bool XTMIsEndBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] != X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State By Neutural ... +bool XTMIsEndBullishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL && + xTMStateBuffer[bar_index + 1] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down ... +bool XTMIsStartBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] != X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down After Neutural State ... +bool XTMIsStartBearishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Down State ... +bool XTMIsBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State ... +bool XTMIsEndBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] != X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State By Neutural ... +bool XTMIsEndBearishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL && + xTMStateBuffer[bar_index + 1] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM In Neutural State ... +bool XTMIsNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTMIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xTMMaBuffer) < size || + ArraySize(xTMStateBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XTM Custom Functions ... +// diff --git a/XEU5/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 b/XEU5/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 new file mode 100644 index 0000000..875eec0 --- /dev/null +++ b/XEU5/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 @@ -0,0 +1,1179 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTS Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +///////////////////////////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// Methods to Calculate TimeFrames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// Buffer Lines ... +enum ENUM_X_XTS_BUFFER_LINES +{ + X_XTS_CURRENT_LINE = 0, + X_XTS_NEAREST_LINE = 1, + X_XTS_MEDIEST_LINE = 2, + X_XTS_FAREST_LINE = 3, +}; + +// +// Periods ... +enum ENUM_X_XTS_PERIODS +{ + // + // Current Period ... + X_XTS_PERIOD_CURRENT, + // + // Nearest Period ... + X_XTS_PERIOD_NEAREST, + // + // Mediest Period ... + X_XTS_PERIOD_MEDIEST, + // + // Farest Period ... + X_XTS_PERIOD_FAREST, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// // +// input group "XTS Oscillator"; + +// // +// input group "XTS Current Period"; +// input ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To +// // +// input group "XTS Nearest Period"; +// input ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +// input ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame +// input ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// // +// input group "XTS Mediest Period"; +// input ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +// input ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame +// input ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// // +// input group "XTS Farest Period"; +// input ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period +// input ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame +// input ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// Configurations ... +ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To +// +ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame +ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// +ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame +ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// +ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period +ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame +ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTSHandler = INVALID_HANDLE; +double xTSCurrentBuffer[]; +double xTSNearestBuffer[]; +double xTSMediestBuffer[]; +double xTSFarestBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTSValidateInputs() +{ + // + bool result = false; + + // + result = true; + + // + if (!result) + { + // + LogMessage("XTS Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XTSInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTS Handler ... + ArraySetAsSeries(xTSCurrentBuffer, true); + ArraySetAsSeries(xTSNearestBuffer, true); + ArraySetAsSeries(xTSMediestBuffer, true); + ArraySetAsSeries(xTSFarestBuffer, true); + xTSHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xts.oscillator", + // + // Inputs ... + "", + xTSCurrentAppliedTo, + "", + xTSNearestMethod, + xTSNearestPeriod, + xTSNearestAppliedTo, + "", + xTSMediestMethod, + xTSMediestPeriod, + xTSMediestAppliedTo, + "", + xTSFarestMethod, + xTSFarestPeriod, + xTSFarestAppliedTo + // + ); + if (xTSHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTS Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XTSReleaseHandlers() +{ + IndicatorRelease(xTSHandler); +} + +// +// Handle Reading Buffers ... +void XTSReadBuffers( + int xTSItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XTS Current ... + CopyBuffer( + xTSHandler, + X_XTS_CURRENT_LINE, + 0, + xTSItemsPerTick, + xTSCurrentBuffer); + + // + // XTS Nearest ... + CopyBuffer( + xTSHandler, + X_XTS_NEAREST_LINE, + 0, + xTSItemsPerTick, + xTSNearestBuffer); + + // + // XTS Mediest ... + CopyBuffer( + xTSHandler, + X_XTS_MEDIEST_LINE, + 0, + xTSItemsPerTick, + xTSMediestBuffer); + + // + // XTS Farest ... + CopyBuffer( + xTSHandler, + X_XTS_FAREST_LINE, + 0, + xTSItemsPerTick, + xTSFarestBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTS Custom Functions ... +// + +// +// Calculate Min Value ... +double XTSGetMinValue( + int bar_index // Specified Index ... +) +{ + // + ENUM_X_XTS_PERIODS periods[]; + XTSGetAllPeriodsEnum(periods); + + // + double result = XTSGetPeriodsMinValue( + periods, + bar_index); + + // + return result; +} + +// +// Calculate Max Value ... +double XTSGetMaxValue( + int bar_index // Specified Index ... +) +{ + // + ENUM_X_XTS_PERIODS periods[]; + XTSGetAllPeriodsEnum(periods); + + // + double result = XTSGetPeriodsMaxValue( + periods, + bar_index); + + // + return result; +} + +// +// Check if all Periods Values are Same ... +bool XTSIsAllSame( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xTSCurrentBuffer[bar_index] == xTSNearestBuffer[bar_index] && + xTSNearestBuffer[bar_index] == xTSMediestBuffer[bar_index] && + xTSMediestBuffer[bar_index] == xTSFarestBuffer[bar_index]; + + // + return result; +} + +// +// Current ... + +// +// Check Current Buffer is Min Or Not ... +bool XTSIsCurrentMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double minValue = XTSGetMinValue(bar_index); + + // + result = + xTSCurrentBuffer[bar_index] == minValue; + + // + return result; +} + +// +// Check Current Buffer is Max Or Not ... +bool XTSIsCurrentMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double maxValue = XTSGetMaxValue(bar_index); + + // + result = + xTSCurrentBuffer[bar_index] == maxValue; + + // + return result; +} + +// +// Current VS Nearest ... + +// +// Check Current Crossed Over Nearest ... +bool XTSIsCurrentCrossedOverNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Over Nearest ... +bool XTSIsCurrentOverNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Nearest ... +bool XTSIsCurrentCrossedUnderNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Under Nearest ... +bool XTSIsCurrentUnderNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Current VS Mediest ... + +// +// Check Current Crossed Over Mediest ... +bool XTSIsCurrentCrossedOverMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Over Mediest ... +bool XTSIsCurrentOverMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Mediest ... +bool XTSIsCurrentCrossedUnderMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Under Mediest ... +bool XTSIsCurrentUnderMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Current VS Farest ... + +// +// Check Current Crossed Over Farest ... +bool XTSIsCurrentCrossedOverFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Over Farest ... +bool XTSIsCurrentOverFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Farest ... +bool XTSIsCurrentCrossedUnderFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Under Farest ... +bool XTSIsCurrentUnderFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Globally Custom Functions ... + +// +// Check a Period Crossed Over another one ... +bool XTSIsPeriodCrossedOverAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + double sourceValue1 = XTSGetPeriodValue( + source, + bar_index + 1); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + double destValue1 = XTSGetPeriodValue( + dest, + bar_index + 1); + + // + result = + sourceValue > destValue && + sourceValue1 <= destValue1; + + // + return result; +} + +// +// Check a Period Over another one ... +bool XTSIsPeriodOverAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + + // + result = + sourceValue > destValue; + + // + return result; +} + +// +// Check a Period Crossed Under another one ... +bool XTSIsPeriodCrossedUnderAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + double sourceValue1 = XTSGetPeriodValue( + source, + bar_index + 1); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + double destValue1 = XTSGetPeriodValue( + dest, + bar_index + 1); + + // + result = + sourceValue < destValue && + sourceValue1 >= destValue1; + + // + return result; +} + +// +// Check a Period Under another one ... +bool XTSIsPeriodUnderAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + + // + result = + sourceValue < destValue; + + // + return result; +} + +// +// Retrieve Specific Period's Value from Buffer for Specific Bar Index ... +double XTSGetPeriodValue( + ENUM_X_XTS_PERIODS period, // Specified Period to read it's Value ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (period) + { + // + case X_XTS_PERIOD_CURRENT: + result = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + result = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + result = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + result = xTSFarestBuffer[bar_index]; + break; + } + + // + return result; +} + +// +// Fill All Exists Periods ... +void XTSGetAllPeriodsEnum( + ENUM_X_XTS_PERIODS &result[] // Hold's Result ... +) +{ + // + CleanBuffer(result); + + // + Add( + X_XTS_PERIOD_CURRENT, + result); + + // + Add( + X_XTS_PERIOD_NEAREST, + result); + + // + Add( + X_XTS_PERIOD_MEDIEST, + result); + + // + Add( + X_XTS_PERIOD_FAREST, + result); +} + +// +// Fill All Exists Periods Except ... +void XTSGetAllPeriodsEnumExcept( + ENUM_X_XTS_PERIODS &result[], // Hold's Result ... + ENUM_X_XTS_PERIODS exception // Excepted Period ... +) +{ + // + CleanBuffer(result); + + // + ENUM_X_XTS_PERIODS allPeriods[]; + XTSGetAllPeriodsEnum(allPeriods); + int periodsCount = ArraySize(allPeriods); + if (periodsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; + + // + if (iPeriod != exception) + { + Add( + iPeriod, + result); + } + } +} + +// +// Fill All Exists Periods Except ... +void XTSGetAllPeriodsEnumExcept( + ENUM_X_XTS_PERIODS &result[], // Hold's Result ... + ENUM_X_XTS_PERIODS &exceptions[] // Excepted Periods ... +) +{ + // + CleanBuffer(result); + + // + ENUM_X_XTS_PERIODS allPeriods[]; + XTSGetAllPeriodsEnum(allPeriods); + int periodsCount = ArraySize(allPeriods); + if (periodsCount <= 0) + { + return; + } + + // + int exceptionsCount = ArraySize(exceptions); + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; + + // + bool canAddIPeriod = false; + if (exceptionsCount <= 0) + { + canAddIPeriod = true; + } + else + { + // + // Loop through Exceptions ... + for (int j = 0; j < exceptionsCount; j++) + { + // + ENUM_X_XTS_PERIODS jException = exceptions[j]; + + // + if (iPeriod == jException) + { + // + canAddIPeriod = false; + break; + } + + // + canAddIPeriod = true; + } + } + + // + if (canAddIPeriod) + { + // + Add( + iPeriod, + result); + } + } +} + +// +// Calculate Periods Min Value ... +double XTSGetPeriodsMinValue( + ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + int periodsCount = ArraySize(periods); + + // + // Validate Args ... + if ( + bar_index < 0 || + periodsCount <= 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = periods[i]; + + // + double iValue = 0; + + // + switch (iPeriod) + { + // + case X_XTS_PERIOD_CURRENT: + iValue = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + iValue = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + iValue = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + iValue = xTSFarestBuffer[bar_index]; + break; + } + + // + // Compare iValue to result ... + result = + result == 0 || + result > iValue + ? iValue + : result; + } + + // + return result; +} + +// +// Calculate Periods Max Value ... +double XTSGetPeriodsMaxValue( + ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + int periodsCount = ArraySize(periods); + + // + // Validate Args ... + if ( + bar_index < 0 || + periodsCount <= 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = periods[i]; + + // + double iValue = 0; + + // + switch (iPeriod) + { + // + case X_XTS_PERIOD_CURRENT: + iValue = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + iValue = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + iValue = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + iValue = xTSFarestBuffer[bar_index]; + break; + } + + // + // Compare iValue to result ... + result = + result == 0 || + result < iValue + ? iValue + : result; + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTSIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xTSCurrentBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +void Add( + ENUM_X_XTS_PERIODS item, // Specified Item ... + ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... +) +{ + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; +} + +void CleanBuffer( + ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... +) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// END XTS Custom Functions ... +// diff --git a/XEU5/Indicators/.gitkeep b/XEU5/Indicators/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Indicators/x-saherelm.xama.indicator.mq5 b/XEU5/Indicators/x-saherelm.xama.indicator.mq5 new file mode 100644 index 0000000..14d1ef7 --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xama.indicator.mq5 @@ -0,0 +1,353 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAMA Indicator +// --------------------------------------------- +// Name: XAMA +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XAMA Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XAMA" + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 1, + X_XAMA_BEARISH = -1, + X_XAMA_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Period +input int fastEMA = 2; // Fast EMA Period +input int slowEMA = 30; // Slow EMA Period +input int maShift = 0; // Shift +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XAMA" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Initializing MA Handler ... + maHandler = iAMA( + _Symbol, + _Period, + length, + fastEMA, + slowEMA, + maShift, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(maHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(fastEMA, slowEMA); + maxLength = MathMax(maxLength, length); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XAMA " + "(" + (string)length + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", length, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XAMA_BULLISH : lineColorIndex == 2 ? X_XAMA_BEARISH + : X_XAMA_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xchlh.oscillator.mq5 b/XEU5/Indicators/x-saherelm.xchlh.oscillator.mq5 new file mode 100644 index 0000000..5c74787 --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xchlh.oscillator.mq5 @@ -0,0 +1,753 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel LH Oscillator +// --------------------------------------------------- +// Name: XCHLH +// Description: detecting HH and LL based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHLH Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHLH" + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// Including Models Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotHHArrowCode = 234; // Hot HH Arrow Code +input color hotHHArrowColor = clrAqua; // Hot HH Arrow Color +input uchar hotLLArrowCode = 233; // Hot LL Arrow Code +input color hotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcLength = 28; // Length +input double lcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE lcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE lcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcHHColor = clrAqua; // Highest High Color +input color lcLLColor = clrFuchsia; // Lowest Low Color +input group "LC Drawings"; +input bool lcDrawHH = true; // Draw Highest High +input bool lcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcLength = 14; // Length +input double mcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE mcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE mcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcHHColor = clrLime; // Highest High Color +input color mcLLColor = clrRed; // Lowest Low Color +input group "MC Drawings"; +input bool mcDrawHH = true; // Draw Highest High +input bool mcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scLength = 7; // Length +input double scThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE scHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE scLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_DOT; // Draw Style +input color scHHColor = clrLightBlue; // Highest High Color +input color scLLColor = clrLightSalmon; // Lowest Low Color +input group "SC Drawings"; +input bool scDrawHH = true; // Draw Highest High +input bool scDrawLL = true; // Draw Lowest Low +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 7 +#property indicator_plots 6 + +// +// LC ... +#define lcHHBufferIndex 0 +#define lcLLBufferIndex 1 + +// +double lcHHBuffer[]; +double lcLLBuffer[]; + +// +// MC ... +#define mcHHBufferIndex 2 +#define mcLLBufferIndex 3 + +// +double mcHHBuffer[]; +double mcLLBuffer[]; + +// +// SC ... +#define scHHBufferIndex 4 +#define scLLBufferIndex 5 + +// +double scHHBuffer[]; +double scLLBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcLength, mcLength); + maxLength = MathMax(maxLength, scLength); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = + lcLength >= 4 && + lcLength > mcLength && + lcLength > scLength; + bool isMCInputsValid = + mcLength >= 4 && + mcLength > scLength && + mcLength < lcLength; + bool isSCInputsValid = + scLength >= 4 && + scLength < mcLength && + scLength < lcLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + LCCalculateBuffers(bar_index); + + // + // MC ... + MCCalculateBuffers(bar_index); + + // + // SC ... + SCCalculateBuffers(bar_index); + + // + // SIGNAL ... + SignalCalculateBuffers(bar_index); + + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC HH Buffer ... + string lcHHBufferLabel = ShortName + " LC HH (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcHHDrawType = lcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcHHBufferIndex, PLOT_LABEL, lcHHBufferLabel); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_COLOR, lcHHColor); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_TYPE, lcHHDrawType); + + // + // LC LL Buffer ... + string lcLLBufferLabel = ShortName + " LC LL (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcLLDrawType = lcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcLLBufferIndex, PLOT_LABEL, lcLLBufferLabel); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_COLOR, lcLLColor); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_TYPE, lcLLDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC HH Buffer ... + string mcHHBufferLabel = ShortName + " MC HH (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcHHDrawType = mcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcHHBufferIndex, PLOT_LABEL, mcHHBufferLabel); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_COLOR, mcHHColor); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_TYPE, mcHHDrawType); + + // + // MC LL Buffer ... + string mcLLBufferLabel = ShortName + " MC LL (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcLLDrawType = mcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcLLBufferIndex, PLOT_LABEL, mcLLBufferLabel); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_COLOR, mcLLColor); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_TYPE, mcLLDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC HH Buffer ... + string scHHBufferLabel = ShortName + " SC HH (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scHHDrawType = scDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scHHBufferIndex, PLOT_LABEL, scHHBufferLabel); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_COLOR, scHHColor); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_TYPE, scHHDrawType); + + // + // SC LL Buffer ... + string scLLBufferLabel = ShortName + " SC LL (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scLLDrawType = scDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scLLBufferIndex, PLOT_LABEL, scLLBufferLabel); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_COLOR, scLLColor); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_TYPE, scLLDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Calculations ... +void LCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = lcLength; + ENUM_SERIESMODE hhMode = lcHHMode; + ENUM_SERIESMODE llMode = lcLLMode; + double threshold = PipsToPrice(lcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + lcHHBuffer[bar_index] = hhValue; + lcLLBuffer[bar_index] = llValue; +} + +// +// MC Calculations ... +void MCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = mcLength; + ENUM_SERIESMODE hhMode = mcHHMode; + ENUM_SERIESMODE llMode = mcLLMode; + double threshold = PipsToPrice(mcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + mcHHBuffer[bar_index] = hhValue; + mcLLBuffer[bar_index] = llValue; +} + +// +// SC Calculations ... +void SCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = scLength; + ENUM_SERIESMODE hhMode = scHHMode; + ENUM_SERIESMODE llMode = scLLMode; + double threshold = PipsToPrice(scThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + scHHBuffer[bar_index] = hhValue; + scLLBuffer[bar_index] = llValue; +} + +// +// SIGNAL Calculations ... +void SignalCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC Values ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + double lcDelta = lcHH - lcLL; + double lcAvg = lcDelta / 2; + + // + // MC Values ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + double mcDelta = mcHH - mcLL; + double mcAvg = mcDelta / 2; + + // + // SC Values ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + double scDelta = scHH - scLL; + double scAvg = scDelta / 2; + + // + // Min Value ... + double minValue = MathMin( + scLL, mcLL); + minValue = MathMin( + lcLL, minValue); + + // + // Max Value ... + double maxValue = MathMin( + scHH, mcHH); + maxValue = MathMin( + lcHH, maxValue); +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + // + double lcHH1 = lcHHBuffer[bar_index + 1]; + double lcLL1 = lcLLBuffer[bar_index + 1]; + + // + // MC ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + // + double mcHH1 = mcHHBuffer[bar_index + 1]; + double mcLL1 = mcLLBuffer[bar_index + 1]; + + // + // SC ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + // + double scHH1 = scHHBuffer[bar_index + 1]; + double scLL1 = scLLBuffer[bar_index + 1]; + + // + bool isHotLLState = scLL == mcLL && mcLL == lcLL; + bool isHotLLState1 = scLL1 == mcLL1 && mcLL1 == lcLL1; + // + bool isHotHHState = scHH == mcHH && mcHH == lcHH; + bool isHotHHState1 = scHH1 == mcHH1 && mcHH1 == lcHH1; + + // + bool isHotLL = isHotLLState && !isHotLLState1; + bool isHotHH = isHotHHState && !isHotHHState1; + + // + double hotStateValue = X_XCHLH_NEUTURAL; + if (isHotHH) + { + hotStateValue = X_XCHLH_HOT_HH; + } + else if (isHotLL) + { + hotStateValue = X_XCHLH_HOT_LL; + } + + // + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotHHArea = hotStateValue == 1; + bool isHotLLArea = hotStateValue == -1; + if (isHotHHArea || isHotLLArea) + { + // + bool isHH = isHotHHArea; + + // + double price = isHH ? candle.high : candle.low; + ENUM_ARROW_ANCHOR anchor = isHH ? ANCHOR_BOTTOM : ANCHOR_TOP; + color clr = isHH ? hotHHArrowColor : hotLLArrowColor; + uchar arrowCode = isHH ? hotHHArrowCode : hotLLArrowCode; + string name = "HOT " + (isHH ? "HH" : "LL") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr, + STYLE_SOLID, + 1); + } + } +} +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xchma.oscillator.mq5 b/XEU5/Indicators/x-saherelm.xchma.oscillator.mq5 new file mode 100644 index 0000000..12d6c69 --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xchma.oscillator.mq5 @@ -0,0 +1,1153 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel Moving Averages Oscillator +// ---------------------------------------------------------------- +// Name: XCHMA +// Description: trend detecting based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHMA Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHMA" + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotBullishArrowCode = 228; // Hot Bullish Arrow Code +input color hotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color +input uchar hotBearishArrowCode = 230; // Hot Bearish Arrow Code +input color hotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcFastLength = 20; // Fast Length +input int lcSlowLength = 50; // Slow Length +input ENUM_MA_METHOD lcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE lcAppliedTo = PRICE_CLOSE; // Applied To +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcFastColor = clrAqua; // Fast Color +input color lcSlowColor = clrFuchsia; // Slow Color +input group "LC Drawings"; +input bool lcDrawFast = true; // Draw Fast +input bool lcDrawSlow = true; // Draw Slow +input bool lcDrawCrosses = true; // Draw Cross Lines + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcFastLength = 10; // Fast Length +input int mcSlowLength = 30; // Slow Length +input ENUM_MA_METHOD mcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE mcAppliedTo = PRICE_CLOSE; // Applied To +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcFastColor = clrLime; // Fast Color +input color mcSlowColor = clrRed; // Slow Color +input group "MC Drawings"; +input bool mcDrawFast = true; // Draw Fast +input bool mcDrawSlow = true; // Draw Slow +input bool mcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scFastLength = 7; // Fast Length +input int scSlowLength = 14; // Slow Length +input ENUM_MA_METHOD scMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE scAppliedTo = PRICE_CLOSE; // Applied To +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_SOLID; // Draw Style +input color scFastColor = clrLightBlue; // Fast Color +input color scSlowColor = clrLightSalmon; // Slow Color +input group "SC Drawings"; +input bool scDrawFast = true; // Draw Fast +input bool scDrawSlow = true; // Draw Slow +input bool scDrawCrosses = false; // Draw Cross Lines +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 7 +#property indicator_plots 6 + +// +// LC ... +#define lcFastBufferIndex 0 +#define lcSlowBufferIndex 1 + +// +double lcFastBuffer[]; +double lcSlowBuffer[]; + +// +// MC ... +#define mcFastBufferIndex 2 +#define mcSlowBufferIndex 3 + +// +double mcFastBuffer[]; +double mcSlowBuffer[]; + +// +// SC ... +#define scFastBufferIndex 4 +#define scSlowBufferIndex 5 + +// +double scFastBuffer[]; +double scSlowBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// LC ... +int lcFastHandler = INVALID_HANDLE; +int lcSlowHandler = INVALID_HANDLE; + +// +// MC ... +int mcFastHandler = INVALID_HANDLE; +int mcSlowHandler = INVALID_HANDLE; + +// +// SC ... +int scFastHandler = INVALID_HANDLE; +int scSlowHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init All Required Handlers ... + if (!InitHandlers()) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcFastLength, lcSlowLength); + + // + // Get Retrieved Values from indicators ... + // + // LC ... + int lcFastCalculatedBars = BarsCalculated(lcFastHandler); + int lcSlowCalculatedBars = BarsCalculated(lcSlowHandler); + + // + // MC ... + int mcFastCalculatedBars = BarsCalculated(mcFastHandler); + int mcSlowCalculatedBars = BarsCalculated(mcSlowHandler); + + // + // SC ... + int scFastCalculatedBars = BarsCalculated(scFastHandler); + int scSlowCalculatedBars = BarsCalculated(scSlowHandler); + + // + // Check Calculated Bars ... + if ( + // + // LC ... + lcFastCalculatedBars < maxLength || + lcSlowCalculatedBars < maxLength || + // + // MC ... + mcFastCalculatedBars < maxLength || + mcSlowCalculatedBars < maxLength || + // + // SC ... + scFastCalculatedBars < maxLength || + scSlowCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Copy Buffers from indicators ... + // + // LC ... + int lcFastCopiedItems = CopyBuffer(lcFastHandler, 0, 0, limit + 1, lcFastBuffer); + int lcSlowCopiedItems = CopyBuffer(lcSlowHandler, 0, 0, limit + 1, lcSlowBuffer); + + // + // MC ... + int mcFastCopiedItems = CopyBuffer(mcFastHandler, 0, 0, limit + 1, mcFastBuffer); + int mcSlowCopiedItems = CopyBuffer(mcSlowHandler, 0, 0, limit + 1, mcSlowBuffer); + + // + // SC ... + int scFastCopiedItems = CopyBuffer(scFastHandler, 0, 0, limit + 1, scFastBuffer); + int scSlowCopiedItems = CopyBuffer(scSlowHandler, 0, 0, limit + 1, scSlowBuffer); + + // + // Check Copied Items Number ... + if ( + // + // LC ... + lcFastCopiedItems <= 0 || + lcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = lcFastLength >= 4 && lcSlowLength > lcFastLength; + bool isMCInputsValid = mcFastLength >= 4 && mcSlowLength > mcFastLength; + bool isSCInputsValid = scFastLength >= 4 && scSlowLength > scFastLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid && + lcFastLength > mcFastLength && + mcFastLength > scFastLength) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Init Handlers ... +bool InitHandlers() +{ + // + bool result = false; + + // + // LC ... + result = LCInitHandlers(); + if (!result) + { + return result; + } + + // + // MC ... + result = MCInitHandlers(); + if (!result) + { + return result; + } + + // + // SC ... + result = SCInitHandlers(); + if (!result) + { + return result; + } + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC Fast Buffer ... + string lcFastBufferLabel = ShortName + " LC Fast (" + (string)lcFastLength + ")"; + ENUM_DRAW_TYPE lcFastDrawType = lcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcFastBuffer, true); + SetIndexBuffer(lcFastBufferIndex, lcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(lcFastBufferIndex, PLOT_LABEL, lcFastBufferLabel); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_COLOR, lcFastColor); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_BEGIN, lcFastLength); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_TYPE, lcFastDrawType); + + // + // LC Slow Buffer ... + string lcSlowBufferLabel = ShortName + " LC Slow (" + (string)lcSlowLength + ")"; + ENUM_DRAW_TYPE lcSlowDrawType = lcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcSlowBuffer, true); + SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(lcSlowBufferIndex, PLOT_LABEL, lcSlowBufferLabel); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_COLOR, lcSlowColor); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_BEGIN, lcSlowLength); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_TYPE, lcSlowDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC Fast Buffer ... + string mcFastBufferLabel = ShortName + " MC Fast (" + (string)mcFastLength + ")"; + ENUM_DRAW_TYPE mcFastDrawType = mcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcFastBuffer, true); + SetIndexBuffer(mcFastBufferIndex, mcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(mcFastBufferIndex, PLOT_LABEL, mcFastBufferLabel); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_COLOR, mcFastColor); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_BEGIN, mcFastLength); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_TYPE, mcFastDrawType); + + // + // MC Slow Buffer ... + string mcSlowBufferLabel = ShortName + " MC Slow (" + (string)mcSlowLength + ")"; + ENUM_DRAW_TYPE mcSlowDrawType = mcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcSlowBuffer, true); + SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(mcSlowBufferIndex, PLOT_LABEL, mcSlowBufferLabel); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_COLOR, mcSlowColor); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_BEGIN, mcSlowLength); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_TYPE, mcSlowDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC Fast Buffer ... + string scFastBufferLabel = ShortName + " SC Fast (" + (string)scFastLength + ")"; + ENUM_DRAW_TYPE scFastDrawType = scDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scFastBuffer, true); + SetIndexBuffer(scFastBufferIndex, scFastBuffer, INDICATOR_DATA); + PlotIndexSetString(scFastBufferIndex, PLOT_LABEL, scFastBufferLabel); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_COLOR, scFastColor); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_BEGIN, scFastLength); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_TYPE, scFastDrawType); + + // + // SC Slow Buffer ... + string scSlowBufferLabel = ShortName + " SC Slow (" + (string)scSlowLength + ")"; + ENUM_DRAW_TYPE scSlowDrawType = scDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scSlowBuffer, true); + SetIndexBuffer(scSlowBufferIndex, scSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(scSlowBufferIndex, PLOT_LABEL, scSlowBufferLabel); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_COLOR, scSlowColor); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_BEGIN, scSlowLength); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_TYPE, scSlowDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Init Handlers ... +bool LCInitHandlers() +{ + // + ResetLastError(); + + // + // LC Fast Handler ... + lcFastHandler = iMA( + _Symbol, + _Period, + lcFastLength, + 0, + lcMethod, + lcAppliedTo); + if (lcFastHandler == INVALID_HANDLE) + { + // + LogMessage("LC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // LC Slow Handler ... + lcSlowHandler = iMA( + _Symbol, + _Period, + lcSlowLength, + 0, + lcMethod, + lcAppliedTo); + if (lcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("LC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// MC Init Handlers ... +bool MCInitHandlers() +{ + // + ResetLastError(); + + // + // MC Fast Handler ... + mcFastHandler = iMA( + _Symbol, + _Period, + mcFastLength, + 0, + mcMethod, + mcAppliedTo); + if (mcFastHandler == INVALID_HANDLE) + { + // + LogMessage("MC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // MC Slow Handler ... + mcSlowHandler = iMA( + _Symbol, + _Period, + mcSlowLength, + 0, + mcMethod, + mcAppliedTo); + if (mcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("MC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// SC Init Handlers ... +bool SCInitHandlers() +{ + // + ResetLastError(); + + // + // SC Fast Handler ... + scFastHandler = iMA( + _Symbol, + _Period, + scFastLength, + 0, + scMethod, + scAppliedTo); + if (scFastHandler == INVALID_HANDLE) + { + // + LogMessage("SC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // SC Slow Handler ... + scSlowHandler = iMA( + _Symbol, + _Period, + scSlowLength, + 0, + scMethod, + scAppliedTo); + if (scSlowHandler == INVALID_HANDLE) + { + // + LogMessage("SC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// LC State ... +double GetLCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// MC State ... +double GetMCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// SC State ... +double GetSCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcFast = lcFastBuffer[bar_index]; + double lcSlow = lcSlowBuffer[bar_index]; + // + double lcFastPrev = lcFastBuffer[bar_index + 1]; + double lcSlowPrev = lcSlowBuffer[bar_index + 1]; + // + double lcState = GetLCState(bar_index); + + // + // MC ... + double mcFast = mcFastBuffer[bar_index]; + double mcSlow = mcSlowBuffer[bar_index]; + // + double mcFastPrev = mcFastBuffer[bar_index + 1]; + double mcSlowPrev = mcSlowBuffer[bar_index + 1]; + // + double mcState = GetMCState(bar_index); + + // + // SC ... + double scFast = scFastBuffer[bar_index]; + double scSlow = scSlowBuffer[bar_index]; + // + double scFastPrev = scFastBuffer[bar_index + 1]; + double scSlowPrev = scSlowBuffer[bar_index + 1]; + // + double scState = GetSCState(bar_index); + + // + // Detect HOT Bearish Area ... + bool isHotBearishArea = + lcFast < lcSlow && + mcFast < mcSlow && + scFast < scSlow; + // + bool isPrevHotBearishArea = + lcFastPrev < lcSlowPrev && + mcFastPrev < mcSlowPrev && + scFastPrev < scSlowPrev; + + // + // Detect HOT Bearish Area ... + bool isHotBullishArea = + lcFast > lcSlow && + mcFast > mcSlow && + scFast > scSlow; + // + bool isPrevHotBullishArea = + lcFastPrev > lcSlowPrev && + mcFastPrev > mcSlowPrev && + scFastPrev > scSlowPrev; + + // + // Generate HotState Value ... + double hotStateValue = + isHotBullishArea && !isPrevHotBullishArea + ? 1 + : isHotBearishArea && !isPrevHotBearishArea + ? -1 + : 0; + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotBullishArea = hotStateValue == 1; + bool isHotBearishArea = hotStateValue == -1; + if (isHotBullishArea || isHotBearishArea) + { + // + bool isBull = isHotBullishArea; + + // + double price = isBull ? candle.low : candle.high; + ENUM_ARROW_ANCHOR anchor = isBull ? ANCHOR_TOP : ANCHOR_BOTTOM; + color clr = isBull ? hotBullishArrowColor : hotBearishArrowColor; + uchar arrowCode = isBull ? hotBullishArrowCode : hotBearishArrowCode; + string name = "HOT " + (isBull ? "Bullish" : "Bearish") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); + } + } + + // + // Draw LC Crosses ... + if (lcDrawCrosses) + { + // + double lcStateValue = GetLCState(bar_index); + bool isLcFastCrossedOverSlow = lcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isLcFastCrossedUnderSlow = lcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isLcFastCrossedOverSlow || isLcFastCrossedUnderSlow) + { + // + bool isBull = isLcFastCrossedOverSlow; + + // + color clr = isBull ? lcFastColor : lcSlowColor; + string name = "LC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw MC Crosses ... + if (mcDrawCrosses) + { + // + double mcStateValue = GetMCState(bar_index); + bool isMcFastCrossedOverSlow = mcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isMcFastCrossedUnderSlow = mcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isMcFastCrossedOverSlow || isMcFastCrossedUnderSlow) + { + // + bool isBull = isMcFastCrossedOverSlow; + + // + color clr = isBull ? mcFastColor : mcSlowColor; + string name = "MC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw SC Crosses ... + if (scDrawCrosses) + { + // + double scStateValue = GetSCState(bar_index); + bool isScFastCrossedOverSlow = scStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isScFastCrossedUnderSlow = scStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isScFastCrossedOverSlow || isScFastCrossedUnderSlow) + { + // + bool isBull = isScFastCrossedOverSlow; + + // + color clr = isBull ? scFastColor : scSlowColor; + string name = "SC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } +} +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xfi.oscillator.mq5 b/XEU5/Indicators/x-saherelm.xfi.oscillator.mq5 new file mode 100644 index 0000000..cfd393c --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xfi.oscillator.mq5 @@ -0,0 +1,317 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator +// --------------------------------------------- +// Name: XFI +// Description: Price Momentum Power Detection +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFI Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XFI" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Length +input ENUM_MA_METHOD method = MODE_SMA; // MA Method +input ENUM_APPLIED_VOLUME appliedTo = VOLUME_TICK; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 2 +#property indicator_plots 1 + +// +// FI Buffer ... +#define fiBufferIndex 0 +#define fiColorBufferIndex 1 + +// +double fiBuffer[]; +double fiColorBuffer[]; + +// +#property indicator_label1 "XFI" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, clrGray, clrFuchsia +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int fiHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + fiHandler = iForce( + _Symbol, + _Period, + length, + method, + appliedTo); + if (fiHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(fiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + // Check Calculated Bars ... + int fiCalculatedBars = BarsCalculated(fiHandler); + if (fiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFis = CopyBuffer(fiHandler, 0, 0, limit, fiBuffer); + if (copiedFis <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string fiBufferLabel = "XFI " + "(" + (string)length + ")"; + + // + // FI Buffer ... + ArraySetAsSeries(fiBuffer, true); + SetIndexBuffer(fiBufferIndex, fiBuffer, INDICATOR_DATA); + PlotIndexSetString(fiBufferIndex, PLOT_LABEL, fiBufferLabel); + + // + // FI Color Buffer ... + ArraySetAsSeries(fiColorBuffer, true); + SetIndexBuffer(fiColorBufferIndex, fiColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + double iValue = fiBuffer[bar_index]; + + // + double iColorIndex = + iValue > 0 ? 0 : iValue < 0 ? 2 + : 1; + + // + // Set Buffer Color Index ... + fiColorBuffer[bar_index] = iColorIndex; +} +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xlh.indicator.mq5 b/XEU5/Indicators/x-saherelm.xlh.indicator.mq5 new file mode 100644 index 0000000..4dfc64e --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xlh.indicator.mq5 @@ -0,0 +1,346 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XLH Indicator +// --------------------------------------------- +// Name: XLH +// Description: Moving Average Indicator +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XLH Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XLH" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 14; // Length +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// HH Buffer ... +#define hhBufferIndex 0 + +// +double hhBuffer[]; + +// +#property indicator_label1 "XLH HH" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// LL Buffer ... +#define llBufferIndex 1 + +// +double llBuffer[]; + +// +#property indicator_label2 "XLH LL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrFuchsia +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Signal Buffer ... +#define signalBufferIndex 2 + +// +double signalBuffer[]; + +// +#property indicator_label3 "XLH S" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // HH Buffer ... + string hhBufferLabel = ShortName + " HH " + "(" + (string)length + ")"; + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hhBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(hhBufferIndex, PLOT_LABEL, hhBufferLabel); + + // + // LL Buffer ... + string llBufferLabel = ShortName + " LL " + "(" + (string)length + ")"; + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + PlotIndexSetInteger(llBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(llBufferIndex, PLOT_LABEL, llBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + " S " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Threshold ... + // + // HH Buffer ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + length, + bar_index); + double hhValue = GetAppliedPrice( + hhIndex, + hhMode); + + // + hhBuffer[bar_index] = hhValue; + + // + // LL Buffer ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + length, + bar_index); + double llValue = GetAppliedPrice( + llIndex, + llMode); + + // + llBuffer[bar_index] = llValue; + + // + XOHCL c = GetCandle(bar_index); + double lhDiff = hhValue - llValue; + double signalValue = (lhDiff / 2); + + // + signalBuffer[bar_index] = (hhValue - signalValue); +} +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xobd.indicator.mq5 b/XEU5/Indicators/x-saherelm.xobd.indicator.mq5 new file mode 100644 index 0000000..4ac05cf --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xobd.indicator.mq5 @@ -0,0 +1,390 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Indicator +// ----------------------------------------------------- +// Name: XOBD +// Description: detect Order Blocks based on Swings ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XOBD Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XOBD" +// +// END Constants ... +// + +// +// START Inputs ... +// +// +input int length = 5; // Swing Length + +// +input uchar swingHighArrowCode = 108; // Swing High Arrow Code +input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color + +// +input uchar swingLowArrowCode = 108; // Swing Low Arrow Code +input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Include Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 1 +#property indicator_plots 0 + +// +#define swingBufferIndex 0 +double swingBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + OnDeinitDrawLibrary(); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length * 3); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ArraySetAsSeries(swingBuffer, true); + SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // GetCandleSwing(bar_index); + ENUM_X_SWING_TYPE type = X_NO_SWING; + + // + // Try To Detect Order Blocks ... + bool isSwingLow = false; + bool isSwingHigh = false; + + // + // Reading Candles Data ... + XOHCL candles[]; + for (int i = bar_index; i < bar_index + ((length * 2) + 2); i++) + { + // + XOHCL iCandle = GetCandle( + _Symbol, + _Period, + i); + + // + Add( + iCandle, + candles); + } + + // + // Swing Low ... + isSwingLow = + // + candles[1].close > candles[2].close && + candles[2].close > candles[3].close && + // + candles[3].close < candles[4].close && + // + candles[5].close > candles[4].close && + candles[6].close > candles[5].close + // + ; + + // + if (isSwingLow) + { + type = X_SWING_LOW; + } + + // + if (!isSwingLow) + { + // + // Swing High ... + isSwingHigh = + // + candles[1].close < candles[2].close && + candles[2].close < candles[3].close && + // + candles[3].close > candles[4].close && + // + candles[5].close < candles[4].close && + candles[6].close < candles[5].close + // + ; + + // + if (isSwingHigh) + { + type = X_SWING_HIGH; + } + } + + // + switch (type) + { + // + // Swing High ... + case X_SWING_HIGH: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(1, bar_index); + break; + + // + // Swinmg Low ... + case X_SWING_LOW: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(0, bar_index); + break; + + // + // No Swing ... + default: + case X_NO_SWING: + // + swingBuffer[bar_index] = 0; + break; + } +} + +// +// Draw a Swing Arrow Shape ... +void DrawSwingArrow( + int type, // Swing Type: 0 - Low / 1 - High ... + int bar_index) +{ + // + bool isSwingHigh = type == 1; + XOHCL candle = GetCandle(bar_index + 3); + double arrowDistanceInPoint = 0; + + // + // Define Required Object Properties fro Draw an Arrow ... + datetime time = iTime(_Symbol, _Period, bar_index + 3); + double purePrice = isSwingHigh ? candle.high : candle.low; + color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor; + ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP; + uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode); + double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint; + string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice; + + // + // Draw desired Arrow ... + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); +} +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xrsi.oscillator.mq5 b/XEU5/Indicators/x-saherelm.xrsi.oscillator.mq5 new file mode 100644 index 0000000..5659e07 --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xrsi.oscillator.mq5 @@ -0,0 +1,397 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Oscillator +// ------------------------------------------------------ +// Name: XRSI +// Description: detect market conditions based on RSI ... +// +// +// 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 XRSI Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XRSI" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 14; // Market Length +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +input group "Short Entry"; +input double shortEntryValue = 70; // Short Entry Level +input color shortEntryColor = clrRed; // Short Entry Level Color +input ENUM_LINE_STYLE shortEntryLineStyle = STYLE_DOT; // Short Entry Style + +// +input group "Short Exit"; +input double shortExitValue = 40; // Short Exit Level +input color shortExitColor = clrRed; // Short Exit Level Color +input ENUM_LINE_STYLE shortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +input group "Long Entry"; +input double longEntryValue = 30; // Long Entry Level +input color longEntryColor = clrRed; // Long Entry Level Color +input ENUM_LINE_STYLE longEntryLineStyle = STYLE_DOT; // Long Entry Style + +// +input group "Long Exit"; +input double longExitValue = 60; // Long Exit Level +input color longExitColor = clrRed; // Long Exit Level Color +input ENUM_LINE_STYLE longExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// START Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_separate_window +#property indicator_buffers 2 +#property indicator_plots 1 + +// +#define rsiBufferIndex 0 +#define rsiColorBufferIndex 1 + +// +double rsiBuffer[]; +double rsiColorBuffer[]; + +// +#property indicator_label1 "XRSI" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, clrGray, clrFuchsia +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int rsiHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + rsiHandler = iRSI( + _Symbol, + _Period, + length, + appliedTo); + if (rsiHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(rsiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + int rsiCalculatedBars = BarsCalculated(rsiHandler); + if (rsiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + if (rsiCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RSI ... + string rsiBufferLabel = ShortName + " (" + (string)length + ")"; + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rsiBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(rsiBufferIndex, PLOT_LABEL, rsiBufferLabel); + + // + // RSI Color Buffer ... + ArraySetAsSeries(rsiColorBuffer, true); + SetIndexBuffer(rsiColorBufferIndex, rsiColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set Indicator Levels here ... + // OB, ExitLong, ExitShort, OS ... + IndicatorSetInteger(INDICATOR_LEVELS, 4); + + // + // SHORTENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, shortEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, shortEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, shortEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 0, "Short Entry"); + + // + // LONGEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, longExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, longExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, shortExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Long Exit"); + + // + // SHORTEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 2, shortExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 2, shortExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 2, longEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 2, "Short Exit"); + + // + // LONGENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 3, longEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 3, longEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 3, longExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 3, "Long Entry"); + + // + // Set Maximum and Minimum for subwindow + IndicatorSetInteger(INDICATOR_DIGITS, 2); + IndicatorSetDouble(INDICATOR_MINIMUM, 0); + IndicatorSetDouble(INDICATOR_MAXIMUM, 100); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + double iValue = rsiBuffer[bar_index]; + + // + double iColorIndex = 0; + + // + if ( + iValue >= shortEntryValue || + iValue <= longEntryValue || + (iValue < longExitValue && + iValue > shortExitValue)) + { + iColorIndex = 0; + } + else if ( + iValue <= shortEntryValue && + iValue >= longExitValue) + { + iColorIndex = 2; + } + else if ( + iValue < shortExitValue && + iValue > longEntryValue) + { + iColorIndex = 1; + } + + // + rsiColorBuffer[bar_index] = iColorIndex; +} + +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xtd.oscillator.mq5 b/XEU5/Indicators/x-saherelm.xtd.oscillator.mq5 new file mode 100644 index 0000000..5f46d18 --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xtd.oscillator.mq5 @@ -0,0 +1,465 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Trend Detector Oscillator +// -------------------------------------------------- +// Name: XTD +// Description: trend detecting in both sides ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTD Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTD" + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; +// +// END Constants ... +// + +// +// Include Models Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// START Inputs ... +// +input int length = 14; // Market Length +input bool drawCrosses = true; // Draw Cross Arrows + +// +// Bullish ... +input uchar bullishArrowCode = 228; // Cross Over Arrow Code +input color bullishArrowColor = clrAqua; // Cross Over Arrow Color + +// +// Bearish ... +input uchar bearishArrowCode = 230; // Cross Under Arrow Code +input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +#define bullishBufferIndex 0 +#define bearishBufferIndex 1 +#define signalBufferIndex 2 + +// +double bullishBuffer[]; +double bearishBuffer[]; +double signalBuffer[]; + +// +#property indicator_label1 "XBullPower" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#property indicator_label2 "XBearPower" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#property indicator_label3 "XSignal" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +int xtdBullishCandleCount = 0; +int xtdBearishCandleCount = 0; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i, close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 5) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Bullish Buffer ... + string bullishBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishBuffer, true); + SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel); + + // + // Bearish Buffer ... + string bearishBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishBuffer, true); + SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + "Signal " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, + const double &close[]) +{ + // + // Reset Global Counters ... + xtdBullishCandleCount = 0; + xtdBearishCandleCount = 0; + + // + // Loop through Closes ... + for (int i = bar_index; i <= bar_index + length; i++) + { + for (int j = i + 1; j <= bar_index + length; j++) + { + // + if (close[i] > close[j]) + { + xtdBullishCandleCount++; + } + + // + if (close[i] < close[j]) + { + xtdBearishCandleCount++; + } + } + } + + // + // Bullish Power Buffer ... + bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount); + + // + // Bearish Power Buffer ... + bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount); + + // + // Signal Buffer ... + signalBuffer[bar_index] = bullishBuffer[bar_index] - bearishBuffer[bar_index]; + + // + // Check and Draw Crosses if it's Specified ... + if (drawCrosses) + { + DrawCrosses(bar_index); + } +} + +// +// +double GetState( + int bar_index // Specified Bar Index +) +{ + // + // Check Cross Points ... + // bullishCrossedOverBearish = 2; + // bullishOverBearish = 1; + // bullishCrossedUnderBearish = -2; + // bullishUnderBearish = -1; + // OtherWise = 0; + bool isBullishCrossedOverBearish = IsCrossOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishCrossedUnderBearish = IsCrossUnder( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishOverBearish = IsOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishUnderBearish = IsUnder( + bullishBuffer, + bearishBuffer, + bar_index); + + // + double result = X_XTD_NEUTURAL; + if (isBullishCrossedOverBearish) + { + result = X_XTD_BULLISH_CROSSED_OVER_BEARISH; + } + else if (isBullishCrossedUnderBearish) + { + result = X_XTD_BULLISH_CROSSED_UNDER_BEARISH; + } + else if (isBullishOverBearish) + { + result = X_XTD_BULLISH_OVER_BEARISH; + } + else if (isBullishUnderBearish) + { + result = X_XTD_BULLISH_UNDER_BEARISH; + } + else + { + result = X_XTD_NEUTURAL; + } + + // + return result; +} + +// +// Draw Crosses ... +void DrawCrosses( + int bar_index // the bars which required to draw cross arrow on it ... +) +{ + // + double stateValue = GetState(bar_index); + + // + bool isOver = stateValue == 2; + double low = iLow(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + + // + double price = isOver ? low : high; + datetime time = iTime(_Symbol, _Period, bar_index); + ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM; + uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode; + color arrowColor = isOver ? bullishArrowColor : bearishArrowColor; + string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price; + + // + DrawArrow( + 0, + crossName, + 0, + time, + price, + arrowCode, + anchor, + arrowColor); +} +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xtm.indicator.mq5 b/XEU5/Indicators/x-saherelm.xtm.indicator.mq5 new file mode 100644 index 0000000..eac88e0 --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xtm.indicator.mq5 @@ -0,0 +1,349 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Indicator +// --------------------------------------------- +// Name: XTM +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int maPeriod = 14; // Period +input int maShift = 0; // Shift +input ENUM_MA_METHOD maMethod = MODE_SMA; // Method +input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XTM" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + maPeriod, + maShift, + maMethod, + maAppliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, maPeriod); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (maPeriod >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XTM " + "(" + (string)maPeriod + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XTM_BULLISH : lineColorIndex == 2 ? X_XTM_BEARISH + : X_XTM_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/XEU5/Indicators/x-saherelm.xts.oscillator.mq5 b/XEU5/Indicators/x-saherelm.xts.oscillator.mq5 new file mode 100644 index 0000000..46e9fbf --- /dev/null +++ b/XEU5/Indicators/x-saherelm.xts.oscillator.mq5 @@ -0,0 +1,558 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTS Oscillator +// --------------------------------------------- +// Name: XTS +// Description: Time Sections Oscillator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTS Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XTS" + +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// XTS Oscillator States ... + +// +// END Constants ... +// + +// +// START Inputs ... +// +input group "Current Period"; +input ENUM_APPLIED_PRICE currentAppliedTo = PRICE_CLOSE; // Current Applied To +// +input group "Nearest Period"; +input ENUM_X_PERIOD_METHOD nearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +input ENUM_TIMEFRAMES nearestPeriod = NULL; // Nearest Time Frame +input ENUM_APPLIED_PRICE nearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// +input group "Mediest Period"; +input ENUM_X_PERIOD_METHOD mediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +input ENUM_TIMEFRAMES mediestPeriod = NULL; // Mediest Time Frame +input ENUM_APPLIED_PRICE mediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// +input group "Farest Period"; +input ENUM_X_PERIOD_METHOD farestMethod = X_PERIOD_AUTO; // How to Find Farest Period +input ENUM_TIMEFRAMES farestPeriod = NULL; // Farest Time Frame +input ENUM_APPLIED_PRICE farestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// Current ... +#define currentBufferIndex 0 + +double currentBuffer[]; + +#property indicator_label1 "XTS C" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// Nearest ... +#define nearestBufferIndex 1 + +double nearestBuffer[]; + +#property indicator_label2 "XTS N" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrAqua +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// Mediest ... +#define mediestBufferIndex 2 + +double mediestBuffer[]; + +#property indicator_label3 "XTS M" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrLime +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +// Farest ... +#define farestBufferIndex 3 + +double farestBuffer[]; + +#property indicator_label4 "XTS F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrLightBlue +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +ENUM_TIMEFRAMES mNearestPeriod = NULL; +ENUM_TIMEFRAMES mMediestPeriod = NULL; +ENUM_TIMEFRAMES mFarestPeriod = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Oscillator ShortName ... + SetOscillatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = 30; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + int maxLength = 30; + + // + // Current ... + ArraySetAsSeries(currentBuffer, true); + SetIndexBuffer(currentBufferIndex, currentBuffer, INDICATOR_DATA); + PlotIndexSetInteger(currentBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Nearest ... + ArraySetAsSeries(nearestBuffer, true); + SetIndexBuffer(nearestBufferIndex, nearestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(nearestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Mediest ... + ArraySetAsSeries(mediestBuffer, true); + SetIndexBuffer(mediestBufferIndex, mediestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mediestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Farest ... + ArraySetAsSeries(farestBuffer, true); + SetIndexBuffer(farestBufferIndex, farestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(farestBufferIndex, PLOT_DRAW_BEGIN, maxLength); +} + +// +// Set Oscillator Short Name and also we can define Buffers Labels ... +void SetOscillatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Current ... + CalculateCurrent(bar_index); + + // + // Nearest ... + CalculateNearest(bar_index); + + // + // Mediest ... + CalculateMediest(bar_index); + + // + // Farest ... + CalculateFarest(bar_index); + + // + // Commenting ... + string comment = GenerateDescriptionComment(); + Comment(comment); +} + +// +// Current ... +void CalculateCurrent(int bar_index) +{ + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + _Period, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + currentAppliedTo); + + // + currentBuffer[bar_index] = value; +} + +// +// Nearest ... +void CalculateNearest(int bar_index) +{ + // + if (mNearestPeriod == NULL) + { + // + switch (nearestMethod) + { + // + case X_PERIOD_AUTO: + mNearestPeriod = GetNearestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mNearestPeriod = nearestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mNearestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + nearestAppliedTo); + + // + nearestBuffer[bar_index] = value; +} + +// +// Mediest ... +void CalculateMediest(int bar_index) +{ + // + if (mMediestPeriod == NULL) + { + // + switch (mediestMethod) + { + // + case X_PERIOD_AUTO: + mMediestPeriod = GetMediestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mMediestPeriod = mediestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mMediestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + mediestAppliedTo); + + // + mediestBuffer[bar_index] = value; +} + +// +// Farest ... +void CalculateFarest(int bar_index) +{ + // + if (mFarestPeriod == NULL) + { + // + switch (farestMethod) + { + // + case X_PERIOD_AUTO: + mFarestPeriod = GetFarestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mFarestPeriod = farestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mFarestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + farestAppliedTo); + + // + farestBuffer[bar_index] = value; +} + +// +// Generate Comment ... +string GenerateDescriptionComment() +{ + // + string result = ""; + + // + result += "Nearest : " + EnumToString(mNearestPeriod) + "\n"; + result += "Mediest : " + EnumToString(mMediestPeriod) + "\n"; + result += "Farest : " + EnumToString(mFarestPeriod) + "\n"; + + // + return result; +} +// +// END Functions ... +// diff --git a/XEU5/Libraries/.gitkeep b/XEU5/Libraries/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Libraries/x-saherelm.alert.lib.mq5 b/XEU5/Libraries/x-saherelm.alert.lib.mq5 new file mode 100644 index 0000000..1079063 --- /dev/null +++ b/XEU5/Libraries/x-saherelm.alert.lib.mq5 @@ -0,0 +1,200 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Alert Library +// -------------------------------------- +// Name: XAlert +// Description: provides Alerts abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Alerts"; +input bool enableAlerts = true; // Enable Alerts +input bool logAlerts = true; // Log Alerts +input bool terminalAlerts = false; // Terminal Alerts +input bool mailAlerts = false; // Mail Alerts +input bool pushAlerts = false; // Push Alerts +// +// END Inputs ... +// + +// +#include "x-saherelm.log.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string alertPrefix = "X-Alert"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitAlertLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitAlertLibrary() +{ +} + +// +// Attach Alert Prefix to Message ... +string PrepareAlertMessage(string message) +{ + // + StringReplace(message, "\n", " | "); + + // + StringConcatenate(message, alertPrefix, " > ", message); + + // + return message; +} + +// +// Logging an Alert ... +void LogAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !logAlerts) + { + return; + } + + // + LogMessage(alertPrefix, message); +} + +// +// Terminal Alert ... +void TerminalAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !terminalAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // Send Terminal Alert ... + Alert(message); +} + +// +// Mail Alert ... +void MailAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !mailAlerts) + { + return; + } + + // + // Send Mail Alert ... + SendMail(alertPrefix, message); +} + +// +// Send Push Notification ... +void PushAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts || !pushAlerts) + { + return; + } + + // + // Prepare Message ... + message = PrepareAlertMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); +} + +// +// Alert Sending ... +void SendAlert(string message) +{ + // + // Validate Args ... + if (!enableAlerts) + { + return; + } + + // + // Log ... + if (logAlerts) + { + LogAlert(message); + } + + // + // Terminal ... + if (terminalAlerts) + { + TerminalAlert(message); + } + + // + // Mail ... + if (mailAlerts) + { + MailAlert(message); + } + + // + // Push ... + if (pushAlerts) + { + PushAlert(message); + } +} +void SendAlert( + XSignal &signal, // the Signal Object which requred to Alert + bool asExecuted = true // determines Alert Signal as Executed Signal or not +) +{ + // + // Prepare Message ... + string message = asExecuted ? ExecutedSignalToString(signal) : SignalToString(signal); + + // + // Do Alerting ... + SendAlert(message); +} +// +// END Provided Functions ... +// diff --git a/XEU5/Libraries/x-saherelm.common.lib.mq5 b/XEU5/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..290dde9 --- /dev/null +++ b/XEU5/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,4429 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommon +// Description: provide all commonly used 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 + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// Include Models Library ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Detect is new Candle or not ... +bool IsNewCandle() +{ + // + bool result = false; + + // + static int barsOnChart = 0; + int currentBarsOnChart = Bars(_Symbol, _Period); + result = currentBarsOnChart > barsOnChart; + if (!result) + { + return result; + } + + // + barsOnChart = currentBarsOnChart; + result = true; + + // + return result; +} + +// +// Retrive Ask Price ... +double GetAsk() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_ASK); +} +double GetAsk( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_BID); +} +double GetBid( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_BID); + + // + return result; +} + +// +// Calculate and Retrieve Spread Price ... +double GetSpread() +{ + // + double ask = GetAsk(); + double bid = GetBid(); + double result = MathAbs(ask - bid); + + // + return result; +} +double GetSpread( + string symbol // selected symbol for calculations +) +{ + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Get Points ... +double GetPoints() +{ + return _Point; +} +double GetPoints( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + return result; +} + +// +// Get Digits ... +int GetDigits() +{ + return _Digits; +} +int GetDigits( + string symbol // selected symbol for calculations +) +{ + // + int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Get Signal Entry ... +double GetEntry( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + bool isLong = type == X_SIGNAL_LONG; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice() +{ + // + double result = _Point; + if (_Digits == 3 || _Digits == 5) + { + result *= 10; + } + + // + return result; +} +double GetPipPrice( + string symbol // selected symbol for calculations +) +{ + // + double symbolPoint = GetPoints(symbol); + int symbolDigits = GetDigits(symbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + int pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + double pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + int pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + double pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(); + double pipPrice = GetPipPrice(); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PriceToPips( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(symbol); + double pipPrice = GetPipPrice(symbol); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Get a Candle Body ... +double GetCandleBody( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.open - candle.close); + + // + return result; +} + +// +// Get a Candle Range ... +double GetCandleRange( + XOHCL &candle // specified candle +) +{ + // + double result = MathAbs(candle.high - candle.low); + + // + return result; +} + +// +// Get a Candle Shadow ... +double GetCandleShadow( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + double result = MathAbs(range - body); + + // + return result; +} + +// +// Retrieve Applied Price at Specific Candle ... +double GetAppliedPrice( + XOHCL &candle, // specified candle + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + switch (source) + { + // + // Open ... + case PRICE_OPEN: + result = candle.open; + break; + + // + // High ... + case PRICE_HIGH: + result = candle.high; + break; + + // + // Low ... + case PRICE_LOW: + result = candle.low; + break; + + // + // Median ((High + Low) / 2) ... + case PRICE_MEDIAN: + result = (candle.high + candle.low) / 2; + break; + + // + // Typical ((High + Low + Close)/3) ... + case PRICE_TYPICAL: + result = (candle.high + candle.low + candle.close) / 3; + break; + + // + // Weighted ((High + Low + Close + Close)/4) ... + case PRICE_WEIGHTED: + result = (candle.high + candle.low + (candle.close * 2)) / 4; + break; + + // + // Close ... + default: + case PRICE_CLOSE: + result = candle.close; + break; + } + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + XOHCL candle = GetCandle(bar_index); + result = GetAppliedPrice(candle, source); + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + double result = 0; + + // + ENUM_APPLIED_PRICE mAppliedTo = To(mode); + result = GetAppliedPrice( + bar_index, + mAppliedTo); + + // + return result; +} + +// +// Converts ... +ENUM_APPLIED_PRICE To( + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + ENUM_APPLIED_PRICE result = PRICE_CLOSE; + + // + switch (mode) + { + // + // High ... + case MODE_HIGH: + result = PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve a Candel Data ... +XOHCL GetCandle(int bar_index) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + double close = iClose(_Symbol, _Period, bar_index); + double low = iLow(_Symbol, _Period, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, mPeriod, bar_index); + double high = iHigh(_Symbol, mPeriod, bar_index); + double close = iClose(_Symbol, mPeriod, bar_index); + double low = iLow(_Symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(symbol, mPeriod, bar_index); + double high = iHigh(symbol, mPeriod, bar_index); + double close = iClose(symbol, mPeriod, bar_index); + double low = iLow(symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} + +// +// Retrieve a candle index in current timeframe inside another timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(_Symbol, _Period, bar_index); + result = iBarShift(_Symbol, destPeriod, barTime); + + // + return result; +} + +// +// Retrieve a symbol candle index in source time frame inside dest timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + string symbol, // Specify desired Symbol + ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(symbol, sourcePeriod, bar_index); + result = iBarShift(symbol, destPeriod, barTime); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBullishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open < candle.close; + + // + return result; +} +bool IsBullishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} +bool IsBullishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBearishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = candle.open > candle.close; + + // + return result; +} +bool IsBearishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} +bool IsBearishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} + +// +// Check Candle Body Bigger Than it's Shadow ... +bool HasStrongBody(XOHCL &candle) +{ + // + double bodySize = MathAbs(candle.open - candle.close); + double shadowSize = MathAbs(candle.high - candle.low) - bodySize; + + // + bool result = bodySize > (shadowSize * 1.5); + + // + return result; +} + +// +// Determines a cnadle is Swing High +// or Swing Low order block ... +ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(bar_index + 1); + candles[1] = GetCandle(bar_index + 2); + candles[2] = GetCandle(bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(mPeriod, bar_index + 1); + candles[1] = GetCandle(mPeriod, bar_index + 2); + candles[2] = GetCandle(mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); + candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); + candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = HasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} + +// +// Retrieve Market Highest High ... +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Retrieve Market Lowest Low ... +double GetLowestLow( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} + +// +// Check first Cross Over second at bar_index ... +bool IsCrossOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + !(first[bar_index + 1] > second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Over second at bar_index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + first[bar_index + 1] > second[bar_index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at bar_index ... +bool IsCrossUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + !(first[bar_index + 1] < second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Under second at bar_index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + first[bar_index + 1] < second[bar_index + 1]; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + int from, // In Past Index ... + int to, // In Past Index ... + double &buffer[]) +{ + // + double result = 0; + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Get Max Value of Specific Loopback of a Buffer ... +double GetMaxValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min Value of Specific Loopback of a Buffer ... +double GetMinValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +bool IsInPeak( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue > lastValue + // + && + // + ( + firstValue > q1Value && + firstValue > halfValue) + // + ; + + // + return result; +} + +// +bool IsInVale( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue < lastValue + // + && + // + ( + firstValue < q1Value && + firstValue < halfValue) + // + ; + + // + return result; +} + +// +// Check Sharp Happens or not ... +bool IsSharpChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check InCreased Sharp Happens or not ... +bool IsSharpIncreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check Decreased Sharp Happens or not ... +bool IsSharpDecreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + !isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Validate Struct ... +bool IsValid(XSignal &model, ulong magicNumber) +{ + // + bool result = false; + + // + // Validate Signal Type ... + result = model.type != X_SIGNAL_UNKNOWN; + if (!result) + { + return result; + } + + // + // Check Symbol ... + result = StringLen(model.symbol) == 0 ? true : model.symbol == _Symbol; + if (!result) + { + return result; + } + + // + // Check magic number ... + result = model.magicNumber <= 0 ? true : model.magicNumber == magicNumber; + if (!result) + { + return result; + } + + // + // Check Entry ... + result = model.entry > 0; + if (!result) + { + return result; + } + + // + // Check SL ... + result = model.sl == 0 ? true : model.type == X_SIGNAL_LONG ? model.sl < model.entry + : model.sl > model.entry; + if (!result) + { + return result; + } + + // + // Check TP ... + result = model.tp == 0 ? true : model.type == X_SIGNAL_LONG ? model.tp > model.entry + : model.tp < model.entry; + if (!result) + { + return result; + } + + // + // Check Volume ... + result = model.volume > 0; + if (!result) + { + return result; + } + + // + // Check Time ... + result = model.time > 0; + if (!result) + { + return result; + } + + // + return result; +} + +// +void CleanBuffer(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(ulong &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(double &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(XSignal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(XDeal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void CleanBuffer(XOrder &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +bool GetLastItem( + double &item, // Holds Result + double &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} +bool GetLastItem( + datetime &item, // Holds Result + datetime &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} + +// +void Add( + int item, // item want to add + int &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + ulong item, // item want to add + ulong &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + string item, // item want to add + string &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + double item, // item want to add + double &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOHCL &item, // item want to add + XOHCL &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + datetime &item, // item want to add + datetime &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XSignal &item, // item want to add + XSignal &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XDeal &item, // item want to add + XDeal &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOrder &item, // item want to add + XOrder &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Converts a Buffer to String Representation ... +string ToString( + const int &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const double &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const string &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const datetime &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} + +// +// Check a Signal is Long or not ... +bool IsLong(ENUM_X_SIGNAL_TYPE type) +{ + return type == X_SIGNAL_LONG; +} +bool IsLong(XSignal &signal) +{ + // + bool result = IsLong(signal.type); + + // + return result; +} + +// +// Check a Signal is Short or not ... +bool IsShort(ENUM_X_SIGNAL_TYPE type) +{ + return type == X_SIGNAL_SHORT; +} +bool IsShort(XSignal &signal) +{ + // + bool result = IsShort(signal.type); + + // + return result; +} + +// +// Retrieve a Signal Type String Value ... +string GetSignalType(ENUM_X_SIGNAL_TYPE type) +{ + // + string result = ""; + + // + if (type == X_SIGNAL_UNKNOWN) + { + return result; + } + + // + result = type == X_SIGNAL_LONG ? "Long" : "Short"; + + // + return result; +} +string GetSignalType(XSignal &signal) +{ + // + string result = ""; + + // + result = GetSignalType(signal.type); + + // + return result; +} +ENUM_X_SIGNAL_TYPE GetSignalType(string typeStr) +{ + // + ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; + + // + if (typeStr == GetSignalType(X_SIGNAL_LONG)) + { + result = X_SIGNAL_LONG; + } + else if (typeStr == GetSignalType(X_SIGNAL_SHORT)) + { + result = X_SIGNAL_SHORT; + } + + // + return result; +} + +// +// Retrieve Signal Execution String ... +string GetSignalExecutionError(int error) +{ + // + string result = ""; + + // + switch (error) + { + // + case X_TRADER_INVALID_SIGNAL_ERROR: + result = "Invalid Signal ..."; + break; + + // + case X_TRADER_NOT_ENOUGH_EQUITY_ERROR: + result = "Not Enough Equity for Trade ..."; + break; + + // + case X_TRADER_NOT_ENOUGH_BALANCE_ERROR: + result = "Not Enough Balance for Trade ..."; + break; + + // + case X_TRADER_NOT_ENOUGH_MARIGIN_ERROR: + result = "Not Enough Marigin For Trade ..."; + break; + + // + case X_TRADER_MAX_TRADES_REACHED_ERROR: + result = "Max Allowed Trade Reached ..."; + break; + + // + case X_TRADER_UNKNOWN_ERROR: + default: + result = "Unknown Issue ..."; + break; + } + + // + return result; +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double volume, // desired volume to normalize + string symbol = NULL, // Specified Symbol for Normalization + int mLength = 2 // Length of Digits +) +{ + // + double result = volume; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Normalize Digits ... + int digits = GetDigits(symbol); + mLength = + mLength == 0 || mLength > digits + ? digits + : MathMin(mLength, digits); + + // + // Normalize Volume ... + result = NormalizeDouble(result, mLength); + + // + double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double price, // desired Price for normalization + string symbol = NULL // Specified Symbol for Normalization +) +{ + // + double result = 0; + + // + // Mormalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + int digits = GetDigits(symbol); + result = NormalizeDouble(price, digits); + + // + return result; +} + +// +// Error Descriptions Functions ... +// + +// +// Retrieve Specified Error Code Description ... +string GetErrorDescription(int err_code) +{ + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; +} + +// +// Retrieve Specified Error Code Description ... +string GetTradeServerReturnCodeDescription(int return_code) +{ + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; +} + +// +// Check Expert Running in Testing Mode or not ... +bool IsRunningOnTestMode() +{ + // + bool result = false; + + // + // check programm mode ... + result = MQL5InfoInteger(MQL5_TESTING); + + // + return result; +} + +// +// Date Time Manipulation Functions ... +// + +// +// Representation of Time Struct ... +// struct MqlDateTime +// { +// int year; // Year +// int mon; // Month +// int day; // Day +// int hour; // Hour +// int min; // Minutes +// int sec; // Seconds +// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) +// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) +// }; + +// +// Converts Time to Seconds ... +ulong TimeToSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = (ulong)time; + + // + return result; +} +ulong TimeToSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToSeconds(dTime); + + // + return result; +} + +// +// Converts Seconds To Time ... +datetime SecondsToTime( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime result = (datetime)seconds; + + // + return result; +} +MqlDateTime SecondsToStruct( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime dTime = SecondsToTime(seconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Converts Time to MilliSeconds ... +ulong TimeToMilliSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = TimeToSeconds(time) * 1000; + + // + return result; +} +ulong TimeToMilliSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToMilliSeconds(dTime); + + // + return result; +} + +// +// Converts MillisSeconds to Time ... +datetime MilliSecondsToTiem( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + ulong seconds = milliSeconds / 1000; + + // + datetime result = SecondsToTime(seconds); + + // + return result; +} +MqlDateTime MilliSecondsToStruct( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + datetime dTime = MilliSecondsToTiem(milliSeconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Retrieve DateTime Structure ... +MqlDateTime GetCurrentTime() +{ + // + MqlDateTime result = {}; + + // + TimeCurrent(result); + + // + return result; +} + +// +// Retrieve Current Time as Seconds ... +ulong GetCurrentTimeAsSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Current Time as MilliSeconds ... +ulong GetCurrentTimeAsMilliSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +datetime GetCandleTime( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Validate and Normalize Args ... + + // + // Normalize Symbol ... + symbol = StringLen(symbol) == 0 + ? _Symbol + : symbol; + + // + // Normalize Period ... + period = period == NULL + ? _Period + : period; + + // + // Retrieve Bar Time ... + datetime result = iTime( + symbol, + period, + bar_index); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsMilliSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve a Candle Time Structure ... +MqlDateTime GetCandleTimeStruct( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + MqlDateTime result = {}; + + // + // Retrieve Bar Time ... + datetime barTime = GetCandleTime( + symbol, + period, + bar_index); + + // + // Convert to Structure ... + TimeToStruct(barTime, result); + + // + return result; +} + +// +// +// + +// +// Holds Month ... +static int xMonth = -1; + +// +// Holds Day Of Week ... +static int xDayOfWeek = -1; +static int xForWeekDay = -1; + +// +// Holds Day ... +static int xDay = -1; + +// +// Holds Hour ... +static int xHour = -1; + +// +// Reset Timing Variables ... +void ResetTiming() +{ + // + xHour = -1; + xDay = -1; + xDayOfWeek = -1; + xMonth = -1; +} + +// +// Detecting New Houre ... +bool IsNewHour() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.hour != xHour; + if (result) + { + xHour = timeStruct.hour; + } + + // + return result; +} + +// +// Detecting New Day ... +bool IsNewDay() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.day_of_year != xDay; + if (result) + { + xDay = timeStruct.day_of_year; + } + + // + return result; +} + +// +// Detecting New Week ... +bool IsNewWeek() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Week ... + // Since Week Starts From Monday in Forex World ... + // we Calculate Start of Week by 1-Monday ... + result = + xDayOfWeek == -1 && + xForWeekDay == -1 + ? true + : timeStruct.day_of_week == 1 && + timeStruct.day_of_year > xForWeekDay; + + // + xForWeekDay = timeStruct.day_of_year; + xDayOfWeek = timeStruct.day_of_week; + + // + return result; +} + +// +// Detecting End Of Week ... +bool IsWeekEnd() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check WeekEnd ... + // Since Week Starts From Monday in Forex World ... + // we Calculate End of Week by 5-Friday ... + result = + xDayOfWeek != -1 && + timeStruct.day_of_week == 5 && + timeStruct.hour == 23 && + timeStruct.min == 59 && + timeStruct.sec == 59; + + // + return result; +} + +// +// Detecting New Month ... +bool IsNewMonth() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.mon != xMonth; + if (result) + { + xMonth = timeStruct.mon; + } + + // + return result; +} + +// +// Find Farest Time Frame ... +ENUM_TIMEFRAMES GetFarestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + case PERIOD_M30: + result = PERIOD_H4; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + result = PERIOD_H12; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Medium Time Frame ... +ENUM_TIMEFRAMES GetMediestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H1; + break; + + // + case PERIOD_M30: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Nearest Time Frame ... +ENUM_TIMEFRAMES GetNearestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M5; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_M30: + result = PERIOD_H1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Get Specific Time Frame Start Candle Time ... +datetime GetPeriodStartTime( + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + datetime mTime = NULL // Specified Bar Time ... +) +{ + // + // Normalize Arg ... + + // + if ( + mSymbol == NULL || + StringLen(mSymbol) == 0) + { + mSymbol = _Symbol; + } + + // + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if ( + mTime < 0 || + mTime == NULL) + { + mTime = TimeCurrent(); + } + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false); + + // + datetime result = iTime( + mSymbol, + mPeriod, + barIndex); + + // + return result; +} + +// +// END Provided Functions ... +// diff --git a/XEU5/Libraries/x-saherelm.draw.lib.mq5 b/XEU5/Libraries/x-saherelm.draw.lib.mq5 new file mode 100644 index 0000000..ece98c8 --- /dev/null +++ b/XEU5/Libraries/x-saherelm.draw.lib.mq5 @@ -0,0 +1,2345 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Draw Library +// -------------------------------------- +// Name: XDraw +// Description: provides Draw abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// Include Logger Library ... +#include "x-saherelm.log.lib.mq5" +#include "x-saherelm.common.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string drawPrefix = "X-OBJ"; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// DeInitial Library if required ... +void OnDeinitDrawLibrary() +{ + RemoveDraws(); +} + +// +void DrawSignalShape( + XSignal &signal, // Specify Signal to Draw + color longColor = clrAqua, // Long Signals Color + color shortColor = clrFuchsia, // Short Signal Color + color entryColor = clrGold // Signal Entry Price Color +) +{ + // + // Draw Signal Info : + // - Draw Entry Price Line; + // - Draw SL; + // - Draw TP; + // - Risk Free; + + // + bool isLong = signal.type == X_SIGNAL_LONG; + + // + color tpColor = longColor; + color slColor = shortColor; + + // + string name = "T(" + (string)signal.ticket + ")" + "_" + "TY(" + EnumToString(signal.type) + ")"; + + // + string tpName = "TP_" + name; + if (IsDrawExists(tpName)) + { + RemoveDraw(tpName); + } + + // + string slName = "SL_" + name; + if (IsDrawExists(slName)) + { + RemoveDraw(slName); + } + + // + string riskFreeName = "RF_" + name; + if (IsDrawExists(riskFreeName)) + { + RemoveDraw(riskFreeName); + } + + // + string entryName = "Entry_" + name; + if (IsDrawExists(entryName)) + { + RemoveDraw(entryName); + } + + // + string vlName = "Time_" + name; + if (IsDrawExists(vlName)) + { + RemoveDraw(vlName); + } + + // + int signalBarIndex = iBarShift( + signal.symbol, + _Period, + signal.time); + + // + datetime time1 = iTime( + signal.symbol, + _Period, + signalBarIndex + 1); + datetime time2 = iTime( + signal.symbol, + _Period, + signalBarIndex - 1); + + // + // Entry ... + bool isTrendLineDrawn = DrawTrendLine( + 0, + entryName, + 0, + time1, + signal.entry, + time2, + signal.entry, + entryColor); + + // + // TP ... + bool isTPDrawn = false; + if (signal.tp > 0) + { + // + isTPDrawn = DrawTrendLine( + 0, + tpName, + 0, + time1, + signal.tp, + time2, + signal.tp, + tpColor, + STYLE_SOLID, + 1, + false, + true); + } + + // + // RISKFREE ... + bool isRFDrawn = false; + if (signal.riskFreeStep > 0) + { + // + double firstStepPrice = isLong ? signal.entry + PipsToPrice(signal.riskFreeStep) + : signal.entry - PipsToPrice(signal.riskFreeStep); + + // + isRFDrawn = DrawTrendLine( + 0, + riskFreeName, + 0, + time1, + firstStepPrice, + time2, + firstStepPrice, + tpColor, + STYLE_DOT, + 1, + false, + true); + } + + // + // SL ... + bool isSLDrawn = false; + if (signal.sl > 0) + { + // + isSLDrawn = DrawTrendLine( + 0, + slName, + 0, + time1, + signal.sl, + time2, + signal.sl, + slColor, + STYLE_SOLID, + 1, + false, + true); + } + + // + // Draw a Vertical Line ... + bool isVerticalLineDrawn = DrawVerticalLine( + 0, + vlName, + 0, + signal.time, + slColor); +} + +// +// remove drawn objects ... +void RemoveDraws( + string tag = NULL, + int chartId = -1, + int subWindow = -1) +{ + // + // Normalize Args ... + // + if (tag == NULL) + { + tag = drawPrefix; + } + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, tag) >= 0) + { + ObjectDelete(chartId, on); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + +// +bool RemoveDraw( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + string objName = ""; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + if (StringFind(on, name) >= 0) + { + // + objName = on; + break; + } + } + + // + if (StringLen(objName) > 0) + { + result = ObjectDelete(chartId, objName); + } + + // + return result; +} + +// +// Check Object Exists ... +bool IsDrawExists( + string name, + int chartId = -1, + int subWindow = -1) +{ + // + bool result = false; + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + string on = ObjectName(chartId, iObj, subWindow); + result = StringFind(on, name) >= 0; + if (result) + { + break; + } + } + + // + return result; +} +// +// END Provided Functions ... +// + +// +// START Regular Draws ... +// + +// +// START Arrow Functions ... +// +// +// Draw an Arrow Object on Chart ... +bool DrawArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // arrow name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const uchar arrowCode = 252, // arrow code + const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position + const color clr = clrAqua, // arrow color + const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style + const int width = 3, // arrow size + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // Order Object ... +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeArrowEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create an arrow ... + if (!ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set the arrow code ... + ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set the arrow color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set the border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set the arrow's size ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the arrow by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is false by default, if you want making it possible to highlight and move the object + // change it to true ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move the anchor point of Arrow ... +bool MoveArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete an arrow ... +bool DeleteArrow( + const long chartID = 0, // chart's ID + const string name = "Arrow" // arrow name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete an arrow ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete an arrow! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change the arrow code ... +bool ArrowCodeChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const uchar code = 252 // arrow code +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change the arrow code ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) + { + // + string message = + __FUNCTION__ + + ": failed to change the arrow code! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change anchor type ... +bool ArrowAnchorChange( + const long chartID = 0, // chart's ID + const string name = "Arrow", // object name + const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change anchor type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) + { + // + string message = + __FUNCTION__ + + ": failed to change anchor type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeArrowEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Arrow Functions ... +// + +// +// START Horizontal Line Functions ... +// +// +// Create, Draw the horizontal line ... +bool DrawHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + const int subWindow = 0, // subwindow index + double price = 0, // line price + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the price is not set, set it at the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a horizontal line ... + if (!ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move horizontal line ... +bool MoveHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine", // line name + double price = 0 // line price +) +{ + // + // if the line price is not set, move it to the current Bid price level ... + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move a horizontal line ... + if (!ObjectMove(chartID, name, 0, 0, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete a horizontal line ... +bool DeleteHorizontalLine( + const long chartID = 0, // chart's ID + const string name = "HLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a horizontal line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a horizontal line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} +// +// END Horizontal Line Functions ... +// + +// +// START Vertical Line Functions ... +// +// +// Create the vertical line ... +bool DrawVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + const int sub_window = 0, // subwindow index + datetime time = 0, // line time + const color clr = clrRed, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // if the line time is not set, draw it via the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a vertical line ... + if (!ObjectCreate(chartID, objName, OBJ_VLINE, sub_window, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return true; +} + +// +// Move the vertical line ... +bool MoveVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine", // line name + datetime time = 0 // line time +) +{ + // + // if line time is not set, move the line to the last bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the vertical line ... + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete the vertical line ... +bool DeleteVerticalLine( + const long chartID = 0, // chart's ID + const string name = "VLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the vertical line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete the vertical line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return false; + } + + // + // successful execution ... + return true; +} +// +// END Vertical Line Functions ... +// + +// +// START RectangleLabel Functions ... +// +// +// Create Rectangle Label Object ... +bool DrawRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // width + const int height = 18, // height + const color back_clr = clrWhiteSmoke, // background color + const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const color clr = clrRed, // flat border color (Flat) + const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style + const int lineWidth = 1, // flat border width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + //--- create a rectangle label + if (!ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set label coordinates ... + ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); + + // + // set label size ... + ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); + + // + // set background color ... + ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, back_clr); + + // + // set border type ... + ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); + + // + // set the chart's corner, relative to which point coordinates are defined ... + ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); + + // + // set flat border color (in Flat mode) ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set flat border line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set flat border width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the label by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move Rectangle Label .. +bool MoveRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // move the rectangle label ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) + { + // + string message = + __FUNCTION__ + + ": failed to move X coordinate of the label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) + { + // + string message = + __FUNCTION__ + + ": failed to move Y coordinate of the label! Error code = " + + (string)GetLastError(); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete the rectangle label ... +bool DeleteRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel" // label name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the label ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a rectangle label! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change Rectangle Label Size ... +bool ChangeSizeRectangleLabel( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const int width = 50, // label width + const int height = 18 // label height +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change label size ... + if (!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's width! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + if (!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) + { + // + string message = + __FUNCTION__ + + ": failed to change the label's height! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change rectangle label border type ... +bool RectLabelChangeBorderType( + const long chartID = 0, // chart's ID + const string name = "RectLabel", // label name + const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change border type ... + if (!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) + { + // + string message = + __FUNCTION__ + + ": failed to change the border type! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} +// +// END RectangleLabel Functions ... +// + +// +// START TrendLine Funcions ... +// +// Create a trend line by the given coordinates ... +bool DrawTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrYellow, // line color + const ENUM_LINE_STYLE style = STYLE_SOLID, // line style + const int width = 1, // line width + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool rayRight = false, // line's continuation to the right + const bool hidden = false, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeTrendLineEmptyPoints( + time1, + price1, + time2, + price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // create a trend line by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set line color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line display style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the line by mouse + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the line's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move trend line anchor point ... | +bool ChangeTrendLinePoint( + const long chartID = 0, // chart's ID + const string name = "TrendLine", // line name + const int pointindex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move trend line's anchor point ... + if (!ObjectMove(chartID, name, pointindex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// The function deletes the trend line from the chart ... +bool DeleteTrendLine( + const long chartID = 0, // chart's ID + const string name = "TrendLine" // line name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete a trend line ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete a trend line! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check the values of trend line's anchor points and set default ... +// values for empty ones ... +void ChangeTrendLineEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the first point's time is not set, it will be on the current bar ... + if (!time1) + { + time1 = TimeCurrent(); + } + + // + // if the first point's price is not set, it will have Bid value ... + if (!price1) + { + price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); + } + + // + // if the second point's time is not set, it is located 9 bars left from the second one ... + if (!time2) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time1, 10, temp); + + // + // set the second point 9 bars left from the first one ... + time2 = temp[0]; + } + + // + // if the second point's price is not set, it is equal to the first point's one ... + if (!price2) + { + price2 = price1; + } +} +// +// END TrendLine Functions ... +// + +// +// START Text Functions ... +// +// Create and Draw a Text Object ... +bool DrawText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const int subWindow = 0, // subwindow index + datetime time = 0, // anchor point time + double price = 0, // anchor point price + const string text = "Text", // the text itself + const string font = "Arial", // font + const int fontSize = 10, // font size + const color clr = clrRed, // color + const double angle = 0.0, // text slope + const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor point coordinates if they are not set ... + ChangeTextEmptyPoint(time, price); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + //--- create Text object + if (!ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set the text ... + ObjectSetString(chartID, objName, OBJPROP_TEXT, text); + + // + // set text font ... + ObjectSetString(chartID, objName, OBJPROP_FONT, font); + + // + // set font size ... + ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); + + // + // set the slope angle of the text ... + ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); + + // + // set anchor type ... + ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving the object by mouse ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Move the anchor point ... +bool MoveText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + //--- if point position is not set, move it to the current bar having Bid price + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point .. + if (!ObjectMove(chartID, name, 0, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Change the object text ... +bool ChangeText( + const long chartID = 0, // chart's ID + const string name = "Text", // object name + const string text = "Text" // text +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // change object text ... + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete Text object ... +bool DeleteText( + const long chartID = 0, // chart's ID + const string name = "Text" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Text\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Check anchor point values and set default values +// for empty ones ... +void ChangeTextEmptyPoint( + datetime &time, + double &price) +{ + // + // if the point's time is not set, it will be on the current bar ... + if (!time) + { + time = TimeCurrent(); + } + + // + // if the point's price is not set, it will have Bid value ... + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } +} +// +// END Text Functions ... +// + +// +// START Fibonacchi Functions ... +// +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawFibonacci( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrRed, // object color + const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // successful execution ... + return (true); +} + +// +// Create Fibonacci Retracement by the given coordinates ... +bool DrawCustomFibonacci( + // + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + // + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int subWindow = 0, // subwindow index + datetime time1 = 0, // first point time + double price1 = 0, // first point price + datetime time2 = 0, // second point time + double price2 = 0, // second point price + const color clr = clrAqua, // object color + const ENUM_LINE_STYLE style = STYLE_DOT, // object line style + const int width = 1, // object line width + const bool back = false, // in the background + const bool selection = true, // highlight to move + const bool rayRight = false, // object's continuation to the right + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + // set anchor points' coordinates if they are not set ... + ChangeFibonacciEmptyPoints(time1, price1, time2, price2); + + // + // reset the error value ... + ResetLastError(); + + // + // Normalize Name ... + string objName = drawPrefix + "_" + name; + + // + // Create Fibonacci Retracement by the given coordinates ... + if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set color ... + ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); + + // + // set line style ... + ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); + + // + // set line width ... + ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) ... + ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of highlighting the channel for moving + // when creating a graphical object using ObjectCreate function, the object cannot be + // highlighted and moved by default. Inside this method, selection parameter + // is true by default making it possible to highlight and move the object ... + ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); + ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); + + // + // enable (true) or disable (false) the mode of continuation of the object's display to the right ... + ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); + + // + // hide (true) or display (false) graphical object name in the object list ... + ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart ... + ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); + + // + // Change Levels Of Fibonacci ... + bool result = FibonacciLevelsSet( + levels, + values, + colors, + styles, + widths, + descriptions, + chartID, + objName); + + // + // successful execution ... + return result; +} + +// +// Set number of levels and their parameters ... +bool FibonacciLevelsSet( + int levels, // number of level lines + double &values[], // values of level lines + color &colors[], // color of level lines + ENUM_LINE_STYLE &styles[], // style of level lines + int &widths[], // width of level lines + string &descriptions[], // level Descriptions + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // check array sizes ... + if ( + levels != ArraySize(colors) || + levels != ArraySize(styles) || + levels != ArraySize(widths) || + levels != ArraySize(widths)) + { + // + string message = + __FUNCTION__ + + ": array length does not correspond to the number of levels, error!"; + + // + LogMessage(message); + + // + return (false); + } + + // + // set the number of levels ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); + + // + // set the properties of levels in the loop ... + for (int i = 0; i < levels; i++) + { + // + // level value ... + ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); + + // + // level color ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); + + // + // level style ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); + + // + // level width ... + ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); + + // + // level description ... + // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); + ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); + } + + // + // successful execution ... + return (true); +} + +// +// Move Fibonacci Retracement anchor point ... +bool FibonacciPointChange( + const long chartID = 0, // chart's ID + const string name = "Fibonacci", // object name + const int pointIndex = 0, // anchor point index + datetime time = 0, // anchor point time coordinate + double price = 0 // anchor point price coordinate +) +{ + // + // if point position is not set, move it to the current bar having Bid price ... + if (!time) + { + time = TimeCurrent(); + } + + // + if (!price) + { + price = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // reset the error value ... + ResetLastError(); + + // + // move the anchor point ... + if (!ObjectMove(chartID, name, pointIndex, time, price)) + { + // + string message = + __FUNCTION__ + + ": failed to move the anchor point! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Delete Fibonacci Retracement ... +bool DeleteFibonachi( + const long chartID = 0, // chart's ID + const string name = "Fibonacci" // object name +) +{ + // + // reset the error value ... + ResetLastError(); + + // + // delete the object ... + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Fibonacci Retracement\"! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution ... + return (true); +} + +// +// Check the values of Fibonacci Retracement anchor points and set +// default values for empty ones ... +void ChangeFibonacciEmptyPoints( + datetime &time1, + double &price1, + datetime &time2, + double &price2) +{ + // + // if the second point's time is not set, it will be on the current bar ... + if (!time2) + { + time2 = TimeCurrent(); + } + + // + // if the second point's price is not set, it will have Bid value ... + if (!price2) + { + price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); + } + + // + // if the first point's time is not set, it is located 9 bars left from the second one ... + if (!time1) + { + // + // array for receiving the open time of the last 10 bars ... + datetime temp[10]; + CopyTime(Symbol(), Period(), time2, 10, temp); + + // + // set the first point 9 bars left from the second one ... + time1 = temp[0]; + } + + // + // if the first point's price is not set, move it 200 points below the second one ... + if (!price1) + { + price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); + } +} +// +// END Fibonacci Functions ... +// + +// +// START Event Functions ... +// + +// +// Create an Event ... +bool EventCreate( + const long chartID = 0, // chart's ID + const string name = "Event", // object name + const int subWindow = 0, // subwindow index + const string text = "Content", // event text + datetime time = 0, // anchor point time + const color clr = clrRed, // color + const int width = 1, // point width when highlighted + const bool back = false, // in the background + const bool selection = false, // highlight to move + const bool hidden = true, // hidden in the object list + const long zOrder = 0 // priority for mouse click +) +{ + // + if (!time) + { + time = TimeCurrent(); + } + + // + ResetLastError(); + + // + if (!ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to create \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // set event text + ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + // set color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set anchor point width if the object is highlighted + ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); + + // + // display in the foreground (false) or background (true) + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // enable (true) or disable (false) the mode of moving event by mouse + ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); + ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); + + // + // hide (true) or display (false) graphical object name in the object list + ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); + + // + // set the priority for receiving the event of a mouse click in the chart + ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); + + // + // successful execution + return (true); +} + +// +// Change Event object text +bool EventTextChange( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + const string text = "Content" // text +) +{ + // + // reset the error value + ResetLastError(); + + // + // change object text + if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) + { + // + string message = + __FUNCTION__ + + ": failed to change the text! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Move Event object +bool EventMove( + const long chartID = 0, // chart's ID + const string name = "Event", // event name + datetime time = 0 // time +) +{ + // + // if time is not set, move event to the last bar + if (!time) + { + time = TimeCurrent(); + } + + // + // reset the error value + ResetLastError(); + + // + // move the object + if (!ObjectMove(chartID, name, 0, time, 0)) + { + // + string message = + __FUNCTION__ + + ": failed to move \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// Delete Event object +bool EventDelete( + const long chartID = 0, // chart's ID + const string name = "Event" // event name +) +{ + // + // reset the error value + ResetLastError(); + + // + // delete the object + if (!ObjectDelete(chartID, name)) + { + // + string message = + __FUNCTION__ + + ": failed to delete \"Event\" object! Error code = " + + (string)GetLastError(); + + // + LogMessage(message); + + // + return (false); + } + + // + // successful execution + return (true); +} + +// +// END Event Functions ... +// + +// +// END Regular Draws ... +// + +// +// START Chart Style Drawers ... +// +// +// Apply Styles On Chart ... +void ApplyChartStyle( + int chartId = -1, // chart's ID + ENUM_CHART_MODE mode = CHART_CANDLES, // chart's mode + bool showBidLine = true, // show bid line + bool showAskLine = true, // show ask line + bool showGrid = false, // show grids on chart + bool showVolumes = false, // show volumes + bool showTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool autoScroll = true, // chart autoscroll + bool quickNavigation = true, // chart quick navigation state + color foreGroundColor = clrWhite, // chart's foreground color + color backGroundColor = clrBlack, // chart's background color + color upColor = clrGreen, // Up Color + color downColor = clrRed, // Down Color + color bullishColor = clrGreen, // Bullish color + color bearishColor = clrRed, // Bearish color + color gridColor = clrGray, // grid color + color bidLineColor = clrGray, // bid line color + color askLineColor = clrRed, // ask line color + color lineColor = clrLime, // line mode and doji candlestick color + color stopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color volumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (chartId == -1) + { + chartId = 0; + } + + // + ChartSetInteger(chartId, CHART_MODE, mode); + ChartSetInteger(chartId, CHART_SHOW_BID_LINE, showBidLine); + ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, showAskLine); + ChartSetInteger(chartId, CHART_SHOW_GRID, showGrid); + ChartSetInteger(chartId, CHART_SHOW_VOLUMES, showVolumes); + ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, showTradeLevels); + ChartSetInteger(chartId, CHART_AUTOSCROLL, autoScroll); + ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, quickNavigation); + ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, foreGroundColor); + ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, backGroundColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_UP, upColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, downColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, bullishColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, bearishColor); + ChartSetInteger(chartId, CHART_COLOR_GRID, gridColor); + ChartSetInteger(chartId, CHART_COLOR_BID, bidLineColor); + ChartSetInteger(chartId, CHART_COLOR_ASK, askLineColor); + ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, stopColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, lineColor); + ChartSetInteger(chartId, CHART_COLOR_VOLUME, volumesColor); +} +// +// END Chart Style Drawers ... +// \ No newline at end of file diff --git a/XEU5/Libraries/x-saherelm.http.lib.mq5 b/XEU5/Libraries/x-saherelm.http.lib.mq5 new file mode 100644 index 0000000..97f7ac0 --- /dev/null +++ b/XEU5/Libraries/x-saherelm.http.lib.mq5 @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Http Library +// ------------------------------------------ +// Name: XHttp +// Description: provide http communication +// abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Model Definition ... +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; +// +// END Model Definition ... +// + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Initial Library if required ... +bool OnInInitHttpLibrary() +{ + return false; +} + +// +// DeInitial Library if required ... +void OnDeinitHttpLibrary() +{ +} + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// +// Send Global Request ... +int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) +{ + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) { + return result; + } + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders + ); + + // + return result; +} + +// +// Get Request ... +int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} + +// +// Post Request ... +int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 +) { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout + ); + + // + return result; +} +// +// END Provided Functions ... +// diff --git a/XEU5/Libraries/x-saherelm.log.lib.mq5 b/XEU5/Libraries/x-saherelm.log.lib.mq5 new file mode 100644 index 0000000..70f1bda --- /dev/null +++ b/XEU5/Libraries/x-saherelm.log.lib.mq5 @@ -0,0 +1,261 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Logger Library +// --------------------------------------- +// Name: XLogger +// Description: provides Logging abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +input group "Logging"; +input bool enableLogging = true; // Enable Logging +// +// END Inputs ... +// + +// +// Including Models ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +string logTag = "X-Logger"; // LogTag +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// +// +// Logging a Message ... +void LogMessage(string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, " > ", message); +} +void LogMessage(string tag, string message) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(tag, " > ", message); +} + +// +// Logging an Array ... +void LogArray(int &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(double &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} +void LogArray(string &array[]) +{ + // + if (!enableLogging) + { + return; + } + + // + Print(logTag, ">"); + ArrayPrint(array); +} + +// +// Convert a Signal to String Message ... +string SignalToString(const XSignal &signal) +{ + // + string result = "\n"; + + // + result += "Signal: " + "\n"; + result += "id: " + (string)signal.id + "\n"; + result += "symbol: " + signal.symbol + "\n"; + result += "type: " + EnumToString(signal.type) + "\n"; + result += "magicNumber: " + (string)signal.magicNumber + "\n"; + result += "ticket: " + (string)signal.ticket + "\n"; + result += "entry: " + (string)signal.entry + "\n"; + result += "tp: " + (string)signal.tp + "\n"; + result += "sl: " + (string)signal.sl + "\n"; + result += "riskFreeStep: " + (string)signal.riskFreeStep + "\n"; + result += "riskFreeRate: " + (string)signal.riskFreeRate + "\n"; + result += "profit: " + (string)signal.profit + "\n"; + result += "time: " + (string)signal.time + "\n"; + result += "volume: " + (string)signal.volume + "\n"; + result += "comment: " + signal.comment + "\n"; + + // + return result; +} + +// +// Convert an Executed Signal to String Message ... +string ExecutedSignalToString(const XSignal &signal) +{ + // + string result = ""; + + // + result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal Executed provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment; + + // + return result; +} + +// +// Logging Signal ... +void LogSignal(const XSignal &signal) +{ + // + string message = SignalToString(signal); + + // + LogMessage(message); +} + +// +// Log Signal Execution ... +void LogExecutedSignal(const XSignal &signal) +{ + // + string message = ExecutedSignalToString(signal); + + // + LogMessage(message); +} + +// +// Convert a Deal to String ... +string DealToString(const XDeal &deal) +{ + // + string result = "\n"; + + // + result += "Deal:" + "\n"; + result += " " + "\n"; + result += "time: " + (string)deal.time + "\n"; + result += "ticket: " + (string)deal.ticket + "\n"; + result += "order: " + (string)deal.order + "\n"; + result += "positionId: " + (string)deal.positionId + "\n"; + result += "type: " + EnumToString(deal.type) + "\n"; + result += "entry: " + EnumToString(deal.entry) + "\n"; + result += "reason: " + EnumToString(deal.reason) + "\n"; + result += "symbol: " + deal.symbol + "\n"; + result += "price: " + (string)deal.price + "\n"; + result += "profit: " + (string)deal.profit + "\n"; + result += "swap: " + (string)deal.swap + "\n"; + result += "commission: " + (string)deal.commission + "\n"; + result += "volume: " + (string)deal.volume + "\n"; + result += "comment: " + deal.comment + "\n"; + + // + return result; +} + +// +// Log Specific Deal ... +void LogDeal(const XDeal &deal) +{ + // + string message = DealToString(deal); + + // + LogMessage(message); +} + +// +// Convert an Order to String ... +string OrderToString(const XOrder &order) +{ + // + string result = "\n"; + + // + result += "Order: " + "\n"; + result += "magic: " + (string)order.magic + "\n"; + result += "positionId: " + (string)order.positionId + "\n"; + result += "symbol: " + (string)order.symbol + "\n"; + result += "ticket: " + (string)order.ticket + "\n"; + result += "timeSetup: " + (string)order.timeSetup + "\n"; + result += "timeDone: " + (string)order.timeDone + "\n"; + result += "timeExpiration: " + (string)order.timeExpiration + "\n"; + result += "priceOpen: " + (string)order.priceOpen + "\n"; + result += "priceCurrent: " + (string)order.priceCurrent + "\n"; + result += "priceStopLimit: " + (string)order.priceStopLimit + "\n"; + result += "stopLoss: " + (string)order.stopLoss + "\n"; + result += "takeProfit: " + (string)order.takeProfit + "\n"; + result += "volumeInitial: " + (string)order.volumeInitial + "\n"; + result += "volumeCurrent: " + (string)order.volumeCurrent + "\n"; + result += "comment: " + order.comment + "\n"; + result += "type: " + EnumToString(order.type) + "\n"; + result += "state: " + EnumToString(order.state) + "\n"; + result += "typeFilling: " + EnumToString(order.typeFilling) + "\n"; + result += "typeTime: " + EnumToString(order.typeTime) + "\n"; + result += "reason: " + EnumToString(order.reason) + "\n"; + + // + return result; +} + +// +// Log Specific Order ... +void LogOrder(const XOrder &order) +{ + // + string message = OrderToString(order); + + // + LogMessage(message); +} + +// +// END Provided Functions ... +// diff --git a/XEU5/Libraries/x-saherelm.models.lib.mq5 b/XEU5/Libraries/x-saherelm.models.lib.mq5 new file mode 100644 index 0000000..b98ae3e --- /dev/null +++ b/XEU5/Libraries/x-saherelm.models.lib.mq5 @@ -0,0 +1,438 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Models Library +// --------------------------------------- +// Name: XModels +// Description: provides all required models ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// +// +// END Inputs ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// How To Calculate Static Volume ... +enum ENUM_STATIC_VOLUME_METHODS +{ + // + // Based On Deposit ... + X_STATIC_VOLUME_BASED_ON_DEPOSIT, + // + // Based On Balance ... + X_STATIC_VOLUME_BASED_ON_BALANCE, +}; + +// +// START Model Definitions ... +// +// +// OHCL Candel Model ... +enum ENUM_X_PRICE +{ + X_PRICE_HIGH, + X_PRICE_OPEN, + X_PRICE_CLOSE, + X_PRICE_LOW +}; + +// +// Describe an Specific Candle ... +struct XOHCL +{ + double high; + double open; + double close; + double low; +}; + +// +// Swing Types Enum ... +enum ENUM_X_SWING_TYPE +{ + X_NO_SWING = 0, + X_SWING_HIGH = 1, + X_SWING_LOW = -1, +}; + +// +// XTrader Execution Signal Result ... +enum ENUM_EXECUTION_SIGNAL_RESULT +{ + // + X_TRADER_UNKNOWN_ERROR, + X_TRADER_SUCCEED_EXECUTION, + X_TRADER_INVALID_SIGNAL_ERROR, + X_TRADER_NOT_ENOUGH_EQUITY_ERROR, + X_TRADER_MAX_TRADES_REACHED_ERROR, + X_TRADER_NOT_ENOUGH_BALANCE_ERROR, + X_TRADER_NOT_ENOUGH_MARIGIN_ERROR + // +}; + +// +// Signal Types ... +enum ENUM_X_SIGNAL_TYPE +{ + X_SIGNAL_LONG, + X_SIGNAL_SHORT, + X_SIGNAL_UNKNOWN, +}; + +// +// Signal Structure ... +struct XSignal +{ + // + // Identifier ... + ulong id; + + // + // Which Symbol used for Signal ... + string symbol; + + // + // Which Type of operations ... + ENUM_X_SIGNAL_TYPE type; + + // + // Magic Number ... + ulong magicNumber; + + // + // Ticket ... + ulong ticket; + + // + // Entry/Open Price ... + double entry; + + // + // TP ... + double tp; + + // + // SL ... + double sl; + + // + // Make Risk Free Trade on this Value if provided ... + double riskFreeStep; + + // + // a Multiplier for determines how much trade volume exit on risk free time ... + double riskFreeRate; + + // + // Trade Profit ... + double profit; + + // + // Time of Operation ... + datetime time; + + // + // Volume ... + double volume; + + // + // Comment ... + string comment; +}; + +// +// Signal Additional Info ... +struct XProvidedSignal +{ + // + // Suggested TP ... + double tp; + + // + // Suggested SL ... + double sl; + + // + // Signallers ... + string signallers[]; +}; + +// +// Model Specific Deal ... +struct XDeal +{ + // + // the ID of the Expert Advisor, that executed the deal ... + ulong magic; + + // + // the ID of position, in which the deal was involved ... + ulong positionId; + + // + // Ticket ... + ulong ticket; + + // + // the name of the deal symbol ... + string symbol; + + // + // order by which the deal is executed ... + ulong order; + + // + // the time of deal execution ... + datetime time; + + // + // Deal price ... + double price; + + // + // the financial result of the deal (in deposit currency) ... + double profit; + + // + // the amount of swap when position is closed ... + double swap; + + // + // the amount of commission of the deal ... + double commission; + + // + // the volume of deal ... + double volume; + + // + // the deal comment ... + string comment; + + // + // the deal type ... + // ------------------------------------------------------------------ + // DEAL_TYPE_BUY => Buy ... + // DEAL_TYPE_SELL => Sell ... + // DEAL_TYPE_BUY_CANCELED => Canceled buy deal ... + // There can be a situation when a previously executed buy deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ... + // + // DEAL_TYPE_SELL_CANCELED => Canceled sell deal ... + // There can be a situation when a previously executed sell deal is canceled. In this case, + // the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED, + // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation + // + // DEAL_TYPE_BALANCE => Balance ... + // DEAL_TYPE_CREDIT => Credit ... + // DEAL_TYPE_CHARGE => Additional charge ... + // DEAL_TYPE_CORRECTION => Correction ... + // DEAL_TAX => Tax charges ... + // DEAL_TYPE_BONUS => Bonus ... + // DEAL_TYPE_INTEREST => Interest rate ... + // DEAL_DIVIDEND => Dividend operations... + // DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ... + // DEAL_TYPE_COMMISSION => Additional commission ... + // DEAL_TYPE_COMMISSION_DAILY => Daily commission ... + // DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ... + // DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ... + // DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission + ENUM_DEAL_TYPE type; + + // + // the deal direction ... + // ---------------------------------- + // DEAL_ENTRY_IN => Entry in ... + // DEAL_ENTRY_OUT => Entry out ... + // DEAL_ENTRY_INOUT => Reverse ... + // DEAL_ENTRY_OUT_BY => Close a position by an opposite one ... + ENUM_DEAL_ENTRY entry; + + // + // deal reson ... + // --------------------- + // DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ... + // DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ... + // DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ... + // DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ... + // DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ... + // DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ... + // DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ... + // DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ... + // DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ... + // DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ... + ENUM_DEAL_REASON reason; +}; + +// +// Model Specific Order ... +struct XOrder +{ + // + // the ID of expert that placed the order ... + ulong magic; + + // + // the ID of position ... + ulong positionId; + + // + // the name of order symbol ... + string symbol; + + // + // the ticket of an order, previously selected for access ... + ulong ticket; + + // + // the time of order placement ... + datetime timeSetup; + + // + // the time of order execution or cancellation ... + datetime timeDone; + + // + // the order expiration time ... + datetime timeExpiration; + + // + // the order price ... + double priceOpen; + + // + // the current price by order symbol ... + double priceCurrent; + + // + // the price of a pending order ... + double priceStopLimit; + + // + // the order's Stop Loss ... + double stopLoss; + + // + // the order's Take Profit ... + double takeProfit; + + // + // the initial volume of order ... + double volumeInitial; + + // + // the unfilled volume of order ... + double volumeCurrent; + + // + // the order comment ... + string comment; + + // + // the order type ... + // -------------------- + // ORDER_TYPE_BUY => Market Buy order ... + // ORDER_TYPE_SELL => Market Sell order ... + // ORDER_TYPE_BUY_LIMIT => Buy Limit pending order ... + // ORDER_TYPE_SELL_LIMIT => Sell Limit pending order ... + // ORDER_TYPE_BUY_STOP => Buy Stop pending order ... + // ORDER_TYPE_SELL_STOP => Sell Stop pending order ... + // ORDER_TYPE_BUY_STOP_LIMIT => Upon reaching the order price, a pending Buy Limit order is placed at the StopLimit price ... + // ORDER_TYPE_SELL_STOP_LIMIT => Upon reaching the order price, a pending Sell Limit order is placed at the StopLimit price ... + // ORDER_TYPE_CLOSE_BY => Order to close a position by an opposite one ... + ENUM_ORDER_TYPE type; + + // + // the order state ... + // -------------------------- + // ORDER_STATE_STARTED => Order checked, but not yet accepted by broker ... + // ORDER_STATE_PLACED => Order accepted ... + // ORDER_STATE_CANCELED => Order canceled by client ... + // ORDER_STATE_PARTIAL => Order partially executed ... + // ORDER_STATE_FILLED => Order fully executed ... + // ORDER_STATE_REJECTED => Order rejected ... + // ORDER_STATE_EXPIRED => Order expired ... + // ORDER_STATE_REQUEST_ADD => Order is being registered (placing to the trading system) + // ORDER_STATE_REQUEST_MODIFY => Order is being modified (changing its parameters) ... + // ORDER_STATE_REQUEST_CANCEL => Order is being deleted (deleting from the trading system) ... + ENUM_ORDER_STATE state; + + // + // the order filling type ... + // ---------------------------- + // ORDER_FILLING_FOK => Fill or Kill + // An order can be executed in the specified volume only. + // If the necessary amount of a financial instrument is currently unavailable in the market, + // the order will not be executed. + // The desired volume can be made up of several available offers. + // The possibility of using FOK orders is determined at the trade server. + // ORDER_FILLING_IOC => Immediate or Cancel + // A trader agrees to execute a deal with the volume maximally available in the market within that indicated in the order. + // If the request cannot be filled completely, an order with the available volume will be executed, + // and the remaining volume will be canceled. + // The possibility of using IOC orders is determined at the trade server. + // ORDER_FILLING_BOC => Passive (Book or Cancel) + // The BoC order assumes that the order can only be placed in the Depth of Market and cannot be immediately executed. + // If the order can be executed immediately when placed, then it is canceled. + // In fact, the BOC policy guarantees that the price of the placed order will be worse than + // the current market. BoC orders are used to implement passive trading, + // so that the order is not executed immediately when placed and does not affect current liquidity. + // Only limit and stop limit orders are supported (ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT, ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT). + // ORDER_FILLING_RETURN => Return + // In case of partial filling, an order with remaining volume is not canceled but processed further. + // Return orders are not allowed in the Market Execution + // mode (market execution — SYMBOL_TRADE_EXECUTION_MARKET). + ENUM_ORDER_TYPE_FILLING typeFilling; + + // + // the type of order at the time of the expiration ... + // -------------------------------------------------------- + // ORDER_TIME_GTC => Good till cancel order ... + // ORDER_TIME_DAY => Good till current trade day order ... + // ORDER_TIME_SPECIFIED => Good till expired order ... + // ORDER_TIME_SPECIFIED_DAY => The order will be effective till 23:59:59 of the specified day. + // If this time is outside a trading session, the order expires in the nearest trading time ... + ENUM_ORDER_TYPE_TIME typeTime; + + // + // The reason for order placing ... + // -------------------------------------- + // ORDER_REASON_SL => The order was placed as a result of Stop Loss activation ... + // ORDER_REASON_TP => The order was placed as a result of Take Profit activation ... + // ORDER_REASON_SO => The order was placed as a result of the Stop Out event ... + // ORDER_REASON_WEB => The order was placed from a web platform ... + // ORDER_REASON_CLIENT => The order was placed from a desktop terminal ... + // ORDER_REASON_MOBILE => The order was placed from a mobile application ... + // ORDER_REASON_EXPERT => The order was placed from an MQL5-program, i.e. by an Expert Advisor or a script ... + ENUM_ORDER_REASON reason; +}; +// +// END Provided Functions ... +// diff --git a/XEU5/Providers/.gitkeep b/XEU5/Providers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 b/XEU5/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 new file mode 100644 index 0000000..c077b65 --- /dev/null +++ b/XEU5/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 @@ -0,0 +1,13599 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XEU5 Signal Provider Indicators Library +// ---------------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Include Provider Inputs ... +#include "x-saherelm.xeu5.provider.inputs.lib.mq5" + +// +// Include Provider Class ... +#include "../Classes/x-saherelm.provider.lib.mq5" + +// +// Signallers ... +input group "XEU5 Signallers"; + +// +// XTD ... +input group "XEU5 XTD Signaller"; +input bool xEU5XTDEnableSignaller = true; // Enable Signaller +input bool xEU5XTDAllowLongSignals = true; // Enable Long Signals +input bool xEU5XTDAllowShortSignals = true; // Enable Short Signals + +// +// XTAM ... +input group "XEU5 XTAM Signaller"; +input bool xEU5XTAMEnableSignaller = true; // Enable Signaller +input bool xEU5XTAMAllowLongSignals = true; // Enable Long Signals +input bool xEU5XTAMAllowShortSignals = true; // Enable Short Signals + +// +// XSI ... +input group "XEU5 XSI Signaller"; +input bool xEU5XSIEnableSignaller = true; // Enable Signaller +input bool xEU5XSIAllowLongSignals = true; // Enable Long Signals +input bool xEU5XSIAllowShortSignals = true; // Enable Short Signals + +// +// XTSFI ... +input group "XEU5 XTSFI Signaller"; +input bool xEU5XTSFIEnableSignaller = true; // Enable Signaller +input bool xEU5XTSFIAllowLongSignals = true; // Enable Long Signals +input bool xEU5XTSFIAllowShortSignals = true; // Enable Short Signals + +// +// XOBDLH ... +input group "XEU5 XOBDLH Signaller"; +input bool xEU5XOBDLHEnableSignaller = true; // Enable Signaller +input bool xEU5XOBDLHAllowLongSignals = true; // Enable Long Signals +input bool xEU5XOBDLHAllowShortSignals = true; // Enable Short Signals + +// +// XCHMACC ... +input group "XEU5 XCHMACC Signaller"; +input bool xEU5XCHMACCEnableSignaller = true; // Enable Signaller +input bool xEU5XCHMACCAllowLongSignals = true; // Enable Long Signals +input bool xEU5XCHMACCAllowShortSignals = true; // Enable Short Signals + +// +// XCHMAMX ... +input group "XEU5 XCHMAMX Signaller"; +input bool xEU5XCHMAMXEnableSignaller = true; // Enable Signaller +input bool xEU5XCHMAMXAllowLongSignals = true; // Enable Long Signals +input bool xEU5XCHMAMXAllowShortSignals = true; // Enable Short Signals + +// +// XCHMAMN ... +input group "XEU5 XCHMAMN Signaller"; +input bool xEU5XCHMAMNEnableSignaller = true; // Enable Signaller +input bool xEU5XCHMAMNAllowLongSignals = true; // Enable Long Signals +input bool xEU5XCHMAMNAllowShortSignals = true; // Enable Short Signals + +// +bool xEU5IsTestMode = true; +int xEU5MaxLengthOfInputs = 0; +int xEU5CalculatedBars = 0; + +// +// Signaller Variables ... +// +// XTD ... +bool xEU5MXTDEnableSignaller = xEU5XTDEnableSignaller; +bool xEU5MXTDAllowLongSignals = xEU5XTDAllowLongSignals; +bool xEU5MXTDAllowShortSignals = xEU5XTDAllowShortSignals; + +// +// XTAM ... +bool xEU5MXTAMEnableSignaller = xEU5XTAMEnableSignaller; +bool xEU5MXTAMAllowLongSignals = xEU5XTAMAllowLongSignals; +bool xEU5MXTAMAllowShortSignals = xEU5XTAMAllowShortSignals; + +// +// XSI ... +bool xEU5MXSIEnableSignaller = xEU5XSIEnableSignaller; +bool xEU5MXSIAllowLongSignals = xEU5XSIAllowLongSignals; +bool xEU5MXSIAllowShortSignals = xEU5XSIAllowShortSignals; + +// +// XTSFI ... +bool xEU5MXTSFIEnableSignaller = xEU5XTSFIEnableSignaller; +bool xEU5MXTSFIAllowLongSignals = xEU5XTSFIAllowLongSignals; +bool xEU5MXTSFIAllowShortSignals = xEU5XTSFIAllowShortSignals; + +// +// XOBDLH ... +bool xEU5MXOBDLHEnableSignaller = xEU5XOBDLHEnableSignaller; +bool xEU5MXOBDLHAllowLongSignals = xEU5XOBDLHAllowLongSignals; +bool xEU5MXOBDLHAllowShortSignals = xEU5XOBDLHAllowShortSignals; + +// +// XCHMACC ... +bool xEU5MXCHMACCEnableSignaller = xEU5XCHMACCEnableSignaller; +bool xEU5MXCHMACCAllowLongSignals = xEU5XCHMACCAllowLongSignals; +bool xEU5MXCHMACCAllowShortSignals = xEU5XCHMACCAllowShortSignals; + +// +// XCHMAMX ... +bool xEU5MXCHMAMXEnableSignaller = xEU5XCHMAMXEnableSignaller; +bool xEU5MXCHMAMXAllowLongSignals = xEU5XCHMAMXAllowLongSignals; +bool xEU5MXCHMAMXAllowShortSignals = xEU5XCHMAMXAllowShortSignals; + +// +// XCHMAMN ... +bool xEU5MXCHMAMNEnableSignaller = xEU5XCHMAMNEnableSignaller; +bool xEU5MXCHMAMNAllowLongSignals = xEU5XCHMAMNAllowLongSignals; +bool xEU5MXCHMAMNAllowShortSignals = xEU5XCHMAMNAllowShortSignals; + +// +XCProvider *xEU5Provider; + +// +// Validate Indicators Inputs ... +bool XEU5ValidateIndicatorsInputs() +{ + // + bool result = false; + + // + // XTM ... + result = XTMValidateInputs(); + if (!result) + { + return result; + } + + // + // XAMA ... + result = XAMAValidateInputs(); + if (!result) + { + return result; + } + + // + // XTD ... + result = XTDValidateInputs(); + if (!result) + { + return result; + } + + // + // XFI ... + result = XFIValidateInputs(); + if (!result) + { + return result; + } + + // + // XTS ... + result = XTSValidateInputs(); + if (!result) + { + return result; + } + + // + // XOBD ... + result = XOBDValidateInputs(); + if (!result) + { + return result; + } + + // + // XLH ... + result = XLHValidateInputs(); + if (!result) + { + return result; + } + + // + // XRSI ... + result = XRSIValidateInputs(); + if (!result) + { + return result; + } + + // + // XCHLH ... + result = XCHLHValidateInputs(); + if (!result) + { + return result; + } + + // + // XCHMA ... + result = XCHMAValidateInputs(); + if (!result) + { + return result; + } + + // + // Make an Instance Of XCProvider Class for Use ... + xEU5Provider = new XCProvider( + // + // Commons ... + _Symbol, + _Period, + // + // Signallers ... + // + // XTD ... + xEU5MXTDEnableSignaller, + xEU5MXTDAllowLongSignals, + xEU5MXTDAllowShortSignals, + // + // XTAM ... + xEU5MXTAMEnableSignaller, + xEU5MXTAMAllowLongSignals, + xEU5MXTAMAllowShortSignals, + // + // XSI ... + xEU5MXSIEnableSignaller, + xEU5MXSIAllowLongSignals, + xEU5MXSIAllowShortSignals, + // + // XTSFI ... + xEU5MXTSFIEnableSignaller, + xEU5MXTSFIAllowLongSignals, + xEU5MXTSFIAllowShortSignals, + // + // XOBDLH ... + xEU5MXOBDLHEnableSignaller, + xEU5MXOBDLHAllowLongSignals, + xEU5MXOBDLHAllowShortSignals, + // + // XCHMACC ... + xEU5MXCHMACCEnableSignaller, + xEU5MXCHMACCAllowLongSignals, + xEU5MXCHMACCAllowShortSignals, + // + // XCHMAMX ... + xEU5MXCHMAMXEnableSignaller, + xEU5MXCHMAMXAllowLongSignals, + xEU5MXCHMAMXAllowShortSignals, + // + // XCHMAMN ... + xEU5MXCHMAMNEnableSignaller, + xEU5MXCHMAMNAllowLongSignals, + xEU5MXCHMAMNAllowShortSignals + // + ); + + // + result = true; + + // + return result; +} + +// +// Init Indicators ... +bool XEU5InitIndicators() +{ + // + bool result = false; + + // + // Make it Enable when we need to Log Market Conditions ... + // xEU5IsTestMode = false; // IsRunningOnTestMode(); + + // + // Check and Calculate Max Length in Inputs ... + // + + // + // XTM ... + xEU5MaxLengthOfInputs = MathMax( + xTMMaPeriod, + xEU5NumberOfItemsPerTick); + + // + // XAMA ... + xEU5MaxLengthOfInputs = MathMax( + xAMALength, + xEU5NumberOfItemsPerTick); + xEU5MaxLengthOfInputs = MathMax( + xAMAFastEMA, + xEU5NumberOfItemsPerTick); + xEU5MaxLengthOfInputs = MathMax( + xAMASlowEMA, + xEU5NumberOfItemsPerTick); + + // + // XLH ... + xEU5MaxLengthOfInputs = MathMax( + xLHLength, + xEU5NumberOfItemsPerTick); + + // + // XTD ... + xEU5MaxLengthOfInputs = MathMax( + xTDLength, + xEU5MaxLengthOfInputs); + + // + // XFI ... + xEU5MaxLengthOfInputs = MathMax( + xFILength, + xEU5MaxLengthOfInputs); + + // + // XRSI ... + xEU5MaxLengthOfInputs = MathMax( + xRSILength, + xEU5MaxLengthOfInputs); + + // + // XOBD ... + xEU5MaxLengthOfInputs = MathMax( + xOBDLength, + xEU5MaxLengthOfInputs); + + // + // XCHLH ... + xEU5MaxLengthOfInputs = MathMax( + xCHLHLcLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHLHMcLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHLHScLength, + xEU5MaxLengthOfInputs); + + // + // XCHMA ... + xEU5MaxLengthOfInputs = MathMax( + xCHMAScFastLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMAScSlowLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMAMcFastLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMAMcSlowLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMALcFastLength, + xEU5MaxLengthOfInputs); + xEU5MaxLengthOfInputs = MathMax( + xCHMALcSlowLength, + xEU5MaxLengthOfInputs); + + // + // Validate Indicators Inputs before Initialization ... + result = XEU5ValidateIndicatorsInputs(); + if (!result) + { + return result; + } + + // + // Validate Signallers ... + + // + // XTD ... + bool isXTDEnable = + xEU5XTDEnableSignaller && + (xEU5XTDAllowLongSignals || + xEU5XTDAllowShortSignals); + + // + // XTAM ... + bool isXTAMEnable = + xEU5XTAMEnableSignaller && + (xEU5XTAMAllowLongSignals || + xEU5XTAMAllowShortSignals); + + // + // XSI ... + bool isXSIEnable = + xEU5XSIEnableSignaller && + (xEU5XSIAllowLongSignals || + xEU5XSIAllowShortSignals); + + // + // XTSFI ... + bool isXTSFIEnable = + xEU5XTSFIEnableSignaller && + (xEU5XTSFIAllowLongSignals || + xEU5XTSFIAllowShortSignals); + + // + // XOBDLH ... + bool isXOBDLHEnable = + xEU5XOBDLHEnableSignaller && + (xEU5XOBDLHAllowLongSignals || + xEU5XOBDLHAllowShortSignals); + + // + // XCHMACC ... + bool isXCHMACCEnable = + xEU5XCHMACCEnableSignaller && + (xEU5XCHMACCAllowLongSignals || + xEU5XCHMACCAllowShortSignals); + + // + // XCHMAMX ... + bool isXCHMAMXEnable = + xEU5XCHMAMXEnableSignaller && + (xEU5XCHMAMXAllowLongSignals || + xEU5XCHMAMXAllowShortSignals); + + // + // XCHMAMN ... + bool isXCHMAMNEnable = + xEU5XCHMAMNEnableSignaller && + (xEU5XCHMAMNAllowLongSignals || + xEU5XCHMAMNAllowShortSignals); + + // + bool hasSignaller = + // + isXTDEnable || + isXTAMEnable || + isXSIEnable || + isXTSFIEnable || + isXOBDLHEnable || + isXCHMACCEnable || + isXCHMAMXEnable || + isXCHMAMNEnable + // + ; + result = hasSignaller; + if (!result) + { + // + LogMessage("XEU5 doesn't enable any Signaller ..."); + + // + return result; + } + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Init ... + result = XTMInitHandlers(); + if (!result) + { + return result; + } + + // + // XAMA Init ... + result = XAMAInitHandlers(); + if (!result) + { + return result; + } + + // + // XLH Init ... + result = XLHInitHandlers(); + if (!result) + { + return result; + } + + // + // XTD Init ... + result = XTDInitHandlers(); + if (!result) + { + return result; + } + + // + // XFI Init ... + result = XFIInitHandlers(); + if (!result) + { + return result; + } + + // + // XTS Init ... + result = XTSInitHandlers(); + if (!result) + { + return result; + } + + // + // XRSI Init ... + result = XRSIInitHandlers(); + if (!result) + { + return result; + } + + // + // XOBD Init ... + result = XOBDInitHandlers(); + if (!result) + { + return result; + } + + // + // XCLH Init ... + result = XCHLHInitHandlers(); + if (!result) + { + return result; + } + + // + // XCHMA Init ... + result = XCHMAInitHandlers(); + if (!result) + { + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XEU5ReleaseIndicators() +{ + // + // Release Handlers ... + XTMReleaseHandlers(); + XAMAReleaseHandlers(); + XLHReleaseHandlers(); + XTDReleaseHandlers(); + XFIReleaseHandlers(); + XTSReleaseHandlers(); + XRSIReleaseHandlers(); + XOBDReleaseHandlers(); + XCHMAReleaseHandlers(); + XCHLHReleaseHandlers(); +} + +// +// Handle Reading Buffers ... +void XEU5HandleReadingBuffers() +{ + // + // Reading Calculated Bars for a Simple Handler ... + xEU5CalculatedBars = BarsCalculated(xTMHandler); + + // + // Read Indicators Buffers ... + XTMReadBuffers(xEU5NumberOfItemsPerTick); + XAMAReadBuffers(xEU5NumberOfItemsPerTick); + XLHReadBuffers(xEU5NumberOfItemsPerTick); + XTDReadBuffers(xEU5NumberOfItemsPerTick); + XFIReadBuffers(xEU5NumberOfItemsPerTick); + XTSReadBuffers(xEU5NumberOfItemsPerTick); + XRSIReadBuffers(xEU5NumberOfItemsPerTick); + XOBDReadBuffers(xEU5NumberOfItemsPerTick); + XCHMAReadBuffers(xEU5NumberOfItemsPerTick); + XCHLHReadBuffers(xEU5NumberOfItemsPerTick); + + // + xEU5Provider.ReadConditions(); +} + +// +// +// START Combination Functions ... +// +// + +// +// Can Open Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XEU5CanOpenLongTrade( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + info.tp = 0; + info.sl = 0; + ArrayResize( + info.signallers, + 0); + + // + bool hasSignal = XEU5HasLongSignal(info); + + // + result = + // + hasSignal + // + ; + + // + if (result) + { + xEU5Provider.ClearConditions(); + } + + // + return result; +} + +// +// Can Close Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XEU5CanCloseLongTrade() +{ + // + bool result = false; + + // + return result; +} + +// +// Can Open Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XEU5CanOpenShortTrade( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + info.tp = 0; + info.sl = 0; + ArrayResize( + info.signallers, + 0); + + // + bool hasSignal = XEU5HasShortSignal(info); + + // + result = + // + hasSignal + // + ; + + // + if (result) + { + xEU5Provider.ClearConditions(); + } + + // + return result; +} + +// +// Can Close Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XEU5CanCloseShortTrade() +{ + // + bool result = false; + + // + return result; +} + +// +// +// END Combination Functions ... +// +// + +// +// +// START Combination Signaling ... +// +// + +// +// Check Market Conditions by Combination of Power of All tools for LONGs ... +bool XEU5HasLongSignal( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // XTD ... + bool isXTDHasSignal = XEU5XTDHasLongSignal(); + if (isXTDHasSignal) + { + // + Add( + EnumToString(XTD), + info.signallers); + } + + // + // XTAM ... + bool isXTAMHasSignal = XEU5XTAMHasLongSignal(); + if (isXTAMHasSignal) + { + // + Add( + EnumToString(XTAM), + info.signallers); + } + + // + // XSI ... + bool isXSIHasSignal = XEU5XSIHasLongSignal(); + if (isXSIHasSignal) + { + // + Add( + EnumToString(XSI), + info.signallers); + } + + // + // XTSFI ... + bool isXTSFIHasSignal = XEU5XTSFIHasLongSignal(); + if (isXTSFIHasSignal) + { + // + Add( + EnumToString(XTSFI), + info.signallers); + } + + // + // XOBD XLH ... + bool isXOBDLHHasSignal = XEU5XOBDLHHasLongSignal(); + if (isXOBDLHHasSignal) + { + // + Add( + EnumToString(XOBDLH), + info.signallers); + } + + // + // XCHMA Cycles Cross ... + bool isXCHMACCHasSignal = XEU5XCHMACCHasLongSignal(); + if (isXCHMACCHasSignal) + { + // + Add( + EnumToString(XCHMACC), + info.signallers); + } + + // + // XCHMA Cycles Min ... + bool isXCHMAMNHasSignal = XEU5XCHMAMNHasLongSignal(); + if (isXCHMAMNHasSignal) + { + // + Add( + EnumToString(XCHMAMN), + info.signallers); + } + + // + // XCHMA Cycles Max + bool isXCHMAMXHasSignal = XEU5XCHMAMXHasLongSignal(); + if (isXCHMAMXHasSignal) + { + // + Add( + EnumToString(XCHMAMX), + info.signallers); + } + + // + result = + // + isXTDHasSignal + // + || + // + isXTAMHasSignal + // + || + // + isXSIHasSignal + // + || + // + isXTSFIHasSignal + // + || + // + isXOBDLHHasSignal + // + || + // + isXCHMACCHasSignal + // + || + // + isXCHMAMNHasSignal + // + || + // + isXCHMAMXHasSignal + // + ; + + // + if (result) + { + // + // Only Log Signals Time Market Conditions if is in Testing Mode ... + if (xEU5IsTestMode) + { + // + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + string message = xEU5Provider.GenerateConditionsString(mConditions); + + // + LogMessage( + "Long Signal Provided by: \n" + + info.signallers[ArraySize(info.signallers) - 1] + "\n" + + "Pusher: " + (string)ArraySize(info.signallers) + "\n" + + "Market Conditions: " + message); + } + } + + // + return result; +} + +// +// Check Market Conditions by Combination of Power of All tools for SHORTs ... +bool XEU5HasShortSignal( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // XTD ... + bool isXTDHasSignal = XEU5XTDHasShortSignal(); + if (isXTDHasSignal) + { + // + Add( + EnumToString(XTD), + info.signallers); + } + + // + // XTAM ... + bool isXTAMHasSignal = XEU5XTAMHasShortSignal(); + if (isXTAMHasSignal) + { + // + Add( + EnumToString(XTAM), + info.signallers); + } + + // + // XSI ... + bool isXSIHasSignal = XEU5XSIHasShortSignal(); + if (isXSIHasSignal) + { + // + Add( + EnumToString(XSI), + info.signallers); + } + + // + // XTSFI ... + bool isXTSFIHasSignal = XEU5XTSFIHasShortSignal(); + if (isXTSFIHasSignal) + { + // + Add( + EnumToString(XTSFI), + info.signallers); + } + + // + // XOBD XLH ... + bool isXOBDLHHasSignal = XEU5XOBDLHHasShortSignal(); + if (isXOBDLHHasSignal) + { + // + Add( + EnumToString(XOBDLH), + info.signallers); + } + + // + // XCHMA Cycles Cross ... + bool isXCHMACCHasSignal = XEU5XCHMACCHasShortSignal(); + if (isXCHMACCHasSignal) + { + // + Add( + EnumToString(XCHMACC), + info.signallers); + } + + // + // XCHMA Cycles Min ... + bool isXCHMAMNHasSignal = XEU5XCHMAMNHasShortSignal(); + if (isXCHMAMNHasSignal) + { + // + Add( + EnumToString(XCHMAMN), + info.signallers); + } + + // + // XCHMA Cycles Max + bool isXCHMAMXHasSignal = XEU5XCHMAMXHasShortSignal(); + if (isXCHMAMXHasSignal) + { + // + Add( + EnumToString(XCHMAMX), + info.signallers); + } + + // + result = + // + isXTDHasSignal + // + || + // + isXTAMHasSignal + // + || + // + isXSIHasSignal + // + || + // + isXTSFIHasSignal + // + || + // + isXOBDLHHasSignal + // + || + // + isXCHMACCHasSignal + // + || + // + isXCHMAMNHasSignal + // + || + // + isXCHMAMXHasSignal + // + ; + + // + if (result) + { + // + // Only Log Signals Time Market Conditions if is in Testing Mode ... + if (xEU5IsTestMode) + { + // + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + string message = xEU5Provider.GenerateConditionsString(mConditions); + + // + LogMessage( + "Short Signal Provided by: \n" + + info.signallers[ArraySize(info.signallers) - 1] + "\n" + + "Pusher: " + (string)ArraySize(info.signallers) + "\n" + + "Market Conditions: " + message); + } + } + + // + return result; +} + +// +// +// END Combination Signaling ... +// +// + +// +// START Signal Providers ... +// + +// +// Disbale All Signallers Longs ... +void XEU5DisableLongSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + // + xEU5Provider.DisbaleXTDLongs(); + xEU5MXTDAllowLongSignals = false; + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + // + xEU5Provider.DisbaleXTAMLongs(); + xEU5MXTAMAllowLongSignals = false; + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + // + xEU5Provider.DisbaleXSILongs(); + xEU5MXSIAllowLongSignals = false; + } + + // + // XTSFI ... + if (xEU5MXTSFIEnableSignaller) + { + // + xEU5Provider.DisbaleXTSFILongs(); + xEU5MXTSFIAllowLongSignals = false; + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + // + xEU5Provider.DisbaleXOBDLHLongs(); + xEU5MXOBDLHAllowLongSignals = false; + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + // + xEU5Provider.DisbaleXCHMACCLongs(); + xEU5MXCHMACCAllowLongSignals = false; + } + + // + // XCHMAMX ... + if (xEU5MXCHMAMXEnableSignaller) + { + // + xEU5Provider.DisbaleXCHMAMXLongs(); + xEU5MXCHMAMXAllowLongSignals = false; + } + + // + // XCHMAMN ... + if (xEU5MXCHMAMNEnableSignaller) + { + // + xEU5Provider.DisbaleXCHMAMNLongs(); + xEU5MXCHMAMNAllowLongSignals = false; + } +} + +// +// Enable All Signallers Longs ... +// Only if they are Configured as Enable at Settings ... +void XEU5EnableLongSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + // + xEU5MXTDAllowLongSignals = + xEU5XTDAllowLongSignals + ? true + : xEU5MXTDAllowLongSignals; + + // + if (xEU5MXTDAllowLongSignals) + { + xEU5Provider.EnableXTDLongs(); + } + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + // + xEU5MXTAMAllowLongSignals = + xEU5XTAMAllowLongSignals + ? true + : xEU5MXTAMAllowLongSignals; + + // + if (xEU5MXTAMAllowLongSignals) + { + xEU5Provider.EnableXTAMLongs(); + } + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + // + xEU5MXSIAllowLongSignals = + xEU5XSIAllowLongSignals + ? true + : xEU5MXSIAllowLongSignals; + + // + if (xEU5MXSIAllowLongSignals) + { + xEU5Provider.EnableXSILongs(); + } + } + + // + // XTSFI ... + if (xEU5MXTSFIEnableSignaller) + { + // + xEU5MXTSFIAllowLongSignals = + xEU5XTSFIAllowLongSignals + ? true + : xEU5MXTSFIAllowLongSignals; + + // + if (xEU5MXTSFIAllowLongSignals) + { + xEU5Provider.EnableXTSFILongs(); + } + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + // + xEU5MXOBDLHAllowLongSignals = + xEU5XOBDLHAllowLongSignals + ? true + : xEU5MXOBDLHAllowLongSignals; + + // + if (xEU5MXOBDLHAllowLongSignals) + { + xEU5Provider.EnableXOBDLHLongs(); + } + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + // + xEU5MXCHMACCAllowLongSignals = + xEU5XCHMACCAllowLongSignals + ? true + : xEU5MXCHMACCAllowLongSignals; + + // + if (xEU5MXCHMACCAllowLongSignals) + { + xEU5Provider.EnableXCHMACCLongs(); + } + } + + // + // XCHMAMX ... + if (xEU5MXCHMAMXEnableSignaller) + { + // + xEU5MXCHMAMXAllowLongSignals = + xEU5XCHMAMXAllowLongSignals + ? true + : xEU5MXCHMAMXAllowLongSignals; + + // + if (xEU5MXCHMAMXAllowLongSignals) + { + xEU5Provider.EnableXCHMAMXLongs(); + } + } + + // + // XCHMAMN ... + if (xEU5MXCHMAMNEnableSignaller) + { + // + xEU5MXCHMAMNAllowLongSignals = + xEU5XCHMAMNAllowLongSignals + ? true + : xEU5MXCHMAMNAllowLongSignals; + + // + if (xEU5MXCHMAMNAllowLongSignals) + { + xEU5Provider.EnableXCHMAMNLongs(); + } + } +} + +// +// Disable All Signallers Shorts ... +void XEU5DisableShortSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + // + xEU5Provider.DisableXTDShorts(); + xEU5MXTDAllowShortSignals = false; + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + // + xEU5Provider.DisableXTAMShorts(); + xEU5MXTAMAllowShortSignals = false; + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + // + xEU5Provider.DisableXSIShorts(); + xEU5MXSIAllowShortSignals = false; + } + + // + // XTSFI ... + if (xEU5MXTSFIEnableSignaller) + { + // + xEU5Provider.DisableXTSFIShorts(); + xEU5MXTSFIAllowShortSignals = false; + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + // + xEU5Provider.DisableXOBDLHShorts(); + xEU5MXOBDLHAllowShortSignals = false; + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + // + xEU5Provider.DisableXCHMACCShorts(); + xEU5MXCHMACCAllowShortSignals = false; + } + + // + // XCHMAMX ... + if (xEU5MXCHMAMXEnableSignaller) + { + // + xEU5Provider.DisableXCHMAMXShorts(); + xEU5MXCHMAMXAllowShortSignals = false; + } + + // + // XCHMAMN ... + if (xEU5MXCHMAMNEnableSignaller) + { + // + xEU5Provider.DisableXCHMAMNShorts(); + xEU5MXCHMAMNAllowShortSignals = false; + } +} + +// +// Enable All Signallers Shorts ... +// Only if they are Configured as Enable at Settings ... +void XEU5EnableShortSignallers() +{ + // + // XTD ... + if (xEU5MXTDEnableSignaller) + { + // + xEU5MXTDAllowShortSignals = + xEU5XTDAllowShortSignals + ? true + : xEU5MXTDAllowShortSignals; + + // + if (xEU5MXTDAllowShortSignals) + { + xEU5Provider.EnableXTDShorts(); + } + } + + // + // XTAM ... + if (xEU5MXTAMEnableSignaller) + { + // + xEU5MXTAMAllowShortSignals = + xEU5XTAMAllowShortSignals + ? true + : xEU5MXTAMAllowShortSignals; + + // + if (xEU5MXTAMAllowShortSignals) + { + xEU5Provider.EnableXTAMShorts(); + } + } + + // + // XSI ... + if (xEU5MXSIEnableSignaller) + { + // + xEU5MXSIAllowShortSignals = + xEU5XSIAllowShortSignals + ? true + : xEU5MXSIAllowShortSignals; + + // + if (xEU5MXSIAllowShortSignals) + { + xEU5Provider.EnableXSIShorts(); + } + } + + // + // XTSFI ... + if (xEU5MXTSFIEnableSignaller) + { + // + xEU5MXTSFIAllowShortSignals = + xEU5XTSFIAllowShortSignals + ? true + : xEU5MXTSFIAllowShortSignals; + + // + if (xEU5MXTSFIAllowShortSignals) + { + xEU5Provider.EnableXTSFIShorts(); + } + } + + // + // XOBDLH ... + if (xEU5MXOBDLHEnableSignaller) + { + // + xEU5MXOBDLHAllowShortSignals = + xEU5XOBDLHAllowShortSignals + ? true + : xEU5MXOBDLHAllowShortSignals; + + // + if (xEU5MXOBDLHAllowShortSignals) + { + xEU5Provider.EnableXOBDLHShorts(); + } + } + + // + // XCHMACC ... + if (xEU5MXCHMACCEnableSignaller) + { + // + xEU5MXCHMACCAllowShortSignals = + xEU5XCHMACCAllowShortSignals + ? true + : xEU5MXCHMACCAllowShortSignals; + + // + if (xEU5MXCHMACCAllowShortSignals) + { + xEU5Provider.EnableXCHMACCShorts(); + } + } + + // + // XCHMAMX ... + if (xEU5MXCHMAMXEnableSignaller) + { + // + xEU5MXCHMAMXAllowShortSignals = + xEU5XCHMAMXAllowShortSignals + ? true + : xEU5MXCHMAMXAllowShortSignals; + + // + if (xEU5MXCHMAMXAllowShortSignals) + { + xEU5Provider.EnableXCHMAMXShorts(); + } + } + + // + // XCHMAMN ... + if (xEU5MXCHMAMNEnableSignaller) + { + // + xEU5MXCHMAMNAllowShortSignals = + xEU5XCHMAMNAllowShortSignals + ? true + : xEU5MXCHMAMNAllowShortSignals; + + // + if (xEU5MXCHMAMNAllowShortSignals) + { + xEU5Provider.EnableXCHMAMNShorts(); + } + } +} + +// +// +// + +// +// XTD Long Signal Checking ... +bool XEU5XTDHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTDEnableSignaller || + !xEU5MXTDAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XTDHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTSCurrentMin && + mConditions.isXTDSignalCrossedOverBear && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + ((mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest) && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCLLSame) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHMASCCrossedOverMin && + mConditions.isXTDSignalCrossedOverBear && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + || + // + ( + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXTSCurrentMax) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentUnderNearest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXFICrossedOverZero && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ( + (mConditions.isXCHMAMCVale && + mConditions.isXTDBearishVale) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) + // + || + // + (mConditions.isXLHLLIncreased && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXTSCurrentUnderFarest && + (mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest)) + // + ) + // + ) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMAMCTrendsDown) + // + ) + // + ) + // + || + // + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ( + (mConditions.isXCHMAMCVale && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) && + ( + // + ( + // + mConditions.isXAMANeutural + // + || + // + (mConditions.isXLHLLDecreased && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXAMAStartBullish) + // + ) + // + ) + // + ) + // + || + // + // + ((mConditions.isXTSCurrentMax && + mConditions.isXLHHHDecreased) && + ( + // + (mConditions.isXTDBearishVale && + mConditions.isXCHLHMCLCLLSame && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTDSignalCrossedOverBear && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + ) + // + ) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXTMEndBullish && + mConditions.isXAMANeutural && + mConditions.isXAMAEndBullish && + mConditions.isXTDSignalCrossedOverBear && + (mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXLHHHDecreased && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTDSignalCrossedOverBear && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + ) + // + ) + // + || + // + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMANeutural && + mConditions.isXAMAEndBearish && + mConditions.isXTDBearishVale && + mConditions.isXTMStartBullish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + || + // + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMAMCVale && + // + ( + // + (mConditions.isXTMNeutural && + mConditions.isXTMEndBullish) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXCHMALCVale && + mConditions.isXTMStartBullish && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXTDBearishVale && + mConditions.isXCHLHMCLCHHSame) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXLHHHDecreased) + // + || + // + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) + // + ) + // + ) + // + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMAMCVale && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXLHHHDecreased && + mConditions.isXFICrossedOverZero) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXAMAStartBearish && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXTSCurrentUnderFarest && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXAMAVale && + mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXLHLLIncreased) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXFICrossedOverZero && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXLHPriceCrossedUnderSignal) + // + ) + // + ) + // + || + // + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTSCurrentCrossedOverFarest && + mConditions.isXTSCurrentCrossedOverNearest && + mConditions.isXTSCurrentCrossedOverMediest && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXLHHHIncreased && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderMediest && + mConditions.isXTDSignalCrossedOverBear && + (mConditions.isXCHMASCTrendsUp && + (mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow))) + // + || + // + (mConditions.isXTDSignalCrossedOverBear && + (mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow))) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderNearest) + // + || + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderNearest) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTDBearishVale && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish) + // + || + // + ((mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDSignalCrossedOverBear) && + ( + // + ( + // + mConditions.isXCHMASCCrossedOverMax + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) + // + || + // + ((mConditions.isXTMNeutural && + mConditions.isXAMANeutural) && + ( + // + ( + // + (mConditions.isXTSCurrentUnderFarest || + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXTDSignalCrossedOverBear) + // + ) && + (mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) && + ( + // + mConditions.isXRSICrossedOverLongExit + // + || + // + (mConditions.isXTSAllSame && + mConditions.isXAMAStartBullish && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXAMAStartBullish) + // + || + // + ((mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest)) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXTSCurrentMax || + mConditions.isXTSCurrentUnderFarest) && + mConditions.isXTDBearishVale && + mConditions.isXLHLLDecreased && + mConditions.isXLHPriceCrossedOverSignal && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + ((mConditions.isXCHLHSCMCHHSame && + mConditions.isXTDSignalCrossedOverBear) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXLHHighAttachedHH) + // + || + // + (mConditions.isXCHLHMCLCLLSame && + ( + // + (mConditions.isXCHMASCCrossedOverMin && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXCHMASCCrossedOverMax && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + ) + // + ) + // + || + // + (((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) || + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) && + // + ( + // + ((mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest)) + // + ) + // + ) + // + ) + // + ) + // + || + // + (( + // + (mConditions.isXFICrossedOverZero && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverMediest) + // + ) && + (mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow))) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXCHLHSameHHs && + mConditions.isXTSCurrentMax && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXTDBearishVale && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXAMAStartBullish) + // + ) + // + ) + // + || + // + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXTDBearishVale && + mConditions.isXCHLHMCLCHHSame && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXTMEndBullish && + mConditions.isXTDBearishVale && + mConditions.isXFICrossedOverZero && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXFICrossedOverZero && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + || + // + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXTSCurrentMax && + mConditions.isXTDSignalCrossedOverBear) && + ( + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH) + // + || + // + (mConditions.isXAMAEndBullish && + mConditions.isXCHLHSCMCLLSame && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + ) + // + ) + // + || + // + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTD Short Signal Checking ... +bool XEU5XTDHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTDEnableSignaller || + !xEU5MXTDAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XTDHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTDBullOverBear && + mConditions.isXFICrossedOverZero && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTDBullOverBear && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXFIOverZero && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear) + // + || + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + ((mConditions.isXAMANeutural || + mConditions.isXAMAEndBullish) && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXCHLHSameLLs && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXLHLowAttachedLL) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullOverBear) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTDBullOverBear && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXCHMASCTrendsUp && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + mConditions.isXCHMASCTrendsUp + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverNearest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMALCTrendsDown && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXTDBullOverBear && + (mConditions.isXAMANeutural || + mConditions.isXTSCurrentOverFarest)) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMALCTrendsUp && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMASCTrendsUp) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTDBullOverBear && + ( + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTMEndBullish && + mConditions.isXAMAEndBullish && + mConditions.isXLHHighAttachedHH) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + mConditions.isXCHMAMCTrendsUp + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTAM Long Signal Checking ... +bool XEU5XTAMHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTAMEnableSignaller || + !xEU5MXTAMAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XTAMHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCVale && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) && + ( + // + (mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXLHLLIncreased && + mConditions.isXCHLHMCLCHHSame) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCLLSame) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCVale && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + ) + // + ) + // + || + // + (mConditions.isXCHMASCPeak && + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + ((mConditions.isXCHMAMCVale && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) && + (mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow))) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCVale && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXLHLLDecreased && + mConditions.isXCHLHMCLCLLSame) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMABearish && + mConditions.isXTMEndBearish && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHLHSCMCLLSame && + (mConditions.isXTSCurrentUnderFarest || + mConditions.isXTSCurrentUnderMediest)) + // + || + // + (mConditions.isXCHLHMCLCHHSame && + (mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest)) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXTSAllSame && + mConditions.isXCHMASCVale && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ( + (mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest && + mConditions.isXTDBullCrossedUnderBear) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXLHPriceCrossedOverSignal && + mConditions.isXTSCurrentCrossedOverFarest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMALCVale && + ( + // + mConditions.isXLHHHDecreased + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBearishVale) + // + ) + // + ) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMASCFastCrossedOverSlow) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) && + ( + // + (mConditions.isXCHLHSameHHs && + mConditions.isXTSCurrentMax && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXAMAStartBullish && + mConditions.isXLHHighAttachedHH) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCVale || + mConditions.isXCHLHSameHHs) && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHLHSameHHs && + mConditions.isXLHLLDecreased && + mConditions.isXLHHighAttachedHH) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBearishVale && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHMASCPeak && + (mConditions.isXCHMAMCTrendsDown || + mConditions.isXCHMAMCFastUnderSlow)) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXTMEndBearish && + mConditions.isXAMANeutural && + mConditions.isXAMAEndBearish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXFICrossedOverZero && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish) + // + ) + // + ) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTAM Short Signal Checking ... +bool XEU5XTAMHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTAMEnableSignaller || + !xEU5MXTAMAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XTAMHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXFIOverZero && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentOverFarest) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTMNeutural || + mConditions.isXTMEndBullish) && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHMASCTrendsUp && + mConditions.isXTSCurrentOverNearest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHMASCTrendsUp) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + || + // + (mConditions.isXFIOverZero && + mConditions.isXCHMASCPeak && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ( + // + mConditions.isXCHMAMCTrendsUp + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMALCTrendsUp && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMin && + mConditions.isXCHMALCTrendsUp && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + || + // + ((mConditions.isXAMAVale && + mConditions.isXCHMASCVale && + mConditions.isXTSCurrentMin) && + ( + // + mConditions.isXRSICrossedUnderShortExit + // + || + // + mConditions.isXTDBullishVale + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMin && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXLHLowAttachedLL) && + ( + // + mConditions.isXCHMALCTrendsDown + // + || + // + (mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXLHPriceCrossedUnderSignal) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + mConditions.isXRSICrossedUnderShortExit + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMBearish && + mConditions.isXCHMASCVale && + mConditions.isXAMABearish && + mConditions.isXCHLHSameLLs && + mConditions.isXTSCurrentMin && + mConditions.isXCHMASCTrendsUp && + mConditions.isXLHLowAttachedLL) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + ( + // + mConditions.isXRSICrossedUnderShortExit + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMASCVale && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest) + // + || + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMin && + mConditions.isXLHLowAttachedLL) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHLHSameLLs && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHMASCVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + ( + // + mConditions.isXRSICrossedUnderShortExit + // + || + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTDSignalVale && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullishVale) && + ( + // + (mConditions.isXTSAllSame && + mConditions.isXLHHHDecreased && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXLHLowAttachedLL && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear && + mConditions.isXTSCurrentOverFarest) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear) && + ( + // + (mConditions.isXCHMASCTrendsUp && + mConditions.isXTDSignalOverBear) + // + || + // + (mConditions.isXFIOverZero && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + (mConditions.isXTDBullOverBear || + mConditions.isXTSCurrentOverFarest)) + // + || + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame && + (mConditions.isXTSCurrentOverFarest || + mConditions.isXTSCurrentOverMediest)) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXLHLLDecreased && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMin && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMASCTrendsUp) + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish) + // + || + // + (mConditions.isXFIOverZero && + mConditions.isXCHMALCVale && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXTSCurrentMin && + mConditions.isXTDSignalUnderBear && + mConditions.isXFICrossedUnderZero && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest && + mConditions.isXTDBullCrossedUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XSI Long Signal Checking ... +bool XEU5XSIHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXSIEnableSignaller || + !xEU5MXSIAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XSIHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentUnderNearest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTSAllSame && + mConditions.isXCHLHSameLLs && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish) + // + || + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale && + mConditions.isXAMANeutural && + mConditions.isXLHHHDecreased && + mConditions.isXTMStartBullish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentUnderFarest) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXTMStartBullish) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTSCurrentMin && + mConditions.isXTSCurrentMax) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBearish)) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMANeutural && + mConditions.isXAMAEndBullish && + mConditions.isXLHLLDecreased && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXAMAEndBearish && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest) + // + || + // + ((mConditions.isXTMVale && + mConditions.isXAMAVale) + // + && + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale) + // + && + // + (mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame)) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + || + // + (mConditions.isXTMVale && + mConditions.isXTMNeutural && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXAMAStartBullish && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale) + // + || + // + (mConditions.isXLHHHDecreased && + mConditions.isXLHLLDecreased) + // + || + // + ((mConditions.isXTMVale || + mConditions.isXTMNeutural || + mConditions.isXTMEndBearish) && + mConditions.isXAMANeutural) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHLHSCMCLLSame) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale) + // + || + // + (mConditions.isXCHMASCVale && + mConditions.isXCHLHSCMCLLSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XSI Short Signal Checking ... +bool XEU5XSIHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXSIEnableSignaller || + !xEU5MXSIAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XSIHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXLHHHIncreased && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTDSignalOverBear) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTMBullish && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBullish)) && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + || + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMASCTrendsUp && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + || + // + ((mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) && + ( + // + (mConditions.isXFIOverZero && + mConditions.isXCHMAMCPeak && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMin && + mConditions.isXTMStartBearish && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest && + mConditions.isXTSCurrentCrossedUnderFarest && + mConditions.isXTSCurrentCrossedUnderNearest && + mConditions.isXTSCurrentCrossedUnderMediest) + // + )) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) + // + || + // + (mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentOverNearest) + // + || + // + (((mConditions.isXTMBullish || + mConditions.isXTMStartBullish) && + (mConditions.isXAMABullish || + mConditions.isXAMAStartBullish)) && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale && + mConditions.isXLHHHIncreased && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXFIOverZero && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMALCPeak && + mConditions.isXCHLHSCMCHHSame) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXTMEndBullish && + mConditions.isXTSCurrentMin && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXAMAStartBearish) + // + || + // + ((mConditions.isXCHMASCPeak && + mConditions.isXTSCurrentOverFarest) && + ( + // + mConditions.isXTMNeutural + // + || + // + mConditions.isXTSCurrentOverMediest + // + || + // + (mConditions.isXTMBullish && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXLHHHIncreased) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMin && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish) + // + || + // + ((mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale) && + ( + // + (mConditions.isXLHHHIncreased && + mConditions.isXLHLLIncreased) + // + || + // + (mConditions.isXCHLHSCMCHHSame && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXTSCurrentMin) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHLHSameHHs && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTDBullOverBear && + (mConditions.isXTDSignalOverBear || + mConditions.isXTDSignalCrossedOverBear)) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + (mConditions.isXFIOverZero || + mConditions.isXTSCurrentOverFarest)) + // + || + // + (mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXTSCurrentMax && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMASCTrendsUp) + // + ) + // + ) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMASCTrendsUp) + // + || + // + ((mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale) && + ( + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXCHLHSCMCHHSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTSFI Long Signal Checking ... +bool XEU5XTSFIHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTSFIEnableSignaller || + !xEU5MXTSFIAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XTSFIHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXAMAEndBearish && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHLHMCLCHHSame) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + ((mConditions.isXTMNeutural && + mConditions.isXTSCurrentUnderMediest) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXTDSignalUnderBear && + mConditions.isXFICrossedUnderZero) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBullish) && + mConditions.isXCHLHSameHHs && + mConditions.isXLHLLIncreased && + mConditions.isXLHHighAttachedHH) + // + ) + // + ) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBearishVale && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXTDSignalUnderBear && + mConditions.isXFICrossedUnderZero && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMASCPeak && + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABearish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMAMCTrendsDown && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMASCOverMax && + mConditions.isXCHMASCOverMin && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + ( + // + mConditions.isXCHMALCVale + // + || + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + || + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXAMAStartBullish) + // + || + // + (mConditions.isXLHLLDecreased && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXTMNeutural || + mConditions.isXTMStartBullish) && + mConditions.isXLHHHDecreased && + (mConditions.isXAMANeutural || + mConditions.isXAMAStartBearish) && + mConditions.isXTSCurrentUnderMediest) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + ( + // + mConditions.isXCHMALCVale + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMASCPeak && + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCPeak && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBullish)) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXCHLHSameHHs && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXCHMALCVale && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBullish) && + mConditions.isXTMStartBearish) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + ((mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentUnderMediest) && + ( + // + mConditions.isXCHMALCVale + // + || + // + (mConditions.isXCHMALCTrendsDown && + mConditions.isXTSCurrentCrossedUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMASCPeak && + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXCHMALCVale && + mConditions.isXAMAStartBullish && + mConditions.isXFICrossedOverZero && + mConditions.isXTDBullCrossedOverBear && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMAMCPeak && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTDBearishVale && + mConditions.isXCHLHSCMCHHSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTSFI Short Signal Checking ... +bool XEU5XTSFIHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXTSFIEnableSignaller || + !xEU5MXTSFIAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XTSFIHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMALCVale && + mConditions.isXCHLHMCLCLLSame) && + ( + // + mConditions.isXCHMASCTrendsDown + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXTMEndBearish && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + || + // + (((mConditions.isXTMVale || + mConditions.isXTMNeutural) && + mConditions.isXAMANeutural) && + (mConditions.isXFIOverZero || + mConditions.isXFICrossedOverZero) && + mConditions.isXTSCurrentOverMediest) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentCrossedUnderNearest) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXTDBearishVale && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTMStartBullish) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXCHMALCPeak && + (mConditions.isXTMNeutural || + mConditions.isXTMEndBullish) && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBullish) && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXCHMALCPeak && + mConditions.isXTDBullOverBear && + (mConditions.isXFIOverZero || + mConditions.isXFICrossedOverZero)) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXAMANeutural && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverMediest) && + ( + // + mConditions.isXTMNeutural + // + || + // + (mConditions.isXTMBullish && + mConditions.isXLHLLDecreased) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXFIOverZero && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXLHHHDecreased && + (mConditions.isXTMBullish || + mConditions.isXTMStartBullish) && + mConditions.isXAMABullish && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTDBullCrossedOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXLHHHDecreased && + mConditions.isXFICrossedOverZero && + mConditions.isXTDBullCrossedOverBear) + // + || + // + (mConditions.isXFIOverZero && + mConditions.isXCHMALCPeak && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXFIOverZero && + mConditions.isXCHMALCPeak && + mConditions.isXLHHHDecreased && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTDBullCrossedUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXTMStartBearish && + mConditions.isXTDBullUnderBear && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalUnderBear) + // + || + // + ((mConditions.isXTMBullish || + mConditions.isXTMStartBullish) && + (mConditions.isXAMABullish || + mConditions.isXAMAStartBullish) && + (mConditions.isXFIOverZero || + mConditions.isXFICrossedOverZero) && + mConditions.isXCHLHSameLLs) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMASCTrendsUp) + // + || + // + (mConditions.isXCHLHSameLLs && + mConditions.isXTDBearishVale && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXCHMALCPeak && + mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTSCurrentCrossedUnderFarest) + // + || + // + ((mConditions.isXCHMAMCVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXTMEndBearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest) && + ( + // + mConditions.isXTSCurrentUnderNearest + // + || + // + (mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMASCTrendsUp) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXLHHHDecreased && + mConditions.isXLHLLDecreased && + mConditions.isXTSCurrentOverMediest) + // + || + // + ((mConditions.isXFIOverZero && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish) + // + || + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) && + ( + // + (mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMALCVale && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + mConditions.isXOBDSwingLow + // + || + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHLHSameLLs && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXTDBullCrossedUnderBear && + mConditions.isXTSCurrentCrossedOverMediest) + // + || + // + ((mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) && + ( + // + mConditions.isXCHMALCPeak + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentCrossedOverMediest) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMNeutural && + mConditions.isXFIOverZero && + mConditions.isXTSCurrentCrossedOverMediest) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMBearish && + mConditions.isXCHMAMCVale && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXFIOverZero && + mConditions.isXLHHHIncreased && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXFICrossedOverZero) + // + || + // + (mConditions.isXAMABearish && + mConditions.isXCHMAMCVale && + mConditions.isXCHLHMCLCLLSame && + (mConditions.isXTMNeutural || + mConditions.isXTMEndBearish)) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXTMStartBearish && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderFarest) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMNeutural && + mConditions.isXCHMAMCVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXFICrossedUnderZero && + mConditions.isXTSCurrentCrossedUnderNearest) + // + || + // + ((mConditions.isXAMAVale && + mConditions.isXTMNeutural && + mConditions.isXCHMALCPeak && + mConditions.isXCHMAMCVale) && + ( + // + mConditions.isXLHPriceCrossedUnderSignal + // + || + // + (mConditions.isXCHLHSCMCLLSame && + mConditions.isXFICrossedUnderZero && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + (((mConditions.isXTMBullish || + mConditions.isXTMNeutural || + mConditions.isXTMStartBullish) && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + (mConditions.isXTMStartBullish || + mConditions.isXTMEndBullish)) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXAMAStartBearish) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXFIOverZero && + mConditions.isXTMEndBearish && + mConditions.isXFICrossedOverZero) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCVale && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXLHHHDecreased && + mConditions.isXCHLHSCMCLLSame) + // + || + // + ((mConditions.isXTMNeutural && + mConditions.isXAMAStartBearish) && + ( + // + (mConditions.isXCHLHSameLLs && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXLHHHDecreased) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) + // + || + // + (mConditions.isXTSCurrentOverMediest && + ( + // + ((mConditions.isXCHMALCVale && + mConditions.isXCHLHSCMCLLSame) && + ( + // + (mConditions.isXAMAVale && + mConditions.isXCHMASCUnderMax && + mConditions.isXCHMASCUnderMin) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXCHMASCTrendsUp && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + ((mConditions.isXCHMAMCVale && + mConditions.isXTSCurrentOverMediest) && + ( + // + mConditions.isXLHHHDecreased + // + || + // + mConditions.isXTSCurrentCrossedOverMediest + // + || + // + (mConditions.isXTMVale && + mConditions.isXTMNeutural && + mConditions.isXAMAVale && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMALCTrendsDown) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXFIOverZero && + mConditions.isXTMEndBearish && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXCHMALCPeak && + ( + // + mConditions.isXCHLHMCLCLLSame + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentCrossedOverMediest) + // + || + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDSignalUnderBear) && + ( + // + mConditions.isXTDBullCrossedUnderBear + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ( + // + ((mConditions.isXCHMALCVale && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXFIOverZero && + mConditions.isXCHMASCTrendsUp) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXLHHHIncreased && + mConditions.isXTMStartBearish && + mConditions.isXCHLHSCMCHHSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMASCVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + mConditions.isXCHLHSameLLs + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMNeutural && + mConditions.isXFIOverZero && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXLHHHDecreased) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXLHHHDecreased && + mConditions.isXTSCurrentCrossedUnderNearest) + // + || + // + (mConditions.isXCHLHSCMCLLSame && + ( + // + (mConditions.isXCHLHMCLCHHSame && + ( + // + (mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXTMStartBearish) + // + || + // + ((mConditions.isXTMNeutural || + mConditions.isXTMEndBearish) && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBearish)) + // + || + // + (mConditions.isXTMVale && + mConditions.isXCHMAMCVale && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest) + // + ) + // + ) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish) + // + || + // + (mConditions.isXFIOverZero && + mConditions.isXCHMAMCVale && + mConditions.isXTMEndBearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXCHMALCPeak && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMABearish && + mConditions.isXFIOverZero && + mConditions.isXCHMAMCVale && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABearish && + mConditions.isXCHMAMCVale && + mConditions.isXLHHHDecreased && + mConditions.isXFICrossedUnderZero && + mConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + ) + // + || + // + ((mConditions.isXAMAVale && + mConditions.isXCHMALCPeak) && + ( + // + mConditions.isXTMNeutural + // + || + // + (mConditions.isXTMVale && + mConditions.isXTMEndBearish && + mConditions.isXLHLLDecreased) + // + ) + // + ) + // + || + // + (mConditions.isXTMVale && + mConditions.isXTMNeutural && + mConditions.isXAMABearish && + mConditions.isXCHMAMCVale && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHMASCUnderMax && + mConditions.isXCHMASCUnderMin && + mConditions.isXTSCurrentOverMediest) && + ( + // + mConditions.isXCHMAMCTrendsDown + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMASCTrendsUp && + mConditions.isXTMStartBearish && + mConditions.isXTDBullOverBear && + mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + ((mConditions.isXCHMAMCVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXAMAVale && + mConditions.isXTMBullish) + // + || + // + (mConditions.isXAMAVale && + (mConditions.isXTMNeutural || + mConditions.isXTMEndBearish)) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXTMNeutural && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXCHLHMCLCLLSame && + mConditions.isXLHPriceCrossedOverSignal) + // + || + // + (mConditions.isXTDBullUnderBear && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentOverMediest) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXFIOverZero && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXAMABullish && + mConditions.isXTDBullCrossedOverBear) + // + ) + // + ) + // + || + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXLHLLIncreased && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMASCTrendsUp) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHMAMCTrendsUp && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXFIOverZero && + mConditions.isXCHMALCPeak) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXLHHHDecreased) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) && + ( + // + ((mConditions.isXTMBullish || + mConditions.isXTMStartBullish) + // + && + // + (mConditions.isXAMABullish || + mConditions.isXAMAStartBullish)) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTDBullCrossedUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXLHPriceCrossedOverSignal) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXLHLLIncreased && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXLHHHIncreased && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMASCTrendsUp) + // + || + // + (mConditions.isXTSCurrentOverMediest && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTMStartBearish && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXCHMALCVale && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMASCTrendsUp) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCTrendsUp && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentOverMediest) + // + || + // + ((mConditions.isXTMBullish || + mConditions.isXTMStartBullish) && + (mConditions.isXAMABullish || + mConditions.isXAMAStartBullish) && + (mConditions.isXTSCurrentOverMediest || + mConditions.isXTSCurrentCrossedOverMediest)) + // + )) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + ((mConditions.isXTSCurrentOverMediest || + mConditions.isXTSCurrentCrossedOverMediest) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMAMCVale && + mConditions.isXLHHHDecreased && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMNeutural && + mConditions.isXFIOverZero && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXTDBullCrossedUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTMStartBearish) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHLHSameLLs) + // + ) + // + ) + // + || + // + (mConditions.isXCHMASCTrendsUp && + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XOBDLH Long Signal Checking ... +bool XEU5XOBDLHHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXOBDLHEnableSignaller || + !xEU5MXOBDLHAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + XMarketConditions xMConditions2 = xEU5Provider.GenerateMarketConditions(2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XOBDLHHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMALCVale && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHLHSCMCLLSame) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXLHLLDecreased && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTSCurrentUnderFarest) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTMEndBearish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + || + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMALCPeak && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXTMVale && + mConditions.isXLHLLDecreased && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXAMAStartBearish) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHLHMCLCHHSame) + // + || + // + ((mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHLHSameLLs) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXLHHHDecreased) + // + ) + // + ) + // + || + // + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) + // + || + // + ((mConditions.isXCHMASCVale && + mConditions.isXCHMALCPeak && + mConditions.isXCHLHSCMCLLSame) && + ( + // + mConditions.isXTSCurrentMax + // + || + // + mConditions.isXLHLowAttachedLL + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentUnderFarest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHMALCPeak && + mConditions.isXTMEndBearish && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTMNeutural && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXTDBearishVale && + mConditions.isXCHLHSCMCLLSame) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXTMStartBearish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXAMAStartBearish) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXTSAllSame && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXTMStartBearish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXLHLowAttachedLL) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXCHLHSameLLs) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXAMANeutural && + mConditions.isXTMStartBullish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XOBDLH Short Signal Checking ... +bool XEU5XOBDLHHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXOBDLHEnableSignaller || + !xEU5MXOBDLHAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XOBDLHHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + ((mConditions.isXTMNeutural && + mConditions.isXAMANeutural) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMASCCrossedUnderMax) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXCHMALCPeak && + mConditions.isXCHMALCTrendsUp) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXFIOverZero && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTDBullOverBear) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXTDSignalOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXTMEndBullish && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXTMEndBullish) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMin && + mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + || + // + (mConditions.isXFIOverZero && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + (((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + ( + // + ((mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) && + ( + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + ( + // + (mConditions.isXCHLHSameHHs && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) && + ( + // + (mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + || + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + (((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullCrossedOverBear) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXCHMASCTrendsUp && + mConditions.isXCHMAMCTrendsUp) + // + || + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak) + // + ) + // + ) + // + ) + // + ) + // + || + // + (((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak && + mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + || + // + ((mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) && + ( + // + (mConditions.isXCHMAMCTrendsUp && + mConditions.isXCHMALCTrendsUp) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMASCTrendsUp && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMStartBullish && + mConditions.isXTDBullOverBear && + mConditions.isXAMAStartBullish && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + || + // + (((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMASCTrendsUp && + mConditions.isXCHMAMCTrendsUp) + // + ) + // + ) + // + || + // + (((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak && + mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXCHLHSameHHs && + mConditions.isXTSCurrentMax && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMACC Long Signal Checking ... +bool XEU5XCHMACCHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACCEnableSignaller || + !xEU5MXCHMACCAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XCHMACCHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCTrendsDown && + ( + // + (mConditions.isXCHMALCPeak && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame && + (mConditions.isXTSCurrentOverFarest || + mConditions.isXTDSignalCrossedUnderBear)) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMANeutural && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXTMStartBullish && + mConditions.isXFICrossedUnderZero) + // + || + // + ( + (mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXAMAStartBullish) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXLHLLDecreased) + // + ) + // + ) + // + ) + // + ) + // + )) + // + || + // + (((mConditions.isXTMNeutural && + mConditions.isXTMEndBullish && + mConditions.isXFICrossedUnderZero) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear)) + // + && + // + (mConditions.isXCHMALCPeak && + ( + // + mConditions.isXCHMALCTrendsDown + // + || + // + (mConditions.isXCHLHMCLCHHSame && + (mConditions.isXTDSignalUnderBear || + mConditions.isXTDSignalCrossedUnderBear)) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCTrendsDown && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCTrendsDown && + ( + // + (mConditions.isXCHMALCPeak && + ( + // + (mConditions.isXTDSignalUnderBear && + ( + // + (mConditions.isXAMAVale && + mConditions.isXAMABearish) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMAStartBearish && + mConditions.isXFICrossedUnderZero) + // + || + // + ((mConditions.isXAMANeutural || + mConditions.isXAMAEndBearish) && + mConditions.isXTMStartBullish && + mConditions.isXFICrossedOverZero) + // + || + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDBullUnderBear) + // + ) + // + ) + // + || + // + ((mConditions.isXAMABearish && + (mConditions.isXTMNeutural || + mConditions.isXTMBearish)) && + mConditions.isXTSCurrentUnderMediest && + (mConditions.isXTDBullCrossedUnderBear || + (mConditions.isXTDBullUnderBear && + mConditions.isXFICrossedUnderZero))) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentOverFarest && + mConditions.isXLHPriceCrossedUnderSignal) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCTrendsDown && + ( + // + (mConditions.isXCHMALCPeak && + ( + // + (mConditions.isXTSCurrentMax && + ( + // + (mConditions.isXAMABearish && + mConditions.isXTDBullCrossedOverBear) + // + || + // + (mConditions.isXTMStartBullish && + ( + // + ( + // + mConditions.isXAMAStartBullish + // + || + // + (mConditions.isXAMAEndBearish && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + (mConditions.isXLHLLDecreased && + mConditions.isXTMStartBullish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMEndBullish && + mConditions.isXAMAEndBullish) + // + || + // + (mConditions.isXTSCurrentMax && + (mConditions.isXTMBullish || + mConditions.isXTMStartBullish) && + (mConditions.isXAMABullish || + mConditions.isXAMAStartBullish) && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalUnderBear) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + ( + // + mConditions.isXTDBearishVale + // + || + // + mConditions.isXRSICrossedOverLongExit + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXTDSignalUnderBear && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + ) + // + ) + // + || + // + (mConditions.isXCHMASCTrendsDown && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame) + // + || + // + (mConditions.isXCHMASCVale && + mConditions.isXFIUnderZero && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXLHPriceCrossedOverSignal) + // + ) + // + ) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame && + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsDown)) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCPeak && + ( + // + ( + // + mConditions.isXCHMALCTrendsDown + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + ( + // + ( + mConditions.isXTDSignalUnderBear && + ( + // + mConditions.isXTSAllSame + // + || + // + ((mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest)) + // + ) + // + ) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHMALCTrendsUp && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXLHPriceCrossedOverSignal && + (mConditions.isXCHMAMCTrendsDown && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow))) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear && + mConditions.isXCHMAMCTrendsDown) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMALCPeak && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + (mConditions.isXCHMALCTrendsDown && + ( + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH) + // + ) + // + ) + // + ) + // + ) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHLHSameHHs && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderNearest) + // + || + // + ( + (mConditions.isXAMABullish && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXTMEndBullish && + mConditions.isXTDSignalUnderBear) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXTSCurrentMax) && + ( + // + (mConditions.isXTDBullOverBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXTDBullCrossedOverBear && + mConditions.isXLHPriceCrossedOverSignal) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + ( + (mConditions.isXCHMAMCTrendsDown && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish) + // + || + (mConditions.isXLHLLDecreased && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXCHMAMCPeak && + ( + // + (mConditions.isXTDBearishVale && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + )) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHLHSameHHs && + (mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest)) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCTrendsDown && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXTMNeutural && + mConditions.isXTMEndBullish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCTrendsDown && + ( + // + (((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax) && + ( + // + mConditions.isXCHLHMCLCHHSame + // + || + // + (mConditions.isXTDSignalUnderBear && + mConditions.isXCHMALCPeak) + // + || + // + (mConditions.isXTDSignalUnderBear && + mConditions.isXFICrossedOverZero) + // + ) + // + ) + // + ) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHMAMCPeak && + mConditions.isXTMEndBullish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTSCurrentUnderNearest) + // + ) + // + ) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMALCPeak && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCTrendsDown && + ( + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHLHSCMCHHSame) && + ( + // + mConditions.isXTSCurrentUnderNearest + // + || + // + (mConditions.isXLHLLIncreased && + mConditions.isXTDBullUnderBear && + mConditions.isXLHHighAttachedHH && + mConditions.isXTDSignalUnderBear && + mConditions.isXFICrossedUnderZero) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCTrendsDown && + ( + // + (mConditions.isXCHMALCPeak && + ( + // + (mConditions.isXCHLHSameHHs && + mConditions.isXTSCurrentMax && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + (mConditions.isXTSCurrentMin || + mConditions.isXTSCurrentMax)) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXCHLHSameHHs && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXLHLLIncreased && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTDBullUnderBear && + mConditions.isXLHHighAttachedHH && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMACC Short Signal Checking ... +bool XEU5XCHMACCHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMACCEnableSignaller || + !xEU5MXCHMACCAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XCHMACCHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTDBullOverBear && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTMStartBullish && + mConditions.isXTDSignalOverBear && + mConditions.isXTSCurrentOverFarest) + // + || + // + ((mConditions.isXFIOverZero && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXAMAStartBearish && + mConditions.isXFICrossedOverZero) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXAMAStartBullish) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) && + ( + // + // + ((mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXLHLLIncreased && + mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentOverNearest) + // + || + // + (((mConditions.isXTMNeutural || + mConditions.isXTMEndBearish) && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBullish)) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXTSAllSame && + mConditions.isXCHMAMCTrendsDown) + // + ) + // + ) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMin && + mConditions.isXCHMALCTrendsUp && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMALCVale && + ( + // + ((mConditions.isXTMEndBearish || + mConditions.isXTMNeutural) && + (mConditions.isXAMABearish || + mConditions.isXAMANeutural) && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear && + mConditions.isXFICrossedOverZero && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTMStartBearish && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXCHMALCVale && + ( + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTMStartBearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentOverMediest) + // + || + // + ((mConditions.isXTMNeutural || + mConditions.isXTMEndBearish) && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBearish) && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest) + // + || + // + ((mConditions.isXTMNeutural && + mConditions.isXAMABearish && + mConditions.isXTMEndBearish && + mConditions.isXTDBullOverBear) && + ( + // + mConditions.isXCHLHSCMCLLSame + // + || + // + (mConditions.isXFIOverZero && + mConditions.isXFICrossedOverZero && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentCrossedOverFarest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullOverBear && + mConditions.isXAMAStartBearish && + mConditions.isXTDSignalUnderBear) + // + || + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXTSCurrentMin && + mConditions.isXCHMASCUnderMin) + // + ) + // + ) + // + || + // + ((mConditions.isXTMStartBearish && + mConditions.isXTDBullOverBear && + mConditions.isXAMAStartBearish) && + ( + // + (mConditions.isXTSCurrentMin && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXTSCurrentOverFarest && + mConditions.isXLHPriceCrossedUnderSignal) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) && + ( + // + mConditions.isXCHMALCTrendsDown + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXFIOverZero && + mConditions.isXFICrossedOverZero) + // + || + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMin) && + ( + // + (mConditions.isXFICrossedUnderZero && + mConditions.isXTDBullCrossedUnderBear) + // + || + // + (mConditions.isXCHMALCTrendsUp && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXFICrossedUnderZero && + mConditions.isXLHPriceCrossedUnderSignal) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCTrendsDown && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentOverNearest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMASCTrendsDown && + mConditions.isXTSCurrentOverNearest) + // + || + // + (mConditions.isXCHMALCVale && + (mConditions.isXTSCurrentOverNearest || + mConditions.isXTSCurrentCrossedOverNearest) && + (mConditions.isXTSCurrentOverFarest || + mConditions.isXTSCurrentCrossedOverFarest)) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMin) && + ( + // + ((mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMALCTrendsUp) + // + || + // + ((mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) && + ( + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXCHMASCVale) + // + || + // + ((mConditions.isXCHLHSameLLs && + mConditions.isXLHHHIncreased && + mConditions.isXLHLowAttachedLL) && + ( + // + mConditions.isXCHMAMCTrendsDown + // + || + // + mConditions.isXCHMASCCrossedUnderMin + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCVale && + mConditions.isXTDBullCrossedUnderBear) && + ( + // + (mConditions.isXCHLHSCMCLLSame && + mConditions.isXLHLowAttachedLL) + // + || + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMALCTrendsDown && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMAMCVale && + mConditions.isXTSCurrentMin && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + ((mConditions.isXAMABearish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) && + ( + // + (mConditions.isXTMEndBearish && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXTSCurrentMin && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXTMBearish && + mConditions.isXAMABearish) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverNearest) + // + || + // + (mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMALCVale && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) && + ( + // + ((mConditions.isXTMNeutural && + mConditions.isXAMANeutural) && + ( + // + (mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentOverMediest) + // + || + // + (mConditions.isXFIUnderZero && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullUnderBear && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest && + mConditions.isXTSCurrentCrossedUnderFarest && + mConditions.isXTSCurrentCrossedUnderNearest && + mConditions.isXTSCurrentCrossedUnderMediest) + // + ) + // + ) + // + || + // + (mConditions.isXTSCurrentOverFarest && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXTMEndBearish && + mConditions.isXAMAEndBearish && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMANeutural && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXFIOverZero && + mConditions.isXTMStartBullish && + mConditions.isXTDBullOverBear && + mConditions.isXAMAStartBullish && + mConditions.isXTSCurrentOverNearest) + // + ) + // + ) + // + || + // + ((mConditions.isXTDSignalVale && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullishVale && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMANeutural) + // + ) + // + ) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMANeutural && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMin && + mConditions.isXCHMASCOverMin && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXCHMASCUnderMax && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest) + // + || + // + ((mConditions.isXTMNeutural || + mConditions.isXTMEndBearish) && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBearish) && + mConditions.isXFIOverZero && + mConditions.isXTDBullOverBear && + mConditions.isXFICrossedOverZero && + mConditions.isXTSCurrentOverNearest) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXFIOverZero && + mConditions.isXTSCurrentMax && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMin) && + ( + // + (mConditions.isXTMVale && + mConditions.isXAMAVale) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXLHLLIncreased && + mConditions.isXCHMALCTrendsUp && + mConditions.isXAMAStartBearish) + // + || + // + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTDSignalVale && + mConditions.isXTDBullishVale && + mConditions.isXLHLLIncreased && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXTSCurrentMin && + mConditions.isXAMAEndBullish && + mConditions.isXTMStartBearish && + mConditions.isXTDBullOverBear && + mConditions.isXCHMAMCTrendsDown) + // + || + // + (mConditions.isXAMAVale && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullUnderBear && + mConditions.isXCHMALCTrendsDown && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMN Long Signal Checking ... +bool XEU5XCHMAMNHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMAMNEnableSignaller || + !xEU5MXCHMAMNAllowLongSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XCHMAMNHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown) && + ( + // + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMAMCVale && + mConditions.isXCHLHMCLCLLSame) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXLHHHDecreased && + mConditions.isXLHLLDecreased && + mConditions.isXTMStartBullish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXLHHHDecreased && + mConditions.isXLHLLDecreased && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + (((mConditions.isXTMVale || + mConditions.isXTMNeutural) && + mConditions.isXTMEndBearish) && + (mConditions.isXAMANeutural || + mConditions.isXAMAEndBearish) && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXLHLLDecreased && + mConditions.isXCHLHMCLCHHSame) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + || + // + // LC Vale ... + (mConditions.isXCHMALCVale && + ( + // + (mConditions.isXCHMAMCVale && + ( + // + (mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + mConditions.isXCHMASCTrendsDown + // + || + // + (mConditions.isXTMVale && + mConditions.isXAMAVale && + mConditions.isXLHLLIncreased && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + || + // + ((mConditions.isXCHMAMCVale && + mConditions.isXCHMAMCTrendsUp && + (mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow)) && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown) && + ( + // + ((mConditions.isXCHMASCPeak && + mConditions.isXCHMALCVale) && + ( + // + mConditions.isXCHMAMCVale + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXLHHHDecreased && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXCHLHMCLCLLSame) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDSignalUnderBear && + mConditions.isXTSCurrentUnderNearest) + // + || + // + (mConditions.isXCHMALCVale && + ( + // + mConditions.isXCHMASCTrendsDown + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale) + // + || + // + (mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXTMStartBullish && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCTrendsDown && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + (mConditions.isXCHLHMCLCHHSame || + mConditions.isXCHLHMCLCLLSame) && + mConditions.isXTSCurrentUnderNearest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown) && + ( + // + mConditions.isXCHMALCVale + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + ((mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + || + // + (mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTDBullUnderBear) + // + ) + // + ) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTDSignalUnderBear) + // + || + // + mConditions.isXCHMASCTrendsDown + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + // LC Vale ... + (mConditions.isXCHMALCVale && + ( + // + (mConditions.isXCHMAMCVale && + ( + // + (mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTDBullUnderBear && + mConditions.isXLHHighAttachedHH && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMN Short Signal Checking ... +bool XEU5XCHMAMNHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMAMNEnableSignaller || + !xEU5MXCHMAMNAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XCHMAMNHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSAllSame && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXTMBearish || + mConditions.isXTMNeutural) && + mConditions.isXAMANeutural && + mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXLHLLIncreased && + mConditions.isXTSCurrentOverNearest) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest) && + ( + // + (mConditions.isXFIOverZero && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXAMAEndBullish && + mConditions.isXTMStartBearish) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMax && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMALCVale && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXFICrossedUnderZero && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + mConditions.isXRSICrossedUnderShortExit + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXTSCurrentOverFarest && + (mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow)) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMAStartBearish) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMASCVale && + mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow))) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXTMEndBearish && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMX Long Signal Checking ... +bool XEU5XCHMAMXHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMAMXEnableSignaller || + !xEU5MXCHMAMXAllowLongSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XCHMAMXHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCPeak && + ( + // + (mConditions.isXCHMALCTrendsDown && + ( + // + ( + // + mConditions.isXCHMASCPeak + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHLHSameHHs && + mConditions.isXLHHighAttachedHH && + mConditions.isXTDSignalUnderBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (((mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow) && + (mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow)) && + ( + // + (mConditions.isXLHHHDecreased && + mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear && + mConditions.isXLHPriceCrossedOverSignal) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + || + // + (((mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMALCTrendsDown) || + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown) || + (mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown)) && + ( + // + (mConditions.isXCHMAMCPeak + // + || + // + mConditions.isXRSICrossedOverLongExit) + // + || + // + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHLHSCMCHHSame) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMASCTrendsDown && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMX Short Signal Checking ... +bool XEU5XCHMAMXHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xEU5MXCHMAMXEnableSignaller || + !xEU5MXCHMAMXAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xEU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xEU5Provider.XCHMAMXHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMNeutural && + mConditions.isXCHMASCVale && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMin) + // + || + // + (((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + (mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMASCVale && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) + // + || + // + (mConditions.isXTSCurrentMin && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXAMAStartBearish) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHLHSameHHs && + mConditions.isXTSCurrentMin && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXLHLowAttachedLL) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + ((mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak) && + ( + // + (mConditions.isXTMVale && + mConditions.isXAMAVale) + // + || + // + (mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMALCPeak && + mConditions.isXTSCurrentMin && + mConditions.isXCHMAMCTrendsDown) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTMBearish && + mConditions.isXCHMAMCPeak && + mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXTSCurrentMin && + mConditions.isXLHHHDecreased && + mConditions.isXTMStartBearish && + mConditions.isXCHMALCTrendsUp && + mConditions.isXAMAStartBearish) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + mConditions.isXCHMALCPeak + // + || + // + (mConditions.isXTSAllSame && + mConditions.isXAMAEndBullish && + mConditions.isXTMStartBearish && + mConditions.isXTDBullOverBear && + mConditions.isXLHLowAttachedLL) + // + ) + // + ) + // + || + // + (((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow)) && + ( + // + ( + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXLHLowAttachedLL) && + ( + // + (mConditions.isXTSCurrentMin && + mConditions.isXCHLHMCLCHHSame) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHLHSameHHs && + mConditions.isXCHLHSameLLs && + mConditions.isXTSCurrentMin && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXLHLowAttachedLL) + // + ) + // + ) + // + || + // + (mConditions.isXTSCurrentMin && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXLHLowAttachedLL && + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + (mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow))) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMAMCPeak && + mConditions.isXTSCurrentMin && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMASCVale && + mConditions.isXTSCurrentMin && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + ((mConditions.isXTMBearish && + mConditions.isXCHMAMCPeak && + mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame) && + ( + // + mConditions.isXTSCurrentOverFarest + // + || + // + (mConditions.isXTSCurrentMin && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCPeak && + mConditions.isXAMANeutural && + mConditions.isXTMStartBearish) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + ((mConditions.isXCHMASCTrendsUp && + (mConditions.isXCHMASCFastUnderSlow || + mConditions.isXCHMASCFastCrossedUnderSlow)) && + ( + // + (mConditions.isXFIUnderZero && + (mConditions.isXTMBearish || + mConditions.isXTMStartBearish) && + (mConditions.isXAMABearish || + mConditions.isXAMAStartBearish) && + (mConditions.isXTDBullUnderBear && + mConditions.isXTDSignalUnderBear)) + // + ) + // + ) + // + ) + // + ) + // + || + // + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + || + // + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + false + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// END Signal Providers ... +// diff --git a/XEU5/Providers/x-saherelm.xeu5.provider.inputs.lib.mq5 b/XEU5/Providers/x-saherelm.xeu5.provider.inputs.lib.mq5 new file mode 100644 index 0000000..03e0a50 --- /dev/null +++ b/XEU5/Providers/x-saherelm.xeu5.provider.inputs.lib.mq5 @@ -0,0 +1,280 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XEU5 Signal Provider Library Inputs +// ----------------------------------------------------------- +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Include Logger ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Classes ... +#include "../Classes/x-saherelm.class.lib.mq5" + +// +input group "XEU5 Provider"; + +// +// Commonly Used Configurations ... +input group "XEU5 Common"; +// +// Provider ... +input bool xEU5EnableProvider = true; // Enable Provider +input int xEU5NumberOfItemsPerTick = 30; // Number Of items Readed In Each Tick +// +// Alerts ... +input bool xEU5EnableAlerts = true; // Enable Events Alert +input bool xEU5EnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEU5EnableDailyAlerts = false; // Send Alert on each new Day +input bool xEU5EnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEU5EnableMonthlyAlerts = true; // Send Alert on each new Month +// +// Reports ... +input bool xEU5EnableDailyReports = false; // Send Report on each new Day +input bool xEU5EnableWeeklyReports = false; // Send Report on each new Week +input bool xEU5EnableMonthlyReports = true; // Send Report on each new Month + +// +// Trader and Expert Specific Configurations ... +input group "XEU5 Trader"; +input int xEU5MagicNumber = 16940560; // Trader MagicNumber +input int xEU5Slippage = 10; // Trader Slippage + +// +// Trades Management Configurations ... +input group "XEU5 Trade Management"; +input bool xEU5AllowLongTrades = true; // Allow Long Trades +input bool xEU5AllowShortTrades = true; // Allow Short Trades + +// +// Risk Management Configurations ... +input group "XEU5 Risk Management"; +// +input bool xEU5UseVirtualTPSl = false; // Use Virtual TP SL +// +// Trade Count ... +input int xEU5MaxAllowedTrades = 10; // Max Allowed Trades at Same Time +input ENUM_X_CROSS_SIGNAL_METHOD xEU5CrossSignalsMethod = X_CROSS_SIGNAL_REGULAR; // Handle Cross Signals Method +// +// Max Allowed Trade Age ... +input int xEU5MaxAllowedTradeAge = 1500; // Detect Long Time Trades +input ENUM_X_GUARD_ACTIONS xEU5OldTradesAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1; // What to do with Old Trades +// +// Trade Volume Specific Configurations ... +input double xEU5StaticVolumeFactor = 0.0002; // Static Volume baesd on Balance +input ENUM_STATIC_VOLUME_METHODS xEU5StaticVolumeMethod = X_STATIC_VOLUME_BASED_ON_BALANCE; // How to Calculate Static Volume +input double xEU5VolumeMultiplier = 0; // Volume Increase Multiplier +input double xEU5ApplyVolumeMultiplierFactor = 0; // Apply Volume Multiplier Rate based on Balance +input double xEU5MaxSupportedVolumePerTradeFactor = 0; // Max Supported Volume Per Trade Factor based on Balance +input double xEU5IncreasedMaxSupportedVolumeRate = 0; // Increase Max Supported Volume based on Balance +// +// Trade Profits ... +input double xEU5MinRewardInPips = 15; // Minimum Reward Per Trade in Pips +input double xEU5RiskFreeStepInPips = 6; // Make Trades Risk Free Steps in Pips +input double xEU5RiskFreeRate = 0.6; // Volume Multiplier for Risk Free Trades +// +// Guard Riskable Money and Profits ... +input double xEU5CriticalDrawDownFactor = 0.40; // Critical Allowed Drawdown Factor based on Balance +input ENUM_X_GUARD_ACTIONS xEU5CriticalGuardAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5; // Specify Guard Action on Critical Drawdown +input double xEU5MaxAllowedDrawDownFactor = 0.45; // Max Allowed Drawdown Factor based on Balance +input ENUM_X_GUARD_ACTIONS xEU5MaxAllowedGuardAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10; // Specify Guard Action on Max Allowed Drawdown +input int xEU5GuardStopoutFiredAfterTouches = 5; // Guard Stopout all Trades if Max Allowed Drawdown touched + +// +// Account Conditions for Trading ... +input double xEU5BalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades +input double xEU5FreeMarginFactorForOpenTrades = 0.8; // Minimum Free Margin for Open Trades + +// +// Validate Inputs before Initialization ... +bool XEU5ValidateInputs() +{ + // + bool result = false; + + // + // Implement Other Verifications ... + + // + // Check Trading Availability ... + bool isTradeAvailable = xEU5AllowLongTrades || xEU5AllowShortTrades; + if (!isTradeAvailable) + { + LogMessage("XEU5 => Warning: Trading disabled ..."); + } + + // + // Chekc Number of reading items per tick ... + result = xEU5NumberOfItemsPerTick >= 5; + if (!result) + { + // + LogMessage("XEU5 invalid Number of items Reading Per Tick ..."); + + // + return result; + } + + // + // Check Max Allowed Trades Count ... + result = isTradeAvailable && xEU5MaxAllowedTrades >= 1; + if (!result) + { + // + LogMessage("XEU5 Number of Trades not valid ..."); + + // + return result; + } + + // + // Check Free Margin ... + result = + isTradeAvailable && + xEU5FreeMarginFactorForOpenTrades > 0 && + xEU5FreeMarginFactorForOpenTrades < 1; + if (!result) + { + // + LogMessage("XEU5 Invalid Free Margin ..."); + + // + return result; + } + + // + // Check min Balance for Open Trades ... + result = + isTradeAvailable && + xEU5BalanceFactorForOpenTrades > 0 && + xEU5BalanceFactorForOpenTrades < 1; + if (!result) + { + // + LogMessage("XEU5 Invalid Min Balance for Open Trades ..."); + + // + return result; + } + + // + // Check Min Reward Per Trade ... + result = xEU5MinRewardInPips > 0; + if (!result) + { + // + LogMessage("XEU5 Invalid Min Reward Per Trade ..."); + + // + return result; + } + + // + // Check Trades Volume ... + result = xEU5StaticVolumeFactor > 0; + if (!result) + { + // + LogMessage("XEU5 Invalid Static Volume ..."); + + // + return result; + } + + // + // Check Volume Multiplier ... + result = xEU5VolumeMultiplier >= 0; + if (!result) + { + // + LogMessage("XEU5 Invalid Volume Multiplier ..."); + + // + return result; + } + + // + result = + xEU5CriticalDrawDownFactor == 0 || (xEU5CriticalDrawDownFactor > 0 && + xEU5CriticalDrawDownFactor < 1); + if (!result) + { + // + LogMessage("XEU5 Invalid Critical DrawDown Factor ..."); + + // + return result; + } + + // + result = + xEU5MaxAllowedDrawDownFactor == 0 || (xEU5MaxAllowedDrawDownFactor > 0 && + xEU5MaxAllowedDrawDownFactor < 1); + if (!result) + { + // + LogMessage("XEU5 Invalid Max Allowed DrawDown Factor ..."); + + // + return result; + } + + // + // Check Guard Actions ... + // + result = + xEU5CriticalDrawDownFactor > 0 && + xEU5CriticalDrawDownFactor < 1 && + xEU5MaxAllowedDrawDownFactor > 0 && + xEU5MaxAllowedDrawDownFactor < 1; + if (!result) + { + // + LogMessage("XEU5 For Critical Drawdown, you have to Specify Max Drawdown also ..."); + + // + return result; + } + + // + result = xEU5CriticalDrawDownFactor > 0 && xEU5CriticalDrawDownFactor < xEU5MaxAllowedDrawDownFactor; + if (!result) + { + // + LogMessage("XEU5 Critical Drawdown must Smaller than Max Drawdown ..."); + + // + return result; + } + + // + if (xEU5CriticalDrawDownFactor > 0 && xEU5CriticalGuardAction == X_GUARD_DO_NOTHING) + { + LogMessage("XEU5 IMPORTANT you Specified Critical Drawdown, but there is no any Guard Action ..."); + } + + // + if (xEU5MaxAllowedDrawDownFactor > 0 && xEU5MaxAllowedGuardAction == X_GUARD_DO_NOTHING) + { + LogMessage("XEU5 IMPORTANT you Specified Max Allowed Drawdown, but there is no any Guard Action ..."); + } + + // + result = true; + + // + return result; +} \ No newline at end of file diff --git a/XEU5/Providers/x-saherelm.xeu5.provider.lib.mq5 b/XEU5/Providers/x-saherelm.xeu5.provider.lib.mq5 new file mode 100644 index 0000000..c57de45 --- /dev/null +++ b/XEU5/Providers/x-saherelm.xeu5.provider.lib.mq5 @@ -0,0 +1,1370 @@ +//////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XEU5 Signal Provider Library +// -------------------------------------------------------- +// Name: XEU5SignalProvider +// Description: XEU5 based signal provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +#define XEU5ProviderName "XEU5" + +// +// START Inputs ... +// + +#include "x-saherelm.xeu5.provider.inputs.lib.mq5"; + +// +// END Inputs ... +// + +// +// Include Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Include Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Alert Library ... +#include "../Libraries/x-saherelm.alert.lib.mq5" + +// +// Include Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Include Class Libraries ... +#include "../Classes/x-saherelm.class.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XCGuard *xEU5Guard; +XCTrade *xEU5Trader; +XCReporter *xEU5Reporter; +XCCollector *xEU5Collector; +XCAccountInfo *xEU5AccountInfo; +XCVolumeManager *xEU5VolumeManager; + +// +#include "x-saherelm.xeu5.provider.indicators.lib.mq5" + +// +// Controlling Variables ... +bool xEU5MEnableProvider = false; +bool xEU5MAllowLongTrades = false; +bool xEU5MAllowShortTrades = false; + +// +double xEU5Deposit = 0; +double xEU5Balance = 0; +double xEU5MinReward = 0; +double xEU5FreeMargin = 0; +double xEU5BalanceForOpenTrades = 0; +double xEU5FreeMarginForOpenTrades = 0; + +// +// Guard ... +double xEU5CriticalDrawDown = 0; +double xEU5MaxAllowedDrawDown = 0; + +// +double xEU5MaxDrawUp = 0; +double xEU5MaxDrawDown = 0; + +// +int NOT_ENOUGH_MONEY_ERROR = 4756; +const string XEU5_SUPPORT_ID = "SP"; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Initial Library if required ... +bool XEU5InitSignalProviderLibrary() +{ + // + bool result = false; + + // + if (!xEU5EnableProvider) + { + return result; + } + + // + // Controlling Variables ... + xEU5MEnableProvider = xEU5EnableProvider; + xEU5MAllowLongTrades = xEU5AllowLongTrades; + xEU5MAllowShortTrades = xEU5AllowShortTrades; + + // + // Validate Inputs ... + result = XEU5ValidateInputs(); + if (!result) + { + return result; + } + + // + // Init Indicators ... + result = XEU5InitIndicators(); + if (!result) + { + return result; + } + + // + xEU5Reporter = new XCReporter(); + xEU5Collector = new XCCollector(); + xEU5AccountInfo = new XCAccountInfo(); + + // + // Calculate Account Deposit ... + xEU5Deposit = xEU5AccountInfo.GetInitialBalance(); + + // + // Prepare Min Reward ... + if (xEU5MinRewardInPips > 0) + { + xEU5MinReward = PipsToPrice(xEU5MinRewardInPips); + } + + // + // Calculate Min Balance for Trades ... + if (xEU5BalanceFactorForOpenTrades > 0) + { + xEU5BalanceForOpenTrades = xEU5BalanceFactorForOpenTrades * xEU5Deposit; + } + + // + // Claculate Min Free Marging for Trades ... + if (xEU5FreeMarginFactorForOpenTrades > 0) + { + xEU5FreeMarginForOpenTrades = xEU5FreeMarginFactorForOpenTrades * xEU5Deposit; + } + + // + // Calculate Init Time Critical DrawDown Value ... + if (xEU5CriticalDrawDownFactor > 0) + { + xEU5CriticalDrawDown = xEU5CriticalDrawDownFactor * xEU5Deposit; + } + + // + // Calculate Init Time Max Allowed DrawDown Value ... + if (xEU5MaxAllowedDrawDownFactor > 0) + { + xEU5MaxAllowedDrawDown = xEU5MaxAllowedDrawDownFactor * xEU5Deposit; + } + + // + // Instant Volume Manager ... + xEU5VolumeManager = new XCVolumeManager( + xEU5StaticVolumeFactor, + xEU5StaticVolumeMethod, + xEU5VolumeMultiplier, + xEU5ApplyVolumeMultiplierFactor, + xEU5MaxSupportedVolumePerTradeFactor, + xEU5IncreasedMaxSupportedVolumeRate); + + // + // Make XCTrader instance ... + xEU5Trader = new XCTrade( + XEU5ProviderName, + _Symbol, + xEU5Slippage, + xEU5MagicNumber, + xEU5UseVirtualTPSl, + xEU5MaxAllowedTrades, + xEU5FreeMarginForOpenTrades, + xEU5BalanceForOpenTrades); + + // + // Instantiate Account Guard ... + xEU5Guard = new XCGuard( + // + // Old Trades ... + xEU5MaxAllowedTradeAge, + xEU5OldTradesAction, + // + // Critical DrawDown ... + xEU5CriticalDrawDownFactor, + xEU5CriticalGuardAction, + // + // Max Allowed DrawDown ... + xEU5MaxAllowedDrawDownFactor, + xEU5MaxAllowedGuardAction, + xEU5GuardStopoutFiredAfterTouches, + // + // xEU5GuardSupportMethod + X_SUPPORT_DO_NOTHING + // + ); + + // + // Reset Calculations Buffers and Variables ... + XEU5ResetCollectors(); + + // + XEU5UpdateReports(); + + // + result = true; + + // + // Logging State ... + XEU5IssueInitializationSucceedAlert(); + + // + return result; +} + +// +// DeInitial Library if required ... +void XEU5DeinitSignalProviderLibrary(const int reason) +{ + // + // Release Handlers ... + XEU5ReleaseIndicators(); + + // + // Logging State ... + XEU5IssueDeinitializationSucceedAlert(); +} + +// +// this is a Globally Function which do all of +// checkings and positions handling ... +void XEU5SignalProviderHandleTick() +{ + // + // Check Provider is Enable or Not ... + if (!xEU5MEnableProvider) + { + return; + } + + // + XEU5SignalProviderDoControlState(); + + // + // Reading Indicator Buffers ... + XEU5HandleReadingBuffers(); + if (xEU5CalculatedBars < xEU5MaxLengthOfInputs) + { + return; + } + + // + // Handle Open Trades ... + XEU5HandleOpenTrades(); + + // + // Handle Close Trades ... + XEU5HandleCloseTrades(); + + // + // DrawDown and DrawUp ... + XEU5HandleCalculateDrawDownUp(); +} + +// +// Do Control Checks here ... +void XEU5SignalProviderDoControlState() +{ + // + // Update account Balance ... + xEU5Balance = xEU5AccountInfo.GetBalance(); + xEU5FreeMargin = xEU5AccountInfo.GetFreeMargin(); + + // + // Check Provider is Enable or Not ... + if (!xEU5MEnableProvider) + { + return; + } + + // + // Protect Account by Guarding Maximum Drawdown ... + // TODO: add Guard Result here ... + string guardMessage = ""; + XGuardHandlerResult guardHandlerResult; + bool isGuarded = xEU5Guard.Guard( + guardHandlerResult, + guardMessage, + xEU5Trader, + _Period); + if (isGuarded) + { + // + // Criticals ... + int criticalsCount = ArraySize(guardHandlerResult.criticals); + if (criticalsCount > 0) + { + // + for (int i = 0; i < criticalsCount; i++) + { + // + XSignal iSignal = guardHandlerResult.criticals[i]; + + // + XEU5OnGuard( + iSignal, + X_GUARDED_CRITICAL, + guardMessage); + } + } + + // + // Maxes ... + int maxesCount = ArraySize(guardHandlerResult.maxes); + if (maxesCount > 0) + { + // + for (int i = 0; i < maxesCount; i++) + { + // + XSignal iSignal = guardHandlerResult.maxes[i]; + + // + XEU5OnGuard( + iSignal, + X_GUARDED_MAX, + guardMessage, + guardHandlerResult.isStopOut); + } + } + + // + // Olds ... + int oldsCount = ArraySize(guardHandlerResult.olds); + if (oldsCount > 0) + { + // + for (int i = 0; i < oldsCount; i++) + { + // + XSignal iSignal = guardHandlerResult.olds[i]; + + // + XEU5OnGuard( + iSignal, + X_GUARDED_OLD, + guardMessage); + } + } + } + + // + // Signal Protection ... + XSignal protectSupports[]; + bool isSupported = xEU5Guard.ProtectSignals( + protectSupports, + xEU5Trader); + if (isSupported) + { + // + LogMessage("Guard do Support Trdae ..."); + } + + // + // Handling Signals ... + XTraderHandlerResult signalHandlerResult; + xEU5Trader.HandleSignals( + signalHandlerResult, + false // Ignore Risk Free Trdaes + ); + + // + // Handle Sl Reports ... + int handledSLsCount = ArraySize(signalHandlerResult.sl); + if (handledSLsCount > 0) + { + // + for (int i = 0; i < handledSLsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.sl[i]; + XEU5OnSL(iSignal); + } + } + + // + // Handle TP Reports ... + int handledTPsCount = ArraySize(signalHandlerResult.tp); + if (handledTPsCount > 0) + { + // + for (int i = 0; i < handledTPsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.tp[i]; + XEU5OnTP(iSignal); + } + } + + // + // Handle RFs as TP Reports ... + int handledRFsCount = ArraySize(signalHandlerResult.rf); + if (handledRFsCount > 0) + { + // + for (int i = 0; i < handledRFsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.rf[i]; + XEU5OnRF(iSignal); + } + } +} + +// +// Handle Trades when OnTrade Event Hnadler Calls ... +void XEU5SignalProviderHandleTrade() +{ + // + // Check Provider Enabled ... + if (!xEU5MEnableProvider) + { + return; + } + + // + // Handle OnTrade Event ... + XOnTradeHandlerResult result = {}; + xEU5Trader.HandleOnTradeEvent( + result); + + // + // Detected TP or SL ... + if (result.hasNewDeal) + { + // + XDeal last = xEU5Trader.GetLastDeal(); + + // + if (last.reason == DEAL_REASON_SL) + { + xEU5Reporter.AddTradeSLInReports(); + } + else if (last.reason == DEAL_REASON_TP) + { + xEU5Reporter.AddTradeTPInReports(); + } + } +} + +// +// Handle Open Trades ... +void XEU5HandleOpenTrades() +{ + // + // Check Can Trade ... + bool canTrade = xEU5MAllowLongTrades || xEU5MAllowShortTrades; + if (!canTrade) + { + return; + } + + // + // Check Max Open Trades ... + int openSignals = xEU5Trader.Count(); + bool canOpenPositions = openSignals < xEU5MaxAllowedTrades; + if (!canOpenPositions) + { + return; + } + + // + // Check Signals Exists ... + XProvidedSignal longSignalInfo; + XProvidedSignal shortSignalInfo; + bool hasLongSignal = XEU5CanOpenLongTrade(longSignalInfo); + bool hasShortSignal = XEU5CanOpenShortTrade(shortSignalInfo); + if (!hasLongSignal && !hasShortSignal) + { + return; + } + + // + // Update Reports ... + XEU5UpdateReports(); + + // + // Open Long Trades ... + if ( + // + hasLongSignal && + xEU5MAllowLongTrades) + { + // + bool isOpened = XEU5OpenLongPosition(longSignalInfo); + } + + // + // Open Short Trades ... + if ( + // + hasShortSignal && + xEU5MAllowShortTrades) + { + // + bool isOpened = XEU5OpenShortPosition(shortSignalInfo); + } +} + +// +// Handle Close Trades ... +void XEU5HandleCloseTrades() +{ + // + // Force Close Long Trades ... + bool isClosedLongTrades = false; + bool canCloseLongTrades = XEU5CanCloseLongTrade(); + if (xEU5MAllowLongTrades && canCloseLongTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG; + + // + XSignal closed[]; + xEU5Trader.CloseSignals( + closed, + type); + + // + int closedTradesCount = ArraySize(closed); + isClosedLongTrades = closedTradesCount > 0; + if (isClosedLongTrades) + { + // + for (int i = 0; i < closedTradesCount; i++) + { + // + XSignal iSignal = closed[i]; + XEU5OnFC(iSignal); + } + } + } + + // + // Force Close Short Trades ... + bool isClosedShortTrades = false; + bool canCloseShortTrades = XEU5CanCloseShortTrade(); + if (xEU5MAllowShortTrades && canCloseShortTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT; + + // + XSignal closed[]; + xEU5Trader.CloseSignals( + closed, + type); + + // + int closedTradesCount = ArraySize(closed); + isClosedShortTrades = closedTradesCount > 0; + if (isClosedShortTrades) + { + // + for (int i = 0; i < closedTradesCount; i++) + { + // + XSignal iSignal = closed[i]; + XEU5OnFC(iSignal); + } + } + } +} + +// +// Open Long Position ... +bool XEU5OpenLongPosition( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double entry = GetEntry(_Symbol, X_SIGNAL_LONG); + double sl = info.sl > 0 ? info.sl : 0; + // entry - (200 * _Point); + // info.sl > 0 ? info.sl : 0; + double tp = info.tp > 0 ? info.tp : entry + xEU5MinReward; + double riskFreeRate = xEU5RiskFreeRate; + double riskFreeStep = xEU5RiskFreeStepInPips; + double volume = XEU5CalculateVolume(ArraySize(info.signallers)); + + // + XSignal signal = {}; + signal = xEU5Trader.GenerateSignal( + X_SIGNAL_LONG, + tp, + sl, + volume, + riskFreeStep, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xEU5MagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int signalsCount = xEU5Trader.Count(); + bool isCross = signalsCount >= 1; + if (isCross) + { + // + // Handle Cross Signals ... + XEU5HnadleCrossSignal(signal); + } + + // + // Retrieve Can Execute Signal or not ... + bool canExecuteSignal = + !isCross + // + || + // + ( + // + isCross && + xEU5CrossSignalsMethod != X_CROSS_SIGNAL_DO_NOTHING + // + ); + if (!canExecuteSignal) + { + return result; + } + + // + // Execute Signal ... + ENUM_EXECUTION_SIGNAL_RESULT executionResult = xEU5Trader.ExecuteSignal( + signal, + false, // Ignore Number of Trades ... + true // Check Account Conditions ... + ); + result = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (result) + { + // + // Update Reports ... + string providers[]; + ArrayCopy( + providers, + info.signallers + ); + + // + XSignal tSignal = xEU5Trader.GetSignal(signal.ticket); + + // + XEU5OnSignal( + tSignal, + providers); + } + else + { + XEU5IssueSignalExecutionError(executionResult); + } + + // + return result; +} + +// +// Open Short Position ... +bool XEU5OpenShortPosition( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double entry = GetEntry(_Symbol, X_SIGNAL_SHORT); + double sl = info.sl > 0 ? info.sl : 0; + // entry + (200 * _Point); + // info.sl > 0 ? info.sl : 0; + double tp = info.tp > 0 ? info.tp : entry - xEU5MinReward; + double riskFreeRate = xEU5RiskFreeRate; + double riskFreeStep = xEU5RiskFreeStepInPips; + double volume = XEU5CalculateVolume(ArraySize(info.signallers)); + + // + XSignal signal = {}; + signal = xEU5Trader.GenerateSignal( + X_SIGNAL_SHORT, + tp, + sl, + volume, + riskFreeStep, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xEU5MagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int signalsCount = xEU5Trader.Count(); + bool isCross = signalsCount >= 1; + if (isCross) + { + // + // Handle Cross Signals ... + XEU5HnadleCrossSignal(signal); + } + + // + // Retrieve Can Execute Signal or not ... + bool canExecuteSignal = + !isCross + // + || + // + ( + // + isCross && + xEU5CrossSignalsMethod != X_CROSS_SIGNAL_DO_NOTHING + // + ); + if (!canExecuteSignal) + { + return result; + } + + // + // Execute Signal ... + ENUM_EXECUTION_SIGNAL_RESULT executionResult = xEU5Trader.ExecuteSignal( + signal, + false, // Ignore Number of Trades ... + true // Check Account Conditions ... + ); + result = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (result) + { + string providers[]; + ArrayCopy( + providers, + info.signallers + ); + + // + XSignal tSignal = xEU5Trader.GetSignal(signal.ticket); + + // + XEU5OnSignal( + tSignal, + providers); + } + else + { + XEU5IssueSignalExecutionError(executionResult); + } + + // + return result; +} + +// +// Apply Cross Signal Actions ... +void XEU5HnadleCrossSignal( + XSignal &signal // Specified Signal ... +) +{ + // + // Check Cross Signal Handling Enabled ... + if (xEU5CrossSignalsMethod == X_CROSS_SIGNAL_DO_NOTHING) + { + return; + } + + // + // First We have to Change Cross Signals Comment ... + string comment = xEU5Trader.GenerateSignalComment( + signal, + true); + + // + signal.comment = comment; + + // + // If Every thing is Regular, prevent any changes here ... + if (xEU5CrossSignalsMethod == X_CROSS_SIGNAL_REGULAR) + { + return; + } + + // + // Retrieve Max in Drawdown Signal ... + XSignal maxInDDSignal = xEU5Trader.GetMaxInDrawdownSignal(); + + // + // Validate Signal ... + bool isValidSignal = + maxInDDSignal.ticket > 0 && + maxInDDSignal.symbol == signal.symbol && + IsValid(maxInDDSignal, xEU5MagicNumber); + if (!isValidSignal) + { + return; + } + + // + double volume = signal.volume; + bool isDirectional = maxInDDSignal.type == signal.type; + + // + // Prevent any changes on Regular Conditions ... + bool isRegular = + isDirectional + ? ( + // + xEU5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_REGULAR || + xEU5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_REGULAR_INDIRECTION_IMPORTANT + // + ) + : ( + // + xEU5CrossSignalsMethod == X_CROSS_SIGNAL_INDIRECTION_REGULAR || + xEU5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_IMPORTANT_INDIRECTION_REGULAR + // + ); + if (isRegular) + { + return; + } + + // + // Important Act needs to Multiply volume by 2 ... + volume *= 2; + + // + // Set Volume of signal ... + signal.volume = volume; +} + +// +// Calculate Usefull data ... +void XEU5HandleCalculateDrawDownUp() +{ + // + XSignal signals[]; + xEU5Trader.GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + double profit = 0; + double volume = 0; + XCollector collector = {}; + double maxAllowedVolume = xEU5VolumeManager.GetMaxAllowedVolume(); + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + profit += iSignal.profit; + + // + volume = + volume == 0 || + volume < iSignal.volume + ? iSignal.volume + : volume; + } + + // + if (profit < 0) + { + // + xEU5MaxDrawDown = + xEU5MaxDrawDown == 0 || + xEU5MaxDrawDown > MathAbs(profit) + ? MathAbs(profit) + : xEU5MaxDrawDown; + + // + // Update Buffers ... + datetime time = iTime(_Symbol, _Period, 0); + + // + // Calculate Max Allowed Drawdown ... + // + collector.time = time; + collector.volume = volume; + collector.maxDrawDown = xEU5MaxDrawDown; + collector.maxAllowedVolume = maxAllowedVolume; + collector.minBalanceForOpenTrade = xEU5Trader.GetMinBalanceForOpenTrades(); + } + else + { + // + xEU5MaxDrawUp = + xEU5MaxDrawUp == 0 || + xEU5MaxDrawUp < profit + ? profit + : xEU5MaxDrawUp; + } + + // + // Update Collector ... + xEU5Collector.Add(collector); + + // + // Update Reports ... + xEU5Reporter.UpdateMaxDrawUpInReports(xEU5MaxDrawUp); + xEU5Reporter.UpdateMaxDrawDownInReports(xEU5MaxDrawDown); + xEU5Reporter.UpdateMaxSameTimeTradesInReports(signalsCount); +} + +// +// START Event Handlers ... +// + +// +// Runs When a Signal Successfully Executed ... +void XEU5OnSignal( + XSignal &signal, // Specified Signal + string &providers[] // Signal Providers +) +{ + // + // Issue Propper Alert ... + XEU5IssueSignalExecutionAlert( + signal, + providers); + + // + // Add Signal To Supports on Guard ... + xEU5Guard.AddSupport(signal); + + // + // Update Reports ... + xEU5Reporter.AddSignalToReports( + signal, + providers); +} + +// +// Runs when a Position Got Take Profit ... +void XEU5OnTP( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueTPAlert(signal); + + // + // Remove Signal From Guard Protector ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeTPInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Got Stop Loss ... +void XEU5OnSL( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueSLAlert(signal); + + // + // Remove Signal From Guard Protector ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Risk Free ... +void XEU5OnRF( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueRFAlert(signal); + + // + // Remove Signal From Guard Protector ... + // since RiskFree Signals has SL ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Force Closed ... +void XEU5OnFC( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XEU5IssueFCAlert(signal); + + // + // Remove Signal From Guard Protector ... + xEU5Guard.Remove(signal.ticket); + xEU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// Runs when a Position Guarded ... +void XEU5OnGuard( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason, // Reason of Guard Applied + string message, // Guard Returned Message + bool isStopOut = false // Specified StopOut Fired or not +) +{ + // + // Chekc StopOut ... + if (isStopOut) + { + // + LogMessage(message); + + // + xEU5MEnableProvider = false; + } + + // + // Issue Propper Alert ... + XEU5IssueGuardAlert(signal, reason, isStopOut); + + // + // Update Reports ... + xEU5Reporter.AddTradeSLInReports(); + XEU5UpdateReports(); +} + +// +// END Event Handlers ... +// + +// +// END Provided Functions ... +// + +// +// START Private Functions ... +// + +// +// START Volume Baseed Functions ... +// + +// +// Calculating Volume for Tradings ... +double XEU5CalculateVolume( + double forceMultiplier = 0 // some times we get more than one signal at the same time, here we increase volume using this ... +) +{ + // + // Check Open Trades ... + int openSignals = xEU5Trader.Count(); + + // + double result = xEU5VolumeManager.CalculateVolume( + openSignals, + _Symbol); + + // + result *= forceMultiplier; + + // + // Normalize Volume ... + result = NormalizeVolume(result, _Symbol, 2); + + // + return result; +} + +// +// END Volume Baseed Functions ... +// + +// +// START Report/Collect and Guard Functions ... +// + +// +// Update Report Info ... +void XEU5UpdateReports() +{ + // + double staticVolume = xEU5VolumeManager.GetStaticVolume(); + string staticVolumeCalculationMethod = EnumToString(xEU5StaticVolumeMethod); + double maxAllowedVolume = xEU5VolumeManager.GetMaxAllowedVolume(); + double volumeIncreaseMultiplier = xEU5VolumeManager.GetVolumeMultiplier(); + double balanceGowingToApplyMultiplier = xEU5VolumeManager.GetIncreaseMultiplierBalance(); + + double balanceGrowingToIncreaseMaxAllowedVolume = xEU5VolumeManager.GetIncreaseMaxAllowedVolumeBalance(); + + // + // Update Reports Volume Info ... + xEU5Reporter.UpdateReportsVolumeInfo( + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Calculate Max Allowed Drawdown ... + double minBalanceForTradeBasedOnBalance = xEU5Trader.GetMinBalanceForOpenTrades(); + xEU5Reporter.UpdateMinBalanceForOpenTradesInReports(minBalanceForTradeBasedOnBalance); +} + +// +// Reset XEU5 Info Buffers ... +void XEU5ResetCollectors() +{ + // + // Reset Calculations Buffers and Variables ... + xEU5MaxDrawUp = 0; + xEU5MaxDrawDown = 0; + + // + xEU5Trader.Reset(); + xEU5Reporter.Reset(); + xEU5Collector.Reset(); + xEU5VolumeManager.ResetForceVolumeMultiplier(); +} + +// +// END Report/Collect and Guard Functions ... +// + +// +// START Alert Functions ... +// + +// +// Send Alert ... +void XEU5IssueAlert(string message) +{ + // + // Validate Args ... + if (StringLen(message) <= 0) + { + return; + } + + // + if (xEU5EnableAlerts) + { + SendAlert(message); + } + else + { + LogMessage(message); + } +} + +// +// Send Take Profit Alert on Specific Signal ... +void XEU5IssueTPAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalTPComment(signal); + + // + XEU5IssueAlert(message); +} + +// +// Send Stop Loss Alert on Specific Signal ... +void XEU5IssueSLAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalSLComment(signal); + + // + XEU5IssueAlert(message); +} + +// +// Send Force Close Alert on Specific Signal ... +void XEU5IssueFCAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalForceCloseComment(signal); + + // + XEU5IssueAlert(message); +} + +// +// Send Risk Free Alert on Specific Signal ... +void XEU5IssueRFAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xEU5Trader.GenerateSignalRFComment(signal, 0); + + // + XEU5IssueAlert(message); +} + +// +// Send Guard Alert on Specific Signal ... +void XEU5IssueGuardAlert( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason, // Specified Guard Reason + bool isStopOut = false // Specified StopOut Fired or not +) +{ + // + string message = ""; + + // + message = xEU5Guard.GenerateGuardedSignalComment( + signal, + reason); + + // + XEU5IssueAlert(message); +} + +// +// Send Initialization Succeed Alert ... +void XEU5IssueInitializationSucceedAlert() +{ + // + string message = "Initializion of (" + XEU5ProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ..."; + XEU5IssueAlert(message); +} + +// +// Send De Initialization Succeed Alert ... +void XEU5IssueDeinitializationSucceedAlert() +{ + // + string message = "De Initializion of (" + XEU5ProviderName + " Provider" + ") Succeeded ..."; + XEU5IssueAlert(message); +} + +// +// Send Signal Successfully Execution Alert ... +void XEU5IssueSignalExecutionAlert( + XSignal &signal, // Specified Signal + string &providers[] // Signal Providers +) +{ + // + string message = xEU5Trader.ToString(signal); + + // + string providersMsg = ToString(providers); + if (StringLen(providersMsg) > 0) + { + message += ", Providers: " + providersMsg; + } + + // + XEU5IssueAlert(message); +} + +// +// Send Signal Execution Alert ... +void XEU5IssueSignalExecutionError(int error) +{ + // + string message = GetSignalExecutionError(error); + if (StringLen(message) == 0) + { + return; + } + + // + XEU5IssueAlert(message); +} + +// +// END Alert Functions ... +// + +// +// END Private Functions ... +// diff --git a/XEU5/Settings/.gitkeep b/XEU5/Settings/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/XEU5/Settings/xeu5.longs.vbb.set b/XEU5/Settings/xeu5.longs.vbb.set new file mode 100644 index 0000000..273e17a Binary files /dev/null and b/XEU5/Settings/xeu5.longs.vbb.set differ diff --git a/XEU5/Settings/xeu5.shorts.vbb.set b/XEU5/Settings/xeu5.shorts.vbb.set new file mode 100644 index 0000000..b80e6d8 Binary files /dev/null and b/XEU5/Settings/xeu5.shorts.vbb.set differ diff --git a/XEU5/Settings/xeu5.vbb.set b/XEU5/Settings/xeu5.vbb.set new file mode 100644 index 0000000..c3b4099 Binary files /dev/null and b/XEU5/Settings/xeu5.vbb.set differ diff --git a/XEU5/Templates/.gitkeep b/XEU5/Templates/.gitkeep new file mode 100644 index 0000000..e69de29