diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xama.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xama.helper.class.ex5 new file mode 100644 index 0000000..723b283 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xama.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xama.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xama.helper.class.mq5 new file mode 100644 index 0000000..42de1bb --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xama.helper.class.mq5 @@ -0,0 +1,470 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXAMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XAMAInputs +{ + // + // Makret ... + int length; // Length + int fastEMA; // Fast EMA Length + int slowEMA; // Slow EMA Length + int maShift; // Shift + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + bool showLine; // Show Line +}; + +// +// Index of Lines ... +enum ENUM_XAMA_BUFFERS +{ + // + // Main Requirements ... + XAMA_LINE = 0, + XAMA_STATE_LINE = 1, +}; + +// +// XAMA Indicator States ... +enum ENUM_XAMA_STATES +{ + X_XAMA_BULLISH = 0, + X_XAMA_BEARISH = 2, + X_XAMA_NEUTURAL = 1, +}; + +// +// Retrieve Info Model ... +struct XAMAInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double value; + + // + // State ... + ENUM_XAMA_STATES state; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; + + // + // Detect Trend is Neutural or not ... + bool isNeutural; + + // + // Detect Trend is Switched to Neutural Or not ... + bool isSwitchedNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXAMAHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double valueBuffer[]; + double stateBuffer[]; + + // + // Constructor ... + void XSCXAMAHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XAMAInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXAMAHelper(symbol, + period, + config.length, + config.fastEMA, + config.slowEMA, + config.maShift, + config.appliedTo, + config.showLine); + } + void XSCXAMAHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int length = 52, + // + // Fast EMA Length ... + int fastEMA = 2, + // + // Slow EMA Length ... + int slowEMA = 30, + // + // Shift ... + int maShift = 0, + // + // Applied To ... + ENUM_APPLIED_PRICE appliedTo = PRICE_LOW, + // + // Presentation ... + // + // Show Line ... + bool showLine = true + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mLength = length; + mFastEMA = fastEMA; + mSlowEMA = slowEMA; + mMaShift = maShift; + mShowLine = showLine; + mAppliedTo = appliedTo; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXAMAHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XAMA" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xama", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mLength, + // + // Fast EMA Length ... + mFastEMA, + // + // Slow EMA Length ... + mSlowEMA, + // + // Shift ... + mMaShift, + // + // Applied To ... + mAppliedTo, + // + // Presentation ... + "", + // + // Show Line ... + mShowLine + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XAMAInputs GetConfig() + { + // + XAMAInputs result; + + // + result.length = mLength; + result.fastEMA = mFastEMA; + result.slowEMA = mSlowEMA; + result.maShift = mMaShift; + result.appliedTo = mAppliedTo; + result.showLine = mShowLine; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XAMAInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mFastEMA = config.fastEMA; + mSlowEMA = config.slowEMA; + mMaShift = config.maShift; + mAppliedTo = config.appliedTo; + mShowLine = config.showLine; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // VALUE ... + ArraySetAsSeries(valueBuffer, true); + CopyBuffer( + mHandler, + XAMA_LINE, + barIndex, + mLoopbackBars, + valueBuffer); + + // + // STATE ... + ArraySetAsSeries(stateBuffer, true); + CopyBuffer( + mHandler, + XAMA_STATE_LINE, + barIndex, + mLoopbackBars, + stateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XAMAInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XAMAInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.value = valueBuffer[barIndex]; + + // + ENUM_XAMA_STATES state = (ENUM_XAMA_STATES)stateBuffer[barIndex]; + ENUM_XAMA_STATES prevState = (ENUM_XAMA_STATES)stateBuffer[barIndex + 1]; + result.state = state; + + // + result.isBullish = state == X_XAMA_BULLISH; + result.isBearish = state == X_XAMA_BEARISH; + result.isNeutural = state == X_XAMA_NEUTURAL; + + // + result.isSwitchedBullish = + state == X_XAMA_BULLISH && prevState != X_XAMA_BULLISH; + result.isSwitchedBearish = + state == X_XAMA_BEARISH && prevState != X_XAMA_BEARISH; + result.isSwitchedNeutural = + state == X_XAMA_NEUTURAL && prevState != X_XAMA_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Fast EMA Length ... + int mFastEMA; + // + // Slow EMA Length ... + int mSlowEMA; + // + // Shift ... + int mMaShift; + // + // Applied To ... + ENUM_APPLIED_PRICE mAppliedTo; + // + // Presentation ... + // + // Show Line ... + bool mShowLine; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xcc.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xcc.helper.class.ex5 new file mode 100644 index 0000000..f7c02aa Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xcc.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xcc.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xcc.helper.class.mq5 new file mode 100644 index 0000000..f27802b --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xcc.helper.class.mq5 @@ -0,0 +1,330 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +struct XCCInputs +{ + // + // Chart Style ... + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + + // + // Presentation ... + bool showCandles; // Show Candles +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCXCCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XCCInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXCCHelper(symbol, + period, + config.upColor, + config.downColor, + config.lineColor, + config.bearishColor, + config.bullishColor, + config.volumesColor, + config.showCandles); + } + void XSCXCCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Chart Style ... + // + // Up Color ... + color upColor = clrLime, + // + // Down Color ... + color downColor = clrRed, + // + // Line mode and Doji candlestick Color ... + color lineColor = clrLime, + // + // Bearish Color ... + color bearishColor = clrRed, + // + // Bullish Color ... + color bullishColor = clrLime, + // + // Volumes Color ... + color volumesColor = clrGreen, + // + // Presentations ... + // + // Show Candles ... + bool showCandles = false + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mUpColor = upColor; + mDownColor = downColor; + mLineColor = lineColor; + mBearishColor = bearishColor; + mBullishColor = bullishColor; + mVolumesColor = volumesColor; + mShowCandles = showCandles; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCCHelper() + { + } + + // + // START Properties ... + // + + // + // Show Candles ... + bool ShowCandles( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowCandles == show) + { + return true; + } + + // + mShowCandles = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCC" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xcc", + // + // Inputs ... + // + // Chart Style ... + "", + // + // Up Color ... + mUpColor, + // + // Down Color ... + mDownColor, + // + // Line mode and Doji candlestick Color ... + mLineColor, + // + // Bullish Color ... + mBearishColor, + // + // Bearish Color ... + mBullishColor, + // + // Volumes Color ... + mVolumesColor, + // + // Presentation ... + "", + // + // Show Candles ... + mShowCandles + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCCInputs GetConfig() + { + // + XCCInputs result; + + // + result.upColor = mUpColor; + result.downColor = mDownColor; + result.lineColor = mLineColor; + result.bearishColor = mBearishColor; + result.bullishColor = mBullishColor; + result.volumesColor = mVolumesColor; + result.showCandles = mShowCandles; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCCInputs &config) + { + // + bool result = false; + + // + mUpColor = config.upColor; + mDownColor = config.downColor; + mLineColor = config.lineColor; + mBearishColor = config.bearishColor; + mBullishColor = config.bullishColor; + mVolumesColor = config.volumesColor; + mShowCandles = config.showCandles; + + // + result = Init(); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Chart Style ... + // + // Up Color ... + color mUpColor; + // + // Down Color ... + color mDownColor; + // + // Line mode and Doji candlestick Color ... + color mLineColor; + // + // Bullish Color ... + color mBearishColor; + // + // Bearish Color ... + color mBullishColor; + // + // Volumes Color ... + color mVolumesColor; + + // + // Presentation ... + // + // Show Candles ... + bool mShowCandles; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xche.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xche.helper.class.ex5 new file mode 100644 index 0000000..a867c4b Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xche.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xche.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xche.helper.class.mq5 new file mode 100644 index 0000000..57ab321 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xche.helper.class.mq5 @@ -0,0 +1,648 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHEHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XCHEInputs +{ + // + // Market ... + int length; // Length + int loopback; // Loopback + double multiplier1; // 1st Multiplier + double multiplier2; // 2nd Multiplier + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied to + + // + // Presentation ... + bool showLongExit1Line; // Show 1st Long Exit + bool showShortExit1Line; // Show 1st Short Exit + bool showLongExit2Line; // Show 2st Long Exit + bool showShortExit2Line; // Show 2st Short Exit +}; + +// +// Index of Lines ... +enum ENUM_XCHE_BUFFERS +{ + // + // Main Requirements ... + XCHE_1ST_LONG_EXIT_LINE = 0, + XCHE_1ST_SHORT_EXIT_LINE = 1, + XCHE_2ND_LONG_EXIT_LINE = 2, + XCHE_2ND_SHORT_EXIT_LINE = 3, +}; + +// +// Retrieve Info Model ... +struct XCHEInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double longExit1; + double longExit2; + double shortExit1; + double shortExit2; + + // + // Conditions ... + // + bool isLongExit1Start; + bool isShortExit1Start; + + // + bool isLongExit2Start; + bool isShortExit2Start; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCHEHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double longExit1Buffer[]; + double shortExit1Buffer[]; + double longExit2Buffer[]; + double shortExit2Buffer[]; + + // + // Constructor ... + void XSCXCHEHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XCHEInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXCHEHelper(symbol, + period, + config.length, + config.loopback, + config.multiplier1, + config.multiplier2, + config.upAppliedTo, + config.downAppliedTo, + config.showLongExit1Line, + config.showShortExit1Line, + config.showLongExit2Line, + config.showShortExit2Line); + } + void XSCXCHEHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int length = 35, + // + // Loopback ... + int loopback = 26, + // + // 1st Multiplier ... + double multiplier1 = 3.0, + // + // 2nd Multiplier ... + double multiplier2 = 3.5, + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH, + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW, + // + // Presentation ... + // + // Show 1st Long Exit ... + bool showLongExit1Line = true, + // + // Show 1st Short Exit ... + bool showShortExit1Line = true, + // + // Show 2st Long Exit ... + bool showLongExit2Line = true, + // + // Show 2st Short Exit ... + bool showShortExit2Line = true + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mLength = length; + mLoopback = loopback; + mMultiplier1 = multiplier1; + mMultiplier2 = multiplier2; + mUpAppliedTo = upAppliedTo; + mDownAppliedTo = downAppliedTo; + mShowLongExit1Line = showLongExit1Line; + mShowShortExit1Line = showShortExit1Line; + mShowLongExit2Line = showLongExit2Line; + mShowShortExit2Line = showShortExit2Line; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCHEHelper() + { + } + + // + // START Properties ... + // + + // + // Show 1st Long Exit ... + bool ShowLongExit1Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowLongExit1Line == show) + { + return true; + } + + // + mShowLongExit1Line = show; + result = Init(); + + // + return result; + } + + // + // Show 1st Short Exit ... + bool ShowShortExit1Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowShortExit1Line == show) + { + return true; + } + + // + mShowShortExit1Line = show; + result = Init(); + + // + return result; + } + + // + // Show 2st Long Exit ... + bool ShowLongExit2Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowLongExit2Line == show) + { + return true; + } + + // + mShowLongExit2Line = show; + result = Init(); + + // + return result; + } + + // + // Show 2st Short Exit ... + bool ShowShortExit2Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowShortExit1Line == show) + { + return true; + } + + // + mShowShortExit1Line = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCHE" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + // + result = + mLength >= 9 && + mLoopback >= 0; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Loopback ... + mLoopback, + // + // 1st Multiplier ... + mMultiplier1, + // + // 2nd Multiplier ... + mMultiplier2, + // + // Calculation ... + "", + // + // Up Zone Applied to ... + mUpAppliedTo, + // + // Down Zone Applied to ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show 1st Long Exit ... + mShowLongExit1Line, + // + // Show 1st Short Exit ... + mShowShortExit1Line, + // + // Show 2st Long Exit ... + mShowLongExit2Line, + // + // Show 2st Short Exit ... + mShowShortExit2Line + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCHEInputs GetConfig() + { + // + XCHEInputs result; + + // + result.length = mLength; + result.loopback = mLoopback; + result.multiplier1 = mMultiplier1; + result.multiplier2 = mMultiplier2; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showLongExit1Line = mShowLongExit1Line; + result.showShortExit1Line = mShowShortExit1Line; + result.showLongExit2Line = mShowLongExit2Line; + result.showShortExit2Line = mShowShortExit2Line; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCHEInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mLoopback = config.loopback; + mMultiplier1 = config.multiplier1; + mMultiplier2 = config.multiplier2; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowLongExit1Line = config.showLongExit1Line; + mShowShortExit1Line = config.showShortExit1Line; + mShowLongExit2Line = config.showLongExit2Line; + mShowShortExit2Line = config.showShortExit2Line; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // LEVEL 1 .. + + // + // LONG Exit ... + ArraySetAsSeries(longExit1Buffer, true); + CopyBuffer( + mHandler, + XCHE_1ST_LONG_EXIT_LINE, + barIndex, + mLoopbackBars, + longExit1Buffer); + + // + // SHORT Exit ... + ArraySetAsSeries(shortExit1Buffer, true); + CopyBuffer( + mHandler, + XCHE_1ST_SHORT_EXIT_LINE, + barIndex, + mLoopbackBars, + shortExit1Buffer); + + // + // LEVEL 2 .. + + // + // LONG Exit ... + ArraySetAsSeries(longExit2Buffer, true); + CopyBuffer( + mHandler, + XCHE_2ND_LONG_EXIT_LINE, + barIndex, + mLoopbackBars, + longExit2Buffer); + + // + // SHORT Exit ... + ArraySetAsSeries(shortExit2Buffer, true); + CopyBuffer( + mHandler, + XCHE_2ND_SHORT_EXIT_LINE, + barIndex, + mLoopbackBars, + shortExit2Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XCHEInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XCHEInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double longExit1 = longExit1Buffer[barIndex]; + double longExit1Prev = longExit1Buffer[barIndex + 1]; + double shortExit1 = shortExit1Buffer[barIndex]; + double shortExit1Prev = shortExit1Buffer[barIndex + 1]; + + // + double longExit2 = longExit2Buffer[barIndex]; + double longExit2Prev = longExit2Buffer[barIndex + 1]; + double shortExit2 = shortExit2Buffer[barIndex]; + double shortExit2Prev = shortExit2Buffer[barIndex + 1]; + + // + result.longExit1 = longExit1; + result.shortExit1 = shortExit1; + result.longExit2 = longExit2; + result.shortExit2 = shortExit2; + + // + result.isLongExit1Start = + longExit1 != EMPTY_VALUE && + longExit1Prev == EMPTY_VALUE; + + // + result.isShortExit1Start = + shortExit1 != EMPTY_VALUE && + shortExit1Prev == EMPTY_VALUE; + + // + result.isLongExit2Start = + longExit2 != EMPTY_VALUE && + longExit2Prev == EMPTY_VALUE; + + // + result.isShortExit2Start = + shortExit2 != EMPTY_VALUE && + shortExit2Prev == EMPTY_VALUE; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Loopback ... + int mLoopback; + // + // 1st Multiplier ... + double mMultiplier1; + // + // 2nd Multiplier ... + double mMultiplier2; + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show 1st Long Exit ... + bool mShowLongExit1Line; + // + // Show 1st Short Exit ... + bool mShowShortExit1Line; + // + // Show 2st Long Exit ... + bool mShowLongExit2Line; + // + // Show 2st Short Exit ... + bool mShowShortExit2Line; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhk.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhk.helper.class.ex5 new file mode 100644 index 0000000..e06ad5c Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhk.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhk.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhk.helper.class.mq5 new file mode 100644 index 0000000..5244956 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhk.helper.class.mq5 @@ -0,0 +1,432 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHKHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XHKInputs +{ + // + // Presentation ... + bool drawCandles; // Draw Hiken Ashi Candle + bool drawCandleLines; // Show HikenAshi Lines +}; + +// +// Index of Lines ... +enum ENUM_XHK_BUFFERS +{ + // + // Main Requirements ... + XHK_OPEN_LINE = 0, + XHK_HIGH_LINE = 1, + XHK_LOW_LINE = 2, + XHK_CLOSE_LINE = 3, +}; + +// +// Retrieve Info Model ... +struct XHKInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double open; + double high; + double low; + double close; + + // + // Conditions ... + + // + // Detect Candle is Bullish or not ... + bool isBullish; + + // + // Detect Candle is Bearish or not ... + bool isBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXHKHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double openBuffer[]; + double highBuffer[]; + double lowBuffer[]; + double closeBuffer[]; + + // + // Constructor ... + void XSCXHKHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XHKInputs &config // Indicator Properties ... + // + ) : XSCBaseHelper(symbol, period) + { + // + XSCXHKHelper(symbol, + period, + config.drawCandles, + config.drawCandleLines); + } + void XSCXHKHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Presentation ... + // + // Draw Hiken Ashi Candle ... + bool drawCandles = true, + // + // Show HikenAshi Lines ... + bool drawCandleLines = false + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mDrawCandles = drawCandles; + mDrawCandleLines = drawCandleLines; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXHKHelper() + { + } + + // + // START Properties ... + // + + // + // Draw Candles ... + bool DrawCandles( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mDrawCandles == show) + { + return true; + } + + // + mDrawCandles = show; + result = Init(); + + // + return result; + } + + // + // Show HikenAshi Lines ... + bool DrawCandleLines( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mDrawCandleLines == show) + { + return true; + } + + // + mDrawCandleLines = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XHK" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xhk", + // + // Inputs ... + // + // Presentation ... + "", + // + // Draw Hiken Ashi Candle ... + mDrawCandles, + // + // Show HikenAshi Lines ... + mDrawCandleLines + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XHKInputs GetConfig() + { + // + XHKInputs result; + + // + result.drawCandles = mDrawCandles; + result.drawCandleLines = mDrawCandleLines; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XHKInputs &config) + { + // + bool result = false; + + // + mDrawCandles = config.drawCandles; + mDrawCandleLines = config.drawCandleLines; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // OPEN ... + ArraySetAsSeries(openBuffer, true); + CopyBuffer( + mHandler, + XHK_OPEN_LINE, + barIndex, + mLoopbackBars, + openBuffer); + + // + // HIGH ... + ArraySetAsSeries(highBuffer, true); + CopyBuffer( + mHandler, + XHK_HIGH_LINE, + barIndex, + mLoopbackBars, + highBuffer); + + // + // LOW ... + ArraySetAsSeries(lowBuffer, true); + CopyBuffer( + mHandler, + XHK_LOW_LINE, + barIndex, + mLoopbackBars, + lowBuffer); + + // + // CLOSE ... + ArraySetAsSeries(closeBuffer, true); + CopyBuffer( + mHandler, + XHK_CLOSE_LINE, + barIndex, + mLoopbackBars, + closeBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XHKInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XHKInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double open = openBuffer[barIndex]; + double high = highBuffer[barIndex]; + double low = lowBuffer[barIndex]; + double close = closeBuffer[barIndex]; + + // + result.open = open; + result.high = high; + result.low = low; + result.close = close; + + // + result.isBullish = open < close; + result.isBearish = open >= close; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Presentation ... + // + // Draw Hiken Ashi Candle ... + bool mDrawCandles; + // + // Show HikenAshi Lines ... + bool mDrawCandleLines; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhull.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhull.helper.class.ex5 new file mode 100644 index 0000000..11f9685 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhull.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhull.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhull.helper.class.mq5 new file mode 100644 index 0000000..1c975d4 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xhull.helper.class.mq5 @@ -0,0 +1,565 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHULLHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XHULLInputs +{ + // + // Market ... + int length; // Length + double divisor; // Divisor (Speed) + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied to + + // + // Presentation ... + bool showUpZone; // Show Up Zone + bool showDownZone; // Show Down Zone +}; + +// +// Index of Lines ... +enum ENUM_XHULL_BUFFERS +{ + // + // Main Requirements ... + XHULL_UP_ZONE_LINE = 0, + XHULL_UP_ZONE_STATE_LINE = 1, + XHULL_DOWN_ZONE_LINE = 2, + XHULL_DOWN_ZONE_STATE_LINE = 3, +}; + +// +// Hull States ... +enum XHULL_ZONE_STATES +{ + XHULL_STATE_NEUTURAL = 0, + XHULL_STATE_BULLISH = 1, + XHULL_STATE_BEARISH = 2 +}; + +// +// Retrieve Info Model ... +struct XHULLInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double up; + XHULL_ZONE_STATES upState; + double down; + XHULL_ZONE_STATES downState; + + // + // Conditions ... + + // + bool isUpBullish; + bool isUpNeutural; + bool isUpBearish; + + // + bool isUpSwitchedToBullish; + bool isUpSwitchedToBearish; + bool isUpSwitchedToNeutural; + + // + bool isDownBullish; + bool isDownBearish; + bool isDownNeutural; + + // + bool isDownSwitchedToBullish; + bool isDownSwitchedToBearish; + bool isDownSwitchedToNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXHULLHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double upBuffer[]; + double upStateBuffer[]; + double downBuffer[]; + double downStateBuffer[]; + + // + // Constructor ... + void XSCXHULLHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XHULLInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXHULLHelper(symbol, + period, + config.length, + config.divisor, + config.upAppliedTo, + config.downAppliedTo, + config.showUpZone, + config.showDownZone); + } + void XSCXHULLHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int length = 72, + // + // Divisor (Speed) ... + double divisor = 2.0, + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH, + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW, + // + // Presentation ... + // + // Show Up Zone ... + bool showUpZone = true, + // + // Show Down Zone ... + bool showDownZone = true + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mLength = length; + mDivisor = divisor; + mUpAppliedTo = upAppliedTo; + mDownAppliedTo = downAppliedTo; + mShowUpZone = showUpZone; + mShowDownZone = showDownZone; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXHULLHelper() + { + } + + // + // START Properties ... + // + + // + // Show Up Zone ... + bool ShowUpZone( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowUpZone == show) + { + return true; + } + + // + mShowUpZone = show; + result = Init(); + + // + return result; + } + + // + // Show Down Zone ... + bool ShowDownZone( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowDownZone == show) + { + return true; + } + + // + mShowDownZone = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XHULL" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + result = + mLength >= 9 && + mDivisor >= 0.5; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xhull", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Divisor (Speed) ... + mDivisor, + // + // Calculation ... + "", + // + // Up Zone Applied to ... + mUpAppliedTo, + // + // Down Zone Applied to ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show Up Zone ... + mShowUpZone, + // + // Show Down Zone ... + mShowDownZone + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XHULLInputs GetConfig() + { + // + XHULLInputs result; + + // + result.length = mLength; + result.divisor = mDivisor; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showUpZone = mShowUpZone; + result.showDownZone = mShowDownZone; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XHULLInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mDivisor = config.divisor; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowUpZone = config.showUpZone; + mShowDownZone = config.showDownZone; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // UP ... + ArraySetAsSeries(upBuffer, true); + CopyBuffer( + mHandler, + XHULL_UP_ZONE_LINE, + barIndex, + mLoopbackBars, + upBuffer); + + // + // UP State ... + ArraySetAsSeries(upStateBuffer, true); + CopyBuffer( + mHandler, + XHULL_UP_ZONE_STATE_LINE, + barIndex, + mLoopbackBars, + upStateBuffer); + + // + // DOWN ... + ArraySetAsSeries(downBuffer, true); + CopyBuffer( + mHandler, + XHULL_DOWN_ZONE_LINE, + barIndex, + mLoopbackBars, + downBuffer); + + // + // DOWN State ... + ArraySetAsSeries(downStateBuffer, true); + CopyBuffer( + mHandler, + XHULL_DOWN_ZONE_STATE_LINE, + barIndex, + mLoopbackBars, + downStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XHULLInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XHULLInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double up = upBuffer[barIndex]; + XHULL_ZONE_STATES upState = (XHULL_ZONE_STATES)upStateBuffer[barIndex]; + XHULL_ZONE_STATES upStatePrev = (XHULL_ZONE_STATES)upStateBuffer[barIndex + 1]; + + // + double down = downBuffer[barIndex]; + XHULL_ZONE_STATES downState = (XHULL_ZONE_STATES)downStateBuffer[barIndex]; + XHULL_ZONE_STATES downStatePrev = (XHULL_ZONE_STATES)downStateBuffer[barIndex + 1]; + + // + result.up = up; + result.upState = upState; + result.down = down; + result.downState = downState; + + // + result.isUpBullish = upState = XHULL_STATE_BULLISH; + result.isUpBearish = upState = XHULL_STATE_BEARISH; + result.isUpNeutural = upState = XHULL_STATE_NEUTURAL; + + // + result.isUpSwitchedToBullish = upState == XHULL_STATE_BULLISH && + upStatePrev != XHULL_STATE_BULLISH; + result.isUpSwitchedToBearish = upState == XHULL_STATE_BEARISH && + upStatePrev != XHULL_STATE_BEARISH; + result.isUpSwitchedToNeutural = upState == XHULL_STATE_NEUTURAL && + upStatePrev != XHULL_STATE_NEUTURAL; + + // + result.isDownBullish = downState = XHULL_STATE_BULLISH; + result.isDownBearish = downState = XHULL_STATE_BEARISH; + result.isDownNeutural = downState = XHULL_STATE_NEUTURAL; + + // + result.isDownSwitchedToBullish = downState == XHULL_STATE_BULLISH && + downStatePrev != XHULL_STATE_BULLISH; + result.isDownSwitchedToBearish = downState == XHULL_STATE_BEARISH && + downStatePrev != XHULL_STATE_BEARISH; + result.isDownSwitchedToNeutural = downState == XHULL_STATE_NEUTURAL && + downStatePrev != XHULL_STATE_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Divisor (Speed) ... + double mDivisor; + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show Up Zone ... + bool mShowUpZone; + // + // Show Down Zone ... + bool mShowDownZone; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xich.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xich.helper.class.ex5 new file mode 100644 index 0000000..07e4e35 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xich.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xich.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xich.helper.class.mq5 new file mode 100644 index 0000000..af66c56 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xich.helper.class.mq5 @@ -0,0 +1,1052 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXICHHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// Inputs ... +struct XICHInputs +{ + // + // TENKANSEN ... + // Tenkan Sen ... + int tenkanSenLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode; // Calculation Mode + + // + // KIJUNSEN ... + // Kijun Sen ... + int kijunSenLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode; // Calculation Mode + + // + // SENKOUSPANB ... + // Senkou Span B ... + int senkouSpanBLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode; // Calculation Mode + + // + // CHIKOUSPAN ... + // Chikou Span ... + ENUM_APPLIED_PRICE chikuoSpanAppliedTo; // Price Type + + // + // Presentation ... + bool showTenkanSen; // Show Tenkan Sen + bool showKijunSen; // Show Kijun Sen + bool showKijunSenPlus; // Show Kijun Sen + + bool showKijunSenNegative; // Show Kijun Sen - + bool showChikouSpan; // Show Chikou Span + bool showSenkouSpanA; // Show Senkou Span A + bool showSenkouSpanB; // Show Senkou Span B + bool showKumo; // Show Kumo + bool shiftKumo; // Shift Kumo to Future +}; + +// +// Index of Lines ... +enum ENUM_XICH_BUFFERS +{ + // + // Main Requirements ... + XICH_TEANKANSEN_LINE = 0, + XICH_KIJUNSEN_LINE = 1, + XICH_CHIKOUSPAN_LINE = 4, + XICH_SENKOUSPANA_LINE = 5, + XICH_SENKOUSPANB_LINE = 6, +}; + +// +// Retrieve Info Model ... +struct XICHInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double tenkanSen; + double kijunSen; + double chikouSpan; + double senkouSpanA; + double senkouSpanB; + double senkouSpanAFuture; + double senkouSpanBFuture; + + // + // Conditions ... + + // + bool isTenkanSenOverKijunSen; + bool isTenkanSenUnderKijunSen; + bool isTenkanSenCrossedOverKijunSen; + bool isTenkanSenCrossedUnderKijunSen; + + // + bool isKumoBullish; + bool isKumoBearish; + bool isFutureKumoBullish; + bool isFutureKumoBearish; + bool isKumoSwitchedToBullish; + bool isKumoSwitchedToBearish; + bool isFutureKumoSwitchedToBullish; + bool isFutureKumoSwitchedToBearish; + + // + bool isTenkanSenOverSenkouSpanA; + bool isTenkanSenUnderSenkouSpanA; + bool isTenkanSenOverFutureSenkouSpanA; + bool isTenkanSenUnderFutureSenkouSpanA; + bool isTenkanSenCrossedOverSenkouSpanA; + bool isTenkanSenCrossedUnderSenkouSpanA; + bool isTenkanSenCrossedOverFutureSenkouSpanA; + bool isTenkanSenCrossedUnderFutureSenkouSpanA; + + // + bool isTenkanSenOverSenkouSpanB; + bool isTenkanSenUnderSenkouSpanB; + bool isTenkanSenOverFutureSenkouSpanB; + bool isTenkanSenUnderFutureSenkouSpanB; + bool isTenkanSenCrossedOverSenkouSpanB; + bool isTenkanSenCrossedUnderSenkouSpanB; + bool isTenkanSenCrossedOverFutureSenkouSpanB; + bool isTenkanSenCrossedUnderFutureSenkouSpanB; + + // + bool isKijunSenOverSenkouSpanA; + bool isKijunSenUnderSenkouSpanA; + bool isKijunSenOverFutureSenkouSpanA; + bool isKijunSenUnderFutureSenkouSpanA; + bool isKijunSenCrossedOverSenkouSpanA; + bool isKijunSenCrossedUnderSenkouSpanA; + bool isKijunSenCrossedOverFutureSenkouSpanA; + bool isKijunSenCrossedUnderFutureSenkouSpanA; + + // + bool isKijunSenOverSenkouSpanB; + bool isKijunSenUnderSenkouSpanB; + bool isKijunSenOverFutureSenkouSpanB; + bool isKijunSenUnderFutureSenkouSpanB; + bool isKijunSenCrossedOverSenkouSpanB; + bool isKijunSenCrossedUnderSenkouSpanB; + bool isKijunSenCrossedOverFutureSenkouSpanB; + bool isKijunSenCrossedUnderFutureSenkouSpanB; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXICHHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double tenkanSenBuffer[]; + double kijunSenBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; + + // + // Constructor ... + void XSCXICHHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XICHInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXICHHelper(symbol, + period, + config.tenkanSenLength, + config.tenkanSenMode, + config.kijunSenLength, + config.kijunSenMode, + config.senkouSpanBLength, + config.senkouSpanBMode, + config.chikuoSpanAppliedTo, + config.showTenkanSen, + config.showKijunSen, + config.showKijunSenPlus, + config.showKijunSenNegative, + config.showChikouSpan, + config.showSenkouSpanA, + config.showSenkouSpanB, + config.showKumo, + config.shiftKumo); + } + void XSCXICHHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // TENKANSEN ... + // + // Length ... + int tenkanSenLength = 9, + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE, + // + // KIJUNSEN ... + // + // Length ... + int kijunSenLength = 26, + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE, + // + // SENKOUSPANB ... + // + // Length ... + int senkouSpanBLength = 52, + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE, + // + // CHIKOUSPAN ... + // + // Price Type ... + ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE, + // + // Presentation ... + // + // Show Tenkan Sen ... + bool showTenkanSen = true, + // + // Show Kijun Sen ... + bool showKijunSen = true, + // + // Show Kijun Sen + ... + bool showKijunSenPlus = false, + // + // Show Kijun Sen - ... + bool showKijunSenNegative = false, + // + // Show Chikou Span ... + bool showChikouSpan = true, + // + // Show Senkou Span A ... + bool showSenkouSpanA = true, + // + // Show Senkou Span B ... + bool showSenkouSpanB = true, + // + // Show Kumo ... + bool showKumo = true, + // + // Shift Kumo to Future ... + bool shiftKumo = true + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mTenkanSenLength = tenkanSenLength; + mTenkanSenMode = tenkanSenMode; + mKijunSenLength = kijunSenLength; + mKijunSenMode = kijunSenMode; + mSenkouSpanBLength = senkouSpanBLength; + mSenkouSpanBMode = senkouSpanBMode; + mChikuoSpanAppliedTo = chikuoSpanAppliedTo; + mShowTenkanSen = showTenkanSen; + mShowKijunSen = showKijunSen; + mShowKijunSenPlus = showKijunSenPlus; + mShowKijunSenNegative = showKijunSenNegative; + mShowChikouSpan = showChikouSpan; + mShowSenkouSpanA = showSenkouSpanA; + mShowSenkouSpanB = showSenkouSpanB; + mShowKumo = showKumo; + mShiftKumo = shiftKumo; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXICHHelper() + { + } + + // + // START Properties ... + // + + // + // Show Tenkan Sen ... + bool ShowTenkanSen( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowTenkanSen == show) + { + return true; + } + + // + mShowTenkanSen = show; + result = Init(); + + // + return result; + } + + // + // Show Kijun Sen ... + bool ShowKijunSen( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowKijunSen == show) + { + return true; + } + + // + mShowKijunSen = show; + result = Init(); + + // + return result; + } + + // + // Show Chikou Span ... + bool ShowChikouSpan( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowChikouSpan == show) + { + return true; + } + + // + mShowChikouSpan = show; + result = Init(); + + // + return result; + } + + // + // Show Senkou Span A ... + bool ShowSenkouSpanA( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSenkouSpanA == show) + { + return true; + } + + // + mShowSenkouSpanA = show; + result = Init(); + + // + return result; + } + + // + // Show Senkou Span B ... + bool ShowSenkouSpanB( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSenkouSpanB == show) + { + return true; + } + + // + mShowSenkouSpanB = show; + result = Init(); + + // + return result; + } + + // + // Show Kumo ... + bool ShowKumo( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowKumo == show) + { + return true; + } + + // + mShowKumo = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XICH" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + result = + (mTenkanSenLength > 2 && + mKijunSenLength > mTenkanSenLength && + mSenkouSpanBLength > mKijunSenLength); + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xich", + // + // Inputs ... + // + // TENKANSEN ... + "", + // + // Length ... + mTenkanSenLength, + // + // Calculation Mode ... + mTenkanSenMode, + // + // KIJUNSEN ... + "", + // + // Length ... + mKijunSenLength, + // + // Calculation Mode ... + mKijunSenMode, + // + // SENKOUSPANA ... + "", + // + // Length ... + mSenkouSpanBLength, + // + // Calculation Mode ... + mSenkouSpanBMode, + // + // CHIKOUSPAN ... + "", + // + // Price Type ... + mChikuoSpanAppliedTo, + // + // PRESENTATION ... + "", + // + // Show Tenkan Sen ... + mShowTenkanSen, + // + // Show Kijun Sen ... + mShowKijunSen, + // + // Show Kijun Sen + ... + mShowKijunSenPlus, + // + // Show Kijun Sen - ... + mShowKijunSenNegative, + // + // Show Chikou Span ... + mShowChikouSpan, + // + // Show Senkou Span A ... + mShowSenkouSpanA, + // + // Show Senkou Span B ... + mShowSenkouSpanB, + // + // Show Kumo ... + mShowKumo, + // + // Shift Kumo to Future ... + mShiftKumo + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XICHInputs GetConfig() + { + // + XICHInputs result; + + // + result.tenkanSenLength = mTenkanSenLength; + result.tenkanSenMode = mTenkanSenMode; + result.kijunSenLength = mKijunSenLength; + result.kijunSenMode = mKijunSenMode; + result.senkouSpanBLength = mSenkouSpanBLength; + result.senkouSpanBMode = mSenkouSpanBMode; + result.chikuoSpanAppliedTo = mChikuoSpanAppliedTo; + result.showTenkanSen = mShowTenkanSen; + result.showKijunSen = mShowKijunSen; + result.showKijunSenPlus = mShowKijunSenPlus; + result.showKijunSenNegative = mShowKijunSenNegative; + result.showChikouSpan = mShowChikouSpan; + result.showSenkouSpanA = mShowSenkouSpanA; + result.showSenkouSpanB = mShowSenkouSpanB; + result.showKumo = mShowKumo; + result.shiftKumo = mShiftKumo; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XICHInputs &config) + { + // + bool result = false; + + // + mTenkanSenLength = config.tenkanSenLength; + mTenkanSenMode = config.tenkanSenMode; + mKijunSenLength = config.kijunSenLength; + mKijunSenMode = config.kijunSenMode; + mSenkouSpanBLength = config.senkouSpanBLength; + mSenkouSpanBMode = config.senkouSpanBMode; + mChikuoSpanAppliedTo = config.chikuoSpanAppliedTo; + mShowTenkanSen = config.showTenkanSen; + mShowKijunSen = config.showKijunSen; + mShowKijunSenPlus = config.showKijunSenPlus; + mShowKijunSenNegative = config.showKijunSenNegative; + mShowChikouSpan = config.showChikouSpan; + mShowSenkouSpanA = config.showSenkouSpanA; + mShowSenkouSpanB = config.showSenkouSpanB; + mShowKumo = config.showKumo; + mShiftKumo = config.shiftKumo; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // Since Ichimoku Has Some Issues ... + mLoopbackBars = 52; + + // + // TENKANSEN ... + ArraySetAsSeries(tenkanSenBuffer, true); + CopyBuffer( + mHandler, + XICH_TEANKANSEN_LINE, + barIndex, + mLoopbackBars, + tenkanSenBuffer); + + // + // KIJUNSEN ... + ArraySetAsSeries(kijunSenBuffer, true); + CopyBuffer( + mHandler, + XICH_KIJUNSEN_LINE, + barIndex, + mLoopbackBars, + kijunSenBuffer); + + // + // CHIKOUSPAN ... + ArraySetAsSeries(chikouSpanBuffer, true); + CopyBuffer( + mHandler, + XICH_CHIKOUSPAN_LINE, + barIndex + mKijunSenLength + 1, + mLoopbackBars, + chikouSpanBuffer); + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + CopyBuffer( + mHandler, + XICH_SENKOUSPANA_LINE, + -1 * (barIndex + mKijunSenLength), + mLoopbackBars, + senkouSpanABuffer); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + CopyBuffer( + mHandler, + XICH_SENKOUSPANB_LINE, + -1 * (barIndex + mKijunSenLength), + mLoopbackBars, + senkouSpanBBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XICHInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XICHInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double tenkanSen = tenkanSenBuffer[barIndex]; + double tenkanSenPrev = tenkanSenBuffer[barIndex + 1]; + + // + double kijunSen = kijunSenBuffer[barIndex]; + double kijunSenPrev = kijunSenBuffer[barIndex + 1]; + + // + double chikouSpan = chikouSpanBuffer[barIndex + mKijunSenLength]; + double chikouSpanPrev = chikouSpanBuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanA = senkouSpanABuffer[barIndex + mKijunSenLength]; + double senkouSpanAPrev = senkouSpanABuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanB = senkouSpanBBuffer[barIndex + mKijunSenLength]; + double senkouSpanBPrev = senkouSpanBBuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanAFuture = senkouSpanABuffer[barIndex]; + double senkouSpanAFuturePrev = senkouSpanABuffer[barIndex + 1]; + + // + double senkouSpanBFuture = senkouSpanBBuffer[barIndex]; + double senkouSpanBFuturePrev = senkouSpanBBuffer[barIndex + 1]; + + // + bool isTenkanSenOverKijunSen = + tenkanSen > kijunSen; + bool isTenkanSenUnderKijunSen = + tenkanSen < kijunSen; + bool isTenkanSenCrossedOverKijunSen = + tenkanSen > kijunSen && + tenkanSenPrev <= kijunSenPrev; + bool isTenkanSenCrossedUnderKijunSen = + tenkanSen < kijunSen && + tenkanSenPrev >= kijunSenPrev; + + // + bool isKumoBullish = + senkouSpanA > senkouSpanB; + bool isKumoBearish = + senkouSpanA < senkouSpanB; + bool isFutureKumoBullish = + senkouSpanAFuture > senkouSpanBFuture; + bool isFutureKumoBearish = + senkouSpanAFuture < senkouSpanBFuture; + bool isKumoSwitchedToBullish = + senkouSpanA > senkouSpanB && + senkouSpanAPrev <= senkouSpanBPrev; + bool isKumoSwitchedToBearish = + senkouSpanA < senkouSpanB && + senkouSpanAPrev >= senkouSpanBPrev; + bool isFutureKumoSwitchedToBullish = + senkouSpanAFuture > senkouSpanBFuture && + senkouSpanAFuturePrev <= senkouSpanBFuturePrev; + bool isFutureKumoSwitchedToBearish = + senkouSpanAFuture < senkouSpanBFuture && + senkouSpanAFuturePrev >= senkouSpanBFuturePrev; + + // + bool isTenkanSenOverSenkouSpanA = + tenkanSen > senkouSpanA; + bool isTenkanSenUnderSenkouSpanA = + tenkanSen < senkouSpanA; + bool isTenkanSenOverFutureSenkouSpanA = + tenkanSen > senkouSpanAFuture; + bool isTenkanSenUnderFutureSenkouSpanA = + tenkanSen < senkouSpanAFuture; + bool isTenkanSenCrossedOverSenkouSpanA = + tenkanSen > senkouSpanA && + tenkanSenPrev <= senkouSpanAPrev; + bool isTenkanSenCrossedUnderSenkouSpanA = + tenkanSen < senkouSpanA && + tenkanSenPrev >= senkouSpanAPrev; + bool isTenkanSenCrossedOverFutureSenkouSpanA = + tenkanSen > senkouSpanAFuture && + tenkanSenPrev <= senkouSpanAFuturePrev; + bool isTenkanSenCrossedUnderFutureSenkouSpanA = + tenkanSen < senkouSpanAFuture && + tenkanSenPrev >= senkouSpanAFuturePrev; + + // + bool isTenkanSenOverSenkouSpanB = + tenkanSen > senkouSpanB; + bool isTenkanSenUnderSenkouSpanB = + tenkanSen < senkouSpanB; + bool isTenkanSenOverFutureSenkouSpanB = + tenkanSen > senkouSpanBFuture; + bool isTenkanSenUnderFutureSenkouSpanB = + tenkanSen < senkouSpanBFuture; + bool isTenkanSenCrossedOverSenkouSpanB = + tenkanSen > senkouSpanB && + tenkanSenPrev <= senkouSpanBPrev; + bool isTenkanSenCrossedUnderSenkouSpanB = + tenkanSen < senkouSpanB && + tenkanSenPrev >= senkouSpanBPrev; + bool isTenkanSenCrossedOverFutureSenkouSpanB = + tenkanSen > senkouSpanBFuture && + tenkanSenPrev <= senkouSpanBFuturePrev; + bool isTenkanSenCrossedUnderFutureSenkouSpanB = + tenkanSen < senkouSpanBFuture && + tenkanSenPrev >= senkouSpanBFuturePrev; + + // + bool isKijunSenOverSenkouSpanA = + kijunSen > senkouSpanA; + bool isKijunSenUnderSenkouSpanA = + kijunSen < senkouSpanA; + bool isKijunSenOverFutureSenkouSpanA = + kijunSen > senkouSpanAFuture; + bool isKijunSenUnderFutureSenkouSpanA = + kijunSen < senkouSpanAFuture; + bool isKijunSenCrossedOverSenkouSpanA = + kijunSen > senkouSpanA && + kijunSenPrev <= senkouSpanAPrev; + bool isKijunSenCrossedUnderSenkouSpanA = + kijunSen < senkouSpanA && + kijunSenPrev >= senkouSpanAPrev; + bool isKijunSenCrossedOverFutureSenkouSpanA = + kijunSen > senkouSpanAFuture && + kijunSenPrev <= senkouSpanAFuturePrev; + bool isKijunSenCrossedUnderFutureSenkouSpanA = + kijunSen < senkouSpanAFuture && + kijunSenPrev >= senkouSpanAFuturePrev; + + // + bool isKijunSenOverSenkouSpanB = + kijunSen > senkouSpanB; + bool isKijunSenUnderSenkouSpanB = + kijunSen < senkouSpanB; + bool isKijunSenOverFutureSenkouSpanB = + kijunSen > senkouSpanBFuture; + bool isKijunSenUnderFutureSenkouSpanB = + kijunSen < senkouSpanBFuture; + bool isKijunSenCrossedOverSenkouSpanB = + kijunSen > senkouSpanB && + kijunSenPrev <= senkouSpanB; + bool isKijunSenCrossedUnderSenkouSpanB = + kijunSen < senkouSpanB && + kijunSenPrev >= senkouSpanB; + bool isKijunSenCrossedOverFutureSenkouSpanB = + kijunSen > senkouSpanBFuture && + kijunSenPrev <= senkouSpanBFuturePrev; + bool isKijunSenCrossedUnderFutureSenkouSpanB = + kijunSen < senkouSpanBFuture && + kijunSenPrev >= senkouSpanBFuturePrev; + + // + result.tenkanSen = tenkanSen; + result.kijunSen = kijunSen; + result.chikouSpan = chikouSpan; + result.senkouSpanA = senkouSpanA; + result.senkouSpanB = senkouSpanB; + result.senkouSpanAFuture = senkouSpanAFuture; + result.senkouSpanBFuture = senkouSpanBFuture; + + // + result.isTenkanSenOverKijunSen = isTenkanSenOverKijunSen; + result.isTenkanSenUnderKijunSen = isTenkanSenUnderKijunSen; + result.isTenkanSenCrossedOverKijunSen = isTenkanSenCrossedOverKijunSen; + result.isTenkanSenCrossedUnderKijunSen = isTenkanSenCrossedUnderKijunSen; + + // + result.isKumoBullish = isKumoBullish; + result.isKumoBearish = isKumoBearish; + result.isFutureKumoBullish = isFutureKumoBullish; + result.isFutureKumoBearish = isFutureKumoBearish; + result.isKumoSwitchedToBullish = isKumoSwitchedToBullish; + result.isKumoSwitchedToBearish = isKumoSwitchedToBearish; + result.isFutureKumoSwitchedToBullish = isFutureKumoSwitchedToBullish; + result.isFutureKumoSwitchedToBearish = isFutureKumoSwitchedToBearish; + + // + result.isTenkanSenOverSenkouSpanA = isTenkanSenOverSenkouSpanA; + result.isTenkanSenUnderSenkouSpanA = isTenkanSenUnderSenkouSpanA; + result.isTenkanSenOverFutureSenkouSpanA = isTenkanSenOverFutureSenkouSpanA; + result.isTenkanSenUnderFutureSenkouSpanA = isTenkanSenUnderFutureSenkouSpanA; + result.isTenkanSenCrossedOverSenkouSpanA = isTenkanSenCrossedOverSenkouSpanA; + result.isTenkanSenCrossedUnderSenkouSpanA = isTenkanSenCrossedUnderSenkouSpanA; + result.isTenkanSenCrossedOverFutureSenkouSpanA = isTenkanSenCrossedOverFutureSenkouSpanA; + result.isTenkanSenCrossedUnderFutureSenkouSpanA = isTenkanSenCrossedUnderFutureSenkouSpanA; + + // + result.isTenkanSenOverSenkouSpanB = isTenkanSenOverSenkouSpanB; + result.isTenkanSenUnderSenkouSpanB = isTenkanSenUnderSenkouSpanB; + result.isTenkanSenOverFutureSenkouSpanB = isTenkanSenOverFutureSenkouSpanB; + result.isTenkanSenUnderFutureSenkouSpanB = isTenkanSenUnderFutureSenkouSpanB; + result.isTenkanSenCrossedOverSenkouSpanB = isTenkanSenCrossedOverSenkouSpanB; + result.isTenkanSenCrossedUnderSenkouSpanB = isTenkanSenCrossedUnderSenkouSpanB; + result.isTenkanSenCrossedOverFutureSenkouSpanB = isTenkanSenCrossedOverFutureSenkouSpanB; + result.isTenkanSenCrossedUnderFutureSenkouSpanB = isTenkanSenCrossedUnderFutureSenkouSpanB; + + // + result.isKijunSenOverSenkouSpanA = isKijunSenOverSenkouSpanA; + result.isKijunSenUnderSenkouSpanA = isKijunSenUnderSenkouSpanA; + result.isKijunSenOverFutureSenkouSpanA = isKijunSenOverFutureSenkouSpanA; + result.isKijunSenUnderFutureSenkouSpanA = isKijunSenUnderFutureSenkouSpanA; + result.isKijunSenCrossedOverSenkouSpanA = isKijunSenCrossedOverSenkouSpanA; + result.isKijunSenCrossedUnderSenkouSpanA = isKijunSenCrossedUnderSenkouSpanA; + result.isKijunSenCrossedOverFutureSenkouSpanA = isKijunSenCrossedOverFutureSenkouSpanA; + result.isKijunSenCrossedUnderFutureSenkouSpanA = isKijunSenCrossedUnderFutureSenkouSpanA; + + // + result.isKijunSenOverSenkouSpanB = isKijunSenOverSenkouSpanB; + result.isKijunSenUnderSenkouSpanB = isKijunSenUnderSenkouSpanB; + result.isKijunSenOverFutureSenkouSpanB = isKijunSenOverFutureSenkouSpanB; + result.isKijunSenUnderFutureSenkouSpanB = isKijunSenUnderFutureSenkouSpanB; + result.isKijunSenCrossedOverSenkouSpanB = isKijunSenCrossedOverSenkouSpanB; + result.isKijunSenCrossedUnderSenkouSpanB = isKijunSenCrossedUnderSenkouSpanB; + result.isKijunSenCrossedOverFutureSenkouSpanB = isKijunSenCrossedOverFutureSenkouSpanB; + result.isKijunSenCrossedUnderFutureSenkouSpanB = isKijunSenCrossedUnderFutureSenkouSpanB; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // TENKANSEN ... + // + // Length ... + int mTenkanSenLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mTenkanSenMode; + // + // KIJUNSEN ... + // + // Length ... + int mKijunSenLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mKijunSenMode; + // + // SENKOUSPANB ... + // + // Length ... + int mSenkouSpanBLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mSenkouSpanBMode; + // + // CHIKOUSPAN ... + // + // Price Type ... + ENUM_APPLIED_PRICE mChikuoSpanAppliedTo; + // + // Presentation ... + // + // Show Tenkan Sen ... + bool mShowTenkanSen; + // + // Show Kijun Sen ... + bool mShowKijunSen; + // + // Show Kijun Sen + ... + bool mShowKijunSenPlus; + // + // Show Kijun Sen - ... + bool mShowKijunSenNegative; + // + // Show Chikou Span ... + bool mShowChikouSpan; + // + // Show Senkou Span A ... + bool mShowSenkouSpanA; + // + // Show Senkou Span B ... + bool mShowSenkouSpanB; + // + // Show Kumo ... + bool mShowKumo; + // + // Shift Kumo to Future ... + bool mShiftKumo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 new file mode 100644 index 0000000..8204095 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 new file mode 100644 index 0000000..ed790b5 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 @@ -0,0 +1,908 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMRBHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XMRBInputs +{ + // + // Ribbon 1 ... + int fast1Length; // Fast + int slow1Length; // Slow + + // + // Ribbon 2 ... + int fast2Length; // Fast + int slow2Length; // Slow + + // + // Ribbon 3 ... + int fast3Length; // Fast + int slow3Length; // Slow + + // + // Ribbon 4 ... + int fast4Length; // Fast + int slow4Length; // Slow + + // + // Ribbon 5 ... + int fast5Length; // Fast + int slow5Length; // Slow + + // + // Calculation ... + ENUM_MA_METHOD ribbonMode; // Mode + ENUM_APPLIED_PRICE ribbonAppliedTo; // Applied To + + // + // Presentation ... + bool showFastMa; // Show Fast + bool showSlowMa; // Show Slow + bool showRibbon; // Show Ribbon +}; + +// +// Index of Lines ... +enum ENUM_XMRB_BUFFERS +{ + // + // Main Requirements ... + XMRB_FAST_LINE = 0, + XMRB_SLOW_LINE = 1, + // + // RIBBON 1 ... + XMRB_R1_FAST_LINE = 2, + XMRB_R1_SLOW_LINE = 3, + // + // RIBBON 2 ... + XMRB_R2_FAST_LINE = 4, + XMRB_R2_SLOW_LINE = 5, + // + // RIBBON 3 ... + XMRB_R3_FAST_LINE = 6, + XMRB_R3_SLOW_LINE = 7, + // + // RIBBON 4 ... + XMRB_R4_FAST_LINE = 8, + XMRB_R4_SLOW_LINE = 9, + // + // RIBBON 5 ... + XMRB_R5_FAST_LINE = 10, + XMRB_R5_SLOW_LINE = 11, +}; + +// +// Retrieve Info Model ... +struct XMRBInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double fast; + double slow; + double fastR1; + double slowR1; + double fastR2; + double slowR2; + double fastR3; + double slowR3; + double fastR4; + double slowR4; + double fastR5; + double slowR5; + + // + // Conditions ... + + // + bool isFastOverSlow; + bool isFastCrossedOverSlow; + bool isFastUnderSlow; + bool isFastCrossedUnderSlow; + + // + bool isR1FastOverSlow; + bool isR1FastCrossedOverSlow; + bool isR1FastUnderSlow; + bool isR1FastCrossedUnderSlow; + + // + bool isR2FastOverSlow; + bool isR2FastCrossedOverSlow; + bool isR2FastUnderSlow; + bool isR2FastCrossedUnderSlow; + + // + bool isR3FastOverSlow; + bool isR3FastCrossedOverSlow; + bool isR3FastUnderSlow; + bool isR3FastCrossedUnderSlow; + + // + bool isR4FastOverSlow; + bool isR4FastCrossedOverSlow; + bool isR4FastUnderSlow; + bool isR4FastCrossedUnderSlow; + + // + bool isR5FastOverSlow; + bool isR5FastCrossedOverSlow; + bool isR5FastUnderSlow; + bool isR5FastCrossedUnderSlow; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXMRBHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double fastBuffer[]; + double slowBuffer[]; + double fastR1Buffer[]; + double slowR1Buffer[]; + double fastR2Buffer[]; + double slowR2Buffer[]; + double fastR3Buffer[]; + double slowR3Buffer[]; + double fastR4Buffer[]; + double slowR4Buffer[]; + double fastR5Buffer[]; + double slowR5Buffer[]; + + // + // Constructor ... + void XSCXMRBHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XMRBInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXMRBHelper(symbol, + period, + config.fast1Length, + config.slow1Length, + config.fast2Length, + config.slow2Length, + config.fast3Length, + config.slow3Length, + config.fast4Length, + config.slow4Length, + config.fast5Length, + config.slow5Length, + config.ribbonMode, + config.ribbonAppliedTo, + config.showFastMa, + config.showSlowMa, + config.showRibbon); + } + void XSCXMRBHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Ribbon 1 ... + int fast1Length = 3, + int slow1Length = 5, + // + // Ribbon 2 ... + int fast2Length = 8, + int slow2Length = 13, + // + // Ribbon 3 ... + int fast3Length = 21, + int slow3Length = 34, + // + // Ribbon 4 ... + int fast4Length = 55, + int slow4Length = 89, + // + // Ribbon 5 ... + int fast5Length = 144, + int slow5Length = 233, + // + // Calculation ... + // + // Mode ... + ENUM_MA_METHOD ribbonMode = MODE_EMA, + // + // Applied To ... + ENUM_APPLIED_PRICE ribbonAppliedTo = PRICE_CLOSE, + // + // Presentation ... + // + // Show Fast ... + bool showFastMa = true, + // + // Show Slow ... + bool showSlowMa = true, + // + // Show Ribbon ... + bool showRibbon = false + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mFast1Length = fast1Length; + mSlow1Length = slow1Length; + mFast2Length = fast2Length; + mSlow2Length = slow2Length; + mFast3Length = fast3Length; + mSlow3Length = slow3Length; + mFast4Length = fast4Length; + mSlow4Length = slow4Length; + mFast5Length = fast5Length; + mSlow5Length = slow5Length; + mRibbonMode = ribbonMode; + mRibbonAppliedTo = ribbonAppliedTo; + mShowFastMa = showFastMa; + mShowSlowMa = showSlowMa; + mShowRibbon = showRibbon; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXMRBHelper() + { + } + + // + // START Properties ... + // + + // + // Show Fast ... + bool ShowFast( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowFastMa == show) + { + return true; + } + + // + mShowFastMa = show; + result = Init(); + + // + return result; + } + + // + // Show Slow ... + bool ShowSlow( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSlowMa == show) + { + return true; + } + + // + mShowSlowMa = show; + result = Init(); + + // + return result; + } + + // + // Show Ribbon ... + bool ShowRibbon( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowRibbon == show) + { + return true; + } + + // + mShowRibbon = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XMRB" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + result = + // + (mFast1Length > 2 && + mFast2Length > mFast1Length && + mFast3Length > mFast2Length && + mFast4Length > mFast3Length && + mFast5Length > mFast4Length && + mSlow1Length > mFast1Length && + mSlow2Length > mFast2Length && + mFast3Length > mFast3Length && + mSlow4Length > mFast4Length && + mSlow5Length > mFast5Length && + mSlow2Length > mSlow1Length && + mFast3Length > mSlow2Length && + mSlow4Length > mFast3Length && + mSlow5Length > mSlow4Length + // + ) + // + ; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xmrb", + // + // Inputs ... + // + // Ribbon 1 ... + "", + mFast1Length, + mSlow1Length, + // + // Ribbon 2 ... + "", + mFast2Length, + mSlow2Length, + // + // Ribbon 3 ... + "", + mFast3Length, + mSlow3Length, + // + // Ribbon 4 ... + "", + mFast4Length, + mSlow4Length, + // + // Ribbon 5 ... + "", + mFast5Length, + mSlow5Length, + // + // Calculation ... + "", + // + // Mode ... + mRibbonMode, + // + // Applied To ... + mRibbonAppliedTo, + // + // Presentation ... + "", + // + // Show Fast ... + mShowFastMa, + // + // Show Slow ... + mShowSlowMa, + // + // Show Ribbon ... + mShowRibbon + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XMRBInputs GetConfig() + { + // + XMRBInputs result; + + // + result.fast1Length = mFast1Length; + result.slow1Length = mSlow1Length; + result.fast2Length = mFast2Length; + result.slow2Length = mSlow2Length; + result.fast3Length = mFast3Length; + result.slow3Length = mSlow3Length; + result.fast4Length = mFast4Length; + result.slow4Length = mSlow4Length; + result.fast5Length = mFast5Length; + result.slow5Length = mSlow5Length; + result.ribbonMode = mRibbonMode; + result.ribbonAppliedTo = mRibbonAppliedTo; + result.showFastMa = mShowFastMa; + result.showSlowMa = mShowSlowMa; + result.showRibbon = mShowRibbon; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XMRBInputs &config) + { + // + bool result = false; + + // + mFast1Length = config.fast1Length; + mSlow1Length = config.slow1Length; + mFast2Length = config.fast2Length; + mSlow2Length = config.slow2Length; + mFast3Length = config.fast3Length; + mSlow3Length = config.slow3Length; + mFast4Length = config.fast4Length; + mSlow4Length = config.slow4Length; + mFast5Length = config.fast5Length; + mSlow5Length = config.slow5Length; + mRibbonMode = config.ribbonMode; + mRibbonAppliedTo = config.ribbonAppliedTo; + mShowFastMa = config.showFastMa; + mShowSlowMa = config.showSlowMa; + mShowRibbon = config.showRibbon; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // FAST ... + ArraySetAsSeries(fastBuffer, true); + CopyBuffer( + mHandler, + XMRB_FAST_LINE, + barIndex, + mLoopbackBars, + fastBuffer); + + // + // SLOW ... + ArraySetAsSeries(slowBuffer, true); + CopyBuffer( + mHandler, + XMRB_SLOW_LINE, + barIndex, + mLoopbackBars, + slowBuffer); + + // + // RIBBON 1 ... + + // + // FAST ... + ArraySetAsSeries(fastR1Buffer, true); + CopyBuffer( + mHandler, + XMRB_R1_FAST_LINE, + barIndex, + mLoopbackBars, + fastR1Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR1Buffer, true); + CopyBuffer( + mHandler, + XMRB_R1_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR1Buffer); + + // + // RIBBON 2 ... + + // + // FAST ... + ArraySetAsSeries(fastR2Buffer, true); + CopyBuffer( + mHandler, + XMRB_R2_FAST_LINE, + barIndex, + mLoopbackBars, + fastR2Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR2Buffer, true); + CopyBuffer( + mHandler, + XMRB_R2_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR2Buffer); + + // + // RIBBON 3 ... + + // + // FAST ... + ArraySetAsSeries(fastR3Buffer, true); + CopyBuffer( + mHandler, + XMRB_R3_FAST_LINE, + barIndex, + mLoopbackBars, + fastR3Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR3Buffer, true); + CopyBuffer( + mHandler, + XMRB_R3_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR3Buffer); + + // + // RIBBON 4 ... + + // + // FAST ... + ArraySetAsSeries(fastR4Buffer, true); + CopyBuffer( + mHandler, + XMRB_R4_FAST_LINE, + barIndex, + mLoopbackBars, + fastR4Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR4Buffer, true); + CopyBuffer( + mHandler, + XMRB_R4_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR4Buffer); + + // + // RIBBON 5 ... + + // + // FAST ... + ArraySetAsSeries(fastR5Buffer, true); + CopyBuffer( + mHandler, + XMRB_R5_FAST_LINE, + barIndex, + mLoopbackBars, + fastR5Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR5Buffer, true); + CopyBuffer( + mHandler, + XMRB_R5_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR5Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XMRBInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XMRBInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double fast = fastBuffer[barIndex]; + double fastPrev = fastBuffer[barIndex + 1]; + double slow = slowBuffer[barIndex]; + double slowPrev = slowBuffer[barIndex + 1]; + double fastR1 = fastR1Buffer[barIndex]; + double fastR1Prev = fastR1Buffer[barIndex + 1]; + double slowR1 = slowR1Buffer[barIndex]; + double slowR1Prev = slowR1Buffer[barIndex + 1]; + double fastR2 = fastR2Buffer[barIndex]; + double fastR2Prev = fastR2Buffer[barIndex + 1]; + double slowR2 = slowR2Buffer[barIndex]; + double slowR2Prev = slowR2Buffer[barIndex + 1]; + double fastR3 = fastR3Buffer[barIndex]; + double fastR3Prev = fastR3Buffer[barIndex + 1]; + double slowR3 = slowR3Buffer[barIndex]; + double slowR3Prev = slowR3Buffer[barIndex + 1]; + double fastR4 = fastR4Buffer[barIndex]; + double fastR4Prev = fastR4Buffer[barIndex + 1]; + double slowR4 = slowR4Buffer[barIndex]; + double slowR4Prev = slowR4Buffer[barIndex + 1]; + double fastR5 = fastR5Buffer[barIndex]; + double fastR5Prev = fastR5Buffer[barIndex + 1]; + double slowR5 = slowR5Buffer[barIndex]; + double slowR5Prev = slowR5Buffer[barIndex + 1]; + + // + result.fast = fast; + result.slow = slow; + result.fastR1 = fastR1; + result.slowR1 = slowR1; + result.fastR2 = fastR2; + result.slowR2 = slowR2; + result.fastR3 = fastR3; + result.slowR3 = slowR3; + result.fastR4 = fastR4; + result.slowR4 = slowR4; + result.fastR5 = fastR5; + result.slowR5 = slowR5; + + // + result.isFastOverSlow = + fast > slow; + result.isFastCrossedOverSlow = + fast > slow && fastPrev <= slowPrev; + result.isFastUnderSlow = + fast < slow; + result.isFastCrossedUnderSlow = + fast < slow && fastPrev >= slowPrev; + + // + result.isR1FastOverSlow = + fastR1 > slowR1; + result.isR1FastCrossedOverSlow = + fastR1 > slowR1 && fastR1Prev <= slowR1Prev; + result.isR1FastUnderSlow = + fastR1 < slowR1; + result.isR1FastCrossedUnderSlow = + fastR1 < slowR1 && fastR1Prev >= slowR1Prev; + + // + result.isR2FastOverSlow = + fastR2 > slowR2; + result.isR2FastCrossedOverSlow = + fastR2 > slowR2 && fastR2Prev <= slowR2Prev; + result.isR2FastUnderSlow = + fastR2 < slowR2; + result.isR2FastCrossedUnderSlow = + fastR2 < slowR2 && fastR2Prev >= slowR2Prev; + + // + result.isR3FastOverSlow = + fastR3 > slowR3; + result.isR3FastCrossedOverSlow = + fastR3 > slowR3 && fastR3Prev <= slowR3Prev; + result.isR3FastUnderSlow = + fastR3 < slowR3; + result.isR3FastCrossedUnderSlow = + fastR3 < slowR3 && fastR3Prev >= slowR3Prev; + + // + result.isR4FastOverSlow = + fastR4 > slowR4; + result.isR4FastCrossedOverSlow = + fastR4 > slowR4 && fastR4Prev <= slowR4Prev; + result.isR4FastUnderSlow = + fastR4 < slowR4; + result.isR4FastCrossedUnderSlow = + fastR4 < slowR4 && fastR4Prev >= slowR4Prev; + + // + result.isR5FastOverSlow = + fastR5 > slowR5; + result.isR5FastCrossedOverSlow = + fastR5 > slowR5 && fastR5Prev <= slowR5Prev; + result.isR5FastUnderSlow = + fastR5 < slowR5; + result.isR5FastCrossedUnderSlow = + fastR5 < slowR5 && fastR5Prev >= slowR5Prev; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Ribbon 1 ... + int mFast1Length; + int mSlow1Length; + // + // Ribbon 2 ... + int mFast2Length; + int mSlow2Length; + // + // Ribbon 3 ... + int mFast3Length; + int mSlow3Length; + // + // Ribbon 4 ... + int mFast4Length; + int mSlow4Length; + // + // Ribbon 5 ... + int mFast5Length; + int mSlow5Length; + // + // Calculation ... + // + // Mode ... + ENUM_MA_METHOD mRibbonMode; + // + // Applied To ... + ENUM_APPLIED_PRICE mRibbonAppliedTo; + // + // Presentation ... + // + // Show Fast ... + bool mShowFastMa; + // + // Show Slow ... + bool mShowSlowMa; + // + // Show Ribbon ... + bool mShowRibbon; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xpv.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xpv.helper.class.ex5 new file mode 100644 index 0000000..fbf479a Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xpv.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xpv.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xpv.helper.class.mq5 new file mode 100644 index 0000000..6b3c4c0 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xpv.helper.class.mq5 @@ -0,0 +1,518 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXPVHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XPVInputs +{ + // + // Makret Cycles ... + int shortLength; // Short Length + int mediumLength; // Medium Length + int longLength; // Long Length + int hindLength; // Hind Length + + // + // Detection Modes ... + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Presentation ... + bool showPeaksAndVales; // Show Peaks and Vales + bool showLevels; // Show Levels +}; + +// +// Index of Lines ... +enum ENUM_XPV_BUFFERS +{ + // + // Main Requirements ... + XPV_PEAKS_LINE = 0, + XPV_VALES_LINE = 1, +}; + +// +// Retrieve Info Model ... +struct XPVInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double peak; + double vale; + + // + // Conditions ... + + // + // Determines New Peaks Happens ... + bool isNewPeak; + + // + // Determines New Vales Happens ... + bool isNewVale; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXPVHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double peaksBuffer[]; + double valesBuffer[]; + + // + // Constructor ... + void XSCXPVHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XPVInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXPVHelper(symbol, + period, + config.shortLength, + config.mediumLength, + config.longLength, + config.hindLength, + config.hhMode, + config.llMode, + config.showPeaksAndVales, + config.showLevels); + } + void XSCXPVHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Short Length ... + int shortLength = 9, + // + // Medium Length + int mediumLength = 17, + // + // Long Length ... + int longLength = 26, + // + // Hind Length ... + int hindLength = 35, + // + // Detection Mode ... + // + // Highest High Calculation Method ... + ENUM_SERIESMODE hhMode = MODE_HIGH, + // + // Lowest Low Calculation Method ... + ENUM_SERIESMODE llMode = MODE_LOW, + // + // Presentations ... + // + // Show Peaks and Vales ... + bool showPeaksAndVales = false, + // + // Show Levels ... + bool showLevels = false + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mHHMode = hhMode; + mLLMode = llMode; + mLongLength = longLength; + mHindLength = hindLength; + mShowLevels = showLevels; + mShortLength = shortLength; + mMediumLength = mediumLength; + mShowPeaksAndVales = showPeaksAndVales; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXPVHelper() + { + } + + // + // START Properties ... + // + + // + // Show Levels ... + bool ShowLevels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowLevels == show) + { + return true; + } + + // + mShowLevels = show; + result = Init(); + + // + return result; + } + + // + // Show Peaks and Vales ... + bool ShowPeaksAnVales( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowPeaksAndVales == show) + { + return true; + } + + // + mShowPeaksAndVales = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XPV" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mShortLength > 2 && + mMediumLength > mShortLength && + mLongLength > mMediumLength && + mHindLength > mLongLength) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xpv", + // + // Inputs ... + // + // Market ... + "", + // + // Short Length ... + mShortLength, + // + // Medium Length + mMediumLength, + // + // Long Length ... + mLongLength, + // + // Hind Length ... + mHindLength, + // + // Detection Mode ... + "", + // + // Highest High Calculation Method ... + mHHMode, + // + // Lowest Low Calculation Method ... + mLLMode, + // + // Presentations ... + "", + // + // Show Peaks and Vales ... + mShowPeaksAndVales, + // + // Show Levels ... + mShowLevels + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XPVInputs GetConfig() + { + // + XPVInputs result; + + // + result.shortLength = mShortLength; + result.mediumLength = mMediumLength; + result.longLength = mLongLength; + result.hindLength = mHindLength; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.showPeaksAndVales = mShowPeaksAndVales; + result.showLevels = mShowLevels; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XPVInputs &config) + { + // + bool result = false; + + // + mShortLength = config.shortLength; + mMediumLength = config.mediumLength; + mLongLength = config.longLength; + mHindLength = config.hindLength; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mShowPeaksAndVales = config.showPeaksAndVales; + mShowLevels = config.showLevels; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + CopyBuffer( + mHandler, + XPV_PEAKS_LINE, + barIndex, + mLoopbackBars, + peaksBuffer); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + CopyBuffer( + mHandler, + XPV_VALES_LINE, + barIndex, + mLoopbackBars, + valesBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XPVInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XPVInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.peak = peaksBuffer[barIndex]; + result.vale = valesBuffer[barIndex]; + + // + result.isNewPeak = + peaksBuffer[barIndex] != peaksBuffer[barIndex + 1]; + result.isNewVale = + valesBuffer[barIndex] != valesBuffer[barIndex + 1]; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Short Length ... + int mShortLength; + // + // Medium Length + int mMediumLength; + // + // Long Length ... + int mLongLength; + // + // Hind Length ... + int mHindLength; + // + // Detection Mode ... + // + // Highest High Calculation Method ... + ENUM_SERIESMODE mHHMode; + // + // Lowest Low Calculation Method ... + ENUM_SERIESMODE mLLMode; + // + // Presentations ... + // + // Show Peaks and Vales ... + bool mShowPeaksAndVales; + // + // Show Levels ... + bool mShowLevels; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 new file mode 100644 index 0000000..d2130ad Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 new file mode 100644 index 0000000..615d13a --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 @@ -0,0 +1,509 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXSSLCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XSSLCInputs +{ + // + // Market ... + int length; // Length + + // + // Calculation ... + ENUM_MA_METHOD method; // Method + ENUM_APPLIED_PRICE upAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE downAppliedTo; // Down Applied To + + // + // Presentation ... + bool showUp; // Show Up + bool showDown; // Show Down +}; + +// +// Index of Lines ... +enum ENUM_XSSLC_BUFFERS +{ + // + // Main Requirements ... + XSSLC_UP_LINE = 0, + XSSLC_DOWN_LINE = 1, +}; + +// +// Retrieve Info Model ... +struct XSSLCInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double up; + double down; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXSSLCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double upBuffer[]; + double downBuffer[]; + + // + // Constructor ... + void XSCXSSLCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XSSLCInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXSSLCHelper(symbol, + period, + config.length, + config.method, + config.upAppliedTo, + config.downAppliedTo, + config.showUp, + config.showDown); + } + void XSCXSSLCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int length = 36, + // + // Calculation ... + // + // Method ... + ENUM_MA_METHOD method = MODE_SMA, + // + // Up Applied To ... + ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH, + // + // Down Applied To ... + ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW, + // + // Presentation ... + // + // Show Up ... + bool showUp = true, + // + // Show Down ... + bool showDown = true + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mLength = length; + mMethod = method; + mUpAppliedTo = upAppliedTo; + mDownAppliedTo = downAppliedTo; + + // + mShowUp = showUp; + mShowDown = showDown; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXSSLCHelper() + { + } + + // + // START Properties ... + // + + // + // Show Up ... + bool ShowUp( + bool show // Show or Hide Line + ) + { + // + bool result = false; + + // + if (mShowUp == show) + { + return true; + } + + // + mShowUp = show; + result = Init(); + + // + return result; + } + + // + // Show Down ... + bool ShowDown( + bool show // Show or Hide Line + ) + { + // + bool result = false; + + // + if (mShowDown == show) + { + return true; + } + + // + mShowDown = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XSSLC" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xsslc", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Calculation ... + "", + // + // Method ... + mMethod, + // + // Up Applied To ... + mUpAppliedTo, + // + // Down Applied To ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show Up ... + mShowUp, + // + // Show Down ... + mShowDown + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XSSLCInputs GetConfig() + { + // + XSSLCInputs result; + + // + result.length = mLength; + result.method = mMethod; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showUp = mShowUp; + result.showDown = mShowDown; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XSSLCInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mMethod = config.method; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowUp = config.showUp; + mShowDown = config.showDown; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // UP ... + ArraySetAsSeries(upBuffer, true); + CopyBuffer( + mHandler, + XSSLC_UP_LINE, + barIndex, + mLoopbackBars, + upBuffer); + + // + // DOWN ... + ArraySetAsSeries(downBuffer, true); + CopyBuffer( + mHandler, + XSSLC_DOWN_LINE, + barIndex, + mLoopbackBars, + downBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XSSLCInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XSSLCInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double up = upBuffer[barIndex]; + double upPrev = upBuffer[barIndex + 1]; + double down = downBuffer[barIndex]; + double downPrev = downBuffer[barIndex + 1]; + + // + result.up = up; + result.down = down; + + // + result.isBullish = up > down; + result.isBearish = up < down; + + // + result.isSwitchedBullish = + up > down && + upPrev <= downPrev; + result.isSwitchedBearish = + up < down && + upPrev >= downPrev; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Calculation ... + // + // Method ... + ENUM_MA_METHOD mMethod; + // + // Up Applied To ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Applied To ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show Up ... + bool mShowUp; + // + // Show Down ... + bool mShowDown; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtm.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtm.helper.class.ex5 new file mode 100644 index 0000000..f9efcc9 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtm.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtm.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtm.helper.class.mq5 new file mode 100644 index 0000000..00899e2 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtm.helper.class.mq5 @@ -0,0 +1,468 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTMHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XTMInputs +{ + // + // Makret ... + int length; // Length + int shift; // Shift + + // + // Calculations ... + ENUM_MA_METHOD method; // Method + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + bool showLine; // Show Line +}; + +// +// Index of Lines ... +enum ENUM_XTM_BUFFERS +{ + // + // Main Requirements ... + XTM_LINE = 0, + XTM_STATE_LINE = 1, +}; + +// +// XTM Indicator States ... +enum ENUM_XTM_STATES +{ + X_XTM_BULLISH = 0, + X_XTM_BEARISH = 2, + X_XTM_NEUTURAL = 1, +}; + +// +// Retrieve Info Model ... +struct XTMInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double value; + + // + // State ... + ENUM_XTM_STATES state; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; + + // + // Detect Trend is Neutural or not ... + bool isNeutural; + + // + // Detect Trend is Switched to Neutural Or not ... + bool isSwitchedNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXTMHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double valueBuffer[]; + double stateBuffer[]; + + // + // Constructor ... + void XSCXTMHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XTMInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXTMHelper(symbol, + period, + config.length, + config.shift, + config.method, + config.appliedTo, + config.showLine); + } + void XSCXTMHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int length = 35, + // + // Shift ... + int shift = 0, + // + // Calculations ... + // + // Method ... + ENUM_MA_METHOD method = MODE_SMA, + // + // Applied To ... + ENUM_APPLIED_PRICE appliedTo = PRICE_LOW, + // + // Presentation ... + // + // Show Line ... + bool showLine = true + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mShift = shift; + mLength = length; + mMethod = method; + mShowLine = showLine; + mAppliedTo = appliedTo; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXTMHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XTM" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xtm", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mLength, + // + // Shift ... + mShift, + // + // Calculations ... + "", + // + // Method ... + mMethod, + // + // Applied To ... + mAppliedTo, + // + // Presentation ... + "", + // + // Show Line ... + mShowLine + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XTMInputs GetConfig() + { + // + XTMInputs result; + + // + result.length = mLength; + result.shift = mShift; + result.method = mMethod; + result.appliedTo = mAppliedTo; + result.showLine = mShowLine; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XTMInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mShift = config.shift; + mMethod = config.method; + mAppliedTo = config.appliedTo; + mShowLine = config.showLine; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // VALUE ... + ArraySetAsSeries(valueBuffer, true); + CopyBuffer( + mHandler, + XTM_LINE, + barIndex, + mLoopbackBars, + valueBuffer); + + // + // STATE ... + ArraySetAsSeries(stateBuffer, true); + CopyBuffer( + mHandler, + XTM_STATE_LINE, + barIndex, + mLoopbackBars, + stateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XTMInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XTMInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.value = valueBuffer[barIndex]; + + // + ENUM_XTM_STATES state = (ENUM_XTM_STATES)stateBuffer[barIndex]; + ENUM_XTM_STATES prevState = (ENUM_XTM_STATES)stateBuffer[barIndex + 1]; + result.state = state; + + // + result.isBullish = state == X_XTM_BULLISH; + result.isBearish = state == X_XTM_BEARISH; + result.isNeutural = state == X_XTM_NEUTURAL; + + // + result.isSwitchedBullish = + state == X_XTM_BULLISH && prevState != X_XTM_BULLISH; + result.isSwitchedBearish = + state == X_XTM_BEARISH && prevState != X_XTM_BEARISH; + result.isSwitchedNeutural = + state == X_XTM_NEUTURAL && prevState != X_XTM_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Makret ... + // + // Length ... + int mLength; + // + // Shift ... + int mShift; + + // + // Calculations ... + // + // Method ... + ENUM_MA_METHOD mMethod; + // + // Applied To ... + ENUM_APPLIED_PRICE mAppliedTo; + + // + // Presentation ... + // + // Show Line ... + bool mShowLine; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 new file mode 100644 index 0000000..0fe2535 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 new file mode 100644 index 0000000..e325a2e --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 @@ -0,0 +1,1158 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTRNDHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// Inputs ... +struct XTRNDInputs +{ + // + // Makret ... + int cycleLength; // Cycle Length to Check + int numberOfVerifications; // Number of Verifications + + // + // Calculation ... + ENUM_SERIESMODE hhMode; // Detect Up + ENUM_SERIESMODE llMode; // Detect Low + + // + // Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period + + // + // Presentation ... + bool showConsolidations; // Show Consolidations + bool showTrend; // Show Trend + bool showL1Trend; // Show Cycle 1 Trend + bool showL2Trend; // Show Cycle 2 Trend + bool showL3Trend; // Show Cycle 3 Trend +}; + +// +// Index of Lines ... +enum ENUM_XTRND_BUFFERS +{ + // + // Main Requirements ... + XTRND_UP_LINE = 0, + XTRND_UP_STATE_LINE = 1, + XTRND_DOWN_LINE = 2, + XTRND_DOWN_STATE_LINE = 3, + // + // LEVEL 1 ... + XTRND_L1_UP_LINE = 4, + XTRND_L1_UP_STATE_LINE = 5, + XTRND_L1_DOWN_LINE = 6, + XTRND_L1_DOWN_STATE_LINE = 7, + // + // LEVEL 2 ... + XTRND_L2_UP_LINE = 8, + XTRND_L2_UP_STATE_LINE = 9, + XTRND_L2_DOWN_LINE = 10, + XTRND_L2_DOWN_STATE_LINE = 11, + // + // LEVEL 3 ... + XTRND_L3_UP_LINE = 12, + XTRND_L3_UP_STATE_LINE = 13, + XTRND_L3_DOWN_LINE = 14, + XTRND_L3_DOWN_STATE_LINE = 15, +}; + +// +enum ENUM_XTRND_STATES +{ + XTRND_STATE_BULLISH = 1, + XTRND_STATE_BEARISH = 2, + XTRND_STATE_CONSOLIDATION = 0, +}; + +// +// Retrieve Info Model ... +struct XTRNDInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double hh; + ENUM_XTRND_STATES hhState; + double ll; + double llState; + double l1hh; + ENUM_XTRND_STATES l1hhState; + double l1ll; + ENUM_XTRND_STATES l1llState; + double l2hh; + ENUM_XTRND_STATES l2hhState; + double l2ll; + ENUM_XTRND_STATES l2llState; + double l3hh; + ENUM_XTRND_STATES l3hhState; + double l3ll; + ENUM_XTRND_STATES l3llState; + + // + // Conditions ... + // + bool isTrendBullish; + bool isTrendSwitchedToBullish; + bool isTrendBearish; + bool isTrendSwitchedToBearish; + bool isTrendConsolidation; + bool isTrendSwitchedToConsolidation; + + // + bool isL1TrendBullish; + bool isL1TrendSwitchedToBullish; + bool isL1TrendBearish; + bool isL1TrendSwitchedToBearish; + bool isL1TrendConsolidation; + bool isL1TrendSwitchedToConsolidation; + + // + bool isL2TrendBullish; + bool isL2TrendSwitchedToBullish; + bool isL2TrendBearish; + bool isL2TrendSwitchedToBearish; + bool isL2TrendConsolidation; + bool isL2TrendSwitchedToConsolidation; + + // + bool isL3TrendBullish; + bool isL3TrendSwitchedToBullish; + bool isL3TrendBearish; + bool isL3TrendSwitchedToBearish; + bool isL3TrendConsolidation; + bool isL3TrendSwitchedToConsolidation; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXTRNDHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double hhBuffer[]; + double hhStateBuffer[]; + double llBuffer[]; + double llStateBuffer[]; + double l1hhBuffer[]; + double l1hhStateBuffer[]; + double l1llBuffer[]; + double l1llStateBuffer[]; + double l2hhBuffer[]; + double l2hhStateBuffer[]; + double l2llBuffer[]; + double l2llStateBuffer[]; + double l3hhBuffer[]; + double l3hhStateBuffer[]; + double l3llBuffer[]; + double l3llStateBuffer[]; + + // + // Constructor ... + void XSCXTRNDHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + XTRNDInputs &config // Indicator Properties ... + ) : XSCBaseHelper(symbol, period) + { + // + XSCXTRNDHelper(symbol, + period, + config.cycleLength, + config.numberOfVerifications, + config.hhMode, + config.llMode, + config.l1Method, + config.l1Period, + config.l2Method, + config.l2Period, + config.l3Method, + config.l3Period, + config.showConsolidations, + config.showTrend, + config.showL1Trend, + config.showL2Trend, + config.showL3Trend); + } + void XSCXTRNDHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Cycle Length to Check ... + int cycleLength = 2, + // + // Number of Verifications ... + int numberOfVerifications = 2, + // + // Calculations ... + // + // Detect Up ... + ENUM_SERIESMODE hhMode = MODE_HIGH, + // + // Detect Low ... + ENUM_SERIESMODE llMode = MODE_LOW, + // + // Cycles ... + // + // LEVEL 1 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO, + // + // Time Period ... + ENUM_TIMEFRAMES l1Period = NULL, + // + // LEVEL 2 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO, + // + // Time Period ... + ENUM_TIMEFRAMES l2Period = NULL, + // + // LEVEL 3 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO, + // + // Time Period ... + ENUM_TIMEFRAMES l3Period = NULL, + // + // Presentation ... + // + // Show Consolidations ... + bool showConsolidations = false, + // + // Show Trend ... + bool showTrend = true, + // + // Show Cycle 1 Trend ... + bool showL1Trend = false, + // + // Show Cycle 2 Trend ... + bool showL2Trend = false, + // + // Show Cycle 3 Trend ... + bool showL3Trend = false + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mCycleLength = cycleLength; + mNumberOfVerifications = numberOfVerifications; + mHHMode = hhMode; + mLLMode = llMode; + mLLMethod = l1Method; + mL1Period = l1Period; + mL2Method = l2Method; + mL2Period = l2Period; + mL3Method = l3Method; + mL3Period = l3Period; + mShowConsolidations = showConsolidations; + mShowTrend = showTrend; + mShowL1Trends = showL1Trend; + mShowL2Trends = showL2Trend; + mShowL3Trends = showL3Trend; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXTRNDHelper() + { + } + + // + // START Properties ... + // + + // + // Show Trend ... + bool ShowTrend( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowTrend == show) + { + return true; + } + + // + mShowTrend = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 1 Trend ... + bool ShowL1Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL1Trends == show) + { + return true; + } + + // + mShowL1Trends = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 2 Trend ... + bool ShowL2Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL2Trends == show) + { + return true; + } + + // + mShowL2Trends = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 3 Trend ... + bool ShowL3Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL3Trends == show) + { + return true; + } + + // + mShowL3Trends = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XTRND" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + // + result = + // + (mCycleLength > 0 && + mNumberOfVerifications > 0) + // + ; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xtrnd", + // + // Inputs ... + // + // Market ... + "", + // + // Cycle Length to Check ... + mCycleLength, + // + // Number of Verifications ... + mNumberOfVerifications, + // + // Calculations ... + "", + // + // Detect Up ... + mHHMode, + // + // Detect Low ... + mLLMode, + // + // Cycles ... + "", + // + // LEVEL 1 ... + "", + // + // How to Find Period ... + mLLMethod, + // + // Time Period ... + mL1Period, + // + // LEVEL 2 ... + "", + // + // How to Find Period ... + mL2Method, + // + // Time Period ... + mL2Period, + // + // LEVEL 3 ... + "", + // + // How to Find Period ... + mL3Method, + // + // Time Period ... + mL3Period, + // + // Presentation ... + "", + // + // Show Consolidations ... + mShowConsolidations, + // + // Show Trend ... + mShowTrend, + // + // Show Cycle 1 Trend ... + mShowL1Trends, + // + // Show Cycle 2 Trend ... + mShowL2Trends, + // + // Show Cycle 3 Trend ... + mShowL3Trends + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XTRNDInputs GetConfig() + { + // + XTRNDInputs result; + + // + result.cycleLength = mCycleLength; + result.numberOfVerifications = mNumberOfVerifications; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.l1Method = mLLMethod; + result.l1Period = mL1Period; + result.l2Method = mL2Method; + result.l2Period = mL2Period; + result.l3Method = mL3Method; + result.l3Period = mL3Period; + result.showConsolidations = mShowConsolidations; + result.showTrend = mShowTrend; + result.showL1Trend = mShowL1Trends; + result.showL2Trend = mShowL2Trends; + result.showL3Trend = mShowL3Trends; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XTRNDInputs &config) + { + // + bool result = false; + + // + mCycleLength = config.cycleLength; + mNumberOfVerifications = config.numberOfVerifications; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mLLMethod = config.l1Method; + mL1Period = config.l1Period; + mL2Method = config.l2Method; + mL2Period = config.l2Period; + mL3Method = config.l3Method; + mL3Period = config.l3Period; + mShowConsolidations = config.showConsolidations; + mShowTrend = config.showTrend; + mShowL1Trends = config.showL1Trend; + mShowL2Trends = config.showL2Trend; + mShowL3Trends = config.showL3Trend; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // HH ... + ArraySetAsSeries(hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_UP_LINE, + barIndex, + mLoopbackBars, + hhBuffer); + + // + // HH State ... + ArraySetAsSeries(hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_UP_STATE_LINE, + barIndex, + mLoopbackBars, + hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(llBuffer, true); + CopyBuffer( + mHandler, + XTRND_DOWN_LINE, + barIndex, + mLoopbackBars, + llBuffer); + + // + // LL State ... + ArraySetAsSeries(llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + llStateBuffer); + + // + // CYCLES ... + + // + // LEVEL 1 ... + + // + // HH ... + ArraySetAsSeries(l1hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_UP_LINE, + barIndex, + mLoopbackBars, + l1hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l1hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l1hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l1llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_DOWN_LINE, + barIndex, + mLoopbackBars, + l1llBuffer); + + // + // LL State ... + ArraySetAsSeries(l1llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l1llStateBuffer); + + // + // LEVEL 2 ... + + // + // HH ... + ArraySetAsSeries(l2hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_UP_LINE, + barIndex, + mLoopbackBars, + l2hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l2hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l2hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l2llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_DOWN_LINE, + barIndex, + mLoopbackBars, + l2llBuffer); + + // + // LL State ... + ArraySetAsSeries(l2llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l2llStateBuffer); + + // + // LEVEL 3 ... + + // + // HH ... + ArraySetAsSeries(l3hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_UP_LINE, + barIndex, + mLoopbackBars, + l3hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l3hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l3hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l3llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_DOWN_LINE, + barIndex, + mLoopbackBars, + l3llBuffer); + + // + // LL State ... + ArraySetAsSeries(l3llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l3llStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XTRNDInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XTRNDInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double hh = hhBuffer[barIndex]; + ENUM_XTRND_STATES hhState = (ENUM_XTRND_STATES)hhStateBuffer[barIndex]; + ENUM_XTRND_STATES hhStatePrev = (ENUM_XTRND_STATES)hhStateBuffer[barIndex + 1]; + + // + double ll = llBuffer[barIndex]; + ENUM_XTRND_STATES llState = (ENUM_XTRND_STATES)llStateBuffer[barIndex]; + ENUM_XTRND_STATES llStatePrev = (ENUM_XTRND_STATES)llStateBuffer[barIndex + 1]; + + // + double l1hh = l1hhBuffer[barIndex]; + ENUM_XTRND_STATES l1hhState = (ENUM_XTRND_STATES)l1hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l1hhStatePrev = (ENUM_XTRND_STATES)l1hhStateBuffer[barIndex + 1]; + + // + double l1ll = l1llBuffer[barIndex]; + ENUM_XTRND_STATES l1llState = (ENUM_XTRND_STATES)l1llStateBuffer[barIndex]; + ENUM_XTRND_STATES l1llStatePrev = (ENUM_XTRND_STATES)l1llStateBuffer[barIndex + 1]; + + // + double l2hh = l2hhBuffer[barIndex]; + ENUM_XTRND_STATES l2hhState = (ENUM_XTRND_STATES)l2hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l2hhStatePrev = (ENUM_XTRND_STATES)l2hhStateBuffer[barIndex + 1]; + + // + double l2ll = l2llBuffer[barIndex]; + ENUM_XTRND_STATES l2llState = (ENUM_XTRND_STATES)l2llStateBuffer[barIndex]; + ENUM_XTRND_STATES l2llStatePrev = (ENUM_XTRND_STATES)l2llStateBuffer[barIndex + 1]; + + // + double l3hh = l3hhBuffer[barIndex]; + ENUM_XTRND_STATES l3hhState = (ENUM_XTRND_STATES)l3hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l3hhStatePrev = (ENUM_XTRND_STATES)l3hhStateBuffer[barIndex + 1]; + + // + double l3ll = l3llBuffer[barIndex]; + ENUM_XTRND_STATES l3llState = (ENUM_XTRND_STATES)l3llStateBuffer[barIndex]; + ENUM_XTRND_STATES l3llStatePrev = (ENUM_XTRND_STATES)l3llStateBuffer[barIndex + 1]; + + // + bool isTrendBullish = + hhState == XTRND_STATE_BULLISH && + llState == XTRND_STATE_BULLISH; + bool isPrevTrendBullish = + hhStatePrev == XTRND_STATE_BULLISH && + llStatePrev == XTRND_STATE_BULLISH; + bool isTrendBearish = + hhState == XTRND_STATE_BEARISH && + llState == XTRND_STATE_BEARISH; + bool isPrevTrendBearish = + hhStatePrev == XTRND_STATE_BEARISH && + llStatePrev == XTRND_STATE_BEARISH; + bool isTrendConsolidation = + hhState == XTRND_STATE_CONSOLIDATION && + llState == XTRND_STATE_CONSOLIDATION; + bool isPrevTrendConsolidation = + hhStatePrev == XTRND_STATE_CONSOLIDATION && + llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isTrendSwitchedToBullish = + isTrendBullish && + !isPrevTrendBullish; + bool isTrendSwitchedToBearish = + isTrendBearish && + !isPrevTrendBearish; + bool isTrendSwitchedToConsolidation = + isTrendConsolidation && + !isPrevTrendConsolidation; + + // + bool isL1TrendBullish = + l1hhState == XTRND_STATE_BULLISH && + l1llState == XTRND_STATE_BULLISH; + bool isL1PrevTrendBullish = + l1hhStatePrev == XTRND_STATE_BULLISH && + l1llStatePrev == XTRND_STATE_BULLISH; + bool isL1TrendBearish = + l1hhState == XTRND_STATE_BEARISH && + l1llState == XTRND_STATE_BEARISH; + bool isL1PrevTrendBearish = + l1hhStatePrev == XTRND_STATE_BEARISH && + l1llStatePrev == XTRND_STATE_BEARISH; + bool isL1TrendConsolidation = + l1hhState == XTRND_STATE_CONSOLIDATION && + l1llState == XTRND_STATE_CONSOLIDATION; + bool isL1PrevTrendConsolidation = + l1hhStatePrev == XTRND_STATE_CONSOLIDATION && + l1llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL1TrendSwitchedToBullish = + isL1TrendBullish && + !isL1PrevTrendBullish; + bool isL1TrendSwitchedToBearish = + isL1TrendBearish && + !isL1PrevTrendBearish; + bool isL1TrendSwitchedToConsolidation = + isL1TrendConsolidation && + !isL1PrevTrendConsolidation; + + // + bool isL2TrendBullish = + l2hhState == XTRND_STATE_BULLISH && + l2llState == XTRND_STATE_BULLISH; + bool isL2PrevTrendBullish = + l2hhStatePrev == XTRND_STATE_BULLISH && + l2llStatePrev == XTRND_STATE_BULLISH; + bool isL2TrendBearish = + l2hhState == XTRND_STATE_BEARISH && + l2llState == XTRND_STATE_BEARISH; + bool isL2PrevTrendBearish = + l2hhStatePrev == XTRND_STATE_BEARISH && + l2llStatePrev == XTRND_STATE_BEARISH; + bool isL2TrendConsolidation = + l2hhState == XTRND_STATE_CONSOLIDATION && + l2llState == XTRND_STATE_CONSOLIDATION; + bool isL2PrevTrendConsolidation = + l2hhStatePrev == XTRND_STATE_CONSOLIDATION && + l2llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL2TrendSwitchedToBullish = + isL2TrendBullish && + !isL2PrevTrendBullish; + bool isL2TrendSwitchedToBearish = + isL2TrendBearish && + !isL2PrevTrendBearish; + bool isL2TrendSwitchedToConsolidation = + isL2TrendConsolidation && + !isL2PrevTrendConsolidation; + + // + bool isL3TrendBullish = + l3hhState == XTRND_STATE_BULLISH && + l3llState == XTRND_STATE_BULLISH; + bool isL3PrevTrendBullish = + l3hhStatePrev == XTRND_STATE_BULLISH && + l3llStatePrev == XTRND_STATE_BULLISH; + bool isL3TrendBearish = + l3hhState == XTRND_STATE_BEARISH && + l3llState == XTRND_STATE_BEARISH; + bool isL3PrevTrendBearish = + l3hhStatePrev == XTRND_STATE_BEARISH && + l3llStatePrev == XTRND_STATE_BEARISH; + bool isL3TrendConsolidation = + l3hhState == XTRND_STATE_CONSOLIDATION && + l3llState == XTRND_STATE_CONSOLIDATION; + bool isL3PrevTrendConsolidation = + l3hhStatePrev == XTRND_STATE_CONSOLIDATION && + l3llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL3TrendSwitchedToBullish = + isL3TrendBullish && + !isL3PrevTrendBullish; + bool isL3TrendSwitchedToBearish = + isL3TrendBearish && + !isL3PrevTrendBearish; + bool isL3TrendSwitchedToConsolidation = + isL3TrendConsolidation && + !isL3PrevTrendConsolidation; + + // + result.hh = hh; + result.hhState = hhState; + result.ll = ll; + result.llState = llState; + result.l1hh = l1hh; + result.l1hhState = l1hhState; + result.l1ll = l1ll; + result.l1llState = l1llState; + result.l2hh = l2hh; + result.l2hhState = l2hhState; + result.l2ll = l2ll; + result.l2llState = l2llState; + result.l3hh = l3hh; + result.l3hhState = l3hhState; + result.l3ll = l3ll; + result.l3llState = l3llState; + + // + result.isTrendBullish = isTrendBullish; + result.isTrendBearish = isTrendBearish; + result.isTrendConsolidation = isTrendConsolidation; + + // + result.isTrendSwitchedToBullish = isTrendSwitchedToBullish; + result.isTrendSwitchedToBearish = isTrendSwitchedToBearish; + result.isTrendSwitchedToConsolidation = isTrendSwitchedToConsolidation; + + // + result.isL1TrendBullish = isL1TrendBullish; + result.isL1TrendBearish = isL1TrendBearish; + result.isL1TrendConsolidation = isL1TrendConsolidation; + + // + result.isL1TrendSwitchedToBullish = isL1TrendSwitchedToBullish; + result.isL1TrendSwitchedToBearish = isL1TrendSwitchedToBearish; + result.isL1TrendSwitchedToConsolidation = isL1TrendSwitchedToConsolidation; + + // + result.isL2TrendBullish = isL2TrendBullish; + result.isL2TrendBearish = isL2TrendBearish; + result.isL2TrendConsolidation = isL2TrendConsolidation; + + // + result.isL2TrendSwitchedToBullish = isL2TrendSwitchedToBullish; + result.isL2TrendSwitchedToBearish = isL2TrendSwitchedToBearish; + result.isL2TrendSwitchedToConsolidation = isL2TrendSwitchedToConsolidation; + + // + result.isL3TrendBullish = isL3TrendBullish; + result.isL3TrendBearish = isL3TrendBearish; + result.isL3TrendConsolidation = isL3TrendConsolidation; + + // + result.isL3TrendSwitchedToBullish = isL3TrendSwitchedToBullish; + result.isL3TrendSwitchedToBearish = isL3TrendSwitchedToBearish; + result.isL3TrendSwitchedToConsolidation = isL3TrendSwitchedToConsolidation; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Cycle Length to Check ... + int mCycleLength; + // + // Number of Verifications ... + int mNumberOfVerifications; + // + // Calculations ... + // + // Detect Up ... + ENUM_SERIESMODE mHHMode; + // + // Detect Low ... + ENUM_SERIESMODE mLLMode; + // + // Cycles ... + // + // LEVEL 1 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mLLMethod; + // + // Time Period ... + ENUM_TIMEFRAMES mL1Period; + // + // LEVEL 2 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mL2Method; + // + // Time Period ... + ENUM_TIMEFRAMES mL2Period; + // + // LEVEL 3 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mL3Method; + // + // Time Period ... + ENUM_TIMEFRAMES mL3Period; + // + // Presentation ... + // + // Show Consolidations ... + bool mShowConsolidations; + // + // Show Trend ... + bool mShowTrend; + // + // Show Cycle 1 Trend ... + bool mShowL1Trends; + // + // Show Cycle 2 Trend ... + bool mShowL2Trends; + // + // Show Cycle 3 Trend ... + bool mShowL3Trends; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Providers/x.saherelm.x121.provider.ex5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Providers/x.saherelm.x121.provider.ex5 new file mode 100644 index 0000000..88d3655 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Providers/x.saherelm.x121.provider.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Providers/x.saherelm.x121.provider.mq5 b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Providers/x.saherelm.x121.provider.mq5 new file mode 100644 index 0000000..3bd4acf --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Constructor Issues/Providers/x.saherelm.x121.provider.mq5 @@ -0,0 +1,965 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121Provider +// Description: X121 Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Helpers/x-saherelm.x121.xcc.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xhk.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xtm.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xpv.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xama.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xmrb.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xche.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xich.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xtrnd.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xsslc.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xhull.helper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// Here we Have to Define an Input Structure Model +// for Provider Class to Handle Helpers Definitions ... +struct X121ProviderInputs +{ + // + // XCC ... + // Candle Styling ... + XCCInputs xccConfig; + + // + // XHK ... + // HikenAshi Candle Representing ... + XHKInputs xhkConfig; + + // + // XTM ... + // Trend Magic ... + XTMInputs xtmConfig; + + // + // XPV ... + // Peaks And Vales ... + XPVInputs xpvConfig; + + // + // XAMA ... + // Adaptive Moving Average ... + XAMAInputs xamaConfig; + + // + // XMRB ... + // Moving Average Ribbon ... + XMRBInputs xmrbConfig; + + // + // XCHE ... + // Chandelier Exit Points ... + XCHEInputs xcheConfig; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + XICHInputs xichConfig; + + // + // XTRND ... + // Trend Detector ... + XTRNDInputs xtrndConfig; + + // + // XSSLC ... + // SSL Channel ... + XSSLCInputs xsslcConfig; + + // + // XHULL ... + // Hull Trend Detection Channel ... + XHULLInputs xhullConfig; +}; + +// +// Model Market Sense based On Current Captured conditions ... +struct X121MarketConditions +{ + // + // Commonly Used Info ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Check Current Market Condition has Signal or not ... + bool hasSignal; + + // + // If has any Signal, Models it's related info here ... + XSignalInfo signal; + + // + // INDICATORS Market Sense ... + + // + // XCC ... + // there is not any Info provided here ... + + // + // XHK ... + XHKInfo xhkInfo; + + // + // XTM ... + XTMInfo xtmInfo; + + // + // XPV ... + XPVInfo xpvInfo; + + // + // XAMA ... + XAMAInfo xamaInfo; + + // + // XMRB ... + XMRBInfo xmrbInfo; + + // + // XCHE ... + XCHEInfo xcheInfo; + + // + // XICH ... + XICHInfo xichInfo; + + // + // XTRND ... + XTRNDInfo xtrndInfo; + + // + // XSSLC ... + XSSLCInfo xsslcInfo; + + // + // XHULL ... + XHULLInfo xhullInfo; +}; + +// +// Notified a Signal was Appears ... +typedef void (*TOnSignalConditions)( + X121MarketConditions &info); + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCX121Provider : public XSCEABaseProvider +{ + // + // Public ... +public: + // + // Props ... + X121ProviderInputs providedConfig; + X121ProviderInputs currentConfig; + X121ProviderInputs cleanConfig; + + // + // Indicator Helper Classes Instance ... + + // + // XCC ... + XSCXCCHelper *mXCCHelper; + + // + // XHK ... + XSCXHKHelper *mXHKHelper; + + // + // XTM ... + XSCXTMHelper *mXTMHelper; + + // + // XPV ... + XSCXPVHelper *mXPVHelper; + + // + // XAMA ... + XSCXAMAHelper *mXAMAHelper; + + // + // XMRB ... + XSCXMRBHelper *mXMRBHelper; + + // + // XCHE ... + XSCXCHEHelper *mXCHEHelper; + + // + // XICH ... + XSCXICHHelper *mXICHHelper; + + // + // XTRND ... + XSCXTRNDHelper *mXTRNDHelper; + + // + // XSSLC ... + XSCXSSLCHelper *mXSSLCHelper; + + // + // XHULL ... + XSCXHULLHelper *mXHULLHelper; + + // + // Define Helpers ... + + // + // Constructor ... + void XSCX121Provider() : XSCEABaseProvider(_Symbol, _Period){}; + void XSCX121Provider( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Time Frame ... + ) : XSCEABaseProvider(symbol, period) + { + // + // Prepare Default and Clean Config ... + // in this Config non of Indicators doesn't Draw anything on chart ... + X121ProviderInputs configs; + + // + // XCC ... + // Candle Styling ... + configs.xccConfig.upColor = clrLime; + configs.xccConfig.downColor = clrRed; + configs.xccConfig.lineColor = clrLime; + configs.xccConfig.bearishColor = clrRed; + configs.xccConfig.bullishColor = clrLime; + configs.xccConfig.volumesColor = clrGreen; + configs.xccConfig.showCandles = true; + + // + // XHK ... + // HikenAshi Candle Representing ... + configs.xhkConfig.drawCandles = false; + configs.xhkConfig.drawCandleLines = false; + + // + // XTM ... + // Trend Magic ... + configs.xtmConfig.length = 35; + configs.xtmConfig.shift = 0; + configs.xtmConfig.method = MODE_SMA; + configs.xtmConfig.appliedTo = PRICE_LOW; + configs.xtmConfig.showLine = false; + + // + // XPV ... + // Peaks And Vales ... + configs.xpvConfig.shortLength = 9; + configs.xpvConfig.mediumLength = 17; + configs.xpvConfig.longLength = 26; + configs.xpvConfig.hindLength = 35; + configs.xpvConfig.hhMode = MODE_HIGH; + configs.xpvConfig.llMode = MODE_LOW; + configs.xpvConfig.showPeaksAndVales = false; + configs.xpvConfig.showLevels = false; + + // + // XAMA ... + // Adaptive Moving Average ... + configs.xamaConfig.length = 52; + configs.xamaConfig.fastEMA = 2; + configs.xamaConfig.slowEMA = 30; + configs.xamaConfig.maShift = 0; + configs.xamaConfig.appliedTo = PRICE_LOW; + configs.xamaConfig.showLine = false; + + // + // XMRB ... + // Moving Average Ribbon ... + configs.xmrbConfig.fast1Length = 3; + configs.xmrbConfig.slow1Length = 5; + configs.xmrbConfig.fast2Length = 8; + configs.xmrbConfig.slow2Length = 13; + configs.xmrbConfig.fast3Length = 21; + configs.xmrbConfig.slow3Length = 34; + configs.xmrbConfig.fast4Length = 55; + configs.xmrbConfig.slow4Length = 89; + configs.xmrbConfig.fast5Length = 144; + configs.xmrbConfig.slow5Length = 233; + configs.xmrbConfig.ribbonMode = MODE_EMA; + configs.xmrbConfig.ribbonAppliedTo = PRICE_CLOSE; + configs.xmrbConfig.showFastMa = false; + configs.xmrbConfig.showSlowMa = false; + configs.xmrbConfig.showRibbon = false; + + // + // XCHE ... + // Chandelier Exit Points ... + configs.xcheConfig.length = 35; + configs.xcheConfig.loopback = 26; + configs.xcheConfig.multiplier1 = 3; + configs.xcheConfig.multiplier2 = 3; + configs.xcheConfig.upAppliedTo = PRICE_HIGH; + configs.xcheConfig.downAppliedTo = PRICE_LOW; + configs.xcheConfig.showLongExit1Line = false; + configs.xcheConfig.showShortExit1Line = false; + configs.xcheConfig.showLongExit2Line = false; + configs.xcheConfig.showShortExit2Line = false; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + configs.xichConfig.tenkanSenLength = 9; + configs.xichConfig.tenkanSenMode = X_XICH_HH_LL_MODE; + configs.xichConfig.kijunSenLength = 26; + configs.xichConfig.kijunSenMode = X_XICH_HH_LL_MODE; + configs.xichConfig.senkouSpanBLength = 52; + configs.xichConfig.senkouSpanBMode = X_XICH_HH_LL_MODE; + configs.xichConfig.chikuoSpanAppliedTo = PRICE_CLOSE; + configs.xichConfig.showTenkanSen = false; + configs.xichConfig.showKijunSen = false; + configs.xichConfig.showKijunSenPlus = false; + configs.xichConfig.showKijunSenNegative = false; + configs.xichConfig.showChikouSpan = false; + configs.xichConfig.showSenkouSpanA = false; + configs.xichConfig.showSenkouSpanB = false; + configs.xichConfig.showKumo = false; + configs.xichConfig.shiftKumo = true; + + // + // XTRND ... + // Trend Detector ... + configs.xtrndConfig.cycleLength = 2; + configs.xtrndConfig.numberOfVerifications = 2; + configs.xtrndConfig.hhMode = MODE_HIGH; + configs.xtrndConfig.llMode = MODE_LOW; + configs.xtrndConfig.l1Method = X_PERIOD_AUTO; + configs.xtrndConfig.l1Period = NULL; + configs.xtrndConfig.l2Method = X_PERIOD_AUTO; + configs.xtrndConfig.l2Period = NULL; + configs.xtrndConfig.l3Method = X_PERIOD_AUTO; + configs.xtrndConfig.l3Period = NULL; + configs.xtrndConfig.showConsolidations = false; + configs.xtrndConfig.showTrend = false; + configs.xtrndConfig.showL1Trend = false; + configs.xtrndConfig.showL2Trend = false; + configs.xtrndConfig.showL3Trend = false; + + // + // XSSLC ... + // SSL Channel ... + configs.xsslcConfig.length = 36; + configs.xsslcConfig.method = MODE_SMA; + configs.xsslcConfig.upAppliedTo = PRICE_HIGH; + configs.xsslcConfig.downAppliedTo = PRICE_LOW; + configs.xsslcConfig.showUp = false; + configs.xsslcConfig.showDown = false; + + // + // XHULL ... + // Hull Trend Detection Channel ... + configs.xhullConfig.length = 72; + configs.xhullConfig.divisor = 2; + configs.xhullConfig.upAppliedTo = PRICE_HIGH; + configs.xhullConfig.downAppliedTo = PRICE_LOW; + configs.xhullConfig.showUpZone = false; + configs.xhullConfig.showDownZone = false; + + // + // Clean Config ... + cleanConfig = configs; + + // + XSCX121Provider(symbol, period, configs); + } + void XSCX121Provider( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading Time Frame ... + X121ProviderInputs &config // Configs ... + ) + { + // + mTag = "X121Provider|" + mSymbol + "," + ToString(mPeriod); + + // // + // mCTimerHandler = iCustom( + // mSymbol, + // mPeriod, + // "x-saherelm.x121.xct", + // // + // // Inputs ... + // clrYellow, + // CORNER_RIGHT_LOWER, + // true + // // + // ); + + // + currentConfig = config; + providedConfig = config; + + // + // Here we Have to Make Provided Config in Clean Style ... + PrepareCleanConfig(); + } + + // + // Deconstructor ... + void ~XSCX121Provider() + { + // + IndicatorRelease(mCTimerHandler); + + // + // De construct Helpers ... + delete mXCCHelper; + delete mXHKHelper; + delete mXTMHelper; + delete mXPVHelper; + delete mXAMAHelper; + delete mXMRBHelper; + delete mXCHEHelper; + delete mXICHHelper; + delete mXTRNDHelper; + delete mXSSLCHelper; + delete mXHULLHelper; + } + + // + bool Init() + { + // + bool result = false; + + // + // Instantiate all Indicators Helper Classes ... + // + // // XCC ... + // mXCCHelper = new XSCXCCHelper( + // mSymbol, + // mPeriod, + // currentConfig.xccConfig); + // result = mXCCHelper.Init(); + // if (!result) + // { + // return result; + // } + + // // + // // XHK ... + // mXHKHelper = new XSCXHKHelper( + // mSymbol, + // mPeriod, + // currentConfig.xhkConfig); + // result = mXHKHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // + // XTM ... + // mXTMHelper = new XSCXTMHelper( + // mSymbol, + // mPeriod, + // currentConfig.xtmConfig); + // result = mXTMHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // // + // // XPV ... + // mXPVHelper = new XSCXPVHelper( + // mSymbol, + // mPeriod, + // currentConfig.xpvConfig); + // result = mXPVHelper.Init(); + // if (!result) + // { + // LogMessage("XPV Error: "); + // return result; + // }; + + // // + // // XAMA ... + // mXAMAHelper = new XSCXAMAHelper( + // mSymbol, + // mPeriod, + // currentConfig.xamaConfig); + // result = mXAMAHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // // + // // XMRB ... + // mXMRBHelper = new XSCXMRBHelper( + // mSymbol, + // mPeriod, + // currentConfig.xmrbConfig); + // result = mXMRBHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // // + // // XCHE ... + // mXCHEHelper = new XSCXCHEHelper( + // mSymbol, + // mPeriod, + // currentConfig.xcheConfig); + // result = mXCHEHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // // + // // XICH ... + // mXICHHelper = new XSCXICHHelper( + // mSymbol, + // mPeriod, + // currentConfig.xichConfig); + // result = mXICHHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // // + // // XTRND ... + // mXTRNDHelper = new XSCXTRNDHelper( + // mSymbol, + // mPeriod, + // currentConfig.xtrndConfig); + // result = mXTRNDHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // // + // // XSSLC ... + // mXSSLCHelper = new XSCXSSLCHelper( + // mSymbol, + // mPeriod, + // currentConfig.xsslcConfig); + // result = mXSSLCHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // // + // // XHULL ... + // mXHULLHelper = new XSCXHULLHelper( + // mSymbol, + // mPeriod, + // currentConfig.xhullConfig); + // result = mXHULLHelper.Init(); + // if (!result) + // { + // return result; + // }; + + // + return result; + } + + // + virtual void ProcessBuffers() + { + } + + // + virtual void ProcessTick() + { + ProcessSignals(); + } + + // + // Generate Market Sense ... + X121MarketConditions GetMarketConditions( + int barIndex // Specified Bar Index + ) + { + // + X121MarketConditions result; + + // + // Fill Common Data ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barIndex = barIndex; + + // + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + result.barTime = barTime; + + // + result.xhkInfo = mXHKHelper.GetInfo(barIndex); + result.xtmInfo = mXTMHelper.GetInfo(barIndex); + result.xpvInfo = mXPVHelper.GetInfo(barIndex); + result.xamaInfo = mXAMAHelper.GetInfo(barIndex); + result.xmrbInfo = mXMRBHelper.GetInfo(barIndex); + result.xcheInfo = mXCHEHelper.GetInfo(barIndex); + result.xichInfo = mXICHHelper.GetInfo(barIndex); + result.xtrndInfo = mXTRNDHelper.GetInfo(barIndex); + result.xsslcInfo = mXSSLCHelper.GetInfo(barIndex); + result.xhullInfo = mXHULLHelper.GetInfo(barIndex); + + // + return result; + } + + // + // Add Specific On SignalConditions Event Handler ... + int AddOnSignalConditionEventHandler(TOnSignalConditions handler) + { + // + ArrayResize( + mSignalConditionsEventHandlers, + ArraySize(mSignalConditionsEventHandlers) + 1); + + // + int result = ArraySize(mSignalConditionsEventHandlers) - 1; + mSignalConditionsEventHandlers[result] = handler; + + // + return result; + } + + // + // Remove All On Signal Event Handler ... + void ReoveOnSignalEventHandlers() + { + // + ArrayFree(mSignalConditionsEventHandlers); + } + + // + // Notify a Signal Found on all Event Listeners ... + void NotifyOnSignalConditionsEvent(X121MarketConditions &info) + { + // + int listenerCount = ArraySize(mSignalConditionsEventHandlers); + if (listenerCount <= 0) + { + return; + } + + // + // Loop Through Listeners ... + for (int i = 0; i < listenerCount; i++) + { + // + TOnSignalConditions listener = mSignalConditionsEventHandlers[i]; + + // + listener(info); + } + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // CCandle Timer ... + int mCTimerHandler; + + // + // Signal Event Handlers ... + TOnSignalConditions mSignalConditionsEventHandlers[]; + + // + // Make Provided Config in Clean Style ... + void PrepareCleanConfig() + { + // + cleanConfig = providedConfig; + + // + // XCC ... + // Candle Styling ... + cleanConfig.xccConfig.showCandles = true; + + // + // XHK ... + // HikenAshi Candle Representing ... + cleanConfig.xhkConfig.drawCandles = false; + cleanConfig.xhkConfig.drawCandleLines = false; + + // + // XTM ... + // Trend Magic ... + cleanConfig.xtmConfig.showLine = false; + + // + // XPV ... + // Peaks And Vales ... + cleanConfig.xpvConfig.showPeaksAndVales = false; + cleanConfig.xpvConfig.showLevels = false; + + // + // XAMA ... + // Adaptive Moving Average ... + cleanConfig.xamaConfig.showLine = false; + + // + // XMRB ... + // Moving Average Ribbon ... + cleanConfig.xmrbConfig.showFastMa = false; + cleanConfig.xmrbConfig.showSlowMa = false; + cleanConfig.xmrbConfig.showRibbon = false; + + // + // XCHE ... + // Chandelier Exit Points ... + cleanConfig.xcheConfig.showLongExit1Line = false; + cleanConfig.xcheConfig.showShortExit1Line = false; + cleanConfig.xcheConfig.showLongExit2Line = false; + cleanConfig.xcheConfig.showShortExit2Line = false; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + cleanConfig.xichConfig.showTenkanSen = false; + cleanConfig.xichConfig.showKijunSen = false; + cleanConfig.xichConfig.showKijunSenPlus = false; + cleanConfig.xichConfig.showKijunSenNegative = false; + cleanConfig.xichConfig.showChikouSpan = false; + cleanConfig.xichConfig.showSenkouSpanA = false; + cleanConfig.xichConfig.showSenkouSpanB = false; + cleanConfig.xichConfig.showKumo = false; + + // + // XTRND ... + // Trend Detector ... + cleanConfig.xtrndConfig.showConsolidations = false; + cleanConfig.xtrndConfig.showTrend = false; + cleanConfig.xtrndConfig.showL1Trend = false; + cleanConfig.xtrndConfig.showL2Trend = false; + cleanConfig.xtrndConfig.showL3Trend = false; + + // + // XSSLC ... + // SSL Channel ... + cleanConfig.xsslcConfig.showUp = false; + cleanConfig.xsslcConfig.showDown = false; + + // + // XHULL ... + // Hull Trend Detection Channel ... + cleanConfig.xhullConfig.showUpZone = false; + cleanConfig.xhullConfig.showDownZone = false; + } + + // + // Here we are Capture Conditions and Check Signals ... + // The Signals Must be Unique for each providers ... + void ProcessSignals() + { + // + X121MarketConditions conditions = GetMarketConditions(1); + + // + // BUY ... + + // + Clean(conditions.signal); + bool hasLongSignal = HasLongSignal(conditions); + if (hasLongSignal) + { + // + NotifyOnSignalEvent( + conditions.signal); + NotifyOnSignalConditionsEvent(conditions); + mWaitUntilNewCandle = true; + return; + } + + // + // SELL ... + + // + Clean(conditions.signal); + bool hasShortignal = HasShortSignal(conditions); + if (hasShortignal) + { + // + NotifyOnSignalEvent( + conditions.signal); + NotifyOnSignalConditionsEvent(conditions); + mWaitUntilNewCandle = true; + return; + } + } + + // + // Check has Long Signal on Each Strategies ... + bool HasLongSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + if (result) + { + } + + // + return result; + } + + // + // Check has Short Signal on Each Strategies ... + bool HasShortSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + if (result) + { + } + + // + return result; + } +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct X121SignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Desired Magic Number ... + ulong magicNumber; + + // + // Provider ... + XSCX121Provider provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + X121SignalProvider &item, // item want to add + X121SignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Generate Identifier Tag ... +string GenerateTag(X121SignalProvider &descriptor) +{ + // + string result = ""; + + // + result = descriptor.symbol + "," + ToString(descriptor.period); + + // + return result; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/Ichimoku.mql4 b/MQLTestWorkspace/BKPS/BKP/Smapls/Ichimoku.mql4 new file mode 100644 index 0000000..f0e7a65 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/Ichimoku.mql4 @@ -0,0 +1,262 @@ +//+------------------------------------------------------------------+ +//| Demo_iIchimoku.mq5 | +//| Copyright 2011, MetaQuotes Software Corp. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2000-2024, MetaQuotes Ltd." +#property link "https://www.mql5.com" +#property version "1.00" +#property description "The indicator demonstrates how to obtain data" +#property description "of indicator buffers for the iIchimoku technical indicator." +#property description "A symbol and timeframe used for calculation of the indicator," +#property description "are set by the symbol and period parameters." +#property description "The method of creation of the handle is set through the 'type' parameter (function type)." +#property description "All other parameters just like in the standard Ichimoku Kinko Hyo." + +#property indicator_chart_window +#property indicator_buffers 5 +#property indicator_plots 4 +//--- the Tenkan_sen plot +#property indicator_label1 "Tenkan_sen" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +//--- the Kijun_sen plot +#property indicator_label2 "Kijun_sen" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrBlue +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 +//--- the Senkou_Span plot +#property indicator_label3 "Senkou Span A;Senkou Span B" // two fields will be shown in Data Window +#property indicator_type3 DRAW_FILLING +#property indicator_color3 clrSandyBrown, clrThistle +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 +//--- the Chikou_Span plot +#property indicator_label4 "Chinkou_Span" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrLime +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 +//+------------------------------------------------------------------+ +//| Enumeration of the methods of handle creation | +//+------------------------------------------------------------------+ +enum Creation + { + Call_iIchimoku, // use iIchimoku + Call_IndicatorCreate // use IndicatorCreate + }; +//--- input parameters +input Creation type=Call_iIchimoku; // type of the function +input int tenkan_sen=9; // period of Tenkan-sen +input int kijun_sen=26; // period of Kijun-sen +input int senkou_span_b=52; // period of Senkou Span B +input string symbol=" "; // symbol +input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe +//--- indicator buffer +double Tenkan_sen_Buffer[]; +double Kijun_sen_Buffer[]; +double Senkou_Span_A_Buffer[]; +double Senkou_Span_B_Buffer[]; +double Chinkou_Span_Buffer[]; +//--- variable for storing the handle of the iIchimoku indicator +int handle; +//--- variable for storing +string name=symbol; +//--- name of the indicator on a chart +string short_name; +//--- we will keep the number of values in the Ichimoku Kinko Hyo indicator +int bars_calculated=0; +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { +//--- assignment of arrays to indicator buffers + SetIndexBuffer(0,Tenkan_sen_Buffer,INDICATOR_DATA); + SetIndexBuffer(1,Kijun_sen_Buffer,INDICATOR_DATA); + SetIndexBuffer(2,Senkou_Span_A_Buffer,INDICATOR_DATA); + SetIndexBuffer(3,Senkou_Span_B_Buffer,INDICATOR_DATA); + SetIndexBuffer(4,Chinkou_Span_Buffer,INDICATOR_DATA); +//--- set the shift for the Senkou Span channel of kijun_sen bars in the future direction + PlotIndexSetInteger(2,PLOT_SHIFT,kijun_sen); +//--- setting a shift for the Chikou Span line is not required, since the Chinkou data Span +//--- is already stored with a shift in iIchimoku +//--- determine the symbol the indicator is drawn for + name=symbol; +//--- delete spaces to the right and to the left + StringTrimRight(name); + StringTrimLeft(name); +//--- if it results in zero length of the 'name' string + if(StringLen(name)==0) + { + //--- take the symbol of the chart the indicator is attached to + name=_Symbol; + } +//--- create handle of the indicator + if(type==Call_iIchimoku) + handle=iIchimoku(name,period,tenkan_sen,kijun_sen,senkou_span_b); + else + { + //--- fill the structure with parameters of the indicator + MqlParam pars[3]; + //--- periods and shifts of the Alligator lines + pars[0].type=TYPE_INT; + pars[0].integer_value=tenkan_sen; + pars[1].type=TYPE_INT; + pars[1].integer_value=kijun_sen; + pars[2].type=TYPE_INT; + pars[2].integer_value=senkou_span_b; + //--- create handle + handle=IndicatorCreate(name,period,IND_ICHIMOKU,3,pars); + } +//--- if the handle is not created + if(handle==INVALID_HANDLE) + { + //--- tell about the failure and output the error code + PrintFormat("Failed to create handle of the iIchimoku indicator for the symbol %s/%s, error code %d", + name, + EnumToString(period), + GetLastError()); + //--- the indicator is stopped early + return(INIT_FAILED); + } +//--- show the symbol/timeframe the Ichimoku Kinko Hyo indicator is calculated for + short_name=StringFormat("iIchimoku(%s/%s, %d, %d ,%d)",name,EnumToString(period), + tenkan_sen,kijun_sen,senkou_span_b); + IndicatorSetString(INDICATOR_SHORTNAME,short_name); +//--- normal initialization of the indicator + return(INIT_SUCCEEDED); + } +//+------------------------------------------------------------------+ +//| Custom indicator iteration function | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { +//--- number of values copied from the iIchimoku indicator + int values_to_copy; +//--- determine the number of values calculated in the indicator + int calculated=BarsCalculated(handle); + if(calculated<=0) + { + PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError()); + return(0); + } +//--- if it is the first start of calculation of the indicator or if the number of values in the iIchimoku indicator changed +//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history) + if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) + { + //--- if the Tenkan_sen_Buffer array is greater than the number of values in the iIchimoku indicator for symbol/period, then we don't copy everything + //--- otherwise, we copy less than the size of indicator buffers + if(calculated>rates_total) values_to_copy=rates_total; + else values_to_copy=calculated; + } + else + { + //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate() + //--- for calculation not more than one bar is added + values_to_copy=(rates_total-prev_calculated)+1; + } +//--- fill the arrays with values of the Ichimoku Kinko Hyo indicator +//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operation + if(!FillArraysFromBuffers(Tenkan_sen_Buffer,Kijun_sen_Buffer,Senkou_Span_A_Buffer,Senkou_Span_B_Buffer,Chinkou_Span_Buffer, + kijun_sen,handle,values_to_copy)) return(0); +//--- form the message + string comm=StringFormat("%s ==> Updated value in the indicator %s: %d", + TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS), + short_name, + values_to_copy); +//--- display the service message on the chart + Comment(comm); +//--- memorize the number of values in the Ichimoku Kinko Hyo indicator + bars_calculated=calculated; +//--- return the prev_calculated value for the next call + return(rates_total); + } +//+------------------------------------------------------------------+ +//| Filling indicator buffers from the iIchimoku indicator | +//+------------------------------------------------------------------+ +bool FillArraysFromBuffers(double &tenkan_sen_buffer[], // indicator buffer of the Tenkan-sen line + double &kijun_sen_buffer[], // indicator buffer of the Kijun_sen line + double &senkou_span_A_buffer[], // indicator buffer of the Senkou Span A line + double &senkou_span_B_buffer[], // indicator buffer of the Senkou Span B line + double &chinkou_span_buffer[], // indicator buffer of the Chinkou Span line + int senkou_span_shift, // shift of the Senkou Span lines in the future direction + int ind_handle, // handle of the iIchimoku indicator + int amount // number of copied values + ) + { +//--- reset error code + ResetLastError(); +//--- fill a part of the Tenkan_sen_Buffer array with values from the indicator buffer that has 0 index + if(CopyBuffer(ind_handle,0,0,amount,tenkan_sen_buffer)<0) + { + //--- if the copying fails, tell the error code + PrintFormat("1.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError()); + //--- quit with zero result - it means that the indicator is considered as not calculated + return(false); + } + +//--- fill a part of the Kijun_sen_Buffer array with values from the indicator buffer that has index 1 + if(CopyBuffer(ind_handle,1,0,amount,kijun_sen_buffer)<0) + { + //--- if the copying fails, tell the error code + PrintFormat("2.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError()); + //--- quit with zero result - it means that the indicator is considered as not calculated + return(false); + } + +//--- fill a part of the Chinkou_Span_Buffer array with values from the indicator buffer that has index 2 +//--- if senkou_span_shift>0, the line is shifted in the future direction by senkou_span_shift bars + if(CopyBuffer(ind_handle,2,-senkou_span_shift,amount,senkou_span_A_buffer)<0) + { + //--- if the copying fails, tell the error code + PrintFormat("3.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError()); + //--- quit with zero result - it means that the indicator is considered as not calculated + return(false); + } + +//--- fill a part of the Senkou_Span_A_Buffer array with values from the indicator buffer that has index 3 +//--- if senkou_span_shift>0, the line is shifted in the future direction by senkou_span_shift bars + if(CopyBuffer(ind_handle,3,-senkou_span_shift,amount,senkou_span_B_buffer)<0) + { + //--- if the copying fails, tell the error code + PrintFormat("4.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError()); + //--- quit with zero result - it means that the indicator is considered as not calculated + return(false); + } + +//--- fill a part of the Senkou_Span_B_Buffer array with values from the indicator buffer that has 0 index +//--- when copying Chinkou Span, we don't need to consider the shift, since the Chinkou Span data +//--- is already stored with a shift in iIchimoku + if(CopyBuffer(ind_handle,4,0,amount,chinkou_span_buffer)<0) + { + //--- if the copying fails, tell the error code + PrintFormat("5.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError()); + //--- quit with zero result - it means that the indicator is considered as not calculated + return(false); + } +//--- everything is fine + return(true); + } +//+------------------------------------------------------------------+ +//| Indicator deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { + if(handle!=INVALID_HANDLE) + IndicatorRelease(handle); +//--- clear the chart after deleting the indicator + Comment(""); + } \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/MT5-TradingView.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/MT5-TradingView.ex5 new file mode 100644 index 0000000..1d8465c Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/MT5-TradingView.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/atrstoploss_ind.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/atrstoploss_ind.ex5 new file mode 100644 index 0000000..376e0ef Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/atrstoploss_ind.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/atrstoploss_ind.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/atrstoploss_ind.mq5 new file mode 100644 index 0000000..ac19757 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/atrstoploss_ind.mq5 @@ -0,0 +1,675 @@ +//+------------------------------------------------------------------+ +//| ATRStopLoss_Ind.mq5 | +//| Rosh Jardine | +//| https://roshjardine.com | +//+------------------------------------------------------------------+ +#property copyright "Rosh Jardine (MQL5/MQL4)" +#property link "https://roshjardine.com" +#property version "1.00" +#property description "Based on https://www.mql5.com/en/forum/349885 , this indicator will draw ATR based stop loss calculation with adjustable multiplier and ATR period." +#property description "This indicator includes helper functions and example to run calculation via function call so the calculation logic can be placed in external include file" +#property indicator_chart_window + +#property indicator_buffers 5 +#property indicator_plots 2 +#property indicator_type1 DRAW_LINE +#property indicator_color1 Orchid +#property indicator_style1 STYLE_SOLID +#property indicator_width1 2 +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_SOLID +#property indicator_width2 2 +#property indicator_color2 Blue +#property indicator_label1 "Up" +#property indicator_label2 "Dn" + + +//---- input parameters +input int Length=10; //how many look back periods to check the price +input int ATRperiod=10; +input double Kv=2.5; +//---- indicator buffers +double UpBuffer1[]; +double DnBuffer1[]; +double smin[]; +double smax[]; +double trend[]; + +int AtrHandle; +double AtrBfr[1]; +int bars_calculated; +string short_name; + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int OnInit() + { + bars_calculated = 0; + + short_name="ATRStopLoss_Ind"; + AtrHandle = iATR(_Symbol,_Period,ATRperiod); + if(AtrHandle==INVALID_HANDLE) + { + return(INIT_FAILED); + } + ArrayInitialize(AtrBfr,EMPTY_VALUE); + SetIndexBuffer(0,UpBuffer1); + SetIndexBuffer(1,DnBuffer1); + SetIndexBuffer(2,smin); + SetIndexBuffer(3,smax); + SetIndexBuffer(4,trend); + IndicatorSetInteger(INDICATOR_DIGITS,Digits()); + IndicatorSetString(INDICATOR_SHORTNAME,short_name); + PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,Length); + PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,Length); + PlotIndexSetInteger(0,PLOT_SHIFT,0); + PlotIndexSetInteger(1,PLOT_SHIFT,0); + return(INIT_SUCCEEDED); + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { + int limit; + if(rates_total<=Length) + return(0); + if(prev_calculated<1) + { + /* + int shift; + ArrayInitialize(UpBuffer1,EMPTY_VALUE); + ArrayInitialize(DnBuffer1,EMPTY_VALUE); + ArrayInitialize(smin,EMPTY_VALUE); + ArrayInitialize(smax,EMPTY_VALUE); + ArrayInitialize(trend,EMPTY_VALUE); + ArraySetAsSeries(UpBuffer1,true); + ArraySetAsSeries(DnBuffer1,true); + ArraySetAsSeries(smin,true); + ArraySetAsSeries(smax,true); + ArraySetAsSeries(trend,true); + + limit = rates_total-Length-1; + + for (shift=limit;shift>=0;shift--) + { + smin[shift] = -100000; smax[shift] = 100000; + for(int i=Length-1;i>=0;i--) + { + int copybuffer = CopyBuffer(AtrHandle,0,shift+i,1,AtrBfr); + if (copybuffer<1) + { + StopIndicator(); + } + smin[shift] = MathMax( smin[shift], iHigh(_Symbol,_Period,shift+i) - Kv*AtrBfr[0]); + smax[shift] = MathMin( smax[shift], iLow(_Symbol,_Period,shift+i) + Kv*AtrBfr[0]); + } + trend[shift]= trend[shift+1]; + if ( iClose(_Symbol,_Period,shift) > smax[shift+1] ) + { + trend[shift] = 1; + } + if ( iClose(_Symbol,_Period,shift) < smin[shift+1] ) + { + trend[shift] = -1; + } + if ( trend[shift] >0 ) + { + if( smin[shift]smax[shift+1] ) smax[shift]=smax[shift+1]; + UpBuffer1[shift] = EMPTY_VALUE; + DnBuffer1[shift] = smax[shift]; + } + } + */ + limit = rates_total-Length-1; + if(!AtrStopFirstRun(limit,UpBuffer1,DnBuffer1,smin,smax,trend,AtrHandle,AtrBfr,Length,_Symbol,_Period,Kv)) + { + StopIndicator(); + } + bars_calculated = limit; + return(rates_total); + } + + + else + { + limit=prev_calculated-Length-1; + + if(limit>bars_calculated) + { + if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,AtrHandle,AtrBfr,Length,_Symbol,_Period,Kv,false)) + { + StopIndicator(); + } + bars_calculated +=1; + } + else + { + if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,AtrHandle,AtrBfr,Length,_Symbol,_Period,Kv,true)) + { + StopIndicator(); + } + } + /* + if (limit>bars_calculated) + { + ArrayResize(UpBuffer1,bars_calculated+1); + ArrayResize(DnBuffer1,bars_calculated+1); + ArrayResize(smin,bars_calculated+1); + ArrayResize(smax,bars_calculated+1); + ArrayResize(trend,bars_calculated+1); + UpBuffer1[0] = DnBuffer1[0]= smin[0] = smax[0] = trend[0] = EMPTY_VALUE; + bars_calculated +=1; + } + for(int j=0;j<=1;j++) + { + smin[j] = -100000; smax[j] = 100000; + for(int k=0;k<=Length-1;k++) + { + int copybuffer = CopyBuffer(AtrHandle,0,j+k,1,AtrBfr); + if (copybuffer<1) + { + StopIndicator(); + + } + smin[j] = MathMax( smin[j], iHigh(_Symbol,_Period,j+k) - Kv*AtrBfr[0]); + smax[j] = MathMin( smax[j], iLow(_Symbol,_Period,j+k) + Kv*AtrBfr[0]); + } + trend[j]= trend[j+1]; + if ( iClose(_Symbol,_Period,j) > smax[j+1] ) trend[j] = 1; + if ( iClose(_Symbol,_Period,j) < smin[j+1] ) trend[j] = -1; + + if ( trend[j] >0 ) + { + if( smin[j]smax[j+1] ) smax[j]=smax[j+1]; + UpBuffer1[j] = EMPTY_VALUE; + DnBuffer1[j] = smax[j]; + } + }*/ + return(rates_total); + } + } + +/************************************ AS HELPERS ************************************/ +bool AtrStopNextRun(int newlimit,double &upbfr[], + double &dnbfr[],double &min[], + double &max[],double &trd[],int &atrhandler, + double &atrbuffer[],int atrlength, + const string symbol,ENUM_TIMEFRAMES tframe, + double multiplier,bool samebar) + { + if(!samebar) + { + ArrayResize(upbfr,newlimit); + ArrayResize(dnbfr,newlimit); + ArrayResize(min,newlimit); + ArrayResize(max,newlimit); + ArrayResize(trd,newlimit); + upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE; + } + else + { + upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE; + } + for(int j=0; j<=1; j++) + { + min[j] = -100000; + max[j] = 100000; + for(int k=0; k<=atrlength-1; k++) + { + int copybuffer = CopyBuffer(atrhandler,0,j+k,1,atrbuffer); + if(copybuffer<1) + { + return(false); + } + min[j] = MathMax(smin[j], iHigh(symbol,tframe,j+k) - multiplier*AtrBfr[0]); + max[j] = MathMin(smax[j], iLow(symbol,tframe,j+k) + multiplier*AtrBfr[0]); + } + trd[j]= trd[j+1]; + if(iClose(symbol,tframe,j) > max[j+1]) + { + trd[j] = 1; + } + if(iClose(symbol,tframe,j) < min[j+1]) + { + trd[j] = -1; + } + if(trd[j] >0) + { + if(min[j]max[j+1]) + { + max[j]=max[j+1]; + } + upbfr[j] = EMPTY_VALUE; + dnbfr[j] = max[j]; + } + } + return(true); + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool AtrStopFirstRun(int limit,double &upbfr[], + double &dnbfr[],double &min[], + double &max[],double &trd[],int &atrhandler, + double &atrbuffer[],int atrlength, + const string symbol,ENUM_TIMEFRAMES tframe, + double multiplier + ) + { + ArrayInitialize(upbfr,EMPTY_VALUE); + ArrayInitialize(dnbfr,EMPTY_VALUE); + ArrayInitialize(min,EMPTY_VALUE); + ArrayInitialize(max,EMPTY_VALUE); + ArrayInitialize(trd,EMPTY_VALUE); + ArraySetAsSeries(upbfr,true); + ArraySetAsSeries(dnbfr,true); + ArraySetAsSeries(min,true); + ArraySetAsSeries(max,true); + ArraySetAsSeries(trd,true); + int shift = 0; + for(shift=limit; shift>=0; shift--) + { + min[shift] = -100000; + max[shift] = 100000; + for(int i=atrlength-1; i>=0; i--) + { + int copybuffer = CopyBuffer(atrhandler,0,shift+i,1,atrbuffer); + if(copybuffer<1) + { + return(false); + } + min[shift] = MathMax(min[shift], iHigh(symbol,tframe,shift+i) - multiplier*atrbuffer[0]); + max[shift] = MathMin(max[shift], iLow(symbol,tframe,shift+i) + multiplier*atrbuffer[0]); + } + trd[shift] = trd[shift+1]; + if(iClose(symbol,tframe,shift) > max[shift+1]) + { + trd[shift] = 1; + } + if(iClose(symbol,tframe,shift) < min[shift+1]) + { + trd[shift] = -1; + } + if(trd[shift] >0) + { + if(min[shift]max[shift+1]) + { + max[shift] = max[shift+1]; + } + upbfr[shift] = EMPTY_VALUE; + dnbfr[shift] = max[shift]; + } + } + return(true); + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void StopIndicator() + { + IndicatorRelease(AtrHandle); + ChartIndicatorDelete(ChartID(),0,short_name); + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { + if(AtrHandle!=INVALID_HANDLE) + IndicatorRelease(AtrHandle); + } + + +//--- +//--- MQL4 +//--- + +#ifdef __MQL4__ +#property indicator_buffers 2 +#property indicator_color1 Blue +#property indicator_color2 Red +#property indicator_style1 STYLE_SOLID +#property indicator_width1 2 +#property indicator_style2 STYLE_SOLID +#property indicator_width2 2 +//---- input parameters +extern int Length=10; +extern int ATRperiod=10; +extern double Kv=2.5; +double UpBuffer1[]; +double DnBuffer1[]; +double smin[]; +double smax[]; +double trend[]; + +double AtrBfr[1]; +int bars_calculated; +string short_name; +int OnInit() + { + bars_calculated = 0; + + short_name="ATRStopLoss_Ind"; + SetIndexStyle(0,DRAW_LINE); + SetIndexStyle(1,DRAW_LINE); + IndicatorBuffers(5); + SetIndexBuffer(0,UpBuffer1); + SetIndexBuffer(1,DnBuffer1); + SetIndexBuffer(2,smin); + SetIndexBuffer(3,smax); + SetIndexBuffer(4,trend); + IndicatorShortName(short_name); + SetIndexLabel(0,"Up"); + SetIndexLabel(1,"Dn"); + SetIndexDrawBegin(0,Length); + SetIndexDrawBegin(1,Length); + return(INIT_SUCCEEDED); + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { + int limit; + if(rates_total<=Length) + { + return(0); + } + if(prev_calculated<1) + { + /* + int shift; + ArrayInitialize(UpBuffer1,EMPTY_VALUE); + ArrayInitialize(DnBuffer1,EMPTY_VALUE); + ArrayInitialize(smin,EMPTY_VALUE); + ArrayInitialize(smax,EMPTY_VALUE); + ArrayInitialize(trend,EMPTY_VALUE); + ArraySetAsSeries(UpBuffer1,true); + ArraySetAsSeries(DnBuffer1,true); + ArraySetAsSeries(smin,true); + ArraySetAsSeries(smax,true); + ArraySetAsSeries(trend,true); + limit = rates_total-Length-1; + for (shift=limit;shift>=0;shift--) + { + smin[shift] = -100000; + smax[shift] = 100000; + for(int i=Length-1;i>=0;i--) + { + smin[shift] = MathMax( smin[shift], iHigh(_Symbol,_Period,shift+i) - Kv*iATR(Symbol(),Period(),ATRperiod,shift+i)); + smax[shift] = MathMin( smax[shift], iLow(_Symbol,_Period,shift+i) + Kv*iATR(Symbol(),Period(),ATRperiod,shift+i)); + } + trend[shift]= trend[shift+1]; + if ( iClose(_Symbol,_Period,shift) > smax[shift+1] ) + { + trend[shift] = 1; + } + if ( iClose(_Symbol,_Period,shift) < smin[shift+1] ) + { + trend[shift] = -1; + } + if ( trend[shift] >0 ) + { + if( smin[shift]smax[shift+1] ) smax[shift]=smax[shift+1]; + UpBuffer1[shift] = EMPTY_VALUE; + DnBuffer1[shift] = smax[shift]; + } + } + */ + + /*** AS FUNCTION CALL EXAMPLE ***/ + + limit = rates_total-Length-1; + if(!AtrStopFirstRun(limit,UpBuffer1,DnBuffer1,smin,smax,trend,Length,Symbol(),Period(),Kv)) + { + return(0); + } + bars_calculated = limit; + return(rates_total); + } + else + { + limit = prev_calculated-Length-1; + /*** AS FUNCTION CALL EXAMPLE ***/ + if(limit>bars_calculated) + { + if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,Length,Symbol(),Period(),Kv,false)) + { + return(0); + } + } + if(!AtrStopNextRun(bars_calculated+1,UpBuffer1,DnBuffer1,smin,smax,trend,Length,Symbol(),Period(),Kv,true)) + { + return(0); + } + /* + if (limit>bars_calculated) + { + ArrayResize(UpBuffer1,bars_calculated+1); + ArrayResize(DnBuffer1,bars_calculated+1); + ArrayResize(smin,bars_calculated+1); + ArrayResize(smax,bars_calculated+1); + ArrayResize(trend,bars_calculated+1); + UpBuffer1[0] = DnBuffer1[0]= smin[0] = smax[0] = trend[0] = EMPTY_VALUE; + bars_calculated +=1; + } + for(int j=0;j<=1;j++) + { + smin[j] = -100000; + smax[j] = 100000; + for(int k=0;k<=Length-1;k++) + { + smin[j] = MathMax( smin[j], iHigh(Symbol(),Period(),j+k) - Kv*iATR(Symbol(),Period(),ATRperiod,j+k)); + smax[j] = MathMin( smax[j], iLow(Symbol(),Period(),j+k) + Kv*AtrBfr[0]); + } + trend[j]= trend[j+1]; + if ( iClose(Symbol(),Period(),j) > smax[j+1] ) trend[j] = 1; + if ( iClose(Symbol(),Period(),j) < smin[j+1] ) trend[j] = -1; + + if ( trend[j] >0 ) + { + if( smin[j]smax[j+1] ) smax[j]=smax[j+1]; + UpBuffer1[j] = EMPTY_VALUE; + DnBuffer1[j] = smax[j]; + } + } + */ + return(rates_total); + } + } + +/************************************ AS HELPERS ************************************/ + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool AtrStopFirstRun(int limit,double &upbfr[], + double &dnbfr[],double &min[], + double &max[],double &trd[],int atrlength, + const string symbol,const int tframe, + double multiplier + ) + { + ArrayInitialize(upbfr,EMPTY_VALUE); + ArrayInitialize(dnbfr,EMPTY_VALUE); + ArrayInitialize(min,EMPTY_VALUE); + ArrayInitialize(max,EMPTY_VALUE); + ArrayInitialize(trd,EMPTY_VALUE); + ArraySetAsSeries(upbfr,true); + ArraySetAsSeries(dnbfr,true); + ArraySetAsSeries(min,true); + ArraySetAsSeries(max,true); + ArraySetAsSeries(trd,true); + int shift = 0; + for(shift=limit; shift>=0; shift--) + { + min[shift] = -100000; + max[shift] = 100000; + for(int i=atrlength-1; i>=0; i--) + { + min[shift] = MathMax(min[shift], iHigh(symbol,tframe,shift+i) - multiplier*iATR(symbol,tframe,ATRperiod,shift+1)); + max[shift] = MathMin(max[shift], iLow(symbol,tframe,shift+i) + multiplier*iATR(symbol,tframe,ATRperiod,shift+1)); + } + trd[shift] = trd[shift+1]; + if(iClose(symbol,tframe,shift) > max[shift+1]) + { + trd[shift] = 1; + } + if(iClose(symbol,tframe,shift) < min[shift+1]) + { + trd[shift] = -1; + } + if(trd[shift] >0) + { + if(min[shift]max[shift+1]) + { + max[shift]= max[shift+1]; + } + upbfr[shift] = EMPTY_VALUE; + dnbfr[shift] = max[shift]; + } + } + return(true); + } + + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool AtrStopNextRun(int newlimit,double &upbfr[], + double &dnbfr[],double &min[], + double &max[],double &trd[],int atrlength, + const string symbol,const int tframe, + double multiplier,bool samebar) + { + if(!samebar) + { + ArrayResize(upbfr,newlimit); + ArrayResize(dnbfr,newlimit); + ArrayResize(min,newlimit); + ArrayResize(max,newlimit); + ArrayResize(trd,newlimit); + upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE; + } + else + { + upbfr[0] = dnbfr[0]= min[0] = max[0] = trd[0] = EMPTY_VALUE; + } + for(int j=0; j<=1; j++) + { + min[j] = -100000; + max[j] = 100000; + for(int k=0; k<=atrlength-1; k++) + { + min[j] = MathMax(smin[j], iHigh(symbol,tframe,j+k) - multiplier*iATR(symbol,tframe,ATRperiod,j+k)); + max[j] = MathMin(smax[j], iLow(symbol,tframe,j+k) + multiplier*iATR(symbol,tframe,ATRperiod,j+k)); + } + trd[j] = trd[j+1]; + if(iClose(symbol,tframe,j) > max[j+1]) + { + trd[j] = 1; + } + if(iClose(symbol,tframe,j) < min[j+1]) + { + trd[j] = -1; + } + if(trd[j] >0) + { + if(min[j]max[j+1]) + { + max[j] = max[j+1]; + } + upbfr[j] = EMPTY_VALUE; + dnbfr[j] = max[j]; + } + } + return(true); + } +#endif + +//+------------------------------------------------------------------+ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/candle_time_end_and_spread.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/candle_time_end_and_spread.ex5 new file mode 100644 index 0000000..12a0b98 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/candle_time_end_and_spread.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/candle_time_end_and_spread.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/candle_time_end_and_spread.mq5 new file mode 100644 index 0000000..3e60455 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/candle_time_end_and_spread.mq5 @@ -0,0 +1,62 @@ +//+------------------------------------------------------------------+ +//| CandleTimeStationary| +//| | +//| | +//+------------------------------------------------------------------+ + +#property indicator_chart_window +#property strict + +//---- input parameters +input color Clock_Color = clrDimGray; +input ENUM_BASE_CORNER Corner = CORNER_RIGHT_UPPER; + +string objname="Spread&Bar"; +double s1[]; + +//+------------------------------------------------------------------+ +//| expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() +{ + ObjectCreate(0, objname, OBJ_LABEL,0, 0, 0); + ObjectSetInteger(0, objname, OBJPROP_CORNER, Corner); + ObjectSetInteger(0, objname, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, objname, OBJPROP_YDISTANCE, 2); + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (Corner) + { + case CORNER_LEFT_UPPER: Anchor=ANCHOR_LEFT_UPPER; break; + case CORNER_RIGHT_UPPER: Anchor=ANCHOR_RIGHT_UPPER; break; + case CORNER_LEFT_LOWER: Anchor=ANCHOR_LEFT_LOWER; break; + case CORNER_RIGHT_LOWER: Anchor=ANCHOR_RIGHT_LOWER; break; + } + ObjectSetInteger(0, objname, OBJPROP_ANCHOR, Anchor); + + return(INIT_SUCCEEDED); +} +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) { ObjectDelete(0, objname); } + +//+------------------------------------------------------------------+ +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& spreads[]) +{ + ArraySetAsSeries(time, true); + int m=int(time[0]+PeriodSeconds()-TimeCurrent()); + int s=m%60; + m=(m-s)/60; + long spread=SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + string _sp="",_m="",_s=""; + if (spread<10) _sp=".."; + else if (spread<100) _sp="."; + if (m<10) _m="0"; + if (s<10) _s="0"; + + ObjectSetString(0, objname, OBJPROP_TEXT, "Spread: " +IntegerToString(spread)+_sp+" Next Bar in "+_m+IntegerToString(m)+":"+_s+IntegerToString(s)); + ObjectSetInteger(0, objname, OBJPROP_FONTSIZE, 10); + ObjectSetInteger(0, objname, OBJPROP_COLOR, Clock_Color); + ObjectSetString(0, objname, OBJPROP_FONT, "Courier"); + + return(rates_total); +} diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/chandelier_exit.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/chandelier_exit.ex5 new file mode 100644 index 0000000..c558aee Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/chandelier_exit.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/chandelier_exit.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/chandelier_exit.mq5 new file mode 100644 index 0000000..907a3ef Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/chandelier_exit.mq5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/demotradeeventprocessing.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/demotradeeventprocessing.ex5 new file mode 100644 index 0000000..6603a40 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/demotradeeventprocessing.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/demotradeeventprocessing.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/demotradeeventprocessing.mq5 new file mode 100644 index 0000000..d414b8f --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/demotradeeventprocessing.mq5 @@ -0,0 +1,172 @@ +//+------------------------------------------------------------------+ +//| DemoTradeEventProcessing.mq5 | +//| Copyright 2011, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2011, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +#property version "1.00" + +input int days=7; // depth of trade history in days +int orders; // number of active orders +int positions; // number of open positions +int deals; // number of deals in the trade history cache +int history_orders; // number of orders in the trade history cache +bool started=false; // flag of initialization of the counters +//--- let's set the limits of the trade history on the global scope +datetime start; // start date for trade history in cache +datetime end; // end date for trade history in cache +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { +//--- + end=TimeCurrent(); + start=end-days*PeriodSeconds(PERIOD_D1); + PrintFormat("Limits of the history to be loaded: start - %s, end - %s", + TimeToString(start),TimeToString(end)); + InitCounters(); +//--- + return(0); + } +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() + { +//--- + if(started) SimpleTradeProcessor(); + else InitCounters(); + } +//+------------------------------------------------------------------+ +//| Called when a Trade event comes | +//+------------------------------------------------------------------+ +void OnTrade() + { + if(started) SimpleTradeProcessor(); + else InitCounters(); + } +//+------------------------------------------------------------------+ +//| initialization of the counters of positions, orders and deals | +//+------------------------------------------------------------------+ +void InitCounters() + { + ResetLastError(); +//--- load history + bool selected=HistorySelect(start,end); + if(!selected) + { + PrintFormat("%s. Failed to load the history from %s to %s to the cache. Error code: %d", + __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError()); + return; + } +//--- get current value + orders=OrdersTotal(); + positions=PositionsTotal(); + deals=HistoryDealsTotal(); + history_orders=HistoryOrdersTotal(); + started=true; + Print("The counters of orders, positions and deals are successfully initialized"); + } +//+------------------------------------------------------------------+ +//| a simple example of processing changes in trade and history | +//+------------------------------------------------------------------+ +void SimpleTradeProcessor() + { + end=TimeCurrent(); + ResetLastError(); +//--- load history + bool selected=HistorySelect(start,end); + if(!selected) + { + PrintFormat("%s. Failed to load the history from %s to %s to the cache. Error code: %d", + __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError()); + return; + } + +//--- get current value + int curr_orders=OrdersTotal(); + int curr_positions=PositionsTotal(); + int curr_deals=HistoryDealsTotal(); + int curr_history_orders=HistoryOrdersTotal(); + +//--- check if the number of active orders has been changed + if(curr_orders!=orders) + { + //--- number of active orders has been changed + PrintFormat("Number of orders has been changed. Previous value is %d, current value is %d", + orders,curr_orders); + /* + other actions connected with change of orders + */ + //--- update value + orders=curr_orders; + } + +//--- changes in the number of open positions + if(curr_positions!=positions) + { + //--- number of open positions has been changed + PrintFormat("Number of positions has been changed. Previous value is %d, current value is %d", + positions,curr_positions); + /* + other actions connected with change of positions + */ + //--- update value + positions=curr_positions; + } + +//--- changes in the number of deals in the trade history cache + if(curr_deals!=deals) + { + //--- number of deals in the trade history cache has been changed + PrintFormat("Number of deals has been changed. Previous value is %d, current value is %d", + deals,curr_deals); + /* + other actions connected with change of deals + */ + //--- update value + deals=curr_deals; + } + +//--- changes in the number of history orders in the trade history cache + if(curr_history_orders!=history_orders) + { + //--- number of history orders in the trade history cache has been changed + PrintFormat("Number of orders in the history has been changed. Previous value is %d, current value is %d", + history_orders,curr_history_orders); + /* + other actions connected with change of the number of orders in the trade history cache + */ + //--- update value + history_orders=curr_history_orders; + } +//--- checking if it is necessary to change the limits of th trade history to be requested in cache + CheckStartDateInTradeHistory(); + } +//+------------------------------------------------------------------+ +//| changing the start date for requesting of the trade history | +//+------------------------------------------------------------------+ +void CheckStartDateInTradeHistory() + { +//--- initial interval, as if we started working right now + datetime curr_start=TimeCurrent()-days*PeriodSeconds(PERIOD_D1); +//--- make sure that the start limit of the trade history has not gone +//--- more than 1 day over intended date + if(curr_start-start>PeriodSeconds(PERIOD_D1)) + { + //--- we should correct the start date of history to be loaded in the cache + start=curr_start; + PrintFormat("New start limit of the trade history to be loaded: start => %s", + TimeToString(start)); + + //--- now load the trade history for the corrected period again + HistorySelect(start,end); + + //--- correct the number of deals and orders in the history for further comparison + history_orders=HistoryOrdersTotal(); + deals=HistoryDealsTotal(); + } + } +//+------------------------------------------------------------------+ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/detrended_synthetic_price_dbarsf.mq4 b/MQLTestWorkspace/BKPS/BKP/Smapls/detrended_synthetic_price_dbarsf.mq4 new file mode 100644 index 0000000..0598987 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/detrended_synthetic_price_dbarsf.mq4 @@ -0,0 +1,247 @@ +//------------------------------------------------------------------ +#property copyright "mladen" +#property link "mladenfx@gmail.com" +#property link "www.forex-station.com" +//------------------------------------------------------------------ +#property indicator_chart_window +#property indicator_buffers 2 +#property indicator_color1 clrLimeGreen +#property indicator_color2 clrOrangeRed +#property indicator_width1 2 +#property indicator_width2 2 +#property strict + +// +// +// +// +// + +enum enPrices +{ + pr_close, // Close + pr_open, // Open + pr_high, // High + pr_low, // Low + pr_median, // Median + pr_typical, // Typical + pr_weighted, // Weighted + pr_average, // Average (high+low+open+close)/4 + pr_medianb, // Average median body (open+close)/2 + pr_tbiased, // Trend biased price + pr_tbiased2, // Trend biased (extreme) price + pr_haclose, // Heiken ashi close + pr_haopen , // Heiken ashi open + pr_hahigh, // Heiken ashi high + pr_halow, // Heiken ashi low + pr_hamedian, // Heiken ashi median + pr_hatypical, // Heiken ashi typical + pr_haweighted, // Heiken ashi weighted + pr_haaverage, // Heiken ashi average + pr_hamedianb, // Heiken ashi median body + pr_hatbiased, // Heiken ashi trend biased price + pr_hatbiased2 // Heiken ashi trend biased (extreme) price +}; +enum enColorOn +{ + chg_onZero, // Change color on zero cross + chg_onOuter, // Change color on levels cross + chg_onOuter2, // Change color on opposite levels cross + chg_onSlope // Change color on slope change +}; +input int DspPeriod = 14; // DSP period +input enPrices Price = pr_median; // DSP price +extern int SignalPeriod = 9; // Signal period +input enColorOn ColorOn = chg_onOuter; // Change color on : + +double val[],histu[],histd[],levelu[],leveld[],state[]; + +//------------------------------------------------------------------ +// +//------------------------------------------------------------------ +// +// +// +// +// + +int OnInit() +{ + IndicatorBuffers(6); + SetIndexBuffer( 0, histu); SetIndexStyle(0,DRAW_HISTOGRAM); + SetIndexBuffer( 1, histd); SetIndexStyle(1,DRAW_HISTOGRAM); + SetIndexBuffer( 2, val); + SetIndexBuffer( 3, levelu); + SetIndexBuffer( 4, leveld); + SetIndexBuffer( 5, state); + IndicatorShortName("DSP bars ("+(string)DspPeriod+")"); + return(0); +} +void OnDeinit(const int reason) { } +//------------------------------------------------------------------ +// +//------------------------------------------------------------------ +// +// +// +// +// + +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) +{ + int counted_bars = prev_calculated; + if(counted_bars < 0) return(-1); + if(counted_bars > 0) counted_bars--; + int limit=MathMin(rates_total-counted_bars,rates_total-1); + + // + // + // + // + // + + double alphas = 2.0/(1.0+SignalPeriod); + double alpham = 2.0/(1.0+DspPeriod); + for(int i=limit; i>=0 && !_StopFlag; i--) + { + double price = getPrice(Price,open,close,high,low,i,rates_total); + val[i] = iEma(price,alpham,i,rates_total,0)-iEma(price,alpham/2.0,i,rates_total,1); + levelu[i] = (i0) ? levelu[i+1]+alphas*(val[i]-levelu[i+1]) : levelu[i+1] : 0; + leveld[i] = (ilevelu[i]) ? 1 : (val[i]levelu[i]) ? 1 : (val[i]0) ? 1 : (val[i]<0) ? -1 : 0; break; + default : state[i] = (ival[i+1]) ? 1 : (val[i]0 && alpha!=-1) + workEma[r][instanceNo] = workEma[r-1][instanceNo]+alpha*(price-workEma[r-1][instanceNo]); + return(workEma[r][instanceNo]); +} + +//------------------------------------------------------------------ +// +//------------------------------------------------------------------ +// +// +// +// +// +// + +#define _priceInstances 1 +#define _priceInstancesSize 4 +double workHa[][_priceInstances*_priceInstancesSize]; +double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int bars, int instanceNo=0) +{ + if (tprice>=pr_haclose) + { + if (ArrayRange(workHa,0)!= bars) ArrayResize(workHa,bars); instanceNo*=_priceInstancesSize; + int r = bars-i-1; + + // + // + // + // + // + + double haOpen; + if (r>0) + haOpen = (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0; + else haOpen = (open[i]+close[i])/2; + double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0; + double haHigh = MathMax(high[i], MathMax(haOpen,haClose)); + double haLow = MathMin(low[i] , MathMin(haOpen,haClose)); + + if(haOpen haOpen) + return((haHigh+haClose)/2.0); + else return((haLow+haClose)/2.0); + case pr_hatbiased2: + if (haClose>haOpen) return(haHigh); + if (haCloseopen[i]) + return((high[i]+close[i])/2.0); + else return((low[i]+close[i])/2.0); + case pr_tbiased2: + if (close[i]>open[i]) return(high[i]); + if (close[i]= 0; v--) + { + ulong positionticket = PositionGetTicket(v); + if(PositionSelectByTicket(positionticket)) + { + if(PositionGetDouble(POSITION_SL) != 0) + { + + delta = (SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_VALUE) / SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_SIZE)) * GetPips2Dbl(PositionGetString(POSITION_SYMBOL)); + sl_value = ((MathAbs(PositionGetDouble(POSITION_PRICE_OPEN) - PositionGetDouble(POSITION_SL)) * delta) * PositionGetDouble(POSITION_VOLUME)) * GetMultiplier(PositionGetString(POSITION_SYMBOL)); + sl_value -= PositionGetDouble(POSITION_SWAP); + sl_value = -(sl_value); + total_sl_value += sl_value; + } + } + } + return(NormalizeDouble(total_sl_value, 2)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +double GetTotalTPValue() + { + double tp_value = 0, total_tp_value = 0, delta; + + for(int v = PositionsTotal() - 1; v >= 0; v--) + { + ulong positionticket = PositionGetTicket(v); + if(PositionSelectByTicket(positionticket)) + { + if(PositionGetDouble(POSITION_TP) != 0) + { + delta = (SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_VALUE) / SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_SIZE)) * GetPips2Dbl(PositionGetString(POSITION_SYMBOL)); + tp_value = ((MathAbs(PositionGetDouble(POSITION_PRICE_OPEN) - PositionGetDouble(POSITION_TP)) * delta) * PositionGetDouble(POSITION_VOLUME)) * GetMultiplier(PositionGetString(POSITION_SYMBOL)); + tp_value -= PositionGetDouble(POSITION_SWAP); + total_tp_value += tp_value; + } + } + } + return(NormalizeDouble(total_tp_value, 2)); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void Display_Info() + { + total = "" + + "SL: $ " + DoubleToString(total_sl, 2) + " " + "TP: $ " + DoubleToString(total_tp, 2); + ObjectSetString(0, label, OBJPROP_TEXT, total); + ChartRedraw(0); + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTick() + { + total_sl = GetTotalSLValue(); + total_tp = GetTotalTPValue(); + if((total_sl != prev_total_sl) || (total_tp != prev_total_tp)) + { + Display_Info(); + prev_total_sl = total_sl; + prev_total_tp = total_tp; + } + } +//+------------------------------------------------------------------+ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/heiken_ashi.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/heiken_ashi.ex5 new file mode 100644 index 0000000..7f89945 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/heiken_ashi.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/heiken_ashi.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/heiken_ashi.mq5 new file mode 100644 index 0000000..215dfc1 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/heiken_ashi.mq5 @@ -0,0 +1,87 @@ + +//+------------------------------------------------------------------+ +//| Heiken_Ashi.mq5 | +//| Copyright 2009, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +//--- indicator settings +#property indicator_chart_window +#property indicator_buffers 5 +#property indicator_plots 1 +#property indicator_type1 DRAW_COLOR_CANDLES +#property indicator_color1 DodgerBlue, Red +#property indicator_label1 "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close" +//--- indicator buffers +double ExtOBuffer[]; +double ExtHBuffer[]; +double ExtLBuffer[]; +double ExtCBuffer[]; +double ExtColorBuffer[]; +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//--- indicator buffers mapping + SetIndexBuffer(0,ExtOBuffer,INDICATOR_DATA); + SetIndexBuffer(1,ExtHBuffer,INDICATOR_DATA); + SetIndexBuffer(2,ExtLBuffer,INDICATOR_DATA); + SetIndexBuffer(3,ExtCBuffer,INDICATOR_DATA); + SetIndexBuffer(4,ExtColorBuffer,INDICATOR_COLOR_INDEX); +//--- + IndicatorSetInteger(INDICATOR_DIGITS,_Digits); +//--- sets first bar from what index will be drawn + IndicatorSetString(INDICATOR_SHORTNAME,"Heiken Ashi"); +//--- sets drawing line empty value + PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); +//--- initialization done + } +//+------------------------------------------------------------------+ +//| Heiken Ashi | +//+------------------------------------------------------------------+ +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 &TickVolume[], + const long &Volume[], + const int &Spread[]) + { + int i,limit; +//--- preliminary calculations + if(prev_calculated==0) + { + //--- set first candle + ExtLBuffer[0]=Low[0]; + ExtHBuffer[0]=High[0]; + ExtOBuffer[0]=Open[0]; + ExtCBuffer[0]=Close[0]; + limit=1; + } + else limit=prev_calculated-1; + +//--- the main loop of calculations + for(i=limit;i0) counted_bars--; + + limit = MathMax(rates_total - counted_bars - Lb, 1); + + + + CopyBuffer(hMAHigh, 0, 0, limit+1, MAHigh); + CopyBuffer(hMALow, 0, 0, limit+1, MALow); + + for(i=limit; i>=0; i--) + { + + Hlv[i]=Hlv[i+1]; + + if (close[rates_total-1-i] > MAHigh[limit-i]) Hlv[i]= 1; + if (close[rates_total-1-i] < MALow[limit-i]) Hlv[i]= -1; + + if(Hlv[i]==-1) + { + ssld[i] = MAHigh[limit-i]; + sslu[i] = MALow[limit-i]; + } + else + { + ssld[i] = MALow[limit-i]; + sslu[i] = MAHigh[limit-i]; + } + + } + +//--- return value of prev_calculated for next call + return(rates_total); + } +//+------------------------------------------------------------------+ \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/ssl_channel_chart.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/ssl_channel_chart.mq5 new file mode 100644 index 0000000..9821142 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/ssl_channel_chart.mq5 @@ -0,0 +1,115 @@ +//+------------------------------------------------------------------+ +//| SSL Channel Chart.mq5 | +//| Copyright 2020, MetaQuotes Software Corp. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2020, MetaQuotes Software Corp." +#property link "https://www.mql5.com" + +//------------------------------------------------------------------ +#property indicator_chart_window +#property indicator_buffers 3 +#property indicator_plots 2 +#property indicator_label1 "Bears" +#property indicator_color1 clrOrange +#property indicator_type1 DRAW_LINE +#property indicator_width1 2 +#property indicator_label2 "Bulls" +#property indicator_color2 clrAqua +#property indicator_type2 DRAW_LINE +#property indicator_width2 2 + + +//------------------------------------------------------------------ + +//---- input parameters +input ENUM_MA_METHOD MA_Method = MODE_SMA; // Method +input int Lb = 10; +//---- buffers + +double ssld[]; +double sslu[]; +double Hlv[]; + +int hMAHigh; +int hMALow; +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { + + SetIndexBuffer(0, ssld, INDICATOR_DATA); + SetIndexBuffer(1, sslu, INDICATOR_DATA); + SetIndexBuffer(2, Hlv, INDICATOR_CALCULATIONS); + + hMAHigh = iMA(_Symbol, PERIOD_CURRENT, Lb, 0, MA_Method, PRICE_HIGH); + hMALow = iMA(_Symbol, PERIOD_CURRENT, Lb, 0, MA_Method, PRICE_LOW); + + + if(hMAHigh==INVALID_HANDLE)Print(" Failed to get handle of the iMA indicator"); + if(hMALow==INVALID_HANDLE)Print(" Failed to get handle of the iMA indicator"); + + ArraySetAsSeries(ssld,true); + ArraySetAsSeries(sslu,true); + ArraySetAsSeries(Hlv,true); +//--- + return(INIT_SUCCEEDED); + } + +//+------------------------------------------------------------------+ +//| Custom indicator iteration function | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { +//--- + int counted_bars = prev_calculated; + int i,limit; + + double MAHigh[]; + double MALow[]; + + if(counted_bars<0) return(-1); + if(counted_bars>0) counted_bars--; + + limit = MathMax(rates_total - counted_bars - Lb, 1); + + + + CopyBuffer(hMAHigh, 0, 0, limit+1, MAHigh); + CopyBuffer(hMALow, 0, 0, limit+1, MALow); + + for(i=limit; i>=0; i--) + { + + Hlv[i]=Hlv[i+1]; + + if (close[rates_total-1-i] > MAHigh[limit-i]) Hlv[i]= 1; + if (close[rates_total-1-i] < MALow[limit-i]) Hlv[i]= -1; + + if(Hlv[i]==-1) + { + ssld[i] = MAHigh[limit-i]; + sslu[i] = MALow[limit-i]; + } + else + { + ssld[i] = MALow[limit-i]; + sslu[i] = MAHigh[limit-i]; + } + + } + +//--- return value of prev_calculated for next call + return(rates_total); + } +//+------------------------------------------------------------------+ \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/tradecontrol_en.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/tradecontrol_en.ex5 new file mode 100644 index 0000000..af93a95 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/tradecontrol_en.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/tradecontrol_en.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/tradecontrol_en.mq5 new file mode 100644 index 0000000..fa68829 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/Smapls/tradecontrol_en.mq5 @@ -0,0 +1,505 @@ +//+------------------------------------------------------------------+ +//| TradeControl_en.mq5 | +//| Copyright KlimMalgin | +//| | +//+------------------------------------------------------------------+ +#property copyright "KlimMalgin" +#property link "" +#property version "1.00" + + +datetime start_date = 0; // Date, from which we begin to read history + +int OrdersPrev = 0; // Number of orders at the time of previous OnTrade() call +int PositionsPrev = 0; // Number of positions at the time of previous OnTrade() call +ulong LastOrderTicket = 0; // Ticket of the last processed order + +int _GetLastError=0; // Error code +long state=0; // Order state + +/* + * + * Structure that stores information about positions + * + */ +struct _position +{ + +long type, // Position type + magic; // Magic number for position +datetime time; // Time of position opening + +double volume, // Position volume + priceopen, // Position price + sl, // Stop Loss level for opened position + tp, // Take Profit level for opened position + pricecurrent, // Symbol current price + comission, // Commission + swap, // Accumulated swap + profit; // Current profit + +string symbol, // Symbol, by which the position has been opened + comment; // Comment to position +}; + +int _ExpertPositionsTotal = 0; + +_position PositionList[], // Array that stores info about position + PrevPositionList[]; + + +/* + * + * Structure that stores information about orders + * + */ +struct _orders +{ + +datetime time_setup, // Time of order placement + time_expiration, // Time of order expiration + time_done; // Time of order execution or cancellation + +long type, // Order type + state, // Order state + type_filling, // Type of execution by remainder + type_time, // Order lifetime + ticket; // Order ticket + +long magic, // Id of Expert Advisor, that placed an order + // (intended to ensure that each Expert + // must place it's own unique number) + + position_id; // Position id, that is placed on order, + // when it is executed. Each executed order invokes a + // deal, that opens new or changes existing + // position. Id of that position is placed on + // executed order in this moment. + +double volume_initial, // Initial volume on order placement + volume_current, // Unfilled volume + price_open, // Price, specified in the order + sl, // Stop Loss level + tp, // Take Profit level + price_current, // Current price by order symbol + price_stoplimit; // Price of placing Limit order when StopLimit order is triggered + +string symbol, // Symbol, by which the order has been placed + comment; // Comment + +}; + +int _ExpertOrdersTotal = 0; + +_orders OrderList[], // Arrays that store info about orders + PrevOrderList[]; + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { +//--- +start_date = 0; + +OrdersPrev = OrdersTotal(); +PositionsPrev = PositionsTotal(); + +GetPosition(PrevPositionList); +GetOrders(PrevOrderList); +//--- + return(0); + } +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { +//--- + + } +//+------------------------------------------------------------------+ +//| OnTrade function | +//+------------------------------------------------------------------+ +void OnTrade() + { +//--- +GetPosition(PositionList); +GetOrders(OrderList); +datetime dc = TimeCurrent(); +HistorySelect(start_date,dc); + + +Alert("The Trade event occurred"); + +if (OrdersPrev < OrdersTotal()) +{ + OrderGetTicket(OrdersTotal()-1);// Select the last order to work with + _GetLastError=GetLastError(); + Print("Error #",_GetLastError);ResetLastError(); + //-- + if (OrderGetInteger(ORDER_STATE) == ORDER_STATE_STARTED) + { + Alert(OrderGetTicket(OrdersTotal()-1),"Order has arrived for processing"); + LastOrderTicket = OrderGetTicket(OrdersTotal()-1); // Saving the order ticket for further work + } + + + state = OrderGetInteger(ORDER_STATE); + if (state == ORDER_STATE_PLACED) + { + switch(OrderGetInteger(ORDER_TYPE)) + { + case 2: + Alert("Pending order Buy Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!"); + break; + + case 3: + Alert("Pending order Sell Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!"); + break; + + case 4: + Alert("Pending order Buy Stop #", OrderGetTicket(OrdersTotal()-1)," accepted!"); + break; + + case 5: + Alert("Pending order Sell Stop #", OrderGetTicket(OrdersTotal()-1)," accepted!"); + break; + + case 6: + Alert("Pending order Buy Stop Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!"); + break; + + case 7: + Alert("Pending order Sell Stop Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!"); + break; + } + + } + + + +} +else if(OrdersPrev > OrdersTotal()) +{ + state = HistoryOrderGetInteger(LastOrderTicket,ORDER_STATE); + + // If order is not found, generate an error + _GetLastError=GetLastError(); + if (_GetLastError != 0){Alert("Error #",_GetLastError," Order ",LastOrderTicket," is not found!");LastOrderTicket = 0;} + Print("Error #",_GetLastError," state: ",state);ResetLastError(); + + + // If order is fully executed + if (state == ORDER_STATE_FILLED) + { + // Then analyze the last deal + // -- + Alert(LastOrderTicket, "Order executed, going to deal"); + switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ENTRY)) + { + + // Entering the market + case DEAL_ENTRY_IN: + Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER), + " order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1)); + + switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE)) + { + case 0: + // If volumes of position and deal are equal, then position has just been opened + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) + && (PositionGetDouble(POSITION_VOLUME) == HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME))) + { + Alert("Buy position has been opened on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)); + } + else + // If volumes of position and deal are not equal, then position has been incremented + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) + && (PositionGetDouble(POSITION_VOLUME) > HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME))) + { + Alert("Buy position has incremented on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)); + } + break; + + case 1: + // If volumes of position and deal are equal, then position has just been opened + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) + && (PositionGetDouble(POSITION_VOLUME) == HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME))) + { + Alert("Sell position has been opened on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)); + } + else + // If volumes of position and deal are not equal, then position has been incremented + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) + && (PositionGetDouble(POSITION_VOLUME) > HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME))) + { + Alert("Sell position has incremented on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)); + } + + break; + + default: + Alert("Unprocessed code of type: ", + HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE)); + break; + } + break; + + // Âûõîä èç ðûíêà + case DEAL_ENTRY_OUT: + Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER), + " order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1)); + + switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE)) + { + case 0: + // If position, we tried to close, is still present, then we have closed only part of it + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == true) + { + Alert("Part of Sell position has been closed on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL), + " with profit = ", + HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT)); + } + else + // If position is not found, then it is fully closed + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == false) + { + Alert("Sell position has been closed on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL), + " with profit = ", + HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT)); + } + break; + + case 1: + // If position, we tried to close, is still present, then we have closed only part of it + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == true) + { + Alert("Part of Buy position has been closed on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL), + " with profit = ", + HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT)); + } + else + // If position is not found, then it is fully closed + if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == false) + { + Alert("Buy position has been closed on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL), + " with profit = ", + HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT)); + } + + break; + + default: + Alert("Unprocessed code of type: ", + HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE)); + break; + } + break; + + // Reverse + case DEAL_ENTRY_INOUT: + Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER), + " order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1)); + + switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE)) + { + case 0: + Alert("Sell is reversed to Buy on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL), + " resulting profit = ", + HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT)); + break; + + case 1: + Alert("Buy is reversed to Sell on pair ", + HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL), + " resulting profit = ", + HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT)); + break; + + default: + Alert("Unprocessed code of type: ", + HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE)); + break; + } + break; + + // Indicates the state record + case DEAL_ENTRY_STATE: + Alert("Indicates the state record. Unprocessed code of direction: ", + HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE)); + break; + } + // -- + } + +} + + +if ((PositionsPrev == PositionsTotal()) && (OrdersPrev == OrdersTotal())) +{ + string _alerts = ""; + bool modify = false; + + for (int i=0;i<_ExpertPositionsTotal;i++) + { + if (PrevPositionList[i].sl != PositionList[i].sl) + { + _alerts += "On pair "+PositionList[i].symbol+" Stop Loss changed from "+ PrevPositionList[i].sl +" to "+ PositionList[i].sl +"\n"; + modify = true; + } + if (PrevPositionList[i].tp != PositionList[i].tp) + { + _alerts += "On pair "+PositionList[i].symbol+" Take Profit changed from "+ PrevPositionList[i].tp +" to "+ PositionList[i].tp +"\n"; + modify = true; + } + + } + + for (int i = 0;i<_ExpertOrdersTotal;i++) + { + if (PrevOrderList[i].sl != OrderList[i].sl) + { + _alerts += "Order "+OrderList[i].ticket+" has changed Stop Loss from "+ PrevOrderList[i].sl +" to "+ OrderList[i].sl +"\n"; + modify = true; + } + if (PrevOrderList[i].tp != OrderList[i].tp) + { + _alerts += "Order "+OrderList[i].ticket+" has changed Take Profit from "+ PrevOrderList[i].tp +" to "+ OrderList[i].tp +"\n"; + modify = true; + } + } + + if (modify == true) + { + Alert(_alerts); + modify = false; + } +} + + +GetPosition(PrevPositionList); +GetOrders(PrevOrderList); +OrdersPrev = OrdersTotal(); +PositionsPrev = PositionsTotal(); + +//--- + } +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() + { +//--- + + } +//+------------------------------------------------------------------+ + + + +void GetPosition(_position &Array[]) + { + int _GetLastError=0,_PositionsTotal=PositionsTotal(); + + int temp_value=(int)MathMax(_PositionsTotal,1); + ArrayResize(Array, temp_value); + + _ExpertPositionsTotal=0; + for(int z=_PositionsTotal-1; z>=0; z--) + { + if(!PositionSelect(PositionGetSymbol(z))) + { + _GetLastError=GetLastError(); + Print("OrderSelect() - Error #",_GetLastError); + continue; + } + else + { + // If the position is found, then put its info to the array + Array[z].type = PositionGetInteger(POSITION_TYPE); + Array[z].time = PositionGetInteger(POSITION_TIME); + Array[z].magic = PositionGetInteger(POSITION_MAGIC); + Array[z].volume = PositionGetDouble(POSITION_VOLUME); + Array[z].priceopen = PositionGetDouble(POSITION_PRICE_OPEN); + Array[z].sl = PositionGetDouble(POSITION_SL); + Array[z].tp = PositionGetDouble(POSITION_TP); + Array[z].pricecurrent = PositionGetDouble(POSITION_PRICE_CURRENT); + Array[z].comission = PositionGetDouble(POSITION_COMMISSION); + Array[z].swap = PositionGetDouble(POSITION_SWAP); + Array[z].profit = PositionGetDouble(POSITION_PROFIT); + Array[z].symbol = PositionGetString(POSITION_SYMBOL); + Array[z].comment = PositionGetString(POSITION_COMMENT); + _ExpertPositionsTotal++; + } + } + + temp_value=(int)MathMax(_ExpertPositionsTotal,1); + ArrayResize(Array,temp_value); + } +//+------------------------------------------------------------------+ + + + +//+------------------------------------------------------------------+ +//| Function GetOrders() | +//+------------------------------------------------------------------+ +void GetOrders(_orders &OrdersList[]) + { + + int _GetLastError=0,_OrdersTotal=OrdersTotal(); + + int temp_value=(int)MathMax(_OrdersTotal,1); + ArrayResize(OrdersList,temp_value); + + _ExpertOrdersTotal=0; + for(int z=_OrdersTotal-1; z>=0; z--) + { + if(!OrderGetTicket(z)) + { + _GetLastError=GetLastError(); + Print("GetOrders() - Error #",_GetLastError); + continue; + } + else + { + OrdersList[z].ticket = OrderGetTicket(z); + OrdersList[z].time_setup = OrderGetInteger(ORDER_TIME_SETUP); + OrdersList[z].time_expiration = OrderGetInteger(ORDER_TIME_EXPIRATION); + OrdersList[z].time_done = OrderGetInteger(ORDER_TIME_DONE); + OrdersList[z].type = OrderGetInteger(ORDER_TYPE); + + OrdersList[z].state = OrderGetInteger(ORDER_STATE); + OrdersList[z].type_filling = OrderGetInteger(ORDER_TYPE_FILLING); + OrdersList[z].type_time = OrderGetInteger(ORDER_TYPE_TIME); + OrdersList[z].magic = OrderGetInteger(ORDER_MAGIC); + OrdersList[z].position_id = OrderGetInteger(ORDER_POSITION_ID); + + OrdersList[z].volume_initial = OrderGetDouble(ORDER_VOLUME_INITIAL); + OrdersList[z].volume_current = OrderGetDouble(ORDER_VOLUME_CURRENT); + OrdersList[z].price_open = OrderGetDouble(ORDER_PRICE_OPEN); + OrdersList[z].sl = OrderGetDouble(ORDER_SL); + OrdersList[z].tp = OrderGetDouble(ORDER_TP); + OrdersList[z].price_current = OrderGetDouble(ORDER_PRICE_CURRENT); + OrdersList[z].price_stoplimit = OrderGetDouble(ORDER_PRICE_STOPLIMIT); + + OrdersList[z].symbol = OrderGetString(ORDER_SYMBOL); + OrdersList[z].comment = OrderGetString(ORDER_COMMENT); + + _ExpertOrdersTotal++; + } + } + + temp_value=(int)MathMax(_ExpertOrdersTotal,1); + ArrayResize(OrdersList,temp_value); + + } +//+------------------------------------------------------------------+ \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/wma.ex5 b/MQLTestWorkspace/BKPS/BKP/Smapls/wma.ex5 new file mode 100644 index 0000000..322c9c7 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/wma.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/Smapls/wma.mq5 b/MQLTestWorkspace/BKPS/BKP/Smapls/wma.mq5 new file mode 100644 index 0000000..6194431 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/Smapls/wma.mq5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.indicator.ex5 b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.indicator.ex5 new file mode 100644 index 0000000..b043c3c Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.indicator.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.indicator.mq5 b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.indicator.mq5 new file mode 100644 index 0000000..44668e9 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.indicator.mq5 @@ -0,0 +1,1874 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121 Indicator +// --------------------------------------------- +// Name: X121 +// Description: Market Analyser +// 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 X121 Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// PEAKSANDVALES ... + +// +input group "Peaks and Vales"; + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +// SUPPORTSANDRESISTANCE ... + +// +input group "Support and Resistance"; + +// +input group "Level 1"; +input ENUM_X_PERIOD_METHOD level1Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES level1Period = NULL; // Time Period + +// +input group "Level 2"; +input ENUM_X_PERIOD_METHOD level2Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES level2Period = NULL; // Time Period + +// +input group "Level 3"; +input ENUM_X_PERIOD_METHOD level3Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES level3Period = NULL; // Time Period + +// +input group "Level 4"; +input ENUM_X_PERIOD_METHOD level4Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES level4Period = NULL; // Time Period + +// +// MA Crosses ... +input group "Moving Averages"; + +// +input group "Fast"; +input int fastMaLength = 9; // Length +input int fastMaShift = 0; // Shift +input ENUM_MA_METHOD fastMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE fastMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Slow"; +input int slowMaLength = 18; // Length +input int slowMaShift = 0; // Shift +input ENUM_MA_METHOD slowMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE slowMaAppliedTo = PRICE_CLOSE; // Applied To + +// +// ICHIMOKU Kinko Hyo ... + +// +input group "Ichimoku Kinko Hyo"; + +// +// TENKANSEN ... +input group "Tenkan Sen"; +input int tenkanSenLength = 9; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// KIJUNSEN ... +input group "Kijun Sen"; +input int kijunSenLength = 26; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// SENKOUSPANB ... +input group "Senkou Span B"; +input int senkouSpanBLength = 52; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// CHIKOUSPAN ... +input group "Chikou Span"; +input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type + +// +input group "Presentation"; + +// +input group "Peaks and Vales"; +input bool showPeaksAndVales = true; // Show Peaks and Vales + +// +input group "Support and Resistance"; +input bool showSRLevel1 = true; // Show Level 1 +input bool showSRLevel2 = true; // Show Level 2 +input bool showSRLevel3 = true; // Show Level 3 +input bool showSRLevel4 = true; // Show Level 4 + +// +input group "Moving Averages"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow + +// +input group "Ichimoku Kinko Hyo"; +input bool showTenkanSen = true; // Show Tenkan Sen +input bool showKijunSen = true; // Show Kijun Sen +input bool showChikouSpan = true; // Show Chikou Span +input bool showKumo = true; // Show Kumo + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// 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" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 27 +#property indicator_plots 18 + +// +// PLOTTED Buffers ... + +// +double rUpBuffer[]; +double rUpColorBuffer[]; + +// +#property indicator_label1 "X121 R UP" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, CLR_NONE +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +double rDownBuffer[]; +double rDownColorBuffer[]; + +// +#property indicator_label2 "X121 R Down" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrMagenta, CLR_NONE +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +double peaksBuffer[]; + +// +#property indicator_label3 "X121 PEAKS" +#property indicator_type3 DRAW_ARROW +#property indicator_color3 clrAqua +#property indicator_width3 3 + +// +// VALES ... + +// +double valesBuffer[]; + +// +#property indicator_label4 "X121 VALES" +#property indicator_type4 DRAW_ARROW +#property indicator_color4 clrMagenta +#property indicator_width4 3 + +// +// MA ... + +// +// FAST ... +double fastMaBuffer[]; + +// +#property indicator_label5 "X121 MA F" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrYellow +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +// SLOW ... +double slowMaBuffer[]; + +// +#property indicator_label6 "X121 MA S" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrDarkOrange +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// SUPPORTANDRESISTANCE ... + +// +// LEVEL 1 ... + +// +// UP ... +double srLevel1UpBuffer[]; + +// +#property indicator_label7 "X121 L1 Up" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// DOWN ... +double srLevel1DownBuffer[]; + +// +#property indicator_label8 "X121 L1 Down" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrLightGray +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +// LEVEL 2 ... + +// +// UP ... +double srLevel2UpBuffer[]; + +// +#property indicator_label9 "X121 L2 Up" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrLightGray +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +// DOWN ... +double srLevel2DownBuffer[]; + +// +#property indicator_label10 "X121 L2 Down" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrLightGray +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +// LEVEL 3 ... + +// +// UP ... +double srLevel3UpBuffer[]; + +// +#property indicator_label11 "X121 L3 Up" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrLightGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +// DOWN ... +double srLevel3DownBuffer[]; + +// +#property indicator_label12 "X121 L3 Down" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrLightGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// LEVEL 4 ... + +// +// UP ... +double srLevel4UpBuffer[]; + +// +#property indicator_label13 "X121 L4 Up" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrLightGray +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +// DOWN ... +double srLevel4DownBuffer[]; + +// +#property indicator_label14 "X121 L4 Down" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrLightGray +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +// ICHIMOKU ... + +// +// TENKANSEN ... + +// +double tenkanSenBuffer[]; + +// +#property indicator_label15 "X121 Tenkan Sen" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrBrown +#property indicator_style15 STYLE_SOLID +#property indicator_width15 1 + +// +// KIJUNSEN ... + +// +double kijunSenBuffer[]; + +// +#property indicator_label16 "X121 Kijun Sen" +#property indicator_type16 DRAW_LINE +#property indicator_color16 clrDodgerBlue +#property indicator_style16 STYLE_SOLID +#property indicator_width16 1 + +// +// CHIKOUSPAN ... + +// +double chikouSpanBuffer[]; + +// +#property indicator_label17 "X121 Chikou Span" +#property indicator_type17 DRAW_LINE +#property indicator_color17 clrDarkGreen +#property indicator_style17 STYLE_SOLID +#property indicator_width17 1 + +// +// SENKOUSPANA ... +double senkouSpanABuffer[]; + +// +// SENKOUSPANB ... +double senkouSpanBBuffer[]; + +// +// KUMOCLOUD ... +#property indicator_label18 "X121 Kumo" +#property indicator_type18 DRAW_FILLING +#property indicator_color18 clrAqua, clrMagenta +#property indicator_style18 STYLE_SOLID +#property indicator_width18 1 + +// +// DATA Buffers ... + +// +double sHHBuffer[]; +double sLLBuffer[]; + +// +double mHHBuffer[]; +double mLLBuffer[]; + +// +double lHHBuffer[]; +double lLLBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +ENUM_SERIESMODE mTenkanSenTopMode = NULL; +ENUM_SERIESMODE mTenkanSenBottomMode = NULL; + +// +ENUM_SERIESMODE mKijunSenTopMode = NULL; +ENUM_SERIESMODE mKijunSenBottomMode = NULL; + +// +ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; +ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; + +// +int currentPeriodSecconds = 0; + +// +int mLevel1Candles; +double mSRLastL1Up; +double mSRLastL1Down; +int mLastLevel1StartBarIndex = 0; +datetime mLevel1StartTime = NULL; +ENUM_TIMEFRAMES mLevel1Period = NULL; + +// +int mLevel2Candles; +double mSRLastL2Up; +double mSRLastL2Down; +int mLastLevel2StartBarIndex = 0; +datetime mLevel2StartTime = NULL; +ENUM_TIMEFRAMES mLevel2Period = NULL; + +// +int mLevel3Candles; +double mSRLastL3Up; +double mSRLastL3Down; +int mLastLevel3StartBarIndex = 0; +datetime mLevel3StartTime = NULL; +ENUM_TIMEFRAMES mLevel3Period = NULL; + +// +int mLevel4Candles; +double mSRLastL4Up; +double mSRLastL4Down; +int mLastLevel4StartBarIndex = 0; +datetime mLevel4StartTime = NULL; +ENUM_TIMEFRAMES mLevel4Period = NULL; + +// +int fastMaHandler = INVALID_HANDLE; +int slowMaHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // MA Initialization ... + + // + // FAST ... + fastMaHandler = iMA( + _Symbol, + _Period, + fastMaLength, + fastMaShift, + fastMaMethod, + fastMaAppliedTo); + if (fastMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + return INIT_FAILED; + } + + // + // SLOW ... + slowMaHandler = iMA( + _Symbol, + _Period, + slowMaLength, + slowMaShift, + slowMaMethod, + slowMaAppliedTo); + if (slowMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + return INIT_FAILED; + } + + // + if (currentPeriodSecconds == 0) + { + currentPeriodSecconds = PeriodSeconds(_Period); + } + + // + // Finde Level 1 Period ... + if (mLevel1Period == NULL) + { + // + if (level1Method == X_PERIOD_AUTO) + { + mLevel1Period = GetNearestTimeFrame(_Period); + } + else + { + mLevel1Period = level1Period; + } + + // + int level1PeriodSecconds = PeriodSeconds(mLevel1Period); + + // + mLevel1Candles = level1PeriodSecconds / currentPeriodSecconds; + } + + // + // Finde Level 2 Period ... + if (mLevel2Period == NULL) + { + // + if (level2Method == X_PERIOD_AUTO) + { + mLevel2Period = GetMediestTimeFrame(_Period); + } + else + { + mLevel2Period = level2Period; + } + + // + int level2PeriodSecconds = PeriodSeconds(mLevel2Period); + + // + mLevel2Candles = level2PeriodSecconds / currentPeriodSecconds; + } + + // + // Finde Level 3 Period ... + if (mLevel3Period == NULL) + { + // + if (level3Method == X_PERIOD_AUTO) + { + mLevel3Period = GetFarestTimeFrame(_Period); + } + else + { + mLevel3Period = level3Period; + } + + // + int level3PeriodSecconds = PeriodSeconds(mLevel3Period); + + // + mLevel3Candles = level3PeriodSecconds / currentPeriodSecconds; + } + + // + // Finde Level 4 Period ... + if (mLevel4Period == NULL) + { + // + if (level4Method == X_PERIOD_AUTO) + { + mLevel4Period = GetHindmostTimeFrame(_Period); + } + else + { + mLevel4Period = level4Period; + } + + // + int level4PeriodSecconds = PeriodSeconds(mLevel4Period); + + // + mLevel4Candles = level4PeriodSecconds / currentPeriodSecconds; + } + + // + string comment = GenerateComment(); + Comment(comment); + + // + // 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(fastMaHandler); + IndicatorRelease(slowMaHandler); + + // + // Clear Comments ... + Comment(""); + + // + // Remove All Drawing Objects ... + RemoveDraws(drawPrefix); +} + +// +// 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; + + // + // Check Calculated Bars ... + int fastMaCalculatedBars = BarsCalculated(fastMaHandler); + int slowMaCalculatedBars = BarsCalculated(slowMaHandler); + if (fastMaCalculatedBars < maxLength || + slowMaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFastMas = CopyBuffer(fastMaHandler, 0, 0, limit, fastMaBuffer); + int copiedSlowMas = CopyBuffer(slowMaHandler, 0, 0, limit, slowMaBuffer); + if (copiedFastMas <= 0 || + copiedSlowMas <= 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 = + // + // Validate Peaks and Vales ... + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength) + // + && + // + // Validate Supports and Resistance ... + ( + // + // Level 1 ... + (level1Method == X_PERIOD_AUTO || + (level1Method == X_PERIOD_MANUALLY && + level1Period != NULL)) + // + && + // + // Level 2 ... + (level2Method == X_PERIOD_AUTO || + (level2Method == X_PERIOD_MANUALLY && + level2Period != NULL)) + // + && + // + // Level 3 ... + (level3Method == X_PERIOD_AUTO || + (level3Method == X_PERIOD_MANUALLY && + level3Period != NULL)) + // + && + // + // Level 4 ... + (level4Method == X_PERIOD_AUTO || + (level4Method == X_PERIOD_MANUALLY && + level4Period != NULL)) + // + ) + // + && + // + // Validate Ma ... + (fastMaLength > 2 && + slowMaLength > fastMaLength) + // + && + // + // Validate Ichimoku Kinko Hyo ... + (tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + + // + // Ma ... + result = MathMax(result, fastMaLength); + result = MathMax(result, slowMaLength); + + // + // Ichimoku ... + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // UP Buffer ... + ArraySetAsSeries(rUpBuffer, true); + SetIndexBuffer(0, rUpBuffer, INDICATOR_DATA); + PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(0, PLOT_SHOW_DATA, false); + + // + // UP Color Buffer ... + ArraySetAsSeries(rUpColorBuffer, true); + SetIndexBuffer(1, rUpColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN Buffer ... + ArraySetAsSeries(rDownBuffer, true); + SetIndexBuffer(2, rDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(1, PLOT_SHOW_DATA, false); + + // + // DOWN Color Buffer ... + ArraySetAsSeries(rDownColorBuffer, true); + SetIndexBuffer(3, rDownColorBuffer, INDICATOR_COLOR_INDEX); + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(4, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(4, PLOT_ARROW, 225); + PlotIndexSetInteger(4, PLOT_ARROW_SHIFT, 20); + PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(2, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(2, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(5, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(5, PLOT_ARROW, 225); + PlotIndexSetInteger(5, PLOT_ARROW_SHIFT, 20); + PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(3, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(3, PLOT_DRAW_TYPE, pvDrawType); + + // + // MA ... + + // + // FAST ... + ENUM_DRAW_TYPE fastMaDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(6, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(6, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(4, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(4, PLOT_DRAW_TYPE, fastMaDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowMaDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(7, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(7, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(5, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(5, PLOT_DRAW_TYPE, slowMaDrawType); + + // + // SUPPORTANDRESISTANCE ... + + // + // LEVEL 1 ... + ENUM_DRAW_TYPE srL1DrawType = showSRLevel1 ? DRAW_LINE : DRAW_NONE; + + // + // UP ... + ArraySetAsSeries(srLevel1UpBuffer, true); + SetIndexBuffer(8, srLevel1UpBuffer, INDICATOR_DATA); + PlotIndexSetInteger(8, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(6, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(6, PLOT_DRAW_TYPE, srL1DrawType); + + // + // DOWN ... + ArraySetAsSeries(srLevel1DownBuffer, true); + SetIndexBuffer(9, srLevel1DownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(9, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(7, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(7, PLOT_DRAW_TYPE, srL1DrawType); + + // + // LEVEL 2 ... + ENUM_DRAW_TYPE srL2DrawType = showSRLevel2 ? DRAW_LINE : DRAW_NONE; + + // + // UP ... + ArraySetAsSeries(srLevel2UpBuffer, true); + SetIndexBuffer(10, srLevel2UpBuffer, INDICATOR_DATA); + PlotIndexSetInteger(10, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(8, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(8, PLOT_DRAW_TYPE, srL2DrawType); + + // + // DOWN ... + ArraySetAsSeries(srLevel2DownBuffer, true); + SetIndexBuffer(11, srLevel2DownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(11, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(9, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(9, PLOT_DRAW_TYPE, srL2DrawType); + + // + // LEVEL 3 ... + ENUM_DRAW_TYPE srL3DrawType = showSRLevel3 ? DRAW_LINE : DRAW_NONE; + + // + // UP ... + ArraySetAsSeries(srLevel3UpBuffer, true); + SetIndexBuffer(12, srLevel3UpBuffer, INDICATOR_DATA); + PlotIndexSetInteger(12, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetDouble(12, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(10, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(10, PLOT_DRAW_TYPE, srL3DrawType); + + // + // DOWN ... + ArraySetAsSeries(srLevel3DownBuffer, true); + SetIndexBuffer(13, srLevel3DownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(13, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetDouble(13, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(11, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(11, PLOT_DRAW_TYPE, srL3DrawType); + + // + // LEVEL 4 ... + ENUM_DRAW_TYPE srL4DrawType = showSRLevel4 ? DRAW_LINE : DRAW_NONE; + + // + // UP ... + ArraySetAsSeries(srLevel4UpBuffer, true); + SetIndexBuffer(14, srLevel4UpBuffer, INDICATOR_DATA); + PlotIndexSetInteger(14, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetDouble(14, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(12, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(12, PLOT_DRAW_TYPE, srL4DrawType); + + // + // DOWN ... + ArraySetAsSeries(srLevel4DownBuffer, true); + SetIndexBuffer(15, srLevel4DownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(15, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetDouble(15, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(13, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(13, PLOT_DRAW_TYPE, srL4DrawType); + + // + // ICHIMOKU ... + + // + // TENKANSEN ... + + // + ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + SetIndexBuffer(16, tenkanSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(16, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(14, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(14, PLOT_DRAW_TYPE, tenkanSenDrawType); + + // + // KIJUNSEN ... + + // + ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenBuffer, true); + SetIndexBuffer(17, kijunSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(17, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(15, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(15, PLOT_DRAW_TYPE, kijunSenDrawType); + + // + // CHIKOUSPAN ... + + // + ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(chikouSpanBuffer, true); + SetIndexBuffer(18, chikouSpanBuffer, INDICATOR_DATA); + PlotIndexSetInteger(18, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(16, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(16, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(16, PLOT_DRAW_TYPE, chikouSpanDrawType); + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(19, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(19, PLOT_DRAW_BEGIN, maxLength); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(20, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(20, PLOT_DRAW_BEGIN, maxLength); + + // + // KUMO ... + + // + ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; + + // + PlotIndexSetInteger(17, PLOT_SHIFT, kijunSenLength); + PlotIndexSetInteger(17, PLOT_DRAW_TYPE, kumoDrawType); + + // + int i = 21; + + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(i, sHHBuffer, INDICATOR_CALCULATIONS); + + // + i++; + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(i, sLLBuffer, INDICATOR_CALCULATIONS); + + // + i++; + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(i, mHHBuffer, INDICATOR_CALCULATIONS); + + // + i++; + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(i, mLLBuffer, INDICATOR_CALCULATIONS); + + // + i++; + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(i, lHHBuffer, INDICATOR_CALCULATIONS); + + // + i++; + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(i, lLLBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + double rUpColorIDX = 1; + double rDownColorIDX = 1; + + // + // PEAKS and VALES ... + + // + // SHORT ... + + // + // HH Buffer ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LL Buffer ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HH Buffer ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LL Buffer ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HH Buffer ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LL Buffer ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // RANGE ... + + // + // UP ... + double rUpValue = (sHHValue + mHHValue + lHHValue) / 3; + rUpBuffer[bar_index] = rUpValue; + + // + // DOWN ... + double rDownValue = (sLLValue + mLLValue + lLLValue) / 3; + rDownBuffer[bar_index] = rDownValue; + + // + // Detecting Peaks and Vales ... + + // + // PEAKS ... + bool isPeak = rUpValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + + // + if (isPeak && lastPeak != rUpValue) + { + // + if (showPeaksAndVales) + { + rUpColorIDX = 0; + } + + // + lastPeak = rUpValue; + peaksBuffer[bar_index] = lastPeak; + } + else + { + peaksBuffer[bar_index] = 0; + } + + // + // VALES ... + bool isVale = rDownValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + if (isVale && lastVale != rDownValue) + { + // + if (showPeaksAndVales) + { + rDownColorIDX = 0; + } + + // + lastVale = rDownValue; + valesBuffer[bar_index] = lastVale; + } + else + { + valesBuffer[bar_index] = 0; + } + + // + // Set Default Colors ... + + // + rUpColorBuffer[bar_index] = rUpColorIDX; + rDownColorBuffer[bar_index] = rDownColorIDX; + + // + // SUPPORTANDRESISTANCE ... + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + + // + // LEVEL 1 ... + + // + // Calculate Start Bar Index ... + if (mLastLevel1StartBarIndex == 0) + { + // + datetime level1StartTime = GetPeriodStartTime( + _Symbol, + mLevel1Period, + barTime); + + // + // Check Level 1 Start Time is New or Not ... + if (mLevel1StartTime != level1StartTime) + { + mLevel1StartTime = level1StartTime; + } + + // + // Access Level 1 Start Bar Index on Current Chart ... + mLastLevel1StartBarIndex = iBarShift( + _Symbol, + _Period, + mLevel1StartTime); + + // + // Calculate level1 Highest Open ... + mSRLastL1Up = GetHighestHigh( + _Symbol, + _Period, + MODE_HIGH, + mLevel1Candles, + mLastLevel1StartBarIndex); + + // + srLevel1UpBuffer[bar_index] = mSRLastL1Up; + + // + // Calculate level1 Lowest Close ... + mSRLastL1Down = GetLowestLow( + _Symbol, + _Period, + MODE_LOW, + mLevel1Candles, + mLastLevel1StartBarIndex); + + // + srLevel1DownBuffer[bar_index] = mSRLastL1Down; + } + else + { + // + int lDiff = mLastLevel1StartBarIndex - bar_index; + if (lDiff == mLevel1Candles) + { + mLastLevel1StartBarIndex = 0; + } + + // + srLevel1UpBuffer[bar_index] = mSRLastL1Up; + srLevel1DownBuffer[bar_index] = mSRLastL1Down; + } + + // + // LEVEL 2 ... + + // + // Calculate Start Bar Index ... + if (mLastLevel2StartBarIndex == 0) + { + // + datetime level2StartTime = GetPeriodStartTime( + _Symbol, + mLevel2Period, + barTime); + + // + // Check Level 2 Start Time is New or Not ... + if (mLevel2StartTime != level2StartTime) + { + mLevel2StartTime = level2StartTime; + } + + // + // Access Level 2 Start Bar Index on Current Chart ... + mLastLevel2StartBarIndex = iBarShift( + _Symbol, + _Period, + mLevel2StartTime); + + // + // Calculate level2 Highest Open ... + mSRLastL2Up = GetHighestHigh( + _Symbol, + _Period, + MODE_HIGH, + mLevel2Candles, + mLastLevel2StartBarIndex); + + // + srLevel2UpBuffer[bar_index] = mSRLastL2Up; + + // + // Calculate level2 Lowest Close ... + mSRLastL2Down = GetLowestLow( + _Symbol, + _Period, + MODE_LOW, + mLevel2Candles, + mLastLevel2StartBarIndex); + + // + srLevel2DownBuffer[bar_index] = mSRLastL2Down; + } + else + { + // + int lDiff = mLastLevel2StartBarIndex - bar_index; + if (lDiff == mLevel2Candles) + { + mLastLevel2StartBarIndex = 0; + } + + // + srLevel2UpBuffer[bar_index] = mSRLastL2Up; + srLevel2DownBuffer[bar_index] = mSRLastL2Down; + } + + // + // LEVEL 3 ... + + // + // Calculate Start Bar Index ... + if (mLastLevel3StartBarIndex == 0) + { + // + datetime level3StartTime = GetPeriodStartTime( + _Symbol, + mLevel3Period, + barTime); + + // + // Check Level 3 Start Time is New or Not ... + if (mLevel3StartTime != level3StartTime) + { + mLevel3StartTime = level3StartTime; + } + + // + // Access Level 3 Start Bar Index on Current Chart ... + mLastLevel3StartBarIndex = iBarShift( + _Symbol, + _Period, + mLevel3StartTime); + + // + // Calculate level3 Highest Open ... + mSRLastL3Up = GetHighestHigh( + _Symbol, + _Period, + MODE_HIGH, + mLevel3Candles, + mLastLevel3StartBarIndex); + + // + srLevel3UpBuffer[bar_index] = mSRLastL3Up; + + // + // Calculate level3 Lowest Close ... + mSRLastL3Down = GetLowestLow( + _Symbol, + _Period, + MODE_LOW, + mLevel3Candles, + mLastLevel3StartBarIndex); + + // + srLevel3DownBuffer[bar_index] = mSRLastL3Down; + } + else + { + // + int lDiff = mLastLevel3StartBarIndex - bar_index; + if (lDiff == mLevel3Candles) + { + mLastLevel3StartBarIndex = 0; + } + + // + srLevel3UpBuffer[bar_index] = mSRLastL3Up; + srLevel3DownBuffer[bar_index] = mSRLastL3Down; + } + + // + // LEVEL 4 ... + + // + // Calculate Start Bar Index ... + if (mLastLevel4StartBarIndex == 0) + { + // + datetime level4StartTime = GetPeriodStartTime( + _Symbol, + mLevel4Period, + barTime); + + // + // Check Level 4 Start Time is New or Not ... + if (mLevel4StartTime != level4StartTime) + { + mLevel4StartTime = level4StartTime; + } + + // + // Access Level 4 Start Bar Index on Current Chart ... + mLastLevel4StartBarIndex = iBarShift( + _Symbol, + _Period, + mLevel4StartTime); + + // + // Calculate level4 Highest Open ... + mSRLastL4Up = GetHighestHigh( + _Symbol, + _Period, + MODE_OPEN, + mLevel4Candles, + mLastLevel4StartBarIndex); + + // + srLevel4UpBuffer[bar_index] = mSRLastL4Up; + + // + // Calculate level4 Lowest Close ... + mSRLastL4Down = GetLowestLow( + _Symbol, + _Period, + MODE_LOW, + mLevel4Candles, + mLastLevel4StartBarIndex); + + // + srLevel4DownBuffer[bar_index] = mSRLastL4Down; + } + else + { + // + int lDiff = mLastLevel4StartBarIndex - bar_index; + if (lDiff == mLevel4Candles) + { + mLastLevel4StartBarIndex = 0; + } + + // + srLevel4UpBuffer[bar_index] = mSRLastL4Up; + srLevel4DownBuffer[bar_index] = mSRLastL4Down; + } + + // + // ICHIMOKU ... + + // + double topValue; + double bottomValue; + + // + // TENKANSEN ... + + // + // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... + if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) + { + // + switch (tenkanSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mTenkanSenTopMode = MODE_HIGH; + mTenkanSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mTenkanSenTopMode = MODE_OPEN; + mTenkanSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mTenkanSenTopMode, + tenkanSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mTenkanSenBottomMode, + tenkanSenLength, + bar_index); + + // + double tenkanSenValue = (topValue + bottomValue) / 2; + tenkanSenBuffer[bar_index] = tenkanSenValue; + + // + // KIJUNSEN ... + + // + // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... + if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) + { + // + switch (kijunSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mKijunSenTopMode = MODE_HIGH; + mKijunSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mKijunSenTopMode = MODE_OPEN; + mKijunSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mKijunSenTopMode, + kijunSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mKijunSenBottomMode, + kijunSenLength, + bar_index); + + // + double kijunSenValue = (topValue + bottomValue) / 2; + kijunSenBuffer[bar_index] = kijunSenValue; + + // + // CHIKOUSPAN ... + double chikouSpanValue = GetAppliedPrice( + bar_index, + chikuoSpanAppliedTo); + chikouSpanBuffer[bar_index] = chikouSpanValue; + + // + // KUMO ... + + // + // SENKOUSPANA ... + double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; + senkouSpanABuffer[bar_index] = senkouSpanAValue; + + // + // SENKOUSPANB ... + + // + // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... + if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) + { + // + switch (senkouSpanBMode) + { + // + case X_XICH_HH_LL_MODE: + // + mSenkouSpanBTopMode = MODE_HIGH; + mSenkouSpanBBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mSenkouSpanBTopMode = MODE_OPEN; + mSenkouSpanBBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mSenkouSpanBTopMode, + senkouSpanBLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mSenkouSpanBBottomMode, + senkouSpanBLength, + bar_index); + + // + double senkouSpanBValue = (topValue + bottomValue) / 2; + senkouSpanBBuffer[bar_index] = senkouSpanBValue; +} + +// +// Generate Comment String ... +string GenerateComment() +{ + // + string result = ""; + + // + result += "L1 P: " + EnumToString(mLevel1Period) + "\n"; + // result += "L1 C: " + (string)mLevel1Candles + "\n"; + // result += "\n"; + + // + result += "L2 P: " + EnumToString(mLevel2Period) + "\n"; + // result += "L2 C: " + (string)mLevel2Candles + "\n"; + // result += "\n"; + + // + result += "L3 P: " + EnumToString(mLevel3Period) + "\n"; + // result += "L3 C: " + (string)mLevel3Candles + "\n"; + // result += "\n"; + + // + result += "L4 P: " + EnumToString(mLevel4Period) + "\n"; + // result += "L4 C: " + (string)mLevel4Candles + "\n"; + // result += "\n"; + + // + return result; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.xpv.mq5 b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.xpv.mq5 new file mode 100644 index 0000000..11b2dac --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.xpv.mq5 @@ -0,0 +1,640 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_PV Peaks and Vales Indicator +// ----------------------------------------------------------- +// Name: X121_PV +// Description: Market Peaks and Vales +// 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 X121_PV Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_PV" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 12 +#property indicator_plots 4 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "X121_PV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 3 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "X121_PV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 3 + +// +#define rUpBufferIndex 2 +#define rUpPlotBufferIndex 2 +double rUpBuffer[]; + +// +#define rUpColorBufferIndex 3 +double rUpColorBuffer[]; + +// +#property indicator_label3 "X121_PV R UP" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, CLR_NONE +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define rDownBufferIndex 4 +#define rDownPlotBufferIndex 3 +double rDownBuffer[]; + +// +#define rDownColorBufferIndex 5 +double rDownColorBuffer[]; + +// +#property indicator_label4 "X121_PV R Down" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrMagenta, CLR_NONE +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// DATA Buffers ... + +// +#define sHHBufferIndex 6 +double sHHBuffer[]; + +#define sLLBufferIndex 7 +double sLLBuffer[]; + +// +#define mHHBufferIndex 8 +double mHHBuffer[]; + +// +#define mLLBufferIndex 9 +double mLLBuffer[]; + +// +#define lHHBufferIndex 10 +double lHHBuffer[]; + +// +#define lLLBufferIndex 11 +double lLLBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// 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; + + // + 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 = + // + // Validate Peaks and Vales ... + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW_SHIFT, -20); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW_SHIFT, 20); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // UP Buffer ... + ArraySetAsSeries(rUpBuffer, true); + SetIndexBuffer(rUpBufferIndex, rUpBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rUpBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(rUpBufferIndex, PLOT_SHOW_DATA, false); + + // + // UP Color Buffer ... + ArraySetAsSeries(rUpColorBuffer, true); + SetIndexBuffer(rUpColorBufferIndex, rUpColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN Buffer ... + ArraySetAsSeries(rDownBuffer, true); + SetIndexBuffer(rDownBufferIndex, rDownBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rDownBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(rDownPlotBufferIndex, PLOT_SHOW_DATA, false); + + // + // DOWN Color Buffer ... + ArraySetAsSeries(rDownColorBuffer, true); + SetIndexBuffer(rDownColorBufferIndex, rDownColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA Buffers ... + + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + double rUpColorIDX = 1; + double rDownColorIDX = 1; + + // + // PEAKS and VALES ... + + // + // SHORT ... + + // + // HH Buffer ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LL Buffer ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HH Buffer ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LL Buffer ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HH Buffer ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LL Buffer ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // RANGE ... + + // + // UP ... + double rUpValue = (sHHValue + mHHValue + lHHValue) / 3; + rUpBuffer[bar_index] = rUpValue; + + // + // DOWN ... + double rDownValue = (sLLValue + mLLValue + lLLValue) / 3; + rDownBuffer[bar_index] = rDownValue; + + // + // Detecting Peaks and Vales ... + + // + // PEAKS ... + bool isPeak = rUpValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + + // + if (isPeak && lastPeak != rUpValue) + { + // + if (showPeaksAndVales) + { + rUpColorIDX = 0; + } + + // + lastPeak = rUpValue; + peaksBuffer[bar_index] = lastPeak; + } + else + { + peaksBuffer[bar_index] = 0; + } + + // + // VALES ... + bool isVale = rDownValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + if (isVale && lastVale != rDownValue) + { + // + if (showPeaksAndVales) + { + rDownColorIDX = 0; + } + + // + lastVale = rDownValue; + valesBuffer[bar_index] = lastVale; + } + else + { + valesBuffer[bar_index] = 0; + } + + // + // Set Default Colors ... + + // + rUpColorBuffer[bar_index] = rUpColorIDX; + rDownColorBuffer[bar_index] = rDownColorIDX; + +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.xtrnd.single.cycle.mq5 b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.xtrnd.single.cycle.mq5 new file mode 100644 index 0000000..769c8af --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x-saherelm.x121.xtrnd.single.cycle.mq5 @@ -0,0 +1,459 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_XTRND Trends Indicator +// ----------------------------------------------------------- +// Name: X121_XTRND +// Description: Market Trend Detector ... +// 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 X121_XTRND Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XTRND" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int cycleLength = 2; // Cycle Length to Check +input int numberOfVerifications = 2; // Number of Verifications + +// +input group "Calculation"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Detect Up +input ENUM_SERIESMODE llMode = MODE_LOW; // Detect Low + +// +input group "Presentation"; +input bool showConsolidations = false; // Show Consolidations +input bool showTrend = true; // Show Trend + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// Higher High ... +#define hhBufferIndex 0 +#define hhPlotBufferIndex 0 +double hhBuffer[]; + +#define hhColorBufferIndex 1 +double hhColorBuffer[]; + +// +#property indicator_label1 "X121_XTRND U" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Lower Low ... +#define llBufferIndex 2 +#define llPlotBufferIndex 1 +double llBuffer[]; + +#define llColorBufferIndex 3 +double llColorBuffer[]; + +// +#property indicator_label2 "X121_XTRND D" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// 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; + + // + 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 = + // + (cycleLength > 0 && + numberOfVerifications > 0) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax( + cycleLength, + numberOfVerifications); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ENUM_DRAW_TYPE drawType = showTrend ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_DRAW_TYPE, drawType); + + // + // COLOR Buffer ... + ArraySetAsSeries(hhColorBuffer, true); + SetIndexBuffer(hhColorBufferIndex, hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(llPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(llPlotBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(llColorBuffer, true); + SetIndexBuffer(llColorBufferIndex, llColorBuffer, 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 +) +{ + // + // HIGHER Highs ... + double hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + cycleLength, + bar_index); + + // + hhBuffer[bar_index] = hh; + + // + // LOWER Lows ... + double ll = GetLowestLow( + _Symbol, + _Period, + llMode, + cycleLength, + bar_index); + + // + llBuffer[bar_index] = ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double hhColorIDX = showConsolidations ? 1 : 0; + double llColorIDX = showConsolidations ? 1 : 0; + + // + // Calculate Cycle Changes ... + + // + int cycleCLength = cycleLength * numberOfVerifications; + bool isCycleCLengthPassed = MathAbs(ArraySize(hhBuffer) - bar_index) > cycleCLength + 1; + + // + if (isCycleCLengthPassed) + { + // + bool isLowestLowUp = true; // ll > llBuffer[bar_index + 1]; + bool isLowestLowDown = true; // ll < llBuffer[bar_index + 1]; + bool isHighsestHighUp = true; // hh > hhBuffer[bar_index + 1]; + bool isHighsestHighDown = true; // hh < hhBuffer[bar_index + 1]; + for (int i = bar_index; i < bar_index + cycleCLength; i++) + { + // + double iHH = hhBuffer[i]; + double iLL = llBuffer[i]; + + // + if (hh < iHH) + { + isHighsestHighUp = false; + } + else if (hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (ll < iLL) + { + isLowestLowUp = false; + } + else if (ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + hhColorIDX = 2; + llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + hhColorIDX = 3; + llColorIDX = 3; + } + } + + // + hhColorBuffer[bar_index] = hhColorIDX; + llColorBuffer[bar_index] = llColorIDX; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x-saherelm.xea.mq5 b/MQLTestWorkspace/BKPS/BKP/x-saherelm.xea.mq5 new file mode 100644 index 0000000..8041b38 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x-saherelm.xea.mq5 @@ -0,0 +1,1359 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: X121EA +// 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 X121EA" +#property strict + +// +// START Definitions ... +// + +// +// 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" + +// +// Account Class ... +#include "../Classes/x-saherelm.xaccount.class.mq5" + +// +// Trade Class ... +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +// Signal Provider Class Library ... +#include "../Providers/x.saherelm.x121.provider.mq5" + +// +// Draw Library ... +#include "../Libraries/x-saherelm.x121.draw.lib.mq5" + +// +#define ShortName "X121EA" + +// +// Convert Position to Signal ... +XSignal ToSignalInfo( + XPosition &position) +{ + // + XSignal result; + + // + result.tp = position.tp; + result.sl = position.sl; + result.type = position.type; + result.entry = position.entry; + result.symbol = position.symbol; + result.period = position.period; + result.volume = position.volume; + + // + return result; +} + +// +// END Definitions ... +// + +// +// START Inputs ... +// + +// +// EA ... +input group "Common"; +input bool xEAEnable = true; // Enable EA +input int xEASlippage = 10; // Slippgae +input ulong xEAMagicNumber = 1604056; // Magic Number + +// +// Signals ... +input group "Signals"; +input bool xEAEnableLongs = true; // Enable Long Trades +input bool xEAEnableShorts = true; // Enable Short Trades + +// +// Risk Management ... +input group "Risk Management"; +input int xEAMaxOpenPositions = 15; // Max Allowed Open Positions +input double xEAMaxAllowedDrawDownFactor = 0.15; // Max Allowed Drawdown Factor +// input double xEAMinProfitPerOpenPositionForHedging = 0.9; // Close All Positions Fctor + +// +// Alerts ... +input group "Alerts"; +input bool xEAEnableAlerts = true; // Enable Events Alert +input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day +input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +bool isXEANewHour; +bool isXEANewDay; +bool isXEANewWeek; +bool isXEANewMonth; + +// +// Determines EA is Running On Test Mode or not ... +bool xEAIsTestMode = false; + +// +// Check prevent Double Signalling on Same Candle ... +bool xEAWaitUntilNextCandle = false; + +// +XSCTrade *xEATrade; +XSCAccount *xEAAccount; +XSCX121Provider *xEAProvider; +// X121SignalProvider xEAProviders[]; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = ShortName; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Reset Timings ... + ResetTiming(); + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize X121EA Providers ... + if (!InitializeProviders()) + { + 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 ... + delete xEATrade; + delete xEAAccount; + delete xEAProvider; + + // + // De Initialize XEA Providers ... +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Handle Monthly Alert ... + bool isFirstMonth = xMonth == -1; + isXEANewMonth = IsNewMonth(); + bool canMonthlyAlert = + isXEANewMonth && + xEAEnableAlerts && + xEAEnableMonthlyAlerts; + if (canMonthlyAlert) + { + // + string message = "New Month ..."; + + // + SendAlert(message); + } + + // + // Handle Weekly Alert ... + bool isFirstWeek = xDayOfWeek == -1; + isXEANewWeek = IsNewWeek(); + bool canWeeklyAlert = + isXEANewWeek && + xEAEnableAlerts && + xEAEnableWeeklyAlerts; + if (canWeeklyAlert) + { + // + string message = "New Week ..."; + + // + SendAlert(message); + } + + // + // Handle Daily Alert ... + bool isFirstDay = xDay == -1; + isXEANewDay = IsNewDay(); + bool canDailyAlert = + isXEANewDay && + xEAEnableAlerts && + xEAEnableDailyAlerts; + if (canDailyAlert) + { + // + string message = "New Day ..."; + + // + SendAlert(message); + } + + // + // Handle Hourly Alert ... + bool isFirstHour = xHour == -1; + isXEANewHour = IsNewHour(); + bool canHourlyAlert = + isXEANewHour && + xEAEnableAlerts && + xEAEnableHourlyAlerts; + if (canHourlyAlert) + { + // + string message = "New Hour ..."; + + // + SendAlert(message); + } + + // + // Handle Guarding Strategies ... + HandleGuard(); + + // + // Prevent Going Forward if user Disable it ... + if (xEAEnable) + { + // + // TODO: Remove this due test ... + // if (IsRunningOnTestMode()) + // { + // xEATrade. + // } + + // + // Call All Providers OnTick Method ... + CallProvidersOnTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + // + // Handle Trading State ... + xEATrade.HandleOnTrade(); +} + +// +// Chart Events Handling ... +void OnChartEvent( + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter +) +{ +} + +// +// Handle Signal Event ... +void OnSignalConditionsRecieved(X121MarketConditions &info) +{ + // + if (!info.hasSignal) + { + return; + } + + // + // Diable Trading if a Direction is Disabled ... + if ((info.signal.type == POSITION_TYPE_BUY && !xEAEnableLongs) || + (info.signal.type != POSITION_TYPE_SELL && !xEAEnableShorts)) + { + return; + } + + // + // Count Open Positions ... + int openPositionsCount = xEATrade.PositionsCount(); + if (xEAMaxOpenPositions > 0 && + openPositionsCount >= xEAMaxOpenPositions) + { + // + string msg = "Max Allowed Positions Reached, Ignore Trading ..."; + LogMessage(msg); + + // + return; + } + + // + // Retrieve Tradable Balance ... + double availableBalance = xEAAccount.GetEquity(); + + // + // Verify Available Balance ... + double balance = xEAAccount.GetBalance(); + + // + double forCalculationBalance = MathMax(balance, availableBalance); + double forTradeBalance = MathMin(balance, availableBalance); + double mustHaveBalanceForTrading = forCalculationBalance * xEAMaxAllowedDrawDownFactor; + if (availableBalance < mustHaveBalanceForTrading) + { + // + string msg = "Max Allowed Equity for Trading Reached, Ignore Trading ..."; + LogMessage(msg); + + // + return; + } + + // + // Here i Must Calculate TP and SL based on R2R and riskable Factor ... + bool isLong = IsLong(info.signal.type); + + // + // Check Order Mode ... + if (info.signal.mode == NULL) + { + // + // Set Market Execution as Default ... + info.signal.mode = X_ORDER_MODE_MARKET; + } + + // + bool isMarketMode = info.signal.mode == X_ORDER_MODE_MARKET; + + // + // Calculate Entry Price ... + if (info.signal.entry <= 0) + { + // + info.signal.entry = GetEntry( + info.signal.symbol, + info.signal.type); + } + + // + // Calculate TP and SL ... + double mPoint = GetPoints(info.signal.symbol); + + // + // Normalize SL Price ... + if (info.signal.sl > 0) + { + info.signal.sl = NormalizePrice(info.signal.sl, info.signal.symbol); + } + + // + // Retrieve Symbol Point Value ... + double pointValue = xEAAccount.GetPointValue(info.signal.symbol); + + // + // Calculate Risk ... + double riskPrice = MathAbs(info.signal.entry - info.signal.sl); + riskPrice = NormalizePrice(riskPrice, info.signal.symbol); + + // + double riskPoints = PriceToPoint(riskPrice); + riskPoints = NormalizeDouble(riskPoints, 0); + + // + // Calculating Reward based On Ratio ... + double rewardPoints = riskPoints * info.signal.r2r; + double rewardPrice = PointToPrice(rewardPoints); + rewardPrice = NormalizePrice(rewardPrice, info.signal.symbol); + + // + // Calculate TP Price ... + double tpValue = isLong + ? info.signal.entry + rewardPrice + : info.signal.entry - rewardPrice; + + // + // Calculate SL Price ... + double slValue = isLong + ? info.signal.entry - riskPrice + : info.signal.entry + riskPrice; + + // + // Balance Amount which we risks on each Provider's Trade ... + double amount = availableBalance * info.signal.riskAmount; + + // + // Calculating Trade Volume based on risk Points and Amount ... + double volume = + info.signal.useRiskAmountAsVolume + ? info.signal.riskAmount + : xEAAccount.CalculateVolume( + info.signal.symbol, + amount, + riskPoints); + volume = NormalizeVolume(volume, info.signal.symbol); + + // + // Set Caculated TP, SL and Volume ... + if (info.signal.calculateTP) + { + // + if (info.signal.useSupportAndResistance) + { + // + double mTmp[]; + double mTmpPrice; + LogMessage("MomentumStep: " + (string)info.momentumStep); + + // + // Find Good Entry Points ... + if (!isMarketMode) + { + // + if (isLong) + { + // + ArrayCopy( + mTmp, + info.supportResistances.res); + } + else + { + // + ArrayCopy( + mTmp, + info.supportResistances.sup); + } + + // + mTmpPrice = + isLong + ? info.signal.entry + info.momentumStep + : info.signal.entry - info.momentumStep; + double entry = + FindLesserThanValue( + mTmpPrice, + mTmp, + !isLong); + Clean(mTmp); + + // + info.signal.entry = entry; + } + + // + // Find Good SL Point ... + + // + if (isLong) + { + // + ArrayCopy( + mTmp, + info.supportResistances.sup); + } + else + { + // + ArrayCopy( + mTmp, + info.supportResistances.res); + } + + // + mTmpPrice = + isLong + ? info.signal.entry - info.momentumStep + : info.signal.entry + info.momentumStep; + double sl = + FindBiggerThanValue( + mTmpPrice, + mTmp, + !isLong); + Clean(mTmp); + + // + info.signal.sl = sl; + + // + // Find Good TP Point ... + + // + if (isLong) + { + // + ArrayCopy( + mTmp, + info.supportResistances.res); + } + else + { + // + ArrayCopy( + mTmp, + info.supportResistances.sup); + } + + // + // Risk Price ... + mTmpPrice = MathAbs(info.signal.entry - info.signal.sl); + + // + // Reward Price ... + mTmpPrice *= info.signal.r2r; + + // + // Start Search TP ... + mTmpPrice = isLong + ? info.signal.entry + mTmpPrice + : info.signal.entry - mTmpPrice; + double tp = + FindLesserThanValue( + mTmpPrice, + mTmp, + !isLong); + Clean(mTmp); + + // + info.signal.tp = tp; + } + else + { + // + info.signal.tp = tpValue; + info.signal.sl = slValue; + } + } + + // + info.signal.volume = volume; + + // + string comment = GenerateProvidersString(info.signal); + + // + // TODO: Remove this ... + ulong mTicket = MathRand() * 100000; + DrawSignal( + mTicket, + info.signal); + + // + DrawSupportResistance( + 0, + info.supportResistances, + info.signal.providers[0]); + + // + return; + + // + // Here We Execute the Signal by Trader Class Instance ... + bool isPositionExecuted = xEATrade.ExecuteSignal( + info.signal, + comment); + + // + if (isPositionExecuted) + { + // + // Retrieve Position Ticket ... + ulong ticket = 0; + bool isMarketMode = info.signal.mode == X_ORDER_MODE_MARKET; + if (isMarketMode) + { + ticket = xEATrade.GetLastOpenPositionTicket(); + } + else + { + ticket = xEATrade.GetLastPlacedOrderTicket(); + } + + if (ticket == 0) + { + return; + } + + // + // Draw Signal ... + DrawSignal(ticket, info.signal); + + // + // Alert Position ... + string msg = + (isMarketMode + ? "Position" + : "Order") + + ": " + (string)ticket + " was " + (isMarketMode ? "Opened" : "Placed") + " ..."; + LogMessage(msg); + } +} + +// +// Handle StopLoss Event ... +void OnStopLossTriggered(const XDeal &deal) +{ + // + string msg = "SL: " + (string)deal.positionId; + LogMessage(msg); +} + +// +// Handle TakeProfit Event ... +void OnTakeProfitTriggered(const XDeal &deal) +{ + // + string msg = "TP: " + (string)deal.positionId; + LogMessage(msg); +} + +// +// Handle Deals Changed Event ... +void OnDealsChangedHandler(int count) +{ + // + // string msg = "Deals Changed: " + (string)count; + // LogMessage(msg); +} + +// +// Handle Order Changed Event ... +void OnOrdersChangedHandler(int count) +{ + // + // string msg = "Orders Changed: " + (string)count; + // LogMessage(msg); +} + +// +// Handle Position Changed Event ... +void OnPositionsChangedHandler(int count) +{ + // // + // int positionsCount = xEATrade.PositionsCount(); + // if (count <= 0 || positionsCount <= 0) + // { + // return; + // } + + // // + // XPosition positions[]; + // xEATrade.GetPositions(positions); + // for (int i = 0; i < positionsCount; i++) + // { + // // + // XPosition iPosition = positions[i]; + + // // + // bool isIPositionHasSupport = + // xEATrade.HasSupport(iPosition.ticket); + // if (isIPositionHasSupport) + // { + // continue; + // } + + // // + // double sl = iPosition.sl; + + // // + // XSignal signal; + // bool isGenerated = xEATrade.GenerateSLSupportSignal( + // signal, + // iPosition.ticket); + // if (!isGenerated) + // { + // continue; + // } + + // // + // string comment = GenerateSupportSignalComment(iPosition.ticket); + + // // + // bool isExecuted = xEATrade.ExecuteSignal( + // signal, + // comment); + // if (!isExecuted) + // { + // continue; + // } + + // // + // // Now we have to Disable Position SL ... + // bool isModified = xEATrade.Modify( + // iPosition.ticket, + // 0, + // iPosition.tp, + // iPosition.comment); + // if (!isModified) + // { + // return; + // } + + // // + // string msg = "Execute SL Support Signal for Position (" + (string)iPosition.ticket + ") successfully ..."; + // LogMessage(msg); + // } + + // + // LogMessage("OnPositionsChangedHandler ..."); +} + +// +// Handle Trade State Changed ... +void OnTradeStateChangedHandler( + const XOnTradeHandlerState &state) +{ + // // + // string msg = "Trade State Changed ..."; + // LogMessage(msg); +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate Args ... + result = + // + xEASlippage > 0 && + xEAMagicNumber > 0 + // + // TODO: add new validations here ... + // + ; + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// Extract Signal Provider Struct from User Input ... +bool InitializeProviders() +{ + // + bool result = false; + + // + // Account Manager ... + xEAAccount = new XSCAccount(); + + // + // Trader ... + xEATrade = new XSCTrade( + xEASlippage, + xEAMagicNumber); + + // + // Attach Event Handlers ... + xEATrade.AddOnStopLossEventHandler(OnStopLossTriggered); + xEATrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); + xEATrade.AddOnDealsChangedEventHandler(OnDealsChangedHandler); + xEATrade.AddOnOrdersChangedEventHandler(OnOrdersChangedHandler); + xEATrade.AddOnPositionsChangedEventHandler(OnPositionsChangedHandler); + xEATrade.AddOnTradeStateChangedEventHandler(OnTradeStateChangedHandler); + + // + // Prepare Config ... + // + // Prepare Default and Clean Config ... + // in this Config non of Indicators doesn't Draw anything on chart ... + // TODO: We Have to Get These from Inputs of Users ... + X121ProviderInputs configs; + + // + // XCT ... + // Candle Timing ... + configs.xctConfig.clr = clrBlueViolet; + configs.xctConfig.corner = CORNER_RIGHT_UPPER; + configs.xctConfig.showCandleTime = true; + + // + // XCC ... + // Candle Styling ... + configs.xccConfig.upColor = clrLime; + configs.xccConfig.downColor = clrRed; + configs.xccConfig.lineColor = clrLime; + configs.xccConfig.bearishColor = clrRed; + configs.xccConfig.bullishColor = clrLime; + configs.xccConfig.volumesColor = clrGreen; + configs.xccConfig.showCandles = true; + + // + // XHK ... + // HikenAshi Candle Representing ... + configs.xhkConfig.drawCandleLines = false; + + // + // XTM ... + // Trend Magic ... + configs.xtmConfig.length = 35; + configs.xtmConfig.shift = 0; + configs.xtmConfig.method = MODE_SMA; + configs.xtmConfig.appliedTo = PRICE_LOW; + configs.xtmConfig.showLine = false; + + // + // XPV ... + // Peaks And Vales ... + configs.xpvConfig.shortLength = 9; + configs.xpvConfig.mediumLength = 17; + configs.xpvConfig.longLength = 26; + configs.xpvConfig.hindLength = 35; + configs.xpvConfig.fiboLevel1 = 0.382; + configs.xpvConfig.fiboLevel2 = 0.5; + configs.xpvConfig.fiboLevel3 = 0.618; + configs.xpvConfig.hhMode = MODE_HIGH; + configs.xpvConfig.llMode = MODE_LOW; + configs.xpvConfig.showPeaksAndVales = false; + configs.xpvConfig.showLevels = false; + configs.xpvConfig.showFibo1Levels = false; + configs.xpvConfig.showFibo2Levels = false; + configs.xpvConfig.showFibo3Levels = false; + + // + // XAMA ... + // Adaptive Moving Average ... + configs.xamaConfig.length = 52; + configs.xamaConfig.fastEMA = 2; + configs.xamaConfig.slowEMA = 30; + configs.xamaConfig.maShift = 0; + configs.xamaConfig.appliedTo = PRICE_LOW; + configs.xamaConfig.showLine = false; + + // + // XMRB ... + // Moving Average Ribbon ... + configs.xmrbConfig.fast1Length = 3; + configs.xmrbConfig.slow1Length = 5; + configs.xmrbConfig.fast2Length = 8; + configs.xmrbConfig.slow2Length = 13; + configs.xmrbConfig.fast3Length = 21; + configs.xmrbConfig.slow3Length = 34; + configs.xmrbConfig.fast4Length = 55; + configs.xmrbConfig.slow4Length = 89; + configs.xmrbConfig.fast5Length = 144; + configs.xmrbConfig.slow5Length = 233; + configs.xmrbConfig.ribbonMode = MODE_EMA; + configs.xmrbConfig.ribbonAppliedTo = PRICE_CLOSE; + configs.xmrbConfig.showFastMa = false; + configs.xmrbConfig.showSlowMa = false; + configs.xmrbConfig.showRibbon = false; + + // + // XCHE ... + // Chandelier Exit Points ... + configs.xcheConfig.length = 35; + configs.xcheConfig.loopback = 26; + configs.xcheConfig.multiplier1 = 3; + configs.xcheConfig.multiplier2 = 3.5; + configs.xcheConfig.upAppliedTo = PRICE_HIGH; + configs.xcheConfig.downAppliedTo = PRICE_LOW; + configs.xcheConfig.showLongExit1Line = false; + configs.xcheConfig.showShortExit1Line = false; + configs.xcheConfig.showLongExit2Line = false; + configs.xcheConfig.showShortExit2Line = false; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + configs.xichConfig.tenkanSenLength = 9; + configs.xichConfig.tenkanSenMode = X_XICH_HH_LL_MODE; + configs.xichConfig.kijunSenLength = 26; + configs.xichConfig.kijunSenMode = X_XICH_HH_LL_MODE; + configs.xichConfig.senkouSpanBLength = 52; + configs.xichConfig.senkouSpanBMode = X_XICH_HH_LL_MODE; + configs.xichConfig.chikuoSpanAppliedTo = PRICE_CLOSE; + configs.xichConfig.showTenkanSen = false; + configs.xichConfig.showKijunSen = false; + configs.xichConfig.showKijunSenPlus = false; + configs.xichConfig.showKijunSenNegative = false; + configs.xichConfig.showChikouSpan = false; + configs.xichConfig.showSenkouSpanA = false; + configs.xichConfig.showSenkouSpanB = false; + configs.xichConfig.showKumo = false; + configs.xichConfig.shiftKumo = true; + + // + // XTRND ... + // Trend Detector ... + configs.xtrndConfig.cycleLength = 2; + configs.xtrndConfig.numberOfVerifications = 2; + configs.xtrndConfig.hhMode = MODE_HIGH; + configs.xtrndConfig.llMode = MODE_LOW; + configs.xtrndConfig.l1Method = X_PERIOD_AUTO; + configs.xtrndConfig.l1Period = NULL; + configs.xtrndConfig.l2Method = X_PERIOD_AUTO; + configs.xtrndConfig.l2Period = NULL; + configs.xtrndConfig.l3Method = X_PERIOD_AUTO; + configs.xtrndConfig.l3Period = NULL; + configs.xtrndConfig.showConsolidations = false; + configs.xtrndConfig.showTrend = false; + configs.xtrndConfig.showL1Trend = false; + configs.xtrndConfig.showL2Trend = false; + configs.xtrndConfig.showL3Trend = false; + + // + // XSSLC ... + // SSL Channel ... + configs.xsslcConfig.length = 36; + configs.xsslcConfig.method = MODE_SMA; + configs.xsslcConfig.upAppliedTo = PRICE_HIGH; + configs.xsslcConfig.downAppliedTo = PRICE_LOW; + configs.xsslcConfig.showUp = false; + configs.xsslcConfig.showDown = false; + + // + // XHULL ... + // Hull Trend Detection Channel ... + configs.xhullConfig.length = 72; + configs.xhullConfig.divisor = 2; + configs.xhullConfig.upAppliedTo = PRICE_HIGH; + configs.xhullConfig.downAppliedTo = PRICE_LOW; + configs.xhullConfig.showUpZone = false; + configs.xhullConfig.showDownZone = false; + + // + // Default Configs For Different States ... + bool showPV = true; + bool showHK = true; + bool showCHE = true; + bool showTRND = true; + bool simpleIchi = true; + + // + + // + if (showHK) + { + // + // Hiken Ashi ... + configs.xccConfig.showCandles = false; + configs.xhkConfig.drawCandles = true; + } + if (showPV) + { + // + // Peaks and Vales ... + configs.xpvConfig.showFibo1Levels = true; + configs.xpvConfig.showFibo2Levels = true; + configs.xpvConfig.showFibo3Levels = true; + configs.xpvConfig.showPeaksAndVales = true; + } + if (simpleIchi) + { + // + // Simple Ichimoku Kinko Hyo ... + configs.xichConfig.showKijunSen = true; + configs.xichConfig.showTenkanSen = true; + configs.xichConfig.showSenkouSpanA = true; + configs.xichConfig.showSenkouSpanB = true; + } + if (showCHE) + { + // + // Chandelier Exit ... + configs.xcheConfig.showLongExit1Line = true; + configs.xcheConfig.showLongExit2Line = true; + configs.xcheConfig.showShortExit1Line = true; + configs.xcheConfig.showShortExit2Line = true; + } + if (showTRND) + { + // + // Show Trend ... + configs.xtrndConfig.showL1Trend = true; + configs.xtrndConfig.showL2Trend = true; + configs.xtrndConfig.showL3Trend = true; + } + + // + xEAProvider = new XSCX121Provider( + _Symbol, + _Period); + + // + // Attach Event Handlers ... + xEAProvider.AddOnSignalConditionEventHandler(OnSignalConditionsRecieved); + + // + // Initialize Provider ... + result = xEAProvider.SetConfig(configs); + if (!result) + { + return result; + } + + // + return result; +} + +// +void CallProvidersOnTick() +{ + // + // int providersCount = ArraySize(xEAProviders); + // if (providersCount <= 0) + // { + // return; + // } + + // // + // // Loop Through Providers ... + // for (int i = 0; i < providersCount; i++) + // { + // // + // X121SignalProvider providerDescriptor = xEAProviders[i]; + + // // + // providerDescriptor.provider.OnTick(); + // } + + // + xEAProvider.OnTick(); +} + +// +void GetPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + ENUM_X121_SIGNAL_PROVIDERS provider = NULL // Trade Provider ... +) +{ + // + Clean(result); + + // + int positionsCount = xEATrade.PositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition positions[]; + xEATrade.GetPositions( + positions, + symbol, + period); + positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + if (provider == NULL && type == NULL) + { + // + ArrayResize( + result, + ArraySize(positions)); + + // + for (int i = 0; i < positionsCount; i++) + { + // + Add( + positions[i], + result); + } + + // + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + ENUM_X121_SIGNAL_PROVIDERS iProvider = ExtractProvider(iPosition); + if (provider != NULL && iProvider != provider) + { + continue; + } + + // + if (type == NULL || iPosition.type == type) + { + // + Add( + iPosition, + result); + } + } +} + +// +// START Guard Functions ... +// + +// +// Do Guard Actions ... +void HandleGuard() +{ + // + // Retrieve Provider Guard Actions ... + X121Guard guards[]; + xEAProvider.ProvideGuard(guards); + int guardsCount = ArraySize(guards); + if (guardsCount <= 0) + { + return; + } + + // + for (int i = 0; i < guardsCount; i++) + { + // + X121Guard iGuard = guards[i]; + + // + switch (iGuard.action) + { + // + // Hedge In Profit Specified Positions ... + case X_GUARD_ACTION_HEDGE: + HandleGuardHedgeAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Trail Stop Loss in Specified Positions ... + case X_GUARD_ACTION_TRAIL_STOP: + HandleGuardTrailingStopAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period, + iGuard.dblPayLoad); + break; + + // + // Force Close Specified Positions ... + case X_GUARD_ACTION_FORCE_CLOSE: + HandleGuardForceCloseAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Generate and Place Support Signals ... + case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL: + HandleGuardAddSupportPositionAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Delete All Placed Pending Orders ... + case X_GUARD_ACTION_CANCEL_PENDING_ORDERS: + HandleGuardCancelPendingOrdersAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + } + } +} + +// +// Close All Specified Provider's Positions in Profit Summary ... +void HandleGuardHedgeAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame +) +{ + // + // TODO: Implement this ... +} + +// +// Force Close Specified Set Of Position ... +void HandleGuardForceCloseAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame +) +{ + // + ENUM_X121_SIGNAL_PROVIDERS mProvider = ExtractProvider(provider); + + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + mProvider); + if (ArraySize(positions) <= 0) + { + return; + } + + // + string comment = provider + " Force Close Due Market Sense Change ..."; + xEATrade.ClosePositions( + positions, + comment); + + // + LogMessage(comment); +} + +// +// Trailing Specified Set Of Positions Stop Losses ... +void HandleGuardTrailingStopAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double sl // Desired SL Value ... +) +{ + // + // TODO: Implement this ... +} + +// +// Add Support Signal for Specified Positions ... +void HandleGuardAddSupportPositionAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame +) +{ + // + // TODO: Implement this ... +} + +// +// Cancel all Placed Orders ... +void HandleGuardCancelPendingOrdersAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame +) +{ + // + // TODO: Implement this ... +} + +// +// END Guard Functions ... +// + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x-saherelm.xhull.class.mq5 b/MQLTestWorkspace/BKPS/BKP/x-saherelm.xhull.class.mq5 new file mode 100644 index 0000000..185449a --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x-saherelm.xhull.class.mq5 @@ -0,0 +1,216 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Hull Class Library +// ---------------------------------------------- +// Name: XSCHull +// Description: provides all Hull requirements ... +// +// +// 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 Definitions ... +// + +// +struct XHullData +{ + // + double value; + double value3; + + // + double wsum1; + double wsum2; + double wsum3; + + // + double lsum1; + double lsum2; + double lsum3; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init(int period, double divisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(period > 1 ? period : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (divisor > 1 ? divisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x-saherelm.xtrade.before.ontrade.handlers.class.mq5 b/MQLTestWorkspace/BKPS/BKP/x-saherelm.xtrade.before.ontrade.handlers.class.mq5 new file mode 100644 index 0000000..f0d5b4a --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x-saherelm.xtrade.before.ontrade.handlers.class.mq5 @@ -0,0 +1,2838 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Class Library +// ---------------------------------------------- +// Name: XSCTrade +// Description: provides all Trade requirements ... +// +// +// 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 Definitions ... +// + +// +// Model an Open Position ... +struct XPosition +{ + // + // Magic Number ... + ulong magic; + + // + // Ticket ID ... + ulong ticket; + + // + // Tradinng Symbol ... + string symbol; + + // + // Trading Period ... + ENUM_TIMEFRAMES period; + + // + // Position Type ... + ENUM_POSITION_TYPE type; + + // + // Take Profit ... + double tp; + + // + // Stop Loss ... + double sl; + + // + // Position Current Profit ... + double profit; + + // + // Position Open Price ... + double entry; + + // + // Current Symbol Price ... + double price; + + // + // Position Swap ... + double swap; + + // + // Position Commission ... + double commission; + + // + // Volume ... + double volume; + + // + // Position Open Time ... + datetime openAt; + + // + // Position Comment ... + string comment; +}; + +// +// Model an Order ... +struct XOrder +{ + // + // Time of order placement ... + datetime setupAt; + + // + // Time of order expiration ... + datetime expiredAt; + + // + // Time of order execution or cancellation ... + datetime executedAt; + + // + // Order type ... + ENUM_ORDER_TYPE type; + + // + // Order state ... + ENUM_ORDER_STATE state; + + // + // Type of execution by remainder ... + ENUM_ORDER_TYPE_FILLING filling; + + // + // Order lifetime ... + ENUM_ORDER_TYPE_TIME lifetime; + + // + // Order ticket ... + ulong ticket; + + // + // Magic Number ... + long magic; + + // + // Position id, that is placed on order, + // when it is executed. Each executed order invokes a + // deal, that opens new or changes existing + // position. Id of that position is placed on + // executed order in this moment. + long pocitionID; + + // + // Initial volume on order placement ... + double initialVolume; + + // + // Unfilled volume ... + double currentVolume; + + // + // Price, specified in the order ... + double openPrice; + + // + // Current price by order symbol ... + double currentPrice; + + // + // Price of placing Limit order when StopLimit order is triggered ... + double stopLimitPrice; + + // + // Take Profit level ... + double tp; + + // + // Stop Loss level ... + double sl; + + // + // Trading Symbol ... + string smybol; + + // + // Order Comment ... + string comment; +}; + +// +// Model a 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; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// XCTrade Base Class ... +class XSCTradeBase : 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 ... +// + +// +// a Class for Manage Trades ... +class XSCTrade +{ + // + // Public ... +public: + // + // Constructor ... + void XSCTrade( + int slippage, // Specify Slippage + ulong magicNumber // Specify Magic Number + ) + { + // + mSlippage = slippage; + mMagicNumber = magicNumber; + + // + mPeriodPrefix = "PR"; + + // + mTrader = new XSCTradeBase(); + + // + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + // Prepare Trade Event Materials ... + mStartDate = 0; + mLastOrdersCount = OrdersTotal(); + mLastDealsCount = HistoryDealsTotal(); + mLastPositionsCount = PositionsTotal(); + + // + GetDeals(mLastDeals); + GetOrders(mLastOrders); + GetPositions(mLastPositions); + } + + // + // Deconstructor ... + void ~XSCTrade() + { + } + + // + // START Event Processing ... + // + + // + // This Must be Called Every time OnTrade Event Happening ... + void HandleOnTrade() + { + // + int ordersCount = OrdersTotal(); + int dealsCount = HistoryDealsTotal(); + int positionsCount = PositionsTotal(); + + // + // LogMessage("Salam"); + + // + GetDeals(mDeals); + GetOrders(mOrders); + GetPositions(mPositions); + + // + datetime currentTime = TimeCurrent(); + HistorySelect(mStartDate, currentTime); + + // + // Processing Positions ... + if (positionsCount > mLastPositionsCount) + { + // + // Position Appeared ... + LogMessage("Position Appeared ..."); + + // + // Update Deals ... + dealsCount = HistoryDealsTotal(); + GetDeals(mDeals); + } + else if (positionsCount < mLastPositionsCount) + { + // + // Position Disappeared ... + LogMessage("Position Disappeared ..."); + + // + // Update Deals ... + dealsCount = HistoryDealsTotal(); + GetDeals(mDeals); + } + + // + // Processing Order Changes ... + if (ordersCount > mLastOrdersCount) + { + // + // Orders Appeared ... + LogMessage("Orders Appeared ..."); + } + else if (ordersCount < mLastOrdersCount) + { + // + // Orders Disappeared ... + LogMessage("Orders Disappeared ..."); + } + + // + // Processing Deal Changes ... + if (dealsCount > mLastDealsCount) + { + // + // Deals Appeared ... + LogMessage("Deals Appeared ..."); + } + else if (dealsCount > mLastDealsCount) + { + // + // Deals Disappeard ... + LogMessage("Deals Disappeard ..."); + } + + // + // Update Date after processing ... + + // + mLastOrdersCount = OrdersTotal(); + mLastDealsCount = HistoryDealsTotal(); + mLastPositionsCount = PositionsTotal(); + + // + GetDeals(mLastDeals); + GetOrders(mLastOrders); + GetPositions(mLastPositions); + } + + // + // END Event Processing ... + // + + // + // START Provided Functions ... + // + + // + // Count Currently Open Positions ... + int PositionsCount( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + int result = 0; + + // + int allPositions = 0; + int longPositions = 0; + int shortPositions = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + allPositions++; + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + allPositions++; + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + } + + // + // Specify Result ... + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + result = allPositions; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions++; + } + } + else if (StringLen(symbol) > 0) + { + // + result = allPositions; + } + else if (type != NULL) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions; + } + } + + // + return result; + } + + // + // Retrieve Max In Profit Position Ticket ... + ulong GetMaxInProfitPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit <= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Max In DrawDown Position Ticket ... + ulong GetMaxInDrawDownPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Specific Position's Profit ... + double GetPositionProfit( + const ulong ticket // Specified Position Ticket + ) + { + // + double result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Profit(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's OpenDate ... + datetime GetPositionOpenDate( + const ulong ticket // Specified Position Ticket + ) + { + // + datetime result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Time(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's Comment ... + string GetPositionComment( + const ulong ticket // Specified Position Ticket + ) + { + // + string result = ""; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Comment(); + break; + } + + // + return result; + } + + // + // Retrieve All Open Positions Profit ... + double GetPositionsProfit( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + double result = 0; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionProfit) + { + // + result += positionProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionProfit) + { + // + result += positionProfit; + } + } + else + { + // + if (profit < positionProfit) + { + // + result += positionProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionProfit) + { + // + result += positionProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionProfit) + { + // + result += positionProfit; + } + } + else + { + // + if (profit < positionProfit) + { + // + result += positionProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Find Oldes Position ... + ulong GetOldestPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = 0; + + // + int age = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + string positionComment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(positionComment); + + // + // Calculate Position's Age ... + datetime positionOpenTime = mPositionInfo.Time(); + + // + // Retrieve Trade Open Bar Index based on Current Period ... + int positionOpenBarIndex = iBarShift( + positionSymbol, + positionPeriod, + positionOpenTime); + + // + // Calculate Trade Life ... + int positionAge = MathAbs(0 - positionOpenBarIndex); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Force Open a Buy/Long Position ... + bool Buy( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Buy( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Force Open a Sell/Short Position ... + bool Sell( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Sell( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellStop( + volume, + price, + symbol, + 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 + string comment = "" // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + if (tp <= 0 && sl <= 0) + { + result = false; + return result; + } + + // + // Use Position Comment when there isn't new One ... + if (StringLen(comment) == 0) + { + comment = GetPositionComment(ticket); + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment); + + // + 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); + + // + return result; + } + + // + // Close All Positions ... + void CloseAllPositions( + string comment = "" // Close Position By Specific Comment + ) + { + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + Close( + positionTicket, + comment); + } + } + + // + // 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); + + // + return result; + } + + // + // Find Position Open Bar Index ... + int GetPositionOpenBarIndex( + const ulong ticket // position ticket + ) + { + // + int result = -1; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + string comment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + result = iBarShift( + symbol, + period, + openAt); + } + + // + return result; + } + + // + // Retrieve Positions as an Array ... + void GetPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clear(result); + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong magic = mPositionInfo.Magic(); + ulong ticket = mPositionInfo.Ticket(); + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + double swap = mPositionInfo.Swap(); + double sl = mPositionInfo.StopLoss(); + double tp = mPositionInfo.TakeProfit(); + double profit = mPositionInfo.Profit(); + double volume = mPositionInfo.Volume(); + string comment = mPositionInfo.Comment(); + double entry = mPositionInfo.PriceOpen(); + double price = mPositionInfo.PriceCurrent(); + double commission = mPositionInfo.Commission(); + ENUM_POSITION_TYPE type = mPositionInfo.PositionType(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + XPosition iPosition = {}; + + // + iPosition.tp = tp; + iPosition.sl = sl; + iPosition.swap = swap; + iPosition.type = type; + iPosition.magic = magic; + iPosition.entry = entry; + iPosition.price = price; + iPosition.ticket = ticket; + iPosition.symbol = symbol; + iPosition.period = period; + iPosition.volume = volume; + iPosition.openAt = openAt; + iPosition.profit = profit; + iPosition.comment = comment; + iPosition.commission = commission; + + // + Add( + iPosition, + result); + } + } + + // + void GetPositions( + XPosition &result[], // Hold Result ... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Period ... + ) + { + // + Clear(result); + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition allPositions[]; + GetPositions(allPositions); + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (symbol != iPosition.symbol) + { + continue; + } + + // + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(iPosition.comment); + if (period != positionPeriod) + { + continue; + } + + // + Add( + iPosition, + result); + } + } + + // + // Retrieve in Profit Positions ... + void GetInProfitPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clear(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit > 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Retrieve in Drawdown Positions ... + void GetInDrawdownPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clear(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit < 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Close a Collection Of Positions ... + void ClosePositions( + XPosition &positions[], // Positions to Close ... + string comment = "" // Specified Comment ... + ) + { + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + Close( + iPosition.ticket, + comment); + } + } + + // + // Retrieve All Orders ... + void GetOrders(XOrder &result[]) + { + // + Clear(result); + + // + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return; + } + + // + // Since Orders may be so more than positions ... + // start Orders Collectiong Loops reverse ... + for (int i = ordersCount - 1; i >= 0; i--) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mOrderInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + long magic = mOrderInfo.Magic(); + double sl = mOrderInfo.StopLoss(); + ulong ticket = mOrderInfo.Ticket(); + double tp = mOrderInfo.TakeProfit(); + string smybol = mOrderInfo.Symbol(); + string comment = mOrderInfo.Comment(); + long pocitionID = mOrderInfo.PositionId(); + double openPrice = mOrderInfo.PriceOpen(); + datetime setupAt = mOrderInfo.TimeSetup(); + datetime executedAt = mOrderInfo.TimeDone(); + ENUM_ORDER_STATE state = mOrderInfo.State(); + ENUM_ORDER_TYPE type = mOrderInfo.OrderType(); + double currentPrice = mOrderInfo.PriceCurrent(); + datetime expiredAt = mOrderInfo.TimeExpiration(); + double initialVolume = mOrderInfo.VolumeInitial(); + double currentVolume = mOrderInfo.VolumeCurrent(); + double stopLimitPrice = mOrderInfo.PriceStopLimit(); + ENUM_ORDER_TYPE_TIME lifetime = mOrderInfo.TypeTime(); + ENUM_ORDER_TYPE_FILLING filling = mOrderInfo.TypeFilling(); + + // + // Now Create an instance of XOrder struct and fill it by + // retrieved data, and add it to results ... + XOrder iOrder = {}; + + // + iOrder.sl = sl; + iOrder.tp = tp; + iOrder.type = type; + iOrder.state = state; + iOrder.magic = magic; + iOrder.ticket = ticket; + iOrder.smybol = smybol; + iOrder.setupAt = setupAt; + iOrder.comment = comment; + iOrder.filling = filling; + iOrder.lifetime = lifetime; + iOrder.expiredAt = expiredAt; + iOrder.openPrice = openPrice; + iOrder.pocitionID = pocitionID; + iOrder.executedAt = executedAt; + iOrder.currentPrice = currentPrice; + iOrder.initialVolume = initialVolume; + iOrder.currentVolume = currentVolume; + iOrder.stopLimitPrice = stopLimitPrice; + + // + Add( + iOrder, + result); + } + } + + // + // Retrieve All Deals ... + void GetDeals(XDeal &result[]) + { + // + Clear(result); + + // + int dealsCount = HistoryDealsTotal(); + if (dealsCount <= 0) + { + return; + } + + // + for (int i = dealsCount - 1; i >= 0; i--) + { + // + if (!mDealInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mDealInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + double swap = mDealInfo.Swap(); + ulong magic = mDealInfo.Magic(); + ulong order = mDealInfo.Order(); + ulong ticket = mDealInfo.Ticket(); + datetime time = mDealInfo.Time(); + double price = mDealInfo.Price(); + string symbol = mDealInfo.Symbol(); + double profit = mDealInfo.Profit(); + double volume = mDealInfo.Volume(); + string comment = mDealInfo.Comment(); + ulong positionId = mDealInfo.PositionId(); + ENUM_DEAL_ENTRY entry = mDealInfo.Entry(); + double commission = mDealInfo.Commission(); + ENUM_DEAL_TYPE type = mDealInfo.DealType(); + ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( + ticket, + DEAL_REASON); + + // + XDeal iDeal = {}; + + // + iDeal.swap = swap; + iDeal.time = time; + iDeal.type = type; + iDeal.magic = magic; + iDeal.entry = entry; + iDeal.order = order; + iDeal.price = price; + iDeal.ticket = ticket; + iDeal.symbol = symbol; + iDeal.profit = profit; + iDeal.volume = volume; + iDeal.reason = reason; + iDeal.comment = comment; + iDeal.positionId = positionId; + iDeal.commission = commission; + + // + Add( + iDeal, + result); + } + } + + // + // Generate String Representation Of Position's Time Frame ... + string GeneratePositionPeriodComment(ENUM_TIMEFRAMES period) + { + // + string result = mPeriodPrefix + "(" + ToString(period) + ")"; + + // + return result; + } + + // + // Extract Position Time Frame From it's Comment ... + ENUM_TIMEFRAMES ExtractPositionPeriod(string comment) + { + // + ENUM_TIMEFRAMES result = _Period; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string periodStr = ExtractString( + comment, + mPeriodPrefix + "(", + ")"); + if (StringLen(periodStr) <= 0) + { + return result; + } + + // + result = ToPeriod(periodStr); + + // + return result; + } + + // + // Retrieve Last Open Position Ticket ... + ulong GetLastOpenPositionTicket() + { + // + ulong result = 0; + + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + result = PositionGetTicket(PositionsTotal() - 1); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // using deviation, it must be in Point ... + int mSlippage; + + // + // using magic number ... + ulong mMagicNumber; + + // + // using CTrade instance ... + XSCTradeBase mTrader; + + // + // Deals Info ... + CDealInfo mDealInfo; + + // + // Order Info ... + COrderInfo mOrderInfo; + + // + // using PositionInfo instance ... + CPositionInfo mPositionInfo; + + // + // ADDITIONAL Data ... + + // + string mPeriodPrefix; + + // + // Trade Processing ... + datetime mStartDate; + int mLastDealsCount; + int mLastOrdersCount; + int mLastPositionsCount; + // + XDeal mDeals[]; + XOrder mOrders[]; + XPosition mPositions[]; + // + XDeal mLastDeals[]; + XOrder mLastOrders[]; + XPosition mLastPositions[]; +}; + +// +// START Usefull Functions ... +// + +// +// Add Specific XPosition to Specified Array ... +void Add( + XDeal &item, + XDeal &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOrder &item, + XOrder &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XPosition &item, + XPosition &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Clear All Items Inside Array ... +void Clear(XDeal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clear(XOrder &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clear(XPosition &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Experts/Test/x-saherelm.xea.test.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Experts/Test/x-saherelm.xea.test.mq5 new file mode 100644 index 0000000..f01ba68 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Experts/Test/x-saherelm.xea.test.mq5 @@ -0,0 +1,1353 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: XEA TEST +// 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 EA" +#property strict + +// +// START Definitions ... +// + +// +string mSupportToken = "SP"; +string mProviderToken = "PRV"; +string mRiskFreeToken = "RF"; + +// +enum ENUM_X_SIGNAL_PROVIDERS +{ + NONE = 0, + XTRND = 1, + XICHI = 2, + XTest = 10, +}; + +// +// END Definitions ... +// + +// +// START Inputs ... +// + +// +// EA ... +input group "Common"; +input bool xEAEnable = true; // Enable EA +input int xEASlippage = 10; // Slippgae +input ulong xEAMagicNumber = 1604056; // Magic Number + +// +// Signals ... +input group "Signals"; +input bool xEAEnableLongs = true; // Enable Long Trades +input bool xEAEnableShorts = true; // Enable Short Trades + +// +// Alerts ... +input group "Alerts"; +input bool xEAEnableAlerts = true; // Enable Events Alert +input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day +input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Classes ... +#include "../../Classes/x-saherelm.xtrade.class.mq5" +#include "../../Classes/x-saherelm.xaccount.class.mq5" +#include "../../Classes/x-saherelm.xdatacollector.class.mq5" + +// +// Test Provider Library ... +#include "../../Providers/Test/x121.test.provider.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +bool isXEANewHour; +bool isXEANewDay; +bool isXEANewWeek; +bool isXEANewMonth; + +// +// Determines EA is Running On Test Mode or not ... +bool xEAIsTestMode = false; + +// +// Check prevent Double Signalling on Same Candle ... +bool xEAWaitUntilNextCandle = false; + +// +XSCTrade *xEATrade; +XSCAccount *xEAAccount; +XSCDataCollector *xEACollector; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = "XEA"; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Reset Timings ... + ResetTiming(); + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Provider ... + if (!XTestPRVDOnInit()) + { + return INIT_FAILED; + } + + // + xEAIsTestMode = IsRunningOnTestMode(); + + // + xEACollector = new XSCDataCollector("XTestEA"); + xEACollector.CleanStore(); + + // + // Initialize Trade Class ... + xEATrade = new XSCTrade( + xEASlippage, + xEAMagicNumber); + + // + // Attach Event Handlers ... + xEATrade.AddOnStopLossEventHandler(OnStopLossTriggered); + xEATrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); + xEATrade.AddOnDealsChangedEventHandler(OnDealsChangedHandler); + xEATrade.AddOnOrdersChangedEventHandler(OnOrdersChangedHandler); + + // + // Initialize Account Class ... + xEAAccount = new XSCAccount(); + + // + // 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 ... + delete xEATrade; + delete xEAAccount; + delete xEACollector; + + // + // De Initialize XEA Providers ... + XTestPRVDOnDeInit(); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Handle Monthly Alert ... + bool isFirstMonth = xMonth == -1; + isXEANewMonth = IsNewMonth(); + bool canMonthlyAlert = + isXEANewMonth && + xEAEnableAlerts && + xEAEnableMonthlyAlerts; + if (canMonthlyAlert) + { + // + string message = "New Month ..."; + + // + SendAlert(message); + } + + // + // Handle Weekly Alert ... + bool isFirstWeek = xDayOfWeek == -1; + isXEANewWeek = IsNewWeek(); + bool canWeeklyAlert = + isXEANewWeek && + xEAEnableAlerts && + xEAEnableWeeklyAlerts; + if (canWeeklyAlert) + { + // + string message = "New Week ..."; + + // + SendAlert(message); + } + + // + // Handle Daily Alert ... + bool isFirstDay = xDay == -1; + isXEANewDay = IsNewDay(); + bool canDailyAlert = + isXEANewDay && + xEAEnableAlerts && + xEAEnableDailyAlerts; + if (canDailyAlert) + { + // + string message = "New Day ..."; + + // + SendAlert(message); + } + + // + // Handle Hourly Alert ... + bool isFirstHour = xHour == -1; + isXEANewHour = IsNewHour(); + bool canHourlyAlert = + isXEANewHour && + xEAEnableAlerts && + xEAEnableHourlyAlerts; + if (canHourlyAlert) + { + // + string message = "New Hour ..."; + + // + SendAlert(message); + } + + // + // Prevent Going Forward if user Disable it ... + if (xEAEnable) + { + // + // Call All Providers OnTick Method ... + XTestPRVDOnTick(); + + // + // Do all Guard Mechanism ... + HandleGuard(); + + // + // Check Can Ignore Tick or not .. + bool canIgnoreTick = xEAIsTestMode + ? !IsNewCandle() + : !IsNewCandle() && xEAWaitUntilNextCandle; + if (canIgnoreTick) + { + return; + } + + // + xEAWaitUntilNextCandle = false; + + // + XSignal signal; + bool hasSignal = XTestPRVDProcessSignals(signal); + if (hasSignal) + { + // + xEAWaitUntilNextCandle = true; + OnSignalRecieved(signal); + } + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + // + // Process Trades ... + xEATrade.HandleOnTrade(); +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + // TODO: Fix this ... + bool result = true; + + // + // Validate Args ... + result = + // + xEASlippage > 0 && + xEAMagicNumber > 0 + // + ; + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// Handle Signal Recieved Event ... +void OnSignalRecieved( + XSignal &signal // Recieved Signal ... +) +{ + // + // Ignore Disabled Signals ... + if ((signal.type == POSITION_TYPE_BUY && !xEAEnableLongs) || + (signal.type == POSITION_TYPE_SELL && !xEAEnableShorts)) + { + return; + } + + // + if (StringLen(signal.symbol) == 0 || signal.period == NULL) + { + return; + } + + // + xEACollector.CollectSignal(signal); + + // + // Count Open Positions ... + int openPositionsCount = xEATrade.PositionsCount(); + + // + string mTagId = GenerateTag(signal); + + // + // Check Last Signal ... + datetime barTime = iTime( + signal.symbol, + signal.period, + 0); + + // + // Retrieve Tradable Balance ... + double availableBalance = xEAAccount.GetEquity(); + + // + // Verify Available Balance ... + double balance = xEAAccount.GetBalance(); + + // + // Here i Must Calculate TP and SL based on R2R and riskable Factor ... + bool isLong = IsLong(signal.type); + + // + // Check Order Mode ... + if (signal.mode == NULL) + { + // + // Set Market Execution as Default ... + signal.mode = X_ORDER_MODE_MARKET; + } + + // + // Calculate Entry Price ... + if (signal.entry <= 0) + { + // + signal.entry = GetEntry( + signal.symbol, + signal.type); + } + + // + // R2R ... + if (signal.r2r <= 0) + { + // + // Set Default Risk to Reward Ratio to 1 ... + signal.r2r = 1; + } + + // + // Calculate TP and SL ... + double mPoint = GetPoints(signal.symbol); + + // + // Normalize SL Price ... + if (signal.sl > 0) + { + signal.sl = NormalizePrice(signal.sl, signal.symbol); + } + + // + // Retrieve Symbol Point Value ... + double pointValue = xEAAccount.GetPointValue(signal.symbol); + + // + // Calculate Risk ... + double riskPrice = MathAbs(signal.entry - signal.sl); + riskPrice = NormalizePrice(riskPrice, signal.symbol); + + // + double riskPoints = PriceToPoint(riskPrice); + riskPoints = NormalizeDouble(riskPoints, 0); + + // + // Calculating Reward based On Ratio ... + double rewardPoints = riskPoints * signal.r2r; + double rewardPrice = PointToPrice(rewardPoints); + rewardPrice = NormalizePrice(rewardPrice, signal.symbol); + + // + // Calculate TP Price ... + double tpValue = isLong + ? signal.entry + rewardPrice + : signal.entry - rewardPrice; + + // + // Calculate SL Price ... + double slValue = isLong + ? signal.entry - riskPrice + : signal.entry + riskPrice; + + // + // Balance Amount which we risks on each Provider's Trade ... + double amount = availableBalance * signal.riskAmount; + + // + // Calculating Trade Volume based on risk Points and Amount ... + double volume = 0.02; + // xEAAccount.CalculateVolume( + // signal.symbol, + // amount, + // riskPoints); + volume = NormalizeVolume(volume, signal.symbol); + + // + // Set Caculated TP, SL and Volume ... + signal.tp = tpValue; + signal.sl = slValue; + signal.volume = volume; + + // + string comment = ""; + int signalProvidersCount = ArraySize(signal.providers); + if (signalProvidersCount > 0) + { + // + string prvs = ""; + for (int i = 0; i < signalProvidersCount; i++) + { + // + string p = signal.providers[i]; + + // + if (StringLen(prvs) > 0) + { + prvs += ","; + } + + // + prvs += p; + } + + // + comment = "PRV(" + prvs + ")"; + } + + // + // Here before Open Signal Position ... + // and after complete TP SL and Volume Calculations ... + // Recieve a List Of Supported Positions, based on retrieve Support and Resistance ares + // for Signal ... + XSignal supportSignals[]; + xEATrade.GenerateSupportSignals( + supportSignals, + signal); + int supportSignalsCount = ArraySize(supportSignals); + + // + bool isPositionOpen = xEATrade.ExecuteSignal( + signal, + comment); + + // + if (isPositionOpen) + { + // + // Retrieve Position Ticket ... + ulong ticket = xEATrade.GetLastOpenPositionTicket(); + if (ticket == 0) + { + return; + } + + // + if (supportSignalsCount >= 0) + { + // + // Here we Must Place Orders ... + string comment = mSupportToken + "(" + (string)ticket + ")"; + + // + // CleanSupport Positions SLs ... + // for (int i = 0; i < supportSignalsCount; i++) { + // // + // XSignal iSignal = supportSignals[i]; + + // // + // // iSignal.sl = 0; + // } + + // + // TODO: Add Expiration Date, Volume Calculation ... + // int executedSignals = xEATrade.ExecuteSignals( + // supportSignals, + // comment); + } + + // + // Draw Signal ... + ReDrawSignal(ticket, signal); + + // + // Alert Position ... + LogMessage("Position: " + (string)ticket + " was Open ..."); + } else { + DrawSupportResistance(1, signal.supportAndResistance); + } +} + +// +// Handle StopLoss Event ... +void OnStopLossTriggered(const XDeal &deal) +{ + // + string msg = "SL: " + (string)deal.positionId; + LogMessage(msg); + + // + xEACollector.CollectLog(msg); + + // + xEACollector.CollectDeal(deal); +} + +// +// Handle TakeProfit Event ... +void OnTakeProfitTriggered(const XDeal &deal) +{ + // + string msg = "TP: " + (string)deal.positionId; + LogMessage(msg); + + // + xEACollector.CollectLog(msg); + + // + xEACollector.CollectDeal(deal); +} + +// +void OnDealsChangedHandler(int count) +{ + // + string msg = "Deals Changed: " + (string)count; + LogMessage(msg); + xEACollector.CollectLog(msg); +} + +// +void OnOrdersChangedHandler(int count) +{ + // + string msg = "Orders Changed: " + (string)count; + LogMessage(msg); + xEACollector.CollectLog(msg); +} + +// +void HandleGuard() +{ + // + // Handle Force Close Positions ... + // HandleForceClosing(); + + // + // Trailing Stops and Make Positions Risk Free ... + // HandleRiskFree(); + + // + // When all Positions Profit Going Positive ... + // HandlePyramidHedge(); + + // + // When a Position running in profit long time ... + // HandleCloseOldInProfitTrades(); +} + +// +// Force Close Provider's Signals on Special Conditions ... +void HandleForceClosing() +{ + // + // Force Close all XTRND Short Positions ... + bool canCloseAllXTRNDShortPositions = + // + XTRNDForceCloseAllShorts() + // + ; + if (canCloseAllXTRNDShortPositions) + { + // + XPosition positions[]; + GetSpecificProviderPositions( + positions, + _Symbol, + _Period, + XTRND, + POSITION_TYPE_SELL); + int positionsCount = ArraySize(positions); + if (positionsCount > 0) + { + // + string comment = "Force Close XTRND Shorts ..."; + + // + xEATrade.ClosePositions( + positions, + comment); + + // + DrawForceCloseEvent(); + } + } + + // + // Force Close all XTRND Long Positions ... + bool canCloseAllXTRNDLongPositions = + // + XTRNDForceCloseAllLongs() + // + ; + if (canCloseAllXTRNDLongPositions) + { + // + XPosition positions[]; + GetSpecificProviderPositions( + positions, + _Symbol, + _Period, + XTRND, + POSITION_TYPE_BUY); + int positionsCount = ArraySize(positions); + if (positionsCount > 0) + { + // + string comment = "Force Close XTRND Shorts ..."; + + // + xEATrade.ClosePositions( + positions, + comment); + + // + DrawForceCloseEvent(); + } + } +} + +// +// Make Positions Risk Free and Trailing Stops ... +void HandleRiskFree() +{ + // + double distanceFactorForRiskFree = 0.3; + + // + XPosition inProfitPositions[]; + xEATrade.GetInProfitPositions(inProfitPositions); + int inProfitPositionsCount = ArraySize(inProfitPositions); + if (inProfitPositionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < inProfitPositionsCount; i++) + { + // + XPosition iPosition = inProfitPositions[i]; + + // + // Only Make Positions Risk Free based On their SL or TP ... + if (iPosition.tp <= 0 && iPosition.sl <= 0) + { + continue; + } + + // + bool isLong = IsLong(iPosition.type); + + // + bool isRFBefore = StringFind( + iPosition.comment, + "RF") > 0; + + // + double lastRFPrice = iPosition.entry; + string lastRFPriceStr = ""; + if (isRFBefore) { + // + lastRFPriceStr = ExtractString( + iPosition.comment, + mRiskFreeToken + "(", + ")" + ); + if (StringLen(lastRFPriceStr) > 0) { + lastRFPrice = (double) lastRFPriceStr; + } + } + + // + double tpDistancePrice = MathAbs(lastRFPrice - iPosition.tp); + double rfPrice = (tpDistancePrice * distanceFactorForRiskFree); + + // + bool canRiskFree = MathAbs(lastRFPrice - iPosition.price) > rfPrice; + if (!canRiskFree) + { + continue; + } + + // + double tp = + isLong + ? iPosition.tp + rfPrice + : iPosition.tp - rfPrice; + double sl = + isLong + ? iPosition.tp - rfPrice + : iPosition.sl - rfPrice; + + // + string comment = iPosition.comment; + if (isRFBefore) { + // + StringReplace( + comment, + lastRFPriceStr, + "" + ); + } + + // + comment += mRiskFreeToken + "(" + (string)iPosition.price + ")"; + + // + bool isModified = xEATrade.Modify( + iPosition.ticket, + sl, + tp, + comment); + if (isModified) + { + // + string msg = "Make Position (" + (string)iPosition.ticket + ") Risk Free ..."; + LogMessage(msg); + } + } +} + +// +// Pyramid Hedging ... +void HandlePyramidHedge() +{ + // + int positionsCount = xEATrade.PositionsCount(); + if (positionsCount <= 1) + { + return; + } + + // + double minProfitForHedging = positionsCount * 1; + double positionsProfit = xEATrade.GetPositionsProfit(); + + // + if (positionsProfit < minProfitForHedging) + { + return; + } + + // + string comment = "Pyramid Hedging ..."; + + // + xEATrade.CloseAllPositions(comment); +} + +// +// Close In Profit Old Trades ... +void HandleCloseOldInProfitTrades() +{ + // + int oldAge = 50; + double minProfit = 1; + bool onlySupports = false; + + // + XPosition inProfitPositions[]; + xEATrade.GetInProfitPositions(inProfitPositions); + int inProfitPositionsCount = ArraySize(inProfitPositions); + if (inProfitPositionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < inProfitPositionsCount; i++) + { + // + XPosition iPosition = inProfitPositions[i]; + if (iPosition.profit < minProfit || + (iPosition.tp > 0 && + MathAbs(iPosition.entry - iPosition.price) < MathAbs(iPosition.entry - iPosition.tp) / 2)) + { + continue; + } + + // + // Check Position Age ... + int iPositionBarIndex = xEATrade.GetPositionOpenBarIndex(iPosition.ticket); + int iPositionAge = MathAbs(iPositionBarIndex - 0); + if (iPositionAge < oldAge) + { + continue; + } + + // + string comment = "Close On Old In Profit Trade ..."; + + // + bool isPositionClosed = false; + + // + if (onlySupports) + { + // + // Check Position is Support or not ... + bool isSupport = IsSupportPosition(iPosition); + if (isSupport) + { + // + // Close Position ... + isPositionClosed = xEATrade.Close( + iPosition.ticket, + comment); + } + } + else + { + // + // Close Position ... + isPositionClosed = xEATrade.Close( + iPosition.ticket, + comment); + } + + // + // Alert Events ... + string msg = "Position (" + (string)iPosition.ticket + ") Closed due InProfit Old Event ..."; + LogMessage(msg); + } +} + +// +// Tools and Usefull Functions ... +// + +// +// Convert Position to Signal ... +XSignal ToSignalInfo( + XPosition &position) +{ + // + XSignal result; + + // + result.tp = position.tp; + result.sl = position.sl; + result.type = position.type; + result.entry = position.entry; + result.symbol = position.symbol; + result.period = position.period; + result.volume = position.volume; + + // + return result; +} + +// +string ToString(ENUM_X_SIGNAL_PROVIDERS provider) +{ + // + return EnumToString(provider); +} + +// +ENUM_X_SIGNAL_PROVIDERS ToProvider(string provider) +{ + // + ENUM_X_SIGNAL_PROVIDERS result; + + // + if (ToString(XTest) == provider) + { + result = XTest; + } + else if (ToString(XTRND) == provider) + { + result = XTRND; + } else if (ToString(XICHI) == provider) { + result = XICHI; + } else + { + result = NONE; + } + + // + return result; +} + +// +// Extract Position Provider ... +ENUM_X_SIGNAL_PROVIDERS ExtractProviderFromComment(string comment) +{ + // + ENUM_X_SIGNAL_PROVIDERS result = NONE; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string providerStr = ExtractString( + comment, + mProviderToken + "(", + ")"); + if (StringLen(providerStr) <= 0) + { + return result; + } + + // + result = ToProvider(providerStr); + + // + return result; +} + +// +// Retrieve Specific Type of Providers Positions ... +void GetSpecificProviderPositions( + XPosition &result[], // Holds Result + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + ENUM_X_SIGNAL_PROVIDERS provider, // Position Provider + ENUM_POSITION_TYPE type = NULL // Position Type +) +{ + // + Clean(result); + + // + if (StringLen(symbol) == 0 || provider == NONE) + { + return; + } + + // + int positionsCount = xEATrade.PositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition symbolPeriodPositions[]; + xEATrade.GetPositions( + symbolPeriodPositions, + symbol, + period); + int symbolPeriodPositionsCount = ArraySize(symbolPeriodPositions); + if (symbolPeriodPositionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < symbolPeriodPositionsCount; i++) + { + // + XPosition iPosition = symbolPeriodPositions[i]; + + // + ENUM_X_SIGNAL_PROVIDERS iProvider = ExtractProviderFromComment(iPosition.comment); + if (iProvider == NONE || iProvider != provider) + { + continue; + } + + // + if (type == NULL) + { + // + Add( + iPosition, + result); + } + else if (type == iPosition.type) + { + // + Add( + iPosition, + result); + } + } +} + +// +// Determines a Position is Support Position or not ... +bool IsSupportPosition(XPosition &position) +{ + // + bool result = false; + + // + if (StringLen(position.comment) <= 0) + { + return result; + } + + // + int supTokenPos = StringFind( + position.comment, + mSupportToken + "("); + result = supTokenPos >= 0; + + // + return result; +} + +// +// END Functions ... +// + +// +// Draw Signal ... +void ReDrawSignal(const ulong ticket, XSignal &signal) +{ + // + // return; + + // + DrawSupportResistance(1, signal.supportAndResistance); + + // + bool isLong = IsLong(signal.type); + + // + string prefix = (string)ticket + "_" + ToString(signal.period); + + // + // Retrieve Time ... + datetime time = iTime( + signal.symbol, + signal.period, + 0); + + // + // Retrieve 3 Time ... + datetime time3 = iTime( + signal.symbol, + signal.period, + 3); + + // + color posColor = isLong + ? clrSpringGreen + : clrTomato; + color tpColor = clrSpringGreen; + color slColor = clrTomato; + color entryColor = clrGold; + + // + ENUM_LINE_STYLE vLineStyle = STYLE_DOT; + ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE slLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID; + + // + int lineWidth = 2; + + // + long chartID = ChartID(); + + // + // Vertical Line ... + string vlName = prefix + "_" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + posColor, + vLineStyle, + lineWidth); + + // + // TP ... + double profit = (MathAbs(signal.tp - signal.entry)) * signal.volume; + string tpName = prefix + "_TP_" + (string)profit; + + // + DrawTrendLine( + chartID, + tpName, + 0, + time3, + signal.tp, + time, + signal.tp, + tpColor, + tpLineStyle, + lineWidth); + + // + // SL ... + double lost = (MathAbs(signal.sl - signal.entry)) * signal.volume; + string slName = prefix + "_SL_" + (string)lost; + + // + DrawTrendLine( + chartID, + slName, + 0, + time3, + signal.sl, + time, + signal.sl, + slColor, + slLineStyle, + lineWidth); + + // + // ENTRY ... + string entryName = prefix + "_ENTRY_" + (string)lost; + + // + DrawTrendLine( + chartID, + entryName, + 0, + time3, + signal.entry, + time, + signal.entry, + entryColor, + entryLineStyle, + lineWidth); +} + +// +// Alert Force Close Event on Chart ... +void DrawForceCloseEvent() +{ + // + datetime barTime = GetCandleTime( + _Symbol, + _Period, + 1); + + // + long chartID = ChartID(); + string vlName = "XTRND Force Close: " + (string)barTime; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + barTime, + clrDarkViolet, + STYLE_SOLID, + 2); +} + +// +void DrawSupportResistance( + int bar_index, + XOHCLSupRes &data, + string prefix = "", + color supportColor = clrLime, + color resistanceColor = clrRed) +{ + // + // return; + + // + datetime barTime = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime prevBarTime = GetCandleTime( + _Symbol, + _Period, + bar_index + 5); + + // + long chID = ChartID(); + int subWindiw = 0; + int lineWidth = 2; + + // + string mPrefix = prefix + "_" + (string)barTime + "_"; + + // + // SUPPORTS ... + + // + int supCount = ArraySize(data.sup); + if (supCount > 0) + { + // + for (int i = 0; i < supCount; i++) + { + // + double iSup = data.sup[i]; + + // + string supTlName = mPrefix + "SUP[" + (string)(i + 1) + "]_(" + (string)iSup + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + supTlName, + subWindiw, + prevBarTime, + iSup, + barTime, + iSup, + supportColor, + STYLE_DOT, + lineWidth, + true); + } + } + + // + // RESISTANCES ... + + // + int resCount = ArraySize(data.res); + if (resCount > 0) + { + // + for (int i = 0; i < resCount; i++) + { + // + double iRes = data.res[i]; + + // + string resTlName = mPrefix + "RES[" + (string)(i + 1) + "]_(" + (string)iRes + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + resTlName, + subWindiw, + prevBarTime, + iRes, + barTime, + iRes, + resistanceColor, + STYLE_DOT, + 2, + true); + } + } +} diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Experts/x-saherelm.xea.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Experts/x-saherelm.xea.mq5 new file mode 100644 index 0000000..c13c604 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Experts/x-saherelm.xea.mq5 @@ -0,0 +1,1553 @@ +/////////////////////////////////////////////////////// +// +// 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 EA" +#property strict + +// +// START Definitions ... +// + +// +string mProviderPrefix = "PRV"; +string mSupportPrefix = "SP"; + +// +enum ENUM_X_SIGNAL_PROVIDERS +{ + NONE = 0, + XICHI = 1, +}; + +// +// END Definitions ... +// + +// +// START Inputs ... +// + +// +// EA ... +input group "Common"; +input bool xEAEnable = true; // Enable EA +input int xEASlippage = 10; // Slippgae +input ulong xEAMagicNumber = 1604056; // Magic Number + +// +// Determine Symbols and TimeFrames ... +input group "Symbols and Time Frames"; +// +// (EURUSDb|M5|0.0005) +// (EURUSDb|M5|0.0005)_(USDCHFb|M5|0.0005)_(USDJPYb|M5|0.0005)_(GBPUSDb|M5|0.0005) +// (EURUSDb|M5,M15,M30|0.0005)_(USDCHFb|M5,M15|0.0005)_(USDJPYb|M5,M15|0.0005)_(GBPUSDb|M5,M15,M30|0.0005)_(AUDUSDb|M5,M15|0.0005)_(USDCADb|M5,M15|0.0005)_(NZDUSDb|M5,M15|0.0005)_(XAUUSDb|M5|0.0005) +input string xEAProvidersDescription = "(EURUSDb|M5|0.0005)"; // Specify Symbols and Time Frames + +// +// Signals ... +input group "Signals"; +input bool xEAEnableLongs = true; // Enable Long Trades +input bool xEAEnableShorts = true; // Enable Short Trades + +// +// Risk Management ... +input group "Risk Management"; +input int xEAMaxOpenPositions = 15; // Max Allowed Open Positions +input bool xEABalancePositions = true; // Balance Positions +input double xEAMaxAllowedDrawDownFactor = 0.15; // Max Allowed Drawdown Factor +input int xEATrailStopsInPoint = 0; // Trail Stops Moving Rate in Points +input int xEAMinProfitForHedging = 5; // Hedge Positions on Minimum Profit +input double xEAMaxDrawdownForClosePosition = 0; // Max Drawdown For Close Positions +input double xEAMaxDrawdownForSupportPosition = 0; // Max Drawdown For Open Support Positions + +// +// Alerts ... +input group "Alerts"; +input bool xEAEnableAlerts = true; // Enable Events Alert +input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day +input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month + +// +// 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" + +// +// Account Class ... +#include "../Classes/x-saherelm.xaccount.class.mq5" + +// +// Trade Class ... +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +// Signal Provider Class Library ... +#include "../Providers/x.saherelm.x121.provider.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +bool isXEANewHour; +bool isXEANewDay; +bool isXEANewWeek; +bool isXEANewMonth; + +// +// Determines EA is Running On Test Mode or not ... +bool xEAIsTestMode = false; + +// +// Check prevent Double Signalling on Same Candle ... +bool xEAWaitUntilNextCandle = false; + +// +XSCTrade *xEATrade; +XSCAccount *xEAAccount; +XLastSignal xEALastSignals[]; +X121SignalProvider xEAProviders[]; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = "XEA"; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Reset Timings ... + ResetTiming(); + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize XEA Providers ... + if (!InitializeProviders()) + { + return INIT_FAILED; + } + + // + // Initialize Trade Class ... + xEATrade = new XSCTrade( + xEASlippage, + xEAMagicNumber); + + // + // Initialize Account Class ... + xEAAccount = new XSCAccount(); + + // + // 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 ... + delete xEATrade; + delete xEAAccount; + + // + // De Initialize XEA Providers ... +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Handle Monthly Alert ... + bool isFirstMonth = xMonth == -1; + isXEANewMonth = IsNewMonth(); + bool canMonthlyAlert = + isXEANewMonth && + xEAEnableAlerts && + xEAEnableMonthlyAlerts; + if (canMonthlyAlert) + { + // + string message = "New Month ..."; + + // + SendAlert(message); + } + + // + // Handle Weekly Alert ... + bool isFirstWeek = xDayOfWeek == -1; + isXEANewWeek = IsNewWeek(); + bool canWeeklyAlert = + isXEANewWeek && + xEAEnableAlerts && + xEAEnableWeeklyAlerts; + if (canWeeklyAlert) + { + // + string message = "New Week ..."; + + // + SendAlert(message); + } + + // + // Handle Daily Alert ... + bool isFirstDay = xDay == -1; + isXEANewDay = IsNewDay(); + bool canDailyAlert = + isXEANewDay && + xEAEnableAlerts && + xEAEnableDailyAlerts; + if (canDailyAlert) + { + // + string message = "New Day ..."; + + // + SendAlert(message); + } + + // + // Handle Hourly Alert ... + bool isFirstHour = xHour == -1; + isXEANewHour = IsNewHour(); + bool canHourlyAlert = + isXEANewHour && + xEAEnableAlerts && + xEAEnableHourlyAlerts; + if (canHourlyAlert) + { + // + string message = "New Hour ..."; + + // + SendAlert(message); + } + + // + Guard(); + + // + // Prevent Going Forward if user Disable it ... + if (xEAEnable) + { + // + // Call All Providers OnTick Method ... + CallProvidersOnTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + // + // TODO: Complete this ... +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + // TODO: Fix this ... + bool result = true; + + // + // Validate Args ... + result = + // + xEASlippage > 0 && + xEAMagicNumber > 0 && + xEAMaxOpenPositions > 0 && + xEAMaxAllowedDrawDownFactor > 0 && + xEAMaxAllowedDrawDownFactor <= 0.4 && + StringLen(xEAProvidersDescription) > 0 + // + ; + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// Extract Signal Provider Struct from User Input ... +bool InitializeProviders() +{ + // + bool result = false; + + // + string workingString = xEAProvidersDescription; + StringTrimLeft(workingString); + StringTrimRight(workingString); + if (StringLen(workingString) == 0) + { + return result; + } + + // + string descriptors[]; + int numOfDescriptors = StringSplit( + workingString, + StringGetCharacter("_", 0), + descriptors); + if (numOfDescriptors <= 0) + { + return result; + } + + // + // Loop Through Descriptors ... + for (int iDX = 0; iDX < numOfDescriptors; iDX++) + { + // + string descriptor = descriptors[iDX]; + + // + // Clear Start and End Pranteses ... + StringReplace( + descriptor, + "(", + ""); + StringReplace( + descriptor, + ")", + ""); + + // + string descriptorData[]; + int numOfData = StringSplit( + descriptor, + StringGetCharacter("|", 0), + descriptorData); + if (numOfData < 3) + { + continue; + } + + // + string symbols[]; + int numOfSymbols = StringSplit( + descriptorData[0], + StringGetCharacter(",", 0), + symbols); + if (numOfSymbols <= 0) + { + continue; + } + + // + string timeFrames[]; + int numOfTimeFrames = StringSplit( + descriptorData[1], + StringGetCharacter(",", 0), + timeFrames); + if (numOfTimeFrames <= 0) + { + continue; + } + + // + string riskAmounts[]; + int numOfRiskAmounts = StringSplit( + descriptorData[2], + StringGetCharacter(",", 0), + riskAmounts); + if (numOfRiskAmounts <= 0) + { + continue; + } + + // + for (int cpIdx = 0; cpIdx < numOfSymbols; cpIdx++) + { + // + string symbol = symbols[cpIdx]; + + // + for (int tfIdx = 0; tfIdx < numOfTimeFrames; tfIdx++) + { + // + string timeFrame = timeFrames[tfIdx]; + ENUM_TIMEFRAMES period = ToPeriod(timeFrame); + + // + double riskAmount = (double)(numOfRiskAmounts == numOfTimeFrames + ? riskAmounts[tfIdx] + : riskAmounts[0]); + + // + string magicNumberString = "169" + (string)iDX + (string)cpIdx + (string)tfIdx + (string)PeriodSeconds(period) + "4056"; + ulong magicNumber = (ulong)magicNumberString; + + // + X121SignalProvider providerDescriptor; + + // + providerDescriptor.symbol = symbol; + providerDescriptor.period = period; + providerDescriptor.riskAmount = riskAmount; + providerDescriptor.magicNumber = magicNumber; + + // + // Initial Provider Class Instance ... + XSCX121Provider *x121Provider = new XSCX121Provider( + symbol, + period); + + // + // Attach On Signal Event Listener ... + x121Provider.AddOnSignalEventHandler(OnSignalRecieved); + + // + providerDescriptor.provider = x121Provider; + + // + Add( + providerDescriptor, + xEAProviders); + } + } + } + + // + result = true; + + // + return result; +} + +// +void CallProvidersOnTick() +{ + // + int providersCount = ArraySize(xEAProviders); + if (providersCount <= 0) + { + return; + } + + // + // Loop Through Providers ... + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider providerDescriptor = xEAProviders[i]; + + // + providerDescriptor.provider.OnTick(); + } +} + +// +void OnSignalRecieved( + XSignalInfo &info) +{ + // + // Ignore Disabled Signals ... + if ((info.type == POSITION_TYPE_BUY && !xEAEnableLongs) || + (info.type == POSITION_TYPE_SELL && !xEAEnableShorts)) + { + return; + } + + // + // Find Provider based On Signal Info ... + int providersCount = ArraySize(xEAProviders); + if (providersCount <= 0) + { + return; + } + + // + if (StringLen(info.symbol) == 0 || info.period == NULL) + { + return; + } + + // + bool isFoundDescriptor = false; + X121SignalProvider providerDescriptor; + + // + for (int i = 0; i < providersCount; i++) + { + // + X121SignalProvider provDesc = xEAProviders[i]; + + // + if (provDesc.symbol == info.symbol && + provDesc.period == info.period) + { + // + isFoundDescriptor = true; + providerDescriptor = provDesc; + + // + break; + } + } + + // + // Prevent Moving Forward if there is no Descriptor Found ... + if (!isFoundDescriptor) + { + return; + } + + // + // Count Open Positions ... + int openPositionsCount = xEATrade.OpenPositionsCount(); + + // + if (xEABalancePositions) + { + // + // Count Same Signals for Balancing ... + int smaeTypeOpenPositionsCount = xEATrade.OpenPositionsCount("", info.type); + + // + if (openPositionsCount > (int)xEAMaxOpenPositions / 3) + { + // + if (smaeTypeOpenPositionsCount > (int)openPositionsCount / 2) + { + return; + } + } + } + + // + string mTagId = GenerateTag(info); + + // + // Check Last Signal ... + datetime barTime = iTime( + info.symbol, + info.period, + 0); + + // + XLastSignal lastSignal = {}; + int foundedLastSignalId = -1; + bool isFoundLastSignal = false; + int lastSignalsCount = ArraySize(xEALastSignals); + + // + for (int i = 0; i < lastSignalsCount; i++) + { + // + XLastSignal mLS = xEALastSignals[i]; + if (mLS.provider == mTagId) + { + // + lastSignal = mLS; + foundedLastSignalId = i; + isFoundLastSignal = true; + + // + break; + } + } + + // + if (isFoundLastSignal) + { + // + bool isSameDate = xEALastSignals[foundedLastSignalId].at == barTime; + if (isSameDate) + { + return; + } + else + { + xEALastSignals[foundedLastSignalId].at = barTime; + } + } + else + { + // + lastSignal.at = barTime; + lastSignal.provider = mTagId; + + // + ArrayResize( + xEALastSignals, + ArraySize(xEALastSignals) + 1); + + // + xEALastSignals[ArraySize(xEALastSignals) - 1] = lastSignal; + } + + // + // Retrieve Tradable Balance ... + double availableBalance = xEAAccount.GetEquity(); + + // + // Here we Have to Check Some Conditions for Open + // Positions, before Do Calculations, for improve Performance ... + + // + // Verify Open Positions ... + if (openPositionsCount >= xEAMaxOpenPositions) + { + // + LogMessage("Max Allowed Positions Reached ..."); + return; + } + + // + // Verify Available Balance ... + double balance = xEAAccount.GetBalance(); + double minBalanceForTrades = balance * xEAMaxAllowedDrawDownFactor; + if (availableBalance <= minBalanceForTrades) + { + // + LogMessage("Max Drawdown Reached ..."); + return; + } + + // + // Here i Must Calculate TP and SL based on R2R and riskable Factor ... + bool isLong = IsLong(info.type); + + // + // Correct Period ... + if (info.period == NULL) + { + info.period = providerDescriptor.period; + } + + // + // Check Order Mode ... + if (info.mode == NULL) + { + // + // Set Market Execution as Default ... + info.mode = X_ORDER_MODE_MARKET; + } + + // + // Calculate Entry Price ... + if (info.entry <= 0) + { + // + info.entry = GetEntry( + info.symbol, + info.type); + } + + // + // R2R ... + if (info.r2r <= 0) + { + // + // Set Default Risk to Reward Ratio to 1 ... + info.r2r = 1; + } + + // + // Set Risk Amount Factor ... + if (info.riskAmount <= 0) + { + // + info.riskAmount = providerDescriptor.riskAmount; + } + + // + // Calculate TP and SL ... + double mPoint = GetPoints(info.symbol); + + // + // Normalize SL Price ... + if (info.sl > 0) + { + info.sl = NormalizePrice(info.sl, info.symbol); + } + + // + // Retrieve Symbol Point Value ... + double pointValue = xEAAccount.GetPointValue(info.symbol); + + // + // Calculate Risk ... + double riskPrice = MathAbs(info.entry - info.sl); + riskPrice = NormalizePrice(riskPrice, info.symbol); + + // + double riskPoints = PriceToPoint(riskPrice); + riskPoints = NormalizeDouble(riskPoints, 0); + + // + // Calculating Reward based On Ratio ... + double rewardPoints = riskPoints * info.r2r; + double rewardPrice = PointToPrice(rewardPoints); + rewardPrice = NormalizePrice(rewardPrice, info.symbol); + + // + // TODO: Remove This ... + // rewardPrice = PipsToPrice( + // info.symbol, + // 15 + // ); + + // + // Calculate TP Price ... + double tpValue = isLong + ? info.entry + rewardPrice + : info.entry - rewardPrice; + + // + // Calculate SL Price ... + double slValue = isLong + ? info.entry - riskPrice + : info.entry + riskPrice; + + // + // Balance Amount which we risks on each Provider's Trade ... + double amount = availableBalance * info.riskAmount; + + // + // Calculating Trade Volume based on risk Points and Amount ... + double volume = xEAAccount.CalculateVolume( + info.symbol, + amount, + riskPoints); + volume = NormalizeVolume(volume, info.symbol); + + // + // Set Caculated TP, SL and Volume ... + info.tp = tpValue; + info.sl = slValue; + info.volume = 0.01; // volume; + + // + string comment = ""; + int signalProvidersCount = ArraySize(info.providers); + if (signalProvidersCount > 0) + { + // + string prvs = ""; + for (int i = 0; i < signalProvidersCount; i++) + { + // + string p = info.providers[i]; + + // + if (StringLen(prvs) > 0) + { + prvs += ","; + } + + // + prvs += p; + } + + // + comment = "PRV(" + prvs + ")"; + } + + // + bool isPositionOpen = false; + + // + // Open Signal Position ... + if (isLong) + { + // + isPositionOpen = xEATrade.Buy( + info.symbol, + info.period, + info.volume, + info.entry, + info.sl, + info.tp, + comment); + } + else + { + // + isPositionOpen = xEATrade.Sell( + info.symbol, + info.period, + info.volume, + info.entry, + info.sl, + info.tp, + comment); + } + + // + if (isPositionOpen) + { + // + // Retrieve Position Ticket ... + ulong ticket = xEATrade.GetLastOpenPositionTicket(); + if (ticket == 0) + { + return; + } + + // + // Draw Signal ... + ReDrawSignal(ticket, info); + + // + // Alert Position ... + LogMessage("Position: " + (string)ticket + " was Open ..."); + } +} + +// +// Do Guard Actions ... +void Guard() +{ + // + // Close Max In Drawdown Position ... + HandleMaxDrawdown(); + + // + // Trailing Stops ... + HandleTrailing(); + + // + // Close All Open Positions in Pyramid ... + HandleHedging(); + + // + // Handle Support Signal Opening ... + HandleSupport(); +} + +// +// it is a way to Protect Open Signal ... +void HandleTrailing() +{ + // + if (xEATrailStopsInPoint <= 0) + { + return; + } + + // + XPosition inProfitPositions[]; + xEATrade.GetInProfitPositions(inProfitPositions); + int inProfitPositionsCount = ArraySize(inProfitPositions); + if (inProfitPositionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < inProfitPositionsCount; i++) + { + // + XPosition iPosition = inProfitPositions[i]; + + // + bool isLong = IsLong(iPosition.type); + + // + // Retrieve Exit Price ... + double exitPrice = GetExit( + iPosition.symbol, + iPosition.type); + + // + double entryPrice = GetEntry( + iPosition.symbol, + iPosition.type); + + // + // Calculate Price Distance ... + double distancePrice = iPosition.sl == 0 + ? MathAbs(iPosition.entry - exitPrice) + : MathAbs(iPosition.sl - exitPrice); + double distancePoint = PriceToPoint( + iPosition.symbol, + distancePrice); + + // + if (distancePoint >= xEATrailStopsInPoint) + { + // + double trailStepPrice = PointToPrice( + iPosition.symbol, + xEATrailStopsInPoint); + + // + double tp = + isLong + ? iPosition.tp + trailStepPrice + : iPosition.tp - trailStepPrice; + double sl = + iPosition.sl == 0 + ? isLong + ? entryPrice - trailStepPrice + : entryPrice + trailStepPrice + : isLong + ? iPosition.sl + trailStepPrice + : iPosition.sl - trailStepPrice; + + // + bool isModified = xEATrade.Modify( + iPosition.ticket, + sl, + tp); + if (isModified) + { + // + // Convert Position to Signal ... + + // + XSignalInfo signal = ToSignalInfo(iPosition); + // ReDrawSignal(iPosition.ticket, signal); + + // + // Alert Trailing ... + LogMessage("Position: " + (string)iPosition.ticket + ", was Trailed ..."); + } + } + } +} + +// +// Hedging Close Positions ... +void HandleHedging() +{ + // + if (xEAMinProfitForHedging <= 0) + { + return; + } + + // + int positionsCount = xEATrade.OpenPositionsCount(); + if (positionsCount <= 1) + { + return; + } + + // + double profit = xEATrade.GetPositionsProfit(); + + // + if (profit < xEAMinProfitForHedging) + { + return; + } + + // + string comment = "Hedging Pyramid ..."; + + // + xEATrade.CloseAllPositions(comment); +} + +// +// Support Positions ... +void HandleSupport() +{ + // + if (xEAMaxDrawdownForSupportPosition <= 0) + { + return; + } + + // + int positionsCount = xEATrade.OpenPositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition inDrawdownPositions[]; + xEATrade.GetInDrawdownPositions(inDrawdownPositions); + int inDrawdownPositionsCount = ArraySize(inDrawdownPositions); + if (inDrawdownPositionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < inDrawdownPositionsCount; i++) + { + // + XPosition iPosition = inDrawdownPositions[i]; + + // + if (MathAbs(iPosition.profit) >= xEAMaxDrawdownForSupportPosition) + { + // + // Here we have to Open Support Indirectional Position ... + OpenSupportPosition(iPosition); + } + } +} + +// +// Close Max In Drawdown Position ... +void HandleMaxDrawdown() +{ + // + if (xEAMaxDrawdownForClosePosition <= 0) + { + return; + } + + // + int positionsCount = xEATrade.OpenPositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition inDrawdownPositions[]; + xEATrade.GetInDrawdownPositions(inDrawdownPositions); + int inDrawdownPositionsCount = ArraySize(inDrawdownPositions); + if (inDrawdownPositionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < inDrawdownPositionsCount; i++) + { + // + XPosition iPosition = inDrawdownPositions[i]; + + // + if (MathAbs(iPosition.profit) >= xEAMaxDrawdownForClosePosition) + { + // + // Here we have to Force Close Position ... + string comment = "Close On Guard ..."; + bool isClosed = xEATrade.Close( + iPosition.ticket, + comment); + if (isClosed) + { + LogMessage("Position: " + (string)iPosition.ticket + " was Closed On Guard ..."); + } + } + } +} + +// +// Draw Signal ... +void ReDrawSignal(const ulong ticket, XSignalInfo &signal) +{ + // + return; + + // + bool isLong = IsLong(signal.type); + + // + string prefix = (string)ticket + "_" + ToString(signal.period); + + // + RemoveDraws(prefix); + + // + // Retrieve Time ... + datetime time = iTime( + signal.symbol, + signal.period, + 0); + + // + // Retrieve 3 Time ... + datetime time3 = iTime( + signal.symbol, + signal.period, + 3); + + // + color posColor = isLong + ? clrAqua + : clrMagenta; + color tpColor = clrAqua; + color slColor = clrMagenta; + color entryColor = clrGold; + + // + ENUM_LINE_STYLE vLineStyle = STYLE_DOT; + ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE slLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID; + + // + long chartID = ChartID(); + + // + // Vertical Line ... + string vlName = prefix + "_" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + posColor, + vLineStyle); + + // + // TP ... + double profit = (MathAbs(signal.tp - signal.entry)) * signal.volume; + string tpName = prefix + "_TP_" + (string)profit; + + // + DrawTrendLine( + chartID, + tpName, + 0, + time3, + signal.tp, + time, + signal.tp, + tpColor, + tpLineStyle); + + // + // SL ... + double lost = (MathAbs(signal.sl - signal.entry)) * signal.volume; + string slName = prefix + "_SL_" + (string)lost; + + // + DrawTrendLine( + chartID, + slName, + 0, + time3, + signal.sl, + time, + signal.sl, + slColor, + slLineStyle); + + // + // ENTRY ... + string entryName = prefix + "_ENTRY_" + (string)lost; + + // + DrawTrendLine( + chartID, + entryName, + 0, + time3, + signal.entry, + time, + signal.entry, + entryColor, + entryLineStyle); +} + +// +// Convert Position to Signal ... +XSignalInfo ToSignalInfo( + XPosition &position) +{ + // + XSignalInfo result; + + // + result.tp = position.tp; + result.sl = position.sl; + result.type = position.type; + result.entry = position.entry; + result.symbol = position.symbol; + result.period = position.period; + result.volume = position.volume; + + // + return result; +} + +// +string ToString(ENUM_X_SIGNAL_PROVIDERS provider) +{ + // + return EnumToString(provider); +} + +// +ENUM_X_SIGNAL_PROVIDERS ToProvider(string provider) +{ + // + ENUM_X_SIGNAL_PROVIDERS result; + + // + if (ToString(XICHI) == provider) + { + result = XICHI; + } + else + { + result = NONE; + } + + // + return result; +} + +// +// Extract Position Provider ... +ENUM_X_SIGNAL_PROVIDERS ExtractProviderFromComment(string comment) +{ + // + ENUM_X_SIGNAL_PROVIDERS result = NONE; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string providerStr = ExtractString( + comment, + mProviderPrefix + "(", + ")"); + if (StringLen(providerStr) <= 0) + { + return result; + } + + // + result = ToProvider(providerStr); + + // + return result; +} + +// +// Retrieve Specific Type of Providers Positions ... +void GetSpecificProviderPositions( + XPosition &result[], // Holds Result + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + ENUM_X_SIGNAL_PROVIDERS provider // Position Provider +) +{ + // + Clear(result); + + // + if (StringLen(symbol) == 0 || provider == NONE) + { + return; + } + + // + int positionsCount = xEATrade.OpenPositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition symbolPeriodPositions[]; + xEATrade.GetPositions( + symbolPeriodPositions, + symbol, + period); + int symbolPeriodPositionsCount = ArraySize(symbolPeriodPositions); + if (symbolPeriodPositionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < symbolPeriodPositionsCount; i++) + { + // + XPosition iPosition = symbolPeriodPositions[i]; + + // + ENUM_X_SIGNAL_PROVIDERS iProvider = ExtractProviderFromComment(iPosition.comment); + if (iProvider == NONE || iProvider != provider) + { + continue; + } + + // + Add( + iPosition, + result); + } +} + +// +// Find Reversal Position Type ... +ENUM_POSITION_TYPE GetSupportPositionType(ENUM_POSITION_TYPE type) +{ + // + ENUM_POSITION_TYPE result = POSITION_TYPE_BUY; + + // + if (type == POSITION_TYPE_BUY) + { + result = POSITION_TYPE_SELL; + } + else + { + result = POSITION_TYPE_BUY; + } + + // + return result; +} + +// +// Check a Position Has Supportable or not ... +bool IsSupportablePosition(XPosition &position) +{ + // + bool result = false; + + // + if (StringLen(position.comment) <= 0) + { + return result; + } + + // + int supStrPos = StringFind( + position.comment, + mSupportPrefix + "("); + + // + result = supStrPos < 0; + + // + return result; +} + +// +// Check a Position has Support Position or not ... +bool HasSupportPosition(XPosition &position) +{ + // + bool result = false; + + // + int positionsCount = xEATrade.OpenPositionsCount(); + + // + if (positionsCount <= 0 || + position.ticket == 0 || + StringLen(position.comment) <= 0) + { + return result; + } + + // + string supCommentStr = mSupportPrefix + "(" + (string)position.ticket + ")"; + + // + XPosition positions[]; + xEATrade.GetPositions(positions); + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + int supCommentPos = StringFind( + iPosition.comment, + supCommentStr); + + // + result = supCommentPos >= 0; + if (result) + { + break; + } + } + + // + return result; +} + +// +// Open a Support Position based on Exists ... +void OpenSupportPosition(XPosition &position) +{ + // + bool isSupportable = IsSupportablePosition(position); + if (!isSupportable) + { + return; + } + + // + bool hasSupport = HasSupportPosition(position); + if (hasSupport) + { + return; + } + + // + ENUM_POSITION_TYPE type = GetSupportPositionType(position.type); + double entry = GetEntry( + position.symbol, + type); + + // + bool isLong = IsLong(type); + + // + double tpPrice = PipsToPrice( + position.symbol, + 10); + double slPrice = PipsToPrice( + position.symbol, + 5); + + // + double tp = 0; + // isLong + // ? entry + tpPrice + // : entry - tpPrice; + + // + double sl = 0; + // isLong + // ? entry - slPrice + // : entry + slPrice; + + // + string comment = mSupportPrefix + "(" + (string)position.ticket + ")"; + + // + bool isPositionOpen = false; + // + // Open Signal Position ... + if (isLong) + { + // + isPositionOpen = xEATrade.Buy( + position.symbol, + position.period, + position.volume, + entry, + sl, + tp, + comment); + } + else + { + // + isPositionOpen = xEATrade.Sell( + position.symbol, + position.period, + position.volume, + entry, + sl, + tp, + comment); + } + + // + if (isPositionOpen) + { + // + LogMessage("Open Support Psition for: " + position.comment); + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xatrsl.test.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xatrsl.test.helper.mq5 new file mode 100644 index 0000000..d5c8985 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xatrsl.test.helper.mq5 @@ -0,0 +1,235 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XATRSLHLP 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 + +// +// START Includes ... +// + +// +// Includes ... +#include "../../Libraries/x-saherelm.alert.lib.mq5" +#include "../../Libraries/x-saherelm.models.lib.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes ... +// + +// +// START Constants/Enums ... +// + +// +// XPeaksAndVales Exported Buffers ... +enum ENUM_X_XATRSL_BUFFERS +{ + // + X_ATRSL_UP_LINE = 0, + X_ATRSL_DOWN_LINE = 1, + X_ATRSL_SAR_LINE = 2, + X_ATRSL_RMA_LINE = 3, + X_ATRSL_WMA_LINE = 4, + X_ATRSL_MA1_LINE = 5, + X_ATRSL_SMA_LINE = 6, + X_ATRSL_EMA_LINE = 7, + X_ATRSL_ATR_LINE = 8, +}; + +// +// END Constants/Enums ... +// + +// +// START Definitions ... +// + +// +double atrslUpBuffer[]; +double atrslDownBuffer[]; +double atrslSarBuffer[]; + +// +int atrslHandler = INVALID_HANDLE; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +bool XATRSLHLPOnInit() +{ + // + bool result = false; + + // + ArraySetAsSeries(atrslUpBuffer, true); + ArraySetAsSeries(atrslSarBuffer, true); + ArraySetAsSeries(atrslDownBuffer, true); + + // + // Initial Handler ... + atrslHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xatrsl", + // + // Inputs ... + // + // MARKET ... + "", + 14, + 0.02, + 0.2, + PRICE_HIGH, + PRICE_LOW, + // + // PRESENTATION ... + "", + false, + false, + true + // + ); + result = atrslHandler != INVALID_HANDLE; + + // + return result; +} + +// +void XATRSLHLPOnDeInit() +{ + // + // Release Indicators ... + IndicatorRelease(atrslHandler); +} + +// +void XATRSLHLPReadBuffers() +{ + // + // UP ... + CopyBuffer( + atrslHandler, + X_ATRSL_UP_LINE, + 0, + 10, + atrslUpBuffer); + + // + // DOWN ... + CopyBuffer( + atrslHandler, + X_ATRSL_DOWN_LINE, + 0, + 10, + atrslDownBuffer); + + // + // SAR ... + CopyBuffer( + atrslHandler, + X_ATRSL_SAR_LINE, + 0, + 10, + atrslSarBuffer); +} + +// +// END Handler Functions ... +// + +// +// START Helper Functions ... +// + +// +// Calculate Change Rate For Specific Bar ... +double XATRSLHLPGetChangeRate( + int bar_index // Bar Index ... +) +{ + // + double result = 0; + + // + if (!XATRSLHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = MathAbs(atrslUpBuffer[bar_index] - atrslDownBuffer[bar_index]); + + // + return result; +} + +// +// Calculate Change Rate For Specific Lenght ... +double XATRSLHLPGetRangeChangeRate( + int bar_index, // Bar Index ... + int length = 5 // Loopback Length ... +) +{ + // + double result = 0; + + // + int size = bar_index + length; + if (!XATRSLHLPIsValidArraySize(size)) + { + return result; + } + + // + double summary = 0; + for (int i = bar_index; i < size; i++) + { + summary += MathAbs(atrslUpBuffer[i] - atrslDownBuffer[i]); + } + + // + result = summary / size; + + // + return result; +} + +// +// Check Array Size ... +bool XATRSLHLPIsValidArraySize(int bar_index) +{ + // + bool result = false; + + // + int rCount = ArraySize(atrslUpBuffer); + result = rCount > bar_index + 1; + + // + return result; +} + +// +// END Helper Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xichi.test.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xichi.test.helper.mq5 new file mode 100644 index 0000000..e00f0cc --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xichi.test.helper.mq5 @@ -0,0 +1,938 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XICHIHLP 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 + +// +// START Includes ... +// + +// +// Includes ... +#include "../../Libraries/x-saherelm.alert.lib.mq5" +#include "../../Libraries/x-saherelm.models.lib.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes ... +// + +// +// START Constants/Enums ... +// + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// Ichimoku Indicator Exported Buffers ... +enum ENUM_X_ICHIMOKU_BUFFERS +{ + // + X_TENKANSEN_LINE = 0, + X_KIJUNSEN_LINE = 1, + X_CHIKOUSPAN_LINE = 4, + X_SENKOUSPAN_A_LINE = 5, + X_SENKOUSPAN_B_LINE = 6, +}; + +// +// Model Ichimoku Data ... +struct XIchiInfo +{ + // + int bar; + + // + double tenkanSen; + double kijunSen; + + // + double chikouSpan; + + // + double senkouSpanA; + double senkouSpanB; + + // + double senkouSpanAFuture; + double senkouSpanBFuture; +}; + +// +double ichiPivots[]; + +// +// END Constants/Enums ... +// + +// +// START Definitions ... +// + +// +double ichiTenkanSenBuffer[]; +double ichiKijunSenBuffer[]; +double ichiChikouSpanBuffer[]; +double ichiSenkouSpanABuffer[]; +double ichiSenkouSpanBBuffer[]; + +// +int ichiHandler = INVALID_HANDLE; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +bool XICHIHLPOnInit() +{ + // + bool result = false; + + // + ArraySetAsSeries(ichiTenkanSenBuffer, true); + ArraySetAsSeries(ichiKijunSenBuffer, true); + ArraySetAsSeries(ichiChikouSpanBuffer, true); + ArraySetAsSeries(ichiSenkouSpanABuffer, true); + ArraySetAsSeries(ichiSenkouSpanBBuffer, true); + + // + ArraySetAsSeries(ichiPivots, true); + + // + // Initial Handler ... + ichiHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xich", + // + // Inputs ... + // + // TENKANSEN ... + "", + 9, + X_XICH_HH_LL_MODE, + // + // KIJUNSEN ... + "", + 26, + X_XICH_HH_LL_MODE, + // + // SENKOUSPANB ... + "", + 52, + X_XICH_HH_LL_MODE, + // + // CHIKOUSPAN ... + "", + PRICE_CLOSE, + // + // PRESENTATION ... + "", + true, + true, + false, + false, + false, + false, + false, + true, + true // Shift Kumo ... + // + ); + result = ichiHandler != INVALID_HANDLE; + + // + return result; +} + +// +void XICHIHLPOnDeInit() +{ + // + // Release Indicators ... + IndicatorRelease(ichiHandler); +} + +// +void XICHIHLPReadBuffers() +{ + // + // TENKANSEN ... + CopyBuffer( + ichiHandler, + X_TENKANSEN_LINE, + 0, + 26, + ichiTenkanSenBuffer); + + // + // KIJUNSEN ... + CopyBuffer( + ichiHandler, + X_KIJUNSEN_LINE, + 0, + 26, + ichiKijunSenBuffer); + + // + // CHIKOUSPAN ... + CopyBuffer( + ichiHandler, + X_CHIKOUSPAN_LINE, + 27, + 52, + ichiChikouSpanBuffer); + + // + // SENKOUSPANA ... + CopyBuffer( + ichiHandler, + X_SENKOUSPAN_A_LINE, + -26, + 52, + ichiSenkouSpanABuffer); + + // + // SENKOUSPANB ... + CopyBuffer( + ichiHandler, + X_SENKOUSPAN_B_LINE, + -26, + 52, + ichiSenkouSpanBBuffer); + + // + XICHIHLPFindPivotPoints(); +} + +// +// END Handler Functions ... +// + +// +// START Helper Functions ... +// + +// +// Retrieve Ichimoku Data at Specific Bar Index ... +XIchiInfo XICHIHLPGetInfo( + int bar_index // Bar Index ... +) +{ + // + XIchiInfo result = {}; + + // + result.bar = bar_index; + result.tenkanSen = ichiTenkanSenBuffer[bar_index]; + result.kijunSen = ichiKijunSenBuffer[bar_index]; + result.chikouSpan = ichiChikouSpanBuffer[bar_index + 26]; + result.senkouSpanA = ichiSenkouSpanABuffer[bar_index + 26]; + result.senkouSpanB = ichiSenkouSpanBBuffer[bar_index + 26]; + result.senkouSpanAFuture = ichiSenkouSpanABuffer[bar_index]; + result.senkouSpanBFuture = ichiSenkouSpanBBuffer[bar_index]; + + // + return result; +} + +// +// Check Tenkan Sen Over Kijun Sen ... +bool XICHIHLPIsTenkanSenOverKijunSen( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + + // + result = + // + point.tenkanSen > point.kijunSen + // + ; + + // + return result; +} + +// +// Is Tenkan Sen Under Kijun Sen ... +bool XICHIHLPIsTenkanSenUnderKijunSen( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + + // + result = + // + point.tenkanSen < point.kijunSen + // + ; + + // + return result; +} + +// +// Tenkan Sen Croosed Over Kijun Sen ... +bool XICHIHLPIsTenkanSenCrossedOverKijunSen( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + result = + // + point.tenkanSen > point.kijunSen && + pointPrev.tenkanSen <= pointPrev.kijunSen + // + ; + + // + return result; +} + +// +// Tenkan Sen Croosed Under Kijun Sen ... +bool XICHIHLPIsTenkanSenCrossedUnderKijunSen( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + result = + // + point.tenkanSen < point.kijunSen && + pointPrev.tenkanSen >= pointPrev.kijunSen + // + ; + + // + return result; +} + +// +// Check Kumo is Bullish ... +bool XICHIHLPIsKumoBullish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double ssa = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double ssb = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + result = + // + ssa > ssb + // + ; + + // + return result; +} + +// +// Check Kumo is Bearish ... +bool XICHIHLPIsKumoBearish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double ssa = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double ssb = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + result = + // + ssa < ssb + // + ; + + // + return result; +} + +// +// Check Kumo is Change to Bullish ... +bool XICHIHLPIsKumoSwitchedToBullish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double ssa = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double ssb = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + double ssaPrev = onFuture + ? pointPrev.senkouSpanAFuture + : pointPrev.senkouSpanA; + + // + double ssbPrev = onFuture + ? pointPrev.senkouSpanBFuture + : pointPrev.senkouSpanB; + + // + result = + // + ssa > ssb && + ssaPrev <= ssbPrev + // + ; + + // + return result; +} + +// +// Check Kumo is Change to Bearish ... +bool XICHIHLPIsKumoSwitchedToBearish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double ssa = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double ssb = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + double ssaPrev = onFuture + ? pointPrev.senkouSpanAFuture + : pointPrev.senkouSpanA; + + // + double ssbPrev = onFuture + ? pointPrev.senkouSpanBFuture + : pointPrev.senkouSpanB; + + // + result = + // + ssa < ssb && + ssaPrev >= ssbPrev + // + ; + + // + return result; +} + +// +// TENKANSEN and SENKOUSPAN ... + +// +bool XICHIHLPIsTenkanSenCrossedOverSenkouSpanA( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanAFuture + : pointPrev.senkouSpanA; + + // + result = + // + point.tenkanSen > dest && + pointPrev.tenkanSen <= destPrev + // + ; + + // + return result; +} + +// +bool XICHIHLPIsTenkanSenCrossedUnderSenkouSpanA( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanAFuture + : pointPrev.senkouSpanA; + + // + result = + // + point.tenkanSen < dest && + pointPrev.tenkanSen >= destPrev + // + ; + + // + return result; +} + +// +bool XICHIHLPIsTenkanSenCrossedOverSenkouSpanB( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanBFuture + : pointPrev.senkouSpanB; + + // + result = + // + point.tenkanSen > dest && + pointPrev.tenkanSen <= destPrev + // + ; + + // + return result; +} + +// +bool XICHIHLPIsTenkanSenCrossedUnderSenkouSpanB( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanBFuture + : pointPrev.senkouSpanB; + + // + result = + // + point.tenkanSen < dest && + pointPrev.tenkanSen >= destPrev + // + ; + + // + return result; +} + +// +// KIJUNSEN and SENKOUSPAN ... + +// +bool XICHIHLPIsKijunSenCrossedOverSenkouSpanA( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanAFuture + : pointPrev.senkouSpanA; + + // + result = + // + point.kijunSen > dest && + pointPrev.kijunSen <= destPrev + // + ; + + // + return result; +} + +// +bool XICHIHLPIsKijunSenCrossedUnderSenkouSpanA( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanAFuture + : point.senkouSpanA; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanAFuture + : pointPrev.senkouSpanA; + + // + result = + // + point.kijunSen < dest && + pointPrev.kijunSen >= destPrev + // + ; + + // + return result; +} + +// +bool XICHIHLPIsKijunSenCrossedOverSenkouSpanB( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanBFuture + : pointPrev.senkouSpanB; + + // + result = + // + point.kijunSen > dest && + pointPrev.kijunSen <= destPrev + // + ; + + // + return result; +} + +// +bool XICHIHLPIsKijunSenCrossedUnderSenkouSpanB( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... +) +{ + // + bool result = false; + + // + XIchiInfo point = XICHIHLPGetInfo(bar_index); + XIchiInfo pointPrev = XICHIHLPGetInfo(bar_index + 1); + + // + double dest = onFuture + ? point.senkouSpanBFuture + : point.senkouSpanB; + + // + double destPrev = onFuture + ? pointPrev.senkouSpanBFuture + : pointPrev.senkouSpanB; + + // + result = + // + point.kijunSen < dest && + pointPrev.kijunSen >= destPrev + // + ; + + // + return result; +} + +// +bool XICHIHLPIsValidArraySize(int bar_index) +{ + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(ichiTenkanSenBuffer); + result = rCount > bar_index + 1; + + // + return result; +} + +// +// SUPPORT and RESISTANCE ... + +// +// Find Pivot Areas in Ichimooku ... +void XICHIHLPFindPivotPoints() +{ + // + double smoothingPoint = 3; + int verifications = 3; + + // + // FLATS ... + double tmpFlats[]; + int tmpFlatsCount = 0; + + // + // TenkanSen Flats ... + FindSameValueInBuffer( + tmpFlats, + ichiTenkanSenBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + ichiPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // KijunSen Flats ... + FindSameValueInBuffer( + tmpFlats, + ichiKijunSenBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + ichiPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // SenkouSpanA Flats ... + FindSameValueInBuffer( + tmpFlats, + ichiSenkouSpanABuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + ichiPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // SenkouSpanB Flats ... + FindSameValueInBuffer( + tmpFlats, + ichiSenkouSpanBBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + ichiPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } +} + +// +// Extract Support and Resistances ... +XOHCLSupRes XICHIHLPFindCandleSupprtAndResistance( + int bar_index, // Bar Index ... + int count = 3 // Number of Requireds ... +) +{ + // + XOHCLSupRes result = ExtractSupportAndResistance( + bar_index, + ichiPivots, + count, + _Symbol, + _Period); + + // + return result; +} + +// +// END Helper Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xmc.test.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xmc.test.helper.mq5 new file mode 100644 index 0000000..52a3d82 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xmc.test.helper.mq5 @@ -0,0 +1,309 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XMCHLP 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 + +// +// START Includes ... +// + +// +// Includes ... +#include "../../Libraries/x-saherelm.alert.lib.mq5" +#include "../../Libraries/x-saherelm.models.lib.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes ... +// + +// +// START Constants/Enums ... +// + +// +// XMC Exported Buffers ... +enum ENUM_X_XMC_BUFFERS +{ + // + X_MC_FAST_LINE = 0, + X_MC_SLOW_LINE = 1, + X_MC_VERIFIER_LINE = 2, +}; + +// +// END Constants/Enums ... +// + +// +// START Definitions ... +// + +// +double mcFastBuffer[]; +double mcSlowBuffer[]; +double mcVerifierBuffer[]; + +// +int mcHandler = INVALID_HANDLE; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +bool XMCHLPOnInit() +{ + // + bool result = false; + + // + ArraySetAsSeries(mcFastBuffer, true); + ArraySetAsSeries(mcSlowBuffer, true); + ArraySetAsSeries(mcVerifierBuffer, true); + + // + // Initial Handler ... + mcHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xmc", + // + // Inputs ... + // + // FAST ... + "", + 9, + 0, + MODE_EMA, + PRICE_CLOSE, + // + // SLOW ... + "", + 18, + 0, + MODE_EMA, + PRICE_CLOSE, + // + // VERIFIER ... + "", + 50, + 0, + MODE_EMA, + PRICE_CLOSE, + // + "", + false, + false, + false + // + ); + result = mcHandler != INVALID_HANDLE; + + // + return result; +} + +// +void XMCHLPOnDeInit() +{ + // + // Release Indicators ... + IndicatorRelease(mcHandler); +} + +// +void XMCHLPReadBuffers() +{ + // + // FAST ... + CopyBuffer( + mcHandler, + X_MC_FAST_LINE, + 0, + 52, + mcFastBuffer); + + // + // SLOW ... + CopyBuffer( + mcHandler, + X_MC_SLOW_LINE, + 0, + 52, + mcSlowBuffer); + + // + // VERIFIER ... + CopyBuffer( + mcHandler, + X_MC_VERIFIER_LINE, + 0, + 52, + mcVerifierBuffer); +} + +// +// END Handler Functions ... +// + +// +// START Helper Functions ... +// + +// +// Check Fast Over Slow ... +bool XMCHLPIsFastOverSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMCHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsOver( + mcFastBuffer, + mcSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +// Check Fast Crossed Over Slow ... +bool XMCHLPIsFastCrossedOverSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMCHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsCrossOver( + mcFastBuffer, + mcSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +// Check Fast Under Slow ... +bool XMCHLPIsFastUnderSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMCHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +// Check Fast Crossed Under Slow ... +bool XMCHLPIsFastCrossedUnderSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMCHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsCrossUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +bool XMCHLPIsValidArraySize(int bar_index) +{ + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(mcFastBuffer); + result = rCount > bar_index + 1; + + // + return result; +} + +// +// END Helper Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xmrb.test.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xmrb.test.helper.mq5 new file mode 100644 index 0000000..c952088 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xmrb.test.helper.mq5 @@ -0,0 +1,314 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XMRBHLP 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 + +// +// START Includes ... +// + +// +// Includes ... +#include "../../Libraries/x-saherelm.alert.lib.mq5" +#include "../../Libraries/x-saherelm.models.lib.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes ... +// + +// +// START Constants/Enums ... +// + +// +// XMRB Exported Buffers ... +enum ENUM_X_XMRB_BUFFERS +{ + // + X_MRB_FAST_LINE = 0, + X_MRB_SLOW_LINE = 1, + + // + X_MRB_FAST_1_LINE = 2, + X_MRB_FAST_2_LINE = 3, + X_MRB_FAST_3_LINE = 4, + X_MRB_FAST_4_LINE = 5, + X_MRB_FAST_5_LINE = 6, + + // + X_MRB_SLOW_1_LINE = 7, + X_MRB_SLOW_2_LINE = 8, + X_MRB_SLOW_3_LINE = 9, + X_MRB_SLOW_4_LINE = 10, + X_MRB_SLOW_5_LINE = 11, +}; + +// +// END Constants/Enums ... +// + +// +// START Definitions ... +// + +// +double mrbFastBuffer[]; +double mrbSlowBuffer[]; + +// +int mrbHandler = INVALID_HANDLE; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +bool XMRBHLPOnInit() +{ + // + bool result = false; + + // + ArraySetAsSeries(mrbFastBuffer, true); + ArraySetAsSeries(mrbSlowBuffer, true); + + // + // Initial Handler ... + mrbHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xmrb", + // + // Inputs ... + // + "", + 3, + 5, + // + "", + 8, + 13, + // + "", + 21, + 34, + // + "", + 55, + 89, + // + "", + 144, + 233, + // + "", + MODE_EMA, + PRICE_CLOSE, + // + "", + false, + false, + false + // + ); + result = mrbHandler != INVALID_HANDLE; + + // + return result; +} + +// +void XMRBHLPOnDeInit() +{ + // + // Release Indicators ... + IndicatorRelease(mrbHandler); +} + +// +void XMRBHLPReadBuffers() +{ + // + // FAST ... + CopyBuffer( + mrbHandler, + X_MRB_FAST_LINE, + 0, + 52, + mrbFastBuffer); + + // + // SLOW ... + CopyBuffer( + mrbHandler, + X_MRB_SLOW_LINE, + 0, + 52, + mrbSlowBuffer); +} + +// +// END Handler Functions ... +// + +// +// START Helper Functions ... +// + +// +// Check Fast Over Slow ... +bool XMRBHLPIsFastOverSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMRBHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsOver( + mrbFastBuffer, + mrbSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +// Check Fast Crossed Over Slow ... +bool XMRBHLPIsFastCrossedOverSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMRBHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsCrossOver( + mrbFastBuffer, + mrbSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +// Check Fast Under Slow ... +bool XMRBHLPIsFastUnderSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMRBHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsUnder( + mrbFastBuffer, + mrbSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +// Check Fast Crossed Under Slow ... +bool XMRBHLPIsFastCrossedUnderSlow( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XMRBHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + IsCrossUnder( + mrbFastBuffer, + mrbSlowBuffer, + bar_index) + // + ; + + // + return result; +} + +// +bool XMRBHLPIsValidArraySize(int bar_index) +{ + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(mrbFastBuffer); + result = rCount > bar_index + 1; + + // + return result; +} + +// +// END Helper Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xpv.test.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xpv.test.helper.mq5 new file mode 100644 index 0000000..0af7755 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xpv.test.helper.mq5 @@ -0,0 +1,803 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XPVHLP 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 + +// +// START Includes ... +// + +// +// Includes ... +#include "../../Libraries/x-saherelm.alert.lib.mq5" +#include "../../Libraries/x-saherelm.models.lib.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes ... +// + +// +// START Constants/Enums ... +// + +// +// XPeaksAndVales Exported Buffers ... +enum ENUM_X_XPV_BUFFERS +{ + // + // PEAKSANDVALES ... + X_PV_P_LINE = 0, + X_PV_V_LINE = 1, + // + // SUPPORTRESISTANCE ... + X_PV_R_LINE = 2, + X_PV_S_LINE = 4, + // + // SHORT ... + X_PV_SHH_LINE = 6, + X_PV_SLL_LINE = 7, + // + // MEDIUM ... + X_PV_MHH_LINE = 8, + X_PV_MLL_LINE = 9, + // + // LONG ... + X_PV_LHH_LINE = 10, + X_PV_LLL_LINE = 11, + // + // HIND ... + X_PV_HHH_LINE = 12, + X_PV_HLL_LINE = 13, +}; + +// +// END Constants/Enums ... +// + +// +// START Definitions ... +// + +// +double pvPivots[]; + +// +double pvPBuffer[]; +double pvVBuffer[]; +double pvRBuffer[]; +double pvSBuffer[]; +double pvSHHBuffer[]; +double pvSLLBuffer[]; +double pvMHHBuffer[]; +double pvMLLBuffer[]; +double pvLHHBuffer[]; +double pvLLLBuffer[]; +double pvHHHBuffer[]; +double pvHLLBuffer[]; + +// +int mpvHandler = INVALID_HANDLE; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +bool XPVHLPOnInit() +{ + // + bool result = false; + + // + ArraySetAsSeries(pvPivots, true); + + // + ArraySetAsSeries(pvPBuffer, true); + ArraySetAsSeries(pvVBuffer, true); + ArraySetAsSeries(pvRBuffer, true); + ArraySetAsSeries(pvSBuffer, true); + ArraySetAsSeries(pvSHHBuffer, true); + ArraySetAsSeries(pvSLLBuffer, true); + ArraySetAsSeries(pvMHHBuffer, true); + ArraySetAsSeries(pvMLLBuffer, true); + ArraySetAsSeries(pvLHHBuffer, true); + ArraySetAsSeries(pvLLLBuffer, true); + ArraySetAsSeries(pvHHHBuffer, true); + ArraySetAsSeries(pvHLLBuffer, true); + + // + // Initial Handler ... + mpvHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xpv", + // + // Inputs ... + // + // MARKET ... + "", + 9, + 17, + 26, + 35, + // + // TREND ... + "", + 10, + // + // DETECTION ... + "", + MODE_HIGH, + MODE_LOW, + // + "", + true, + false, + false, + false + // + ); + result = mpvHandler != INVALID_HANDLE; + + // + return result; +} + +// +void XPVHLPOnDeInit() +{ + // + // Release Indicators ... + IndicatorRelease(mpvHandler); +} + +// +void XPVHLPReadBuffers(int bar_index = 0) +{ + // + // PEAKS ... + CopyBuffer( + mpvHandler, + X_PV_P_LINE, + bar_index, + bar_index + 100, + pvPBuffer); + + // + // VALES ... + CopyBuffer( + mpvHandler, + X_PV_V_LINE, + bar_index, + bar_index + 100, + pvVBuffer); + + // + // R ... + CopyBuffer( + mpvHandler, + X_PV_R_LINE, + bar_index, + bar_index + 100, + pvRBuffer); + + // + // S ... + CopyBuffer( + mpvHandler, + X_PV_S_LINE, + bar_index, + bar_index + 100, + pvSBuffer); + + // + // SHORT ... + + // + // HIGH ... + CopyBuffer( + mpvHandler, + X_PV_SHH_LINE, + bar_index, + bar_index + 100, + pvSHHBuffer); + + // + // LOW ... + CopyBuffer( + mpvHandler, + X_PV_SLL_LINE, + bar_index, + bar_index + 100, + pvSLLBuffer); + + // + // MEIUM ... + + // + // HIGH ... + CopyBuffer( + mpvHandler, + X_PV_MHH_LINE, + bar_index, + bar_index + 100, + pvMHHBuffer); + + // + // LOW ... + CopyBuffer( + mpvHandler, + X_PV_MLL_LINE, + bar_index, + bar_index + 100, + pvMLLBuffer); + + // + // LONG ... + + // + // HIGH ... + CopyBuffer( + mpvHandler, + X_PV_LHH_LINE, + bar_index, + bar_index + 100, + pvLHHBuffer); + + // + // LOW ... + CopyBuffer( + mpvHandler, + X_PV_LLL_LINE, + bar_index, + bar_index + 100, + pvLLLBuffer); + + // + // HIND ... + + // + // HIGH ... + CopyBuffer( + mpvHandler, + X_PV_HHH_LINE, + bar_index, + bar_index + 100, + pvHHHBuffer); + + // + // LOW ... + CopyBuffer( + mpvHandler, + X_PV_HLL_LINE, + bar_index, + bar_index + 100, + pvHLLBuffer); + + // + XPVHLPFindPivotPoints(); +} + +// +// END Handler Functions ... +// + +// +// START Helper Functions ... +// + +// +// Check isPeak ... +bool XPVHLPIsPeak(int bar_index) +{ + // + bool result = false; + + // + if (!XPVHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = pvRBuffer[bar_index] == pvHHHBuffer[bar_index] && + pvHHHBuffer[bar_index] == pvLHHBuffer[bar_index] && + pvLHHBuffer[bar_index] == pvMHHBuffer[bar_index] && + pvMHHBuffer[bar_index] == pvSHHBuffer[bar_index]; + + // + return result; +} + +// +// Check isVale ... +bool XPVHLPIsVale(int bar_index) +{ + // + bool result = false; + + // + if (!XPVHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = pvSBuffer[bar_index] == pvHLLBuffer[bar_index] && + pvHLLBuffer[bar_index] == pvLLLBuffer[bar_index] && + pvLLLBuffer[bar_index] == pvMLLBuffer[bar_index] && + pvMLLBuffer[bar_index] == pvSLLBuffer[bar_index]; + + // + return result; +} + +// +// Is Strong Support ... +bool XPVHLPIsStrongSupport(int bar_index) +{ + // + bool result = false; + + // + if (!XPVHLPIsValidArraySize(bar_index + 3)) + { + return result; + } + + // + result = + // + pvHLLBuffer[bar_index + 1] == pvHLLBuffer[bar_index + 2] && + pvHLLBuffer[bar_index + 2] == pvHLLBuffer[bar_index + 3] && + // + pvLLLBuffer[bar_index + 1] == pvLLLBuffer[bar_index + 2] && + pvLLLBuffer[bar_index + 2] == pvLLLBuffer[bar_index + 3] && + // + pvMLLBuffer[bar_index + 1] == pvMLLBuffer[bar_index + 2] && + pvMLLBuffer[bar_index + 2] == pvMLLBuffer[bar_index + 3] && + // + pvSLLBuffer[bar_index + 1] == pvSLLBuffer[bar_index + 2] && + pvSLLBuffer[bar_index + 2] == pvSLLBuffer[bar_index + 3] + // + ; + + // + return result; +} + +// +// Is Strong Resistance ... +bool XPVHLPIsStrongResistance(int bar_index) +{ + // + bool result = false; + + // + if (!XPVHLPIsValidArraySize(bar_index + 2)) + { + return result; + } + + // + result = + // + pvHHHBuffer[bar_index + 1] == pvHHHBuffer[bar_index + 2] && + pvHHHBuffer[bar_index + 2] == pvHHHBuffer[bar_index + 3] && + // + pvLHHBuffer[bar_index + 1] == pvLHHBuffer[bar_index + 2] && + pvLHHBuffer[bar_index + 2] == pvLHHBuffer[bar_index + 3] && + // + pvMHHBuffer[bar_index + 1] == pvMHHBuffer[bar_index + 2] && + pvMHHBuffer[bar_index + 2] == pvMHHBuffer[bar_index + 3] && + // + pvSHHBuffer[bar_index + 1] == pvSHHBuffer[bar_index + 2] && + pvSHHBuffer[bar_index + 2] == pvSHHBuffer[bar_index + 3] + // + ; + // + return result; +} + +// +// Retrieve Highs ... +double XPVHLPGetMaxHH(int bar_index) +{ + // + double result = 0; + + // + if (!XPVHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = MathMax(pvSHHBuffer[bar_index], pvMHHBuffer[bar_index]); + result = MathMax(result, pvLHHBuffer[bar_index]); + result = MathMax(result, pvHHHBuffer[bar_index]); + + // + return result; +} + +double XPVHLPGetMinHH(int bar_index) +{ + // + double result = 0; + + // + if (!XPVHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = MathMin(pvSHHBuffer[bar_index], pvMHHBuffer[bar_index]); + result = MathMin(result, pvLHHBuffer[bar_index]); + result = MathMin(result, pvHHHBuffer[bar_index]); + + // + return result; +} + +// +// Retrieve Lows ... +double XPVHLPGetMaxLL(int bar_index) +{ + // + double result = 0; + + // + if (!XPVHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = MathMax(pvSLLBuffer[bar_index], pvMLLBuffer[bar_index]); + result = MathMax(result, pvLLLBuffer[bar_index]); + result = MathMax(result, pvHLLBuffer[bar_index]); + + // + return result; +} + +double XPVHLPGetMinLL(int bar_index) +{ + // + double result = 0; + + // + if (!XPVHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = MathMin(pvSLLBuffer[bar_index], pvMLLBuffer[bar_index]); + result = MathMin(result, pvLLLBuffer[bar_index]); + result = MathMin(result, pvHLLBuffer[bar_index]); + + // + return result; +} + +// +bool XPVHLPIsValidArraySize(int bar_index) +{ + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(pvRBuffer); + result = rCount > bar_index + 1; + + // + return result; +} + +// +// SUPPORT and RESISTANCE ... + +// +// Find Pivot Areas in PV ... +void XPVHLPFindPivotPoints() +{ + // + double smoothingPoint = 3; + int verifications = 26; + + // + // FLATS ... + double tmpFlats[]; + int tmpFlatsCount = 0; + + // + // PEAKS and VALES ... + + // + // R ... + FindSameValueInBuffer( + tmpFlats, + pvRBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // S ... + FindSameValueInBuffer( + tmpFlats, + pvSBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // CYCLES ... + + // + // SHORT ... + // LEVEL 1 ... + + // + // HH ... + FindSameValueInBuffer( + tmpFlats, + pvSHHBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // LL ... + FindSameValueInBuffer( + tmpFlats, + pvSLLBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // MEDIUM ... + // LEVEL 2 ... + + // + // HH ... + FindSameValueInBuffer( + tmpFlats, + pvMHHBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // LL ... + FindSameValueInBuffer( + tmpFlats, + pvMLLBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // LONG ... + // LEVEL 3 ... + + // + // HH ... + FindSameValueInBuffer( + tmpFlats, + pvLHHBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // LL ... + FindSameValueInBuffer( + tmpFlats, + pvLLLBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // HINDMOST ... + // LEVEL 4 ... + + // + // HH ... + FindSameValueInBuffer( + tmpFlats, + pvHHHBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // LL ... + FindSameValueInBuffer( + tmpFlats, + pvHLLBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // PEAKS and VALES ... + + // + // PEAKS ... + FindSameValueInBuffer( + tmpFlats, + pvPBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } + + // + // VALES ... + FindSameValueInBuffer( + tmpFlats, + pvVBuffer); + tmpFlatsCount = ArraySize(tmpFlats); + if (tmpFlatsCount > 0) + { + // + AddsIfNotExists( + tmpFlats, + pvPivots, + smoothingPoint); + + // + Clean(tmpFlats); + } +} + +// +// Extract Support and Resistances ... +XOHCLSupRes XPVHLPFindCandleSupprtAndResistance( + int bar_index, // Bar Index ... + int count = 3 // Number of Requireds ... +) +{ + // + XOHCLSupRes result = ExtractSupportAndResistance( + bar_index, + pvPivots, + count, + _Symbol, + _Period); + + // + return result; +} + +// +// END Helper Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xtrnd.test.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xtrnd.test.helper.mq5 new file mode 100644 index 0000000..0b2e4cf --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/Test/x121.xtrnd.test.helper.mq5 @@ -0,0 +1,1383 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTRNDHLP 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 + +// +// START Includes ... +// + +// +// Includes ... +#include "../../Libraries/x-saherelm.alert.lib.mq5" +#include "../../Libraries/x-saherelm.models.lib.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes ... +// + +// +// START Constants/Enums ... +// + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// XPeaksAndVales Exported Buffers ... +enum ENUM_X_XTRND_BUFFERS +{ + // + X_TRND_UP_LINE = 0, + X_TRND_UP_STATE_LINE = 1, + // + X_TRND_DOWN_LINE = 2, + X_TRND_DOWN_STATE_LINE = 3, + // + // Nearest ... + // CYCLE 1 ... + X_TRND_L1_UP_LINE = 4, + X_TRND_L1_UP_STATE_LINE = 5, + // + X_TRND_L1_DOWN_LINE = 6, + X_TRND_L1_DOWN_STATE_LINE = 7, + // + // Mediest ... + // CYCLE 2 ... + X_TRND_L2_UP_LINE = 8, + X_TRND_L2_UP_STATE_LINE = 9, + // + X_TRND_L2_DOWN_LINE = 10, + X_TRND_L2_DOWN_STATE_LINE = 11, + // + // Farest ... + // CYCLE 3 ... + X_TRND_L3_UP_LINE = 12, + X_TRND_L3_UP_STATE_LINE = 13, + // + X_TRND_L3_DOWN_LINE = 14, + X_TRND_L3_DOWN_STATE_LINE = 15, +}; + +// +// Trend State at unique Bar ... +enum ENUM_X_XTRND_STATE +{ + X_TRND_STATE_RANGE = 0, + X_TRND_STATE_CONSOLIDATION = 1, + X_TRND_STATE_UP = 2, + X_TRND_STATE_DOWN = 3, +}; + +// +// END Constants/Enums ... +// + +// +double trndUpBuffer[]; +double trndUpStateBuffer[]; +double trndDownBuffer[]; +double trndDownStateBuffer[]; +// +// Nearest ... +// CYCLE 1 ... +double trndl1UpBuffer[]; +double trndl1UpStateBuffer[]; +double trndl1DownBuffer[]; +double trndl1DownStateBuffer[]; +// +// Mediest ... +// CYCLE 2 ... +double trndl2UpBuffer[]; +double trndl2UpStateBuffer[]; +double trndl2DownBuffer[]; +double trndl2DownStateBuffer[]; +// +// Farest ... +// CYCLE 3 ... +double trndl3UpBuffer[]; +double trndl3UpStateBuffer[]; +double trndl3DownBuffer[]; +double trndl3DownStateBuffer[]; + +// +int mtrndHandler = INVALID_HANDLE; + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +bool XTRNDHLPOnInit() +{ + // + bool result = false; + + // + ArraySetAsSeries(trndUpBuffer, true); + ArraySetAsSeries(trndUpStateBuffer, true); + ArraySetAsSeries(trndDownBuffer, true); + ArraySetAsSeries(trndDownStateBuffer, true); + // + // Nearest ... + // CYCLE 1 ... + ArraySetAsSeries(trndl1UpBuffer, true); + ArraySetAsSeries(trndl1UpStateBuffer, true); + ArraySetAsSeries(trndl1DownBuffer, true); + ArraySetAsSeries(trndl1DownStateBuffer, true); + // + // Mediest ... + // CYCLE 2 ... + ArraySetAsSeries(trndl2UpBuffer, true); + ArraySetAsSeries(trndl2UpStateBuffer, true); + ArraySetAsSeries(trndl2DownBuffer, true); + ArraySetAsSeries(trndl2DownStateBuffer, true); + // + // Farest ... + // CYCLE 3 ... + ArraySetAsSeries(trndl3UpBuffer, true); + ArraySetAsSeries(trndl3UpStateBuffer, true); + ArraySetAsSeries(trndl3DownBuffer, true); + ArraySetAsSeries(trndl3DownStateBuffer, true); + + // + // Initial Handler ... + mtrndHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xtrnd", + // + // Inputs ... + // + // MARKET ... + "", + 2, + 2, + // + // CALCULATIONS ... + "", + MODE_HIGH, + MODE_LOW, + // + // CYCLES ... + "", + // + // LEVEL 1 ... + "", + X_PERIOD_AUTO, + _Period, + // + // LEVEL 2 ... + "", + X_PERIOD_AUTO, + _Period, + // + // LEVEL 3 ... + "", + X_PERIOD_AUTO, + _Period, + // + // PRESENTATION ... + "", + true, + true, + true, + true, + true + // + ); + result = mtrndHandler != INVALID_HANDLE; + + // + return result; +} + +// +void XTRNDHLPOnDeInit() +{ + // + // Release Indicators ... + IndicatorRelease(mtrndHandler); +} + +// +void XTRNDHLPReadBuffers() +{ + // + // UP ... + CopyBuffer( + mtrndHandler, + X_TRND_UP_LINE, + 0, + 52, + trndUpBuffer); + + // + // UP STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_UP_STATE_LINE, + 0, + 52, + trndUpStateBuffer); + + // + // DOWN ... + CopyBuffer( + mtrndHandler, + X_TRND_DOWN_LINE, + 0, + 52, + trndDownBuffer); + + // + // DOWN STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_DOWN_STATE_LINE, + 0, + 52, + trndDownStateBuffer); + + // + // CYCLES ... + + // + // Nearest ... + // CYCLE 1 ... + + // + // UP ... + CopyBuffer( + mtrndHandler, + X_TRND_L1_UP_LINE, + 0, + 52, + trndl1UpBuffer); + + // + // UP STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_L1_UP_STATE_LINE, + 0, + 52, + trndl1UpStateBuffer); + + // + // DOWN ... + CopyBuffer( + mtrndHandler, + X_TRND_L1_DOWN_LINE, + 0, + 52, + trndl1DownBuffer); + + // + // DOWN STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_L1_DOWN_STATE_LINE, + 0, + 52, + trndl1DownStateBuffer); + + // + // Mediest ... + // CYCLE 2 ... + + // + // UP ... + CopyBuffer( + mtrndHandler, + X_TRND_L2_UP_LINE, + 0, + 52, + trndl2UpBuffer); + + // + // UP STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_L2_UP_STATE_LINE, + 0, + 52, + trndl2UpStateBuffer); + + // + // DOWN ... + CopyBuffer( + mtrndHandler, + X_TRND_L2_DOWN_LINE, + 0, + 52, + trndl2DownBuffer); + + // + // DOWN STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_L2_DOWN_STATE_LINE, + 0, + 52, + trndl2DownStateBuffer); + + // + // Farest ... + // CYCLE 3 ... + + // + // UP ... + CopyBuffer( + mtrndHandler, + X_TRND_L3_UP_LINE, + 0, + 52, + trndl3UpBuffer); + + // + // UP STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_L3_UP_STATE_LINE, + 0, + 52, + trndl3UpStateBuffer); + + // + // DOWN ... + CopyBuffer( + mtrndHandler, + X_TRND_L3_DOWN_LINE, + 0, + 52, + trndl3DownBuffer); + + // + // DOWN STATE ... + CopyBuffer( + mtrndHandler, + X_TRND_L3_DOWN_STATE_LINE, + 0, + 52, + trndl3DownStateBuffer); +} + +// +// END Handler Functions ... +// + +// +// START Helper Functions ... +// + +// +// START Strongly Trend Detects ... +// + +// +// Detect Strongly Bullish Trend ... +bool XTRNDHLPIsTrendStronglyBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendBullish(bar_index) && + ( + // + (XTRNDHLPIsL1TrendBullish(bar_index) && + XTRNDHLPIsL2TrendBullish(bar_index)) + // + || + // + (XTRNDHLPIsL1TrendBullish(bar_index) && + XTRNDHLPIsL3TrendBullish(bar_index)) + // + || + // + (XTRNDHLPIsL2TrendBullish(bar_index) && + XTRNDHLPIsL3TrendBullish(bar_index)) + // + ) + // + ; + + // + return result; +} + +// +// Detect Strongly Trends Switched to Bullish ... +bool XTRNDHLPIsTrendStronglySwitchedBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendStronglyBullish(bar_index) && + !XTRNDHLPIsTrendStronglyBullish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Strongly Bearish Trend ... +bool XTRNDHLPIsTrendStronglyBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendBearish(bar_index) && + ( + // + (XTRNDHLPIsL1TrendBearish(bar_index) && + XTRNDHLPIsL2TrendBearish(bar_index)) + // + || + // + (XTRNDHLPIsL1TrendBearish(bar_index) && + XTRNDHLPIsL3TrendBearish(bar_index)) + // + || + // + (XTRNDHLPIsL2TrendBearish(bar_index) && + XTRNDHLPIsL3TrendBearish(bar_index)) + // + ) + // + ; + + // + return result; +} + +// +// Detect Strongly Trends Switched to Bearish ... +bool XTRNDHLPIsTrendStronglySwitchedBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendStronglyBearish(bar_index) && + !XTRNDHLPIsTrendStronglyBearish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Strongly Consolidation/Range Trend ... +bool XTRNDHLPIsTrendStronglyConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendConsolidation(bar_index) && + ( + // + (XTRNDHLPIsL1TrendConsolidation(bar_index) && + XTRNDHLPIsL2TrendConsolidation(bar_index)) + // + || + // + (XTRNDHLPIsL1TrendConsolidation(bar_index) && + XTRNDHLPIsL3TrendConsolidation(bar_index)) + // + || + // + (XTRNDHLPIsL2TrendConsolidation(bar_index) && + XTRNDHLPIsL3TrendConsolidation(bar_index)) + // + ) + // + ; + + // + return result; +} + +// +// Detect Strongly Trends Switched to Consolidation/Range ... +bool XTRNDHLPIsTrendStronglySwitchedConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendStronglyConsolidation(bar_index) && + !XTRNDHLPIsTrendStronglyConsolidation(bar_index + 1) + // + ; + + // + return result; +} + +// +// END Strongly Trend Detects ... +// + +// +// Detect Trend Up ... +bool XTRNDHLPIsTrendBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndUpStateBuffer[bar_index] == X_TRND_STATE_UP && + trndDownStateBuffer[bar_index] == X_TRND_STATE_UP + // + ; + + // + return result; +} + +// +// Detect Trend Switched Up ... +bool XTRNDHLPIsTrendSwitchedBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendBullish(bar_index) && + !XTRNDHLPIsTrendBullish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Down ... +bool XTRNDHLPIsTrendBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndUpStateBuffer[bar_index] == X_TRND_STATE_DOWN && + trndDownStateBuffer[bar_index] == X_TRND_STATE_DOWN + // + ; + + // + return result; +} + +// +// Detect Trend Switched Down ... +bool XTRNDHLPIsTrendSwitchedBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendBearish(bar_index) && + !XTRNDHLPIsTrendBearish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Consolidation ... +bool XTRNDHLPIsTrendConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + (trndUpStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndUpStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + && + // + (trndDownStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndDownStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + ; + + // + return result; +} + +// +// Detect Trend Switched Consolidation ... +bool XTRNDHLPIsTrendSwitchedConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsTrendConsolidation(bar_index) && + !XTRNDHLPIsTrendConsolidation(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Previous Trend Switched To Bullish ... +int XTRNDHLPFindNextTrendSwitchedBullish( + int bar_index // Bar Index ... +) { + // + int result = -1; + + // + int size = ArraySize(trndDownStateBuffer); + if (size <= 0) { + return result; + } + + // + for (int i = bar_index + 1; i < size + bar_index; i++) { + // + bool isTrendSwitched = + XTRNDHLPIsTrendSwitchedBullish(i); + + // + if (isTrendSwitched && i != bar_index) { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Detect Previous Trend Switched To Bearish ... +int XTRNDHLPFindNextTrendSwitchedBearish( + int bar_index // Bar Index ... +) { + // + int result = -1; + + // + int size = ArraySize(trndDownStateBuffer); + if (size <= 0) { + return result; + } + + // + for (int i = bar_index + 1; i < size + bar_index; i++) { + // + bool isTrendSwitched = + XTRNDHLPIsTrendSwitchedBearish(i); + + // + if (isTrendSwitched && i != bar_index) { + // + result = i; + break; + } + } + + // + return result; +} + +// +// CYCLE 1 ... + +// +// Detect Trend Up ... +bool XTRNDHLPIsL1TrendBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndl1UpStateBuffer[bar_index] == X_TRND_STATE_UP && + trndl1DownStateBuffer[bar_index] == X_TRND_STATE_UP + // + ; + + // + return result; +} + +// +// Detect Trend Switched Up ... +bool XTRNDHLPIsL1TrendSwitchedBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL1TrendBullish(bar_index) && + !XTRNDHLPIsL1TrendBullish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Down ... +bool XTRNDHLPIsL1TrendBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndl1UpStateBuffer[bar_index] == X_TRND_STATE_DOWN && + trndl1DownStateBuffer[bar_index] == X_TRND_STATE_DOWN + // + ; + + // + return result; +} + +// +// Detect Trend Switched Down ... +bool XTRNDHLPIsL1TrendSwitchedBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL1TrendBearish(bar_index) && + !XTRNDHLPIsL1TrendBearish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Consolidation ... +bool XTRNDHLPIsL1TrendConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + (trndl1UpStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndl1UpStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + && + // + (trndl1DownStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndl1DownStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + ; + + // + return result; +} + +// +// Detect Trend Switched Consolidation ... +bool XTRNDHLPIsL1TrendSwitchedConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL1TrendConsolidation(bar_index) && + !XTRNDHLPIsL1TrendConsolidation(bar_index + 1) + // + ; + + // + return result; +} + +// +// CYCLE 2 ... + +// +// Detect Trend Up ... +bool XTRNDHLPIsL2TrendBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndl2UpStateBuffer[bar_index] == X_TRND_STATE_UP && + trndl2DownStateBuffer[bar_index] == X_TRND_STATE_UP + // + ; + + // + return result; +} + +// +// Detect Trend Switched Up ... +bool XTRNDHLPIsL2TrendSwitchedBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL2TrendBullish(bar_index) && + !XTRNDHLPIsL2TrendBullish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Down ... +bool XTRNDHLPIsL2TrendBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndl2UpStateBuffer[bar_index] == X_TRND_STATE_DOWN && + trndl2DownStateBuffer[bar_index] == X_TRND_STATE_DOWN + // + ; + + // + return result; +} + +// +// Detect Trend Switched Down ... +bool XTRNDHLPIsL2TrendSwitchedBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL2TrendBearish(bar_index) && + !XTRNDHLPIsL2TrendBearish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Consolidation ... +bool XTRNDHLPIsL2TrendConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + (trndl2UpStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndl2UpStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + && + // + (trndl2DownStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndl2DownStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + ; + + // + return result; +} + +// +// Detect Trend Switched Consolidation ... +bool XTRNDHLPIsL2TrendSwitchedConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL2TrendConsolidation(bar_index) && + !XTRNDHLPIsL2TrendConsolidation(bar_index + 1) + // + ; + + // + return result; +} + +// +// CYCLE 3 ... + +// +// Detect Trend Up ... +bool XTRNDHLPIsL3TrendBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndl3UpStateBuffer[bar_index] == X_TRND_STATE_UP && + trndl3DownStateBuffer[bar_index] == X_TRND_STATE_UP + // + ; + + // + return result; +} + +// +// Detect Trend Switched Up ... +bool XTRNDHLPIsL3TrendSwitchedBullish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL3TrendBullish(bar_index) && + !XTRNDHLPIsL3TrendBullish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Down ... +bool XTRNDHLPIsL3TrendBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + trndl3UpStateBuffer[bar_index] == X_TRND_STATE_DOWN && + trndl3DownStateBuffer[bar_index] == X_TRND_STATE_DOWN + // + ; + + // + return result; +} + +// +// Detect Trend Switched Down ... +bool XTRNDHLPIsL3TrendSwitchedBearish( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL3TrendBearish(bar_index) && + !XTRNDHLPIsL3TrendBearish(bar_index + 1) + // + ; + + // + return result; +} + +// +// Detect Trend Consolidation ... +bool XTRNDHLPIsL3TrendConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + (trndl3UpStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndl3UpStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + && + // + (trndl3DownStateBuffer[bar_index] == X_TRND_STATE_RANGE || + trndl3DownStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + ; + + // + return result; +} + +// +// Detect Trend Switched Consolidation ... +bool XTRNDHLPIsL3TrendSwitchedConsolidation( + int bar_index // Bar Index ... +) +{ + // + bool result = false; + + // + if (!XTRNDHLPIsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + XTRNDHLPIsL3TrendConsolidation(bar_index) && + !XTRNDHLPIsL3TrendConsolidation(bar_index + 1) + // + ; + + // + return result; +} + +// +bool XTRNDHLPIsValidArraySize(int bar_index) +{ + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(trndUpBuffer); + result = rCount > bar_index + 1; + + // + return result; +} +// +// END Helper Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xatrsl.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xatrsl.helper.mq5 new file mode 100644 index 0000000..4286103 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xatrsl.helper.mq5 @@ -0,0 +1,324 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XATRSL Indicator Provider +// Description: ATR Stop Loss ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XPeaksAndVales Exported Buffers ... +enum ENUM_X_XATRSL_BUFFERS +{ + // + X_ATRSL_UP_LINE = 0, + X_ATRSL_DOWN_LINE = 1, + X_ATRSL_SAR_LINE = 2, + X_ATRSL_RMA_LINE = 3, + X_ATRSL_WMA_LINE = 4, + X_ATRSL_MA1_LINE = 5, + X_ATRSL_SMA_LINE = 6, + X_ATRSL_EMA_LINE = 7, + X_ATRSL_ATR_LINE = 8, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXATRSLHelper +{ + // +public: + // + // Properties ... + double upBuffer[]; + double downBuffer[]; + double sarBuffer[]; + double rmaBuffer[]; + double wmaBuffer[]; + double ma1Buffer[]; + double smaBuffer[]; + double emaBuffer[]; + double atrBuffer[]; + + // + // Constructor ... + void XSCXATRSLHelper() { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXATRSLHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // MARKET ... + int length = 14, // Length + double step = 0.02, // Increment Step + double maximum = 0.2, // Maximum + ENUM_APPLIED_PRICE highAppliedTo = PRICE_HIGH, // High Line Applied To + ENUM_APPLIED_PRICE lowAppliedTo = PRICE_LOW // Low Line Applied To + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // MARKET ... + mLength = length; + mStep = step; + mMaximum = maximum; + mHighAppliedTo = highAppliedTo; + mLowAppliedTo = lowAppliedTo; + + // + mTag = "XATRSL " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xatrsl", + // + // Inputs ... + // + // MARKET ... + "", + mLength, + mStep, + mMaximum, + mHighAppliedTo, + mLowAppliedTo, + // + // PRESENTATION ... + "", + false, + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + ArraySetAsSeries(upBuffer, true); + ArraySetAsSeries(downBuffer, true); + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(rmaBuffer, true); + ArraySetAsSeries(wmaBuffer, true); + ArraySetAsSeries(ma1Buffer, true); + ArraySetAsSeries(smaBuffer, true); + ArraySetAsSeries(emaBuffer, true); + ArraySetAsSeries(atrBuffer, true); + } + + // + // DeConstructor ... + void ~XSCXATRSLHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // UP ... + CopyBuffer( + mHandler, + X_ATRSL_UP_LINE, + 0, + mNumberOfItemsReadPerTick, + upBuffer); + + // + // DOWN ... + CopyBuffer( + mHandler, + X_ATRSL_DOWN_LINE, + 0, + mNumberOfItemsReadPerTick, + downBuffer); + + // + // SAR ... + CopyBuffer( + mHandler, + X_ATRSL_SAR_LINE, + 0, + mNumberOfItemsReadPerTick, + sarBuffer); + + // + // RMA ... + CopyBuffer( + mHandler, + X_ATRSL_RMA_LINE, + 0, + mNumberOfItemsReadPerTick, + rmaBuffer); + + // + // WMA ... + CopyBuffer( + mHandler, + X_ATRSL_WMA_LINE, + 0, + mNumberOfItemsReadPerTick, + wmaBuffer); + + // + // MA1 ... + CopyBuffer( + mHandler, + X_ATRSL_MA1_LINE, + 0, + mNumberOfItemsReadPerTick, + ma1Buffer); + + // + // MA 1 ... + CopyBuffer( + mHandler, + X_ATRSL_SMA_LINE, + 0, + mNumberOfItemsReadPerTick, + smaBuffer); + + // + // EMA ... + CopyBuffer( + mHandler, + X_ATRSL_EMA_LINE, + 0, + mNumberOfItemsReadPerTick, + emaBuffer); + + // + // ATR ... + CopyBuffer( + mHandler, + X_ATRSL_ATR_LINE, + 0, + mNumberOfItemsReadPerTick, + atrBuffer); + } + + // + // START Tools Functions ... + // + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + // MARKET ... + + // + // Length ... + int mLength; + + // + // Increment Step ... + double mStep; + + // + // Maximum ... + double mMaximum; + + // + // High Line Applied To ... + ENUM_APPLIED_PRICE mHighAppliedTo; + + // + // Low Line Applied To ... + ENUM_APPLIED_PRICE mLowAppliedTo; + + // + string mTag; + + // + int mHandler; +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xhk.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xhk.helper.mq5 new file mode 100644 index 0000000..acd7b21 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xhk.helper.mq5 @@ -0,0 +1,215 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XHikenAshi Indicator Provider +// Description: Provides Features ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XHikenAshi Exported Buffers ... +enum ENUM_X_HIKENASHI_BUFFERS +{ + // + X_HK_OPEN_LINE = 0, + X_HK_HIGH_LINE = 1, + X_HK_LOW_LINE = 2, + X_HK_CLOSE_LINE = 3, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXHKHelper +{ + // +public: + // + // Properties ... + double openBuffer[]; + double highBuffer[]; + double lowBuffer[]; + double closeBuffer[]; + + // + // Constructor ... + void XSCXHKHelper() { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXHKHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52 + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + mTag = "XHK " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xhk", + // + // Inputs ... + "", + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + ArraySetAsSeries(openBuffer, true); + ArraySetAsSeries(highBuffer, true); + ArraySetAsSeries(lowBuffer, true); + ArraySetAsSeries(closeBuffer, true); + } + + // + // DeConstructor ... + void ~XSCXHKHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // OPEN ... + CopyBuffer( + mHandler, + X_HK_OPEN_LINE, + 0, + mNumberOfItemsReadPerTick, + openBuffer); + + // + // HIGH ... + CopyBuffer( + mHandler, + X_HK_HIGH_LINE, + 0, + mNumberOfItemsReadPerTick, + highBuffer); + + // + // LOW ... + CopyBuffer( + mHandler, + X_HK_LOW_LINE, + 0, + mNumberOfItemsReadPerTick, + lowBuffer); + + // + // CLOSE ... + CopyBuffer( + mHandler, + X_HK_CLOSE_LINE, + 0, + mNumberOfItemsReadPerTick, + closeBuffer); + } + + // + // START Tools Functions ... + // + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + string mTag; + + // + int mHandler; +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xich.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xich.helper.mq5 new file mode 100644 index 0000000..d67b1d0 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xich.helper.mq5 @@ -0,0 +1,690 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XIchimoku Indicator Provider +// Description: Provides Features ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// Ichimoku Indicator Exported Buffers ... +enum ENUM_X_ICHIMOKU_BUFFERS +{ + // + X_TENKANSEN_LINE = 0, + X_KIJUNSEN_LINE = 1, + X_CHIKOUSPAN_LINE = 4, + X_SENKOUSPAN_A_LINE = 5, + X_SENKOUSPAN_B_LINE = 6, +}; + +// +// Model Ichimoku Data ... +struct XIchiInfo +{ + // + int bar; + + // + double tenkanSen; + double kijunSen; + + // + double senkouSpanA; + double senkouSpanB; + + // + double senkouSpanAFuture; + double senkouSpanBFuture; +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXICHHelper +{ + // + // Public ... +public: + // + // Properties ... + double tenkanSenBuffer[]; + double kijunSenBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; + + // + // Constructor ... + void XSCXICHHelper() + { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXICHHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // TenkanSen ... + int tenkanSenLength = 9, + ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE, + // + // KijunSen ... + int kijunSenLength = 26, + ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE, + // + // Senkou Span B ... + int senkouSpanBLength = 52, + ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE, + // + // Chikou Span ... + ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // TenkanSen ... + mKijunSenMode = kijunSenMode; + mKijunSenLength = kijunSenLength; + + // + // KijunSen ... + mTenkanSenMode = tenkanSenMode; + mTenkanSenLength = tenkanSenLength; + + // + // Senkou Span B ... + mSenkouSpanBMode = senkouSpanBMode; + mSenkouSpanBLength = senkouSpanBLength; + + // + mSenkouSpanBTopMode = NULL; + mSenkouSpanBBottomMode = NULL; + + // + // Chikou Span ... + mChikuoSpanAppliedTo = chikuoSpanAppliedTo; + + // + mTag = "XICH " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xich", + // + // Inputs ... + // + // TENKANSEN ... + "", + mTenkanSenLength, + mTenkanSenMode, + // + // KIJUNSEN ... + "", + kijunSenLength, + kijunSenMode, + // + // SENKOUSPANB ... + "", + senkouSpanBLength, + senkouSpanBMode, + // + // CHIKOUSPAN ... + "", + mChikuoSpanAppliedTo, + // + // PRESENTATION ... + "", + false, + false, + false, + false, + false, + false, + false, + false, + true // Shift Kumo ... + // + ); + if (mHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + ArraySetAsSeries(tenkanSenBuffer, true); + ArraySetAsSeries(kijunSenBuffer, true); + ArraySetAsSeries(chikouSpanBuffer, true); + ArraySetAsSeries(senkouSpanABuffer, true); + ArraySetAsSeries(senkouSpanBBuffer, true); + } + + // + // DeConstructor ... + void ~XSCXICHHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // TENKANSEN ... + CopyBuffer( + mHandler, + X_TENKANSEN_LINE, + 0, + mNumberOfItemsReadPerTick, + tenkanSenBuffer); + + // + // KIJUNSEN ... + CopyBuffer( + mHandler, + X_KIJUNSEN_LINE, + 0, + mNumberOfItemsReadPerTick, + kijunSenBuffer); + + // + // CHIKOUSPAN ... + CopyBuffer( + mHandler, + X_CHIKOUSPAN_LINE, + mKijunSenLength - 1, + mNumberOfItemsReadPerTick, + chikouSpanBuffer); + + // + // SENKOUSPANA ... + CopyBuffer( + mHandler, + X_SENKOUSPAN_A_LINE, + -mKijunSenLength + 1, + mNumberOfItemsReadPerTick, + senkouSpanABuffer); + + // + // SENKOUSPANB ... + CopyBuffer( + mHandler, + X_SENKOUSPAN_B_LINE, + -mKijunSenLength + 1, + mNumberOfItemsReadPerTick, + senkouSpanBBuffer); + } + + // + // START Tools Functions ... + // + + // + // Retrieve Ichimoku Data at Specific Bar Index ... + XIchiInfo GetInfo( + int bar_index // Bar Index ... + ) + { + // + XIchiInfo result = {}; + + // + result.bar = bar_index; + result.tenkanSen = tenkanSenBuffer[bar_index]; + result.kijunSen = kijunSenBuffer[bar_index]; + result.senkouSpanA = senkouSpanABuffer[bar_index + mKijunSenLength]; + result.senkouSpanB = senkouSpanBBuffer[bar_index + mKijunSenLength]; + result.senkouSpanAFuture = senkouSpanABuffer[bar_index]; + result.senkouSpanBFuture = senkouSpanBBuffer[bar_index]; + + // + return result; + } + + // + // Check Tenkan Sen Over Kijun Sen ... + bool IsTenkanSenOverKijunSen( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + tenkanSenBuffer[bar_index] > kijunSenBuffer[bar_index] + // + ; + + // + return result; + } + + // + // Is Tenkan Sen Under Kijun Sen ... + bool IsTenkanSenUnderKijunSen( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + tenkanSenBuffer[bar_index] < kijunSenBuffer[bar_index] + // + ; + + // + return result; + } + + // + // Tenkan Sen Croosed Over Kijun Sen ... + bool IsTenkanSenCrossedOverKijunSen( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 2)) + { + return result; + } + + // + result = IsCrossOver( + tenkanSenBuffer, + kijunSenBuffer, + bar_index); + + // + return result; + } + + // + // Tenkan Sen Croosed Under Kijun Sen ... + bool IsTenkanSenCrossedUnderKijunSen( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 2)) + { + return result; + } + + // + result = IsCrossUnder( + tenkanSenBuffer, + kijunSenBuffer, + bar_index); + + // + return result; + } + + // + // Check Kumo is Bullish ... + bool IsKumoBullish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... + ) + { + // + bool result = false; + + // + int start = 0; + + // + if (!onFuture) + { + start = (mKijunSenLength - bar_index); + } + else + { + start = (mKijunSenLength - bar_index) * 2; + } + + // + if (!IsValidArraySize(start)) + { + return result; + } + + // + result = + // + senkouSpanABuffer[start + 1] > senkouSpanBBuffer[start + 1] && + senkouSpanABuffer[start] > senkouSpanBBuffer[start] + // + ; + + // + return result; + } + + // + // Check Kumo is Bearish ... + bool IsKumoBearish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... + ) + { + // + bool result = false; + + // + int start = 0; + + // + if (!onFuture) + { + start = (mKijunSenLength - bar_index); + } + else + { + start = (mKijunSenLength - bar_index) * 2; + } + + // + if (!IsValidArraySize(start)) + { + return result; + } + + // + result = + // + senkouSpanABuffer[start + 1] < senkouSpanBBuffer[start + 1] && + senkouSpanABuffer[start] < senkouSpanBBuffer[start] + // + ; + + // + return result; + } + + // + // Check Kumo is Change to Bullish ... + bool IsKumoSwitchedToBullish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... + ) + { + // + bool result = false; + + // + int start = 0; + + // + if (!onFuture) + { + start = (mKijunSenLength - bar_index); + } + else + { + start = (mKijunSenLength - bar_index) * 2; + } + + // + if (!IsValidArraySize(start)) + { + return result; + } + + // + result = + // + senkouSpanABuffer[start + 1] > senkouSpanBBuffer[start + 1] && + senkouSpanABuffer[start] <= senkouSpanBBuffer[start] + // + ; + + // + return result; + } + + // + // Check Kumo is Change to Bearish ... + bool IsKumoSwitchedToBearish( + int bar_index, // Bar Index ... + bool onFuture = false // Future Check ... + ) + { + // + bool result = false; + + // + int start = 0; + + // + if (!onFuture) + { + start = (mKijunSenLength - bar_index); + } + else + { + start = (mKijunSenLength - bar_index) * 2; + } + + // + if (!IsValidArraySize(start)) + { + return result; + } + + // + result = + // + senkouSpanABuffer[start + 1] < senkouSpanBBuffer[start + 1] && + senkouSpanABuffer[start] >= senkouSpanBBuffer[start] + // + ; + + // + return result; + } + + // + // Check Ichimokou Common Conditions for Long Trades ... + // TenkanSen > Kumo + // KijunSen > Kumo + // ChikouSpan > Kumo + // Kumo has Good Body + bool CheckCommonLongConditions() { + // + bool result = false; + + // + // TODO: Complete this ... + + // + return result; + } + + // + // Check Ichimoku Common Conditions for Short Trades ... + // TenkanSen < Kumo + // KijunSen < Kumo + // ChikouSpan < Kumo + // Kumo has Good Body + bool CheckCommonShortConditions() { + // + bool result = false; + + // + // TODO: Complete this ... + + // + return result; + } + + // + // END Tools Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + // TenkanSen ... + int mTenkanSenLength; + ENUM_X_ICHIMOKU_CALCULATION_MODE mTenkanSenMode; + + // + // KijunSen ... + int mKijunSenLength; + ENUM_X_ICHIMOKU_CALCULATION_MODE mKijunSenMode; + + // + // Senkou Span B ... + int mSenkouSpanBLength; + ENUM_X_ICHIMOKU_CALCULATION_MODE mSenkouSpanBMode; + + // + ENUM_SERIESMODE mSenkouSpanBTopMode; + ENUM_SERIESMODE mSenkouSpanBBottomMode; + + // + // Chikou Span ... + ENUM_APPLIED_PRICE mChikuoSpanAppliedTo; + + // + string mTag; + + // + int mHandler; + + // + bool IsValidArraySize(int bar_index) + { + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(tenkanSenBuffer); + result = rCount > bar_index + 1; + + // + return result; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xmc.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xmc.helper.mq5 new file mode 100644 index 0000000..42dfaba --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xmc.helper.mq5 @@ -0,0 +1,418 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XMC Indicator Provider +// Description: Provides Features ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XMC Exported Buffers ... +enum ENUM_X_XMC_BUFFERS +{ + // + X_MC_FAST_LINE = 0, + X_MC_SLOW_LINE = 1, + X_MC_VERIFIER_LINE = 2, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXMCHelper +{ + // +public: + // + // Properties ... + double fastBuffer[]; + double slowBuffer[]; + double verifierBuffer[]; + + // + // Constructor ... + void XSCXMCHelper() { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXMCHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // FAST ... + int fastMaLength = 9, + int fastMaShift = 0, + ENUM_MA_METHOD fastMaMethod = MODE_EMA, + ENUM_APPLIED_PRICE fastMaAppliedTo = PRICE_CLOSE, + // + // SLOW ... + int slowMaLength = 18, + int slowMaShift = 0, + ENUM_MA_METHOD slowMaMethod = MODE_EMA, + ENUM_APPLIED_PRICE slowMaAppliedTo = PRICE_CLOSE, + // + // VERIFIER ... + int verifierMaLength = 50, + int verifierMaShift = 0, + ENUM_MA_METHOD verifierMaMethod = MODE_EMA, + ENUM_APPLIED_PRICE verifierMaAppliedTo = PRICE_CLOSE + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // FAST ... + mFastMaLength = fastMaLength; + mFastMaShift = fastMaShift; + mFastMaMethod = fastMaMethod; + mFastMaAppliedTo = fastMaAppliedTo; + + // + // SLOW ... + mSlowMaLength = slowMaLength; + mSlowMaShift = slowMaShift; + mSlowMaMethod = slowMaMethod; + mSlowMaAppliedTo = slowMaAppliedTo; + + // + // VERIFIER ... + mVerifierMaLength = verifierMaLength; + mVerifierMaShift = verifierMaShift; + mVerifierMaMethod = verifierMaMethod; + mVerifierMaAppliedTo = verifierMaAppliedTo; + + // + mTag = "XMC " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xmc", + // + // Inputs ... + // + // FAST ... + "", + mFastMaLength, + mFastMaShift, + mFastMaMethod, + mFastMaAppliedTo, + // + // SLOW ... + "", + mSlowMaLength, + mSlowMaShift, + mSlowMaMethod, + mSlowMaAppliedTo, + // + // VERIFIER ... + "", + mVerifierMaLength, + mVerifierMaShift, + mVerifierMaMethod, + mVerifierMaAppliedTo, + // + "", + false, + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(verifierBuffer, true); + } + + // + // DeConstructor ... + void ~XSCXMCHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // FAST ... + CopyBuffer( + mHandler, + X_MC_FAST_LINE, + 0, + mNumberOfItemsReadPerTick, + fastBuffer); + + // + // SLOW ... + CopyBuffer( + mHandler, + X_MC_SLOW_LINE, + 0, + mNumberOfItemsReadPerTick, + slowBuffer); + + // + // VERIFIER ... + CopyBuffer( + mHandler, + X_MC_VERIFIER_LINE, + 0, + mNumberOfItemsReadPerTick, + verifierBuffer); + } + + // + // START Tools Functions ... + // + + // + // Check Fast Over Slow ... + bool IsFastOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsOver( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Over Slow ... + bool IsFastCrossedOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossOver( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Under Slow ... + bool IsFastUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsUnder( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Under Slow ... + bool IsFastCrossedUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossUnder( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + // FAST ... + int mFastMaLength; + int mFastMaShift; + ENUM_MA_METHOD mFastMaMethod; + ENUM_APPLIED_PRICE mFastMaAppliedTo; + + // + // SLOW ... + int mSlowMaLength; + int mSlowMaShift; + ENUM_MA_METHOD mSlowMaMethod; + ENUM_APPLIED_PRICE mSlowMaAppliedTo; + + // + // VERIFIER ... + int mVerifierMaLength; + int mVerifierMaShift; + ENUM_MA_METHOD mVerifierMaMethod; + ENUM_APPLIED_PRICE mVerifierMaAppliedTo; + + // + string mTag; + + // + int mHandler; + + // + bool IsValidArraySize(int bar_index) + { + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(fastBuffer); + result = rCount > bar_index + 1; + + // + return result; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xmrb.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xmrb.helper.mq5 new file mode 100644 index 0000000..2d85cdd --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xmrb.helper.mq5 @@ -0,0 +1,1102 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XMRB Indicator Provider +// Description: MA Ribbons ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XMRB Exported Buffers ... +enum ENUM_X_XMRB_BUFFERS +{ + // + X_MRB_FAST_LINE = 0, + X_MRB_SLOW_LINE = 1, + + // + X_MRB_FAST_1_LINE = 2, + X_MRB_FAST_2_LINE = 3, + X_MRB_FAST_3_LINE = 4, + X_MRB_FAST_4_LINE = 5, + X_MRB_FAST_5_LINE = 6, + + // + X_MRB_SLOW_1_LINE = 7, + X_MRB_SLOW_2_LINE = 8, + X_MRB_SLOW_3_LINE = 9, + X_MRB_SLOW_4_LINE = 10, + X_MRB_SLOW_5_LINE = 11, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXMRBHelper +{ + // +public: + // + // Properties ... + double fastBuffer[]; + double slowBuffer[]; + + // + double fast1Buffer[]; + double fast2Buffer[]; + double fast3Buffer[]; + double fast4Buffer[]; + double fast5Buffer[]; + + // + double slow1Buffer[]; + double slow2Buffer[]; + double slow3Buffer[]; + double slow4Buffer[]; + double slow5Buffer[]; + + // + // Constructor ... + void XSCXMRBHelper() { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXMRBHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // RIBBONS ... + // + int fast1Length = 3, + int slow1Length = 5, + // + int fast2Length = 8, + int slow2Length = 13, + // + int fast3Length = 21, + int slow3Length = 34, + // + int fast4Length = 55, + int slow4Length = 89, + // + int fast5Length = 144, + int slow5Length = 233, + // + // CALCULATION ... + ENUM_MA_METHOD ribbonMode = MODE_EMA, + ENUM_APPLIED_PRICE ribbonAppliedTo = PRICE_CLOSE + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // RIBBONS ... + // + mFast1Length = fast1Length; + mSlow1Length = slow1Length; + // + mFast2Length = fast2Length; + mSlow2Length = slow2Length; + // + mFast3Length = fast3Length; + mSlow3Length = slow3Length; + // + mFast4Length = fast4Length; + mSlow4Length = slow4Length; + // + mFast5Length = fast5Length; + mSlow5Length = slow5Length; + // + // CALCULATION ... + mRibbonMode = ribbonMode; + mRibbonAppliedTo = ribbonAppliedTo; + + // + mTag = "XMRB " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xmrb", + // + // Inputs ... + // + "", + mFast1Length, + mSlow1Length, + // + "", + mFast2Length, + mSlow2Length, + // + "", + mFast3Length, + mSlow3Length, + // + "", + mFast4Length, + mSlow4Length, + // + "", + mFast5Length, + mSlow5Length, + // + "", + mRibbonMode, + mRibbonAppliedTo, + // + "", + false, + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(slowBuffer, true); + + // + ArraySetAsSeries(fast1Buffer, true); + ArraySetAsSeries(fast2Buffer, true); + ArraySetAsSeries(fast3Buffer, true); + ArraySetAsSeries(fast4Buffer, true); + ArraySetAsSeries(fast5Buffer, true); + + // + ArraySetAsSeries(slow1Buffer, true); + ArraySetAsSeries(slow2Buffer, true); + ArraySetAsSeries(slow3Buffer, true); + ArraySetAsSeries(slow4Buffer, true); + ArraySetAsSeries(slow5Buffer, true); + } + + // + // DeConstructor ... + void ~XSCXMRBHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // FAST ... + CopyBuffer( + mHandler, + X_MRB_FAST_LINE, + 0, + mNumberOfItemsReadPerTick, + fastBuffer); + + CopyBuffer( + mHandler, + X_MRB_FAST_1_LINE, + 0, + mNumberOfItemsReadPerTick, + fast1Buffer); + + CopyBuffer( + mHandler, + X_MRB_FAST_2_LINE, + 0, + mNumberOfItemsReadPerTick, + fast2Buffer); + + CopyBuffer( + mHandler, + X_MRB_FAST_3_LINE, + 0, + mNumberOfItemsReadPerTick, + fast3Buffer); + + CopyBuffer( + mHandler, + X_MRB_FAST_4_LINE, + 0, + mNumberOfItemsReadPerTick, + fast4Buffer); + + CopyBuffer( + mHandler, + X_MRB_FAST_5_LINE, + 0, + mNumberOfItemsReadPerTick, + fast5Buffer); + + // + // SLOW ... + CopyBuffer( + mHandler, + X_MRB_SLOW_LINE, + 0, + mNumberOfItemsReadPerTick, + slowBuffer); + + CopyBuffer( + mHandler, + X_MRB_SLOW_1_LINE, + 0, + mNumberOfItemsReadPerTick, + slow1Buffer); + + CopyBuffer( + mHandler, + X_MRB_SLOW_2_LINE, + 0, + mNumberOfItemsReadPerTick, + slow2Buffer); + + CopyBuffer( + mHandler, + X_MRB_SLOW_3_LINE, + 0, + mNumberOfItemsReadPerTick, + slow3Buffer); + + CopyBuffer( + mHandler, + X_MRB_SLOW_4_LINE, + 0, + mNumberOfItemsReadPerTick, + slow4Buffer); + + CopyBuffer( + mHandler, + X_MRB_SLOW_5_LINE, + 0, + mNumberOfItemsReadPerTick, + slow5Buffer); + } + + // + // START Tools Functions ... + // + + // + // Check Fast Over Slow ... + bool IsFastOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsOver( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Over Slow ... + bool IsFastCrossedOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossOver( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Under Slow ... + bool IsFastUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsUnder( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Under Slow ... + bool IsFastCrossedUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossUnder( + fastBuffer, + slowBuffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // RIBBON 1 ... + + // + // Check Fast Over Slow ... + bool IsR1FastOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsOver( + fast1Buffer, + slow1Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Over Slow ... + bool IsR1FastCrossedOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossOver( + fast1Buffer, + slow1Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Under Slow ... + bool IsR1FastUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsUnder( + fast1Buffer, + slow1Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Under Slow ... + bool IsR1FastCrossedUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossUnder( + fast1Buffer, + slow1Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // RIBBON 2 ... + + // + // Check Fast Over Slow ... + bool IsR2FastOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsOver( + fast2Buffer, + slow2Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Over Slow ... + bool IsR2FastCrossedOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossOver( + fast2Buffer, + slow2Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Under Slow ... + bool IsR2FastUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsUnder( + fast2Buffer, + slow2Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Under Slow ... + bool IsR2FastCrossedUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossUnder( + fast2Buffer, + slow2Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // RIBBON 3 ... + + // + // Check Fast Over Slow ... + bool IsR3FastOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsOver( + fast3Buffer, + slow3Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Over Slow ... + bool IsR3FastCrossedOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossOver( + fast3Buffer, + slow3Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Under Slow ... + bool IsR3FastUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsUnder( + fast3Buffer, + slow3Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Under Slow ... + bool IsR3FastCrossedUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossUnder( + fast3Buffer, + slow3Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // RIBBON 4 ... + + // + // Check Fast Over Slow ... + bool IsR4FastOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsOver( + fast4Buffer, + slow4Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Over Slow ... + bool IsR4FastCrossedOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossOver( + fast4Buffer, + slow4Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Under Slow ... + bool IsR4FastUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsUnder( + fast4Buffer, + slow4Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Under Slow ... + bool IsR4FastCrossedUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossUnder( + fast4Buffer, + slow4Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // RIBBON 5 ... + + // + // Check Fast Over Slow ... + bool IsR5FastOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsOver( + fast5Buffer, + slow5Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Over Slow ... + bool IsR5FastCrossedOverSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossOver( + fast5Buffer, + slow5Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Under Slow ... + bool IsR5FastUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsUnder( + fast5Buffer, + slow5Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // Check Fast Crossed Under Slow ... + bool IsR5FastCrossedUnderSlow( + int bar_index // Bar Index ... + ) { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) { + return result; + } + + // + result = + // + IsCrossUnder( + fast5Buffer, + slow5Buffer, + bar_index + ) + // + ; + + // + return result; + } + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + // RIBBONS ... + // + int mFast1Length; + int mSlow1Length; + // + int mFast2Length; + int mSlow2Length; + // + int mFast3Length; + int mSlow3Length; + // + int mFast4Length; + int mSlow4Length; + // + int mFast5Length; + int mSlow5Length; + + // + // CALCULATION ... + ENUM_MA_METHOD mRibbonMode; + ENUM_APPLIED_PRICE mRibbonAppliedTo; + + // + string mTag; + + // + int mHandler; + + // + bool IsValidArraySize(int bar_index) + { + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(fastBuffer); + result = rCount > bar_index + 1; + + // + return result; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xppsr.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xppsr.helper.mq5 new file mode 100644 index 0000000..2b80595 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xppsr.helper.mq5 @@ -0,0 +1,575 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XPPSR Indicator Provider +// Description: Provides Features ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// XPPSR Exported Buffers ... +enum ENUM_X_XPPSR_BUFFERS +{ + // + // LEVEL 1 ... + X_PPSR_L1_R_LINE = 0, + X_PPSR_L1_R1_LINE = 1, + X_PPSR_L1_R2_LINE = 2, + X_PPSR_L1_S_LINE = 3, + X_PPSR_L1_S1_LINE = 4, + X_PPSR_L1_S2_LINE = 5, + // + // LEVEL 2 ... + X_PPSR_L2_R_LINE = 6, + X_PPSR_L2_R1_LINE = 7, + X_PPSR_L2_R2_LINE = 8, + X_PPSR_L2_S_LINE = 9, + X_PPSR_L2_S1_LINE = 10, + X_PPSR_L2_S2_LINE = 11, + // + // LEVEL 3 ... + X_PPSR_L3_R_LINE = 12, + X_PPSR_L3_R1_LINE = 13, + X_PPSR_L3_R2_LINE = 14, + X_PPSR_L3_S_LINE = 15, + X_PPSR_L3_S1_LINE = 16, + X_PPSR_L3_S2_LINE = 17, + // + // LEVEL 4 ... + X_PPSR_L4_R_LINE = 18, + X_PPSR_L4_R1_LINE = 19, + X_PPSR_L4_R2_LINE = 20, + X_PPSR_L4_S_LINE = 21, + X_PPSR_L4_S1_LINE = 22, + X_PPSR_L4_S2_LINE = 23, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXPPSRHelper +{ + // +public: + // + // Properties ... + + // + // LEVEL 1 ... + double l1RBuffer[]; + double l1R1Buffer[]; + double l1R2Buffer[]; + double l1SBuffer[]; + double l1S1Buffer[]; + double l1S2Buffer[]; + + // + // LEVEL 2 ... + double l2RBuffer[]; + double l2R1Buffer[]; + double l2R2Buffer[]; + double l2SBuffer[]; + double l2S1Buffer[]; + double l2S2Buffer[]; + + // + // LEVEL 3 ... + double l3RBuffer[]; + double l3R1Buffer[]; + double l3R2Buffer[]; + double l3SBuffer[]; + double l3S1Buffer[]; + double l3S2Buffer[]; + + // + // LEVEL 4 ... + double l4RBuffer[]; + double l4R1Buffer[]; + double l4R2Buffer[]; + double l4SBuffer[]; + double l4S1Buffer[]; + double l4S2Buffer[]; + + // + // Constructor ... + void XSCXPPSRHelper() + { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXPPSRHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // LEVEL 1 ... + ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO, + ENUM_TIMEFRAMES l1Period = NULL, + ENUM_SERIESMODE l1HHMode = MODE_HIGH, + ENUM_SERIESMODE l1LLMode = MODE_LOW, + // + // LEVEL 2 ... + ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO, + ENUM_TIMEFRAMES l2Period = NULL, + ENUM_SERIESMODE l2HHMode = MODE_HIGH, + ENUM_SERIESMODE l2LLMode = MODE_LOW, + // + // LEVEL 3 ... + ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO, + ENUM_TIMEFRAMES l3Period = NULL, + ENUM_SERIESMODE l3HHMode = MODE_HIGH, + ENUM_SERIESMODE l3LLMode = MODE_LOW, + // + // LEVEL 4 ... + ENUM_X_PERIOD_METHOD l4Method = X_PERIOD_AUTO, + ENUM_TIMEFRAMES l4Period = NULL, + ENUM_SERIESMODE l4HHMode = MODE_HIGH, + ENUM_SERIESMODE l4LLMode = MODE_LOW + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // LEVEL 1 ... + mL1Method = l1Method; + mL1Period = l1Period; + mL1HHMode = l1HHMode; + mL1LLMode = l1LLMode; + + // + // LEVEL 2 ... + mL2Method = l2Method; + mL2Period = l2Period; + mL2HHMode = l2HHMode; + mL2LLMode = l2LLMode; + + // + // LEVEL 3 ... + mL3Method = l3Method; + mL3Period = l3Period; + mL3HHMode = l3HHMode; + mL3LLMode = l3LLMode; + + // + // LEVEL 4 ... + mL4Method = l4Method; + mL4Period = l4Period; + mL4HHMode = l4HHMode; + mL4LLMode = l4LLMode; + + // + mTag = "XPPSR " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xppsr", + // + // Inputs ... + // + // LEVEL 1 ... + "", + mL1Method, + mL1Period, + mL1HHMode, + mL1LLMode, + // + // LEVEL 2 ... + "", + mL2Method, + mL2Period, + mL2HHMode, + mL2LLMode, + // + // LEVEL 3 ... + "", + mL3Method, + mL3Period, + mL3HHMode, + mL3LLMode, + // + // LEVEL 4 ... + "", + mL4Method, + mL4Period, + mL4HHMode, + mL4LLMode, + // + "", + "", + false, + false, + false, + false, + "", + false, + false, + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + // LEVEL 1 ... + ArraySetAsSeries(l1RBuffer, true); + ArraySetAsSeries(l1R1Buffer, true); + ArraySetAsSeries(l1R2Buffer, true); + ArraySetAsSeries(l1SBuffer, true); + ArraySetAsSeries(l1S1Buffer, true); + ArraySetAsSeries(l1S2Buffer, true); + + // + // LEVEL 2 ... + ArraySetAsSeries(l2RBuffer, true); + ArraySetAsSeries(l2R1Buffer, true); + ArraySetAsSeries(l2R2Buffer, true); + ArraySetAsSeries(l2SBuffer, true); + ArraySetAsSeries(l2S1Buffer, true); + ArraySetAsSeries(l2S2Buffer, true); + + // + // LEVEL 3 ... + ArraySetAsSeries(l3RBuffer, true); + ArraySetAsSeries(l3R1Buffer, true); + ArraySetAsSeries(l3R2Buffer, true); + ArraySetAsSeries(l3SBuffer, true); + ArraySetAsSeries(l3S1Buffer, true); + ArraySetAsSeries(l3S2Buffer, true); + + // + // LEVEL 4 ... + ArraySetAsSeries(l4RBuffer, true); + ArraySetAsSeries(l4R1Buffer, true); + ArraySetAsSeries(l4R2Buffer, true); + ArraySetAsSeries(l4SBuffer, true); + ArraySetAsSeries(l4S1Buffer, true); + ArraySetAsSeries(l4S2Buffer, true); + } + + // + // DeConstructor ... + void ~XSCXPPSRHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // LEVEL 1 ... + CopyBuffer( + mHandler, + X_PPSR_L1_R_LINE, + 0, + mNumberOfItemsReadPerTick, + l1RBuffer); + CopyBuffer( + mHandler, + X_PPSR_L1_R1_LINE, + 0, + mNumberOfItemsReadPerTick, + l1R1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L1_R2_LINE, + 0, + mNumberOfItemsReadPerTick, + l1R2Buffer); + CopyBuffer( + mHandler, + X_PPSR_L1_S_LINE, + 0, + mNumberOfItemsReadPerTick, + l1SBuffer); + CopyBuffer( + mHandler, + X_PPSR_L1_S1_LINE, + 0, + mNumberOfItemsReadPerTick, + l1S1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L1_S2_LINE, + 0, + mNumberOfItemsReadPerTick, + l1S2Buffer); + + // + // LEVEL 2 ... + CopyBuffer( + mHandler, + X_PPSR_L2_R_LINE, + 0, + mNumberOfItemsReadPerTick, + l2RBuffer); + CopyBuffer( + mHandler, + X_PPSR_L2_R1_LINE, + 0, + mNumberOfItemsReadPerTick, + l2R1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L2_R2_LINE, + 0, + mNumberOfItemsReadPerTick, + l2R2Buffer); + CopyBuffer( + mHandler, + X_PPSR_L2_S_LINE, + 0, + mNumberOfItemsReadPerTick, + l2SBuffer); + CopyBuffer( + mHandler, + X_PPSR_L2_S1_LINE, + 0, + mNumberOfItemsReadPerTick, + l2S1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L2_S2_LINE, + 0, + mNumberOfItemsReadPerTick, + l2S2Buffer); + + // + // LEVEL 3 ... + CopyBuffer( + mHandler, + X_PPSR_L3_R_LINE, + 0, + mNumberOfItemsReadPerTick, + l3RBuffer); + CopyBuffer( + mHandler, + X_PPSR_L3_R1_LINE, + 0, + mNumberOfItemsReadPerTick, + l3R1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L3_R2_LINE, + 0, + mNumberOfItemsReadPerTick, + l3R2Buffer); + CopyBuffer( + mHandler, + X_PPSR_L3_S_LINE, + 0, + mNumberOfItemsReadPerTick, + l3SBuffer); + CopyBuffer( + mHandler, + X_PPSR_L3_S1_LINE, + 0, + mNumberOfItemsReadPerTick, + l3S1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L3_S2_LINE, + 0, + mNumberOfItemsReadPerTick, + l3S2Buffer); + + // + // LEVEL 4 ... + CopyBuffer( + mHandler, + X_PPSR_L4_R_LINE, + 0, + mNumberOfItemsReadPerTick, + l4RBuffer); + CopyBuffer( + mHandler, + X_PPSR_L4_R1_LINE, + 0, + mNumberOfItemsReadPerTick, + l4R1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L4_R2_LINE, + 0, + mNumberOfItemsReadPerTick, + l4R2Buffer); + CopyBuffer( + mHandler, + X_PPSR_L4_S_LINE, + 0, + mNumberOfItemsReadPerTick, + l4SBuffer); + CopyBuffer( + mHandler, + X_PPSR_L4_S1_LINE, + 0, + mNumberOfItemsReadPerTick, + l4S1Buffer); + CopyBuffer( + mHandler, + X_PPSR_L4_S2_LINE, + 0, + mNumberOfItemsReadPerTick, + l4S2Buffer); + } + + // + // START Tools Functions ... + // + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + // LEVEL 1 ... + ENUM_X_PERIOD_METHOD mL1Method; + ENUM_TIMEFRAMES mL1Period; + ENUM_SERIESMODE mL1HHMode; + ENUM_SERIESMODE mL1LLMode; + + // + // LEVEL 2 ... + ENUM_X_PERIOD_METHOD mL2Method; + ENUM_TIMEFRAMES mL2Period; + ENUM_SERIESMODE mL2HHMode; + ENUM_SERIESMODE mL2LLMode; + + // + // LEVEL 3 ... + ENUM_X_PERIOD_METHOD mL3Method; + ENUM_TIMEFRAMES mL3Period; + ENUM_SERIESMODE mL3HHMode; + ENUM_SERIESMODE mL3LLMode; + + // + // LEVEL 4 ... + ENUM_X_PERIOD_METHOD mL4Method; + ENUM_TIMEFRAMES mL4Period; + ENUM_SERIESMODE mL4HHMode; + ENUM_SERIESMODE mL4LLMode; + + // + string mTag; + + // + int mHandler; + + // + bool IsValidArraySize(int bar_index) + { + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(l1RBuffer); + result = rCount > bar_index + 1; + + // + return result; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xpv.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xpv.helper.mq5 new file mode 100644 index 0000000..d71d3da --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xpv.helper.mq5 @@ -0,0 +1,707 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XPV Indicator Provider +// Description: Peaks and Vales ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XPeaksAndVales Exported Buffers ... +enum ENUM_X_XPV_BUFFERS +{ + // + // PEAKSANDVALES ... + X_PV_P_LINE = 0, + X_PV_V_LINE = 1, + // + // SUPPORTRESISTANCE ... + X_PV_R_LINE = 2, + X_PV_S_LINE = 4, + // + // SHORT ... + X_PV_SHH_LINE = 6, + X_PV_SLL_LINE = 7, + // + // MEDIUM ... + X_PV_MHH_LINE = 8, + X_PV_MLL_LINE = 9, + // + // LONG ... + X_PV_LHH_LINE = 10, + X_PV_LLL_LINE = 11, + // + // HIND ... + X_PV_HHH_LINE = 12, + X_PV_HLL_LINE = 13, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXPVHelper +{ + // +public: + // + // Properties ... + double pBuffer[]; + double vBuffer[]; + double rBuffer[]; + double sBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + + // + // Constructor ... + void XSCXPVHelper() + { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXPVHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // MARKET ... + int shortLength = 9, + int mediumLength = 17, + int longLength = 26, + int hindLength = 35, + // + // TREND ... + int numOfShoulder = 10, + // + // DETECTION ... + ENUM_SERIESMODE hhMode = MODE_HIGH, + ENUM_SERIESMODE llMode = MODE_LOW + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // MARKET ... + mShortLength = shortLength; + mMediumLength = mediumLength; + mLongLength = longLength; + mHindLength = hindLength; + + // + // TREND ... + mNumOfShoulder = numOfShoulder; + + // + // DETECTION ... + mHhMode = hhMode; + mLlMode = llMode; + + // + mTag = "XPV " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xpv", + // + // Inputs ... + // + // MARKET ... + "", + mShortLength, + mMediumLength, + mLongLength, + mHindLength, + // + // TREND ... + "", + mNumOfShoulder, + // + // DETECTION ... + "", + mHhMode, + mLlMode, + // + "", + false, + false, + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + // PEAKSANDVALES ... + ArraySetAsSeries(pBuffer, true); + ArraySetAsSeries(vBuffer, true); + // + // RESISTANCESUPPORT ... + ArraySetAsSeries(rBuffer, true); + ArraySetAsSeries(sBuffer, true); + // + // SHORT ... + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + // + // MEDIUM ... + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + // + // LONG ... + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + // + // HIND ... + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + } + + // + // DeConstructor ... + void ~XSCXPVHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // PEAKS ... + CopyBuffer( + mHandler, + X_PV_P_LINE, + 0, + mNumberOfItemsReadPerTick, + pBuffer); + + // + // VALES ... + CopyBuffer( + mHandler, + X_PV_V_LINE, + 0, + mNumberOfItemsReadPerTick, + vBuffer); + + // + // R ... + CopyBuffer( + mHandler, + X_PV_R_LINE, + 0, + mNumberOfItemsReadPerTick, + rBuffer); + + // + // S ... + CopyBuffer( + mHandler, + X_PV_S_LINE, + 0, + mNumberOfItemsReadPerTick, + sBuffer); + + // + // SHORT ... + + // + // HIGH ... + CopyBuffer( + mHandler, + X_PV_SHH_LINE, + 0, + mNumberOfItemsReadPerTick, + sHHBuffer); + + // + // LOW ... + CopyBuffer( + mHandler, + X_PV_SLL_LINE, + 0, + mNumberOfItemsReadPerTick, + sLLBuffer); + + // + // MEIUM ... + + // + // HIGH ... + CopyBuffer( + mHandler, + X_PV_MHH_LINE, + 0, + mNumberOfItemsReadPerTick, + mHHBuffer); + + // + // LOW ... + CopyBuffer( + mHandler, + X_PV_MLL_LINE, + 0, + mNumberOfItemsReadPerTick, + mLLBuffer); + + // + // LONG ... + + // + // HIGH ... + CopyBuffer( + mHandler, + X_PV_LHH_LINE, + 0, + mNumberOfItemsReadPerTick, + lHHBuffer); + + // + // LOW ... + CopyBuffer( + mHandler, + X_PV_LLL_LINE, + 0, + mNumberOfItemsReadPerTick, + lLLBuffer); + + // + // HIND ... + + // + // HIGH ... + CopyBuffer( + mHandler, + X_PV_HHH_LINE, + 0, + mNumberOfItemsReadPerTick, + hHHBuffer); + + // + // LOW ... + CopyBuffer( + mHandler, + X_PV_HLL_LINE, + 0, + mNumberOfItemsReadPerTick, + hLLBuffer); + } + + // + // START Tools Functions ... + // + + // + // Check isPeak ... + bool IsPeak(int bar_index) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) + { + return result; + } + + // + result = rBuffer[bar_index] == hHHBuffer[bar_index] && + hHHBuffer[bar_index] == lHHBuffer[bar_index] && + lHHBuffer[bar_index] == mHHBuffer[bar_index] && + mHHBuffer[bar_index] == sHHBuffer[bar_index]; + + // + return result; + } + + // + // Check isVale ... + bool IsVale(int bar_index) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) + { + return result; + } + + // + result = sBuffer[bar_index] == hLLBuffer[bar_index] && + hLLBuffer[bar_index] == lLLBuffer[bar_index] && + lLLBuffer[bar_index] == mLLBuffer[bar_index] && + mLLBuffer[bar_index] == sLLBuffer[bar_index]; + + // + return result; + } + + // + // Is Strong Support ... + bool IsStrongSupport(int bar_index) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 3)) + { + return result; + } + + // + result = + // + hLLBuffer[bar_index + 1] == hLLBuffer[bar_index + 2] && + hLLBuffer[bar_index + 2] == hLLBuffer[bar_index + 3] && + // + lLLBuffer[bar_index + 1] == lLLBuffer[bar_index + 2] && + lLLBuffer[bar_index + 2] == lLLBuffer[bar_index + 3] && + // + mLLBuffer[bar_index + 1] == mLLBuffer[bar_index + 2] && + mLLBuffer[bar_index + 2] == mLLBuffer[bar_index + 3] && + // + sLLBuffer[bar_index + 1] == sLLBuffer[bar_index + 2] && + sLLBuffer[bar_index + 2] == sLLBuffer[bar_index + 3] + // + ; + + // + return result; + } + + // + // Is Strong Resistance ... + bool IsStrongResistance(int bar_index) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 2)) + { + return result; + } + + // + result = + // + hHHBuffer[bar_index + 1] == hHHBuffer[bar_index + 2] && + hHHBuffer[bar_index + 2] == hHHBuffer[bar_index + 3] && + // + lHHBuffer[bar_index + 1] == lHHBuffer[bar_index + 2] && + lHHBuffer[bar_index + 2] == lHHBuffer[bar_index + 3] && + // + mHHBuffer[bar_index + 1] == mHHBuffer[bar_index + 2] && + mHHBuffer[bar_index + 2] == mHHBuffer[bar_index + 3] && + // + sHHBuffer[bar_index + 1] == sHHBuffer[bar_index + 2] && + sHHBuffer[bar_index + 2] == sHHBuffer[bar_index + 3] + // + ; + // + return result; + } + + // + // Find Last Strong Support ... + double GetLastStrongSupport( + int bar_index, // Bar Index ... + int length // LoopBack ... + ) + { + // + double result = 0; + + // + bool isBarIndexSupport = IsStrongSupport(bar_index); + if (isBarIndexSupport) + { + length += bar_index; + } + + // + if (!IsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (IsStrongSupport(i)) + { + // + result = sLLBuffer[i]; + break; + } + } + + // + return result; + } + + // + // Find Last Strong Resistance ... + double GetLastStrongResistance( + int bar_index, // Bar Index ... + int length // LoopBack ... + ) + { + // + double result = 0; + + // + bool isBarIndexResistance = IsStrongResistance(bar_index); + if (isBarIndexResistance) + { + length += bar_index; + } + + // + if (!IsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (IsStrongResistance(i)) + { + // + result = sHHBuffer[i]; + break; + } + } + + // + return result; + } + + // + // Find Strong Support Break Stop ... + bool IsSupportBreakedStop( + int bar_index, // Bar Index ... + int length // LoopBack ... + ) + { + // + bool result = false; + + // + bool isBaIndexSupport = IsStrongSupport(bar_index); + if (isBaIndexSupport) + { + return result; + } + + // + if (!IsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + bool isAllStrongSupport = true; + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (!IsStrongSupport(i) && isAllStrongSupport) + { + // + isAllStrongSupport = false; + break; + } + } + + // + result = !isBaIndexSupport && isAllStrongSupport; + + // + return result; + } + + // + // Find Strong Resistance Break Stop ... + bool IsResistanceBreakedStop( + int bar_index, // Bar Index ... + int length // LoopBack ... + ) + { + // + bool result = false; + + // + bool isBaIndexResistance = IsStrongResistance(bar_index); + if (isBaIndexResistance) + { + return result; + } + + // + if (!IsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + bool isAllStrongResistance = true; + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (!IsStrongResistance(i) && isAllStrongResistance) + { + // + isAllStrongResistance = false; + break; + } + } + + // + result = !isBaIndexResistance && isAllStrongResistance; + + // + return result; + } + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + // MARKET ... + int mShortLength; + int mMediumLength; + int mLongLength; + int mHindLength; + + // + // TREND ... + int mNumOfShoulder; + + // + // DETECTION ... + ENUM_SERIESMODE mHhMode; + ENUM_SERIESMODE mLlMode; + + // + string mTag; + + // + int mHandler; + + // + bool IsValidArraySize(int bar_index) + { + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(rBuffer); + result = rCount > bar_index + 1; + + // + return result; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xsslc.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xsslc.helper.mq5 new file mode 100644 index 0000000..583dddd --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xsslc.helper.mq5 @@ -0,0 +1,332 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XSSLC Indicator Provider +// Description: SSL Channel ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XPeaksAndVales Exported Buffers ... +enum ENUM_X_XSSLC_BUFFERS +{ + // + X_SSLC_UP_LINE = 0, + X_SSLC_DOWN_LINE = 1, + X_SSLC_UP_MA_LINE = 2, + X_SSLC_DOWN_MA_LINE = 3, + X_SSLC_KPI_LINE = 4, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXSSLCHelper +{ + // +public: + // + // Properties ... + double upBuffer[]; + double downBuffer[]; + double kpiBuffer[]; + + // + // Constructor ... + void XSCXSSLCHelper() + { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXSSLCHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // MARKET ... + int length = 10, // Length + // + // CALCULATION ... + ENUM_MA_METHOD method = MODE_SMA, // Method + ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH, // Up Applied To + ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW // Down Applied To + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // MARKET ... + mLength = length; + + // + // CALCULATION ... + mMethod = method; + mUpAppliedTo = upAppliedTo; + mDownAppliedTo = downAppliedTo; + + // + mTag = "XSSLC " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xsslc", + // + // Inputs ... + // + // MARKET ... + "", + mLength, + // + // CALCULATION ... + "", + mMethod, + mUpAppliedTo, + mDownAppliedTo, + // + // PRESENTATION ... + "", + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + ArraySetAsSeries(upBuffer, true); + ArraySetAsSeries(downBuffer, true); + ArraySetAsSeries(kpiBuffer, true); + } + + // + // DeConstructor ... + void ~XSCXSSLCHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // UP ... + CopyBuffer( + mHandler, + X_SSLC_UP_LINE, + 0, + mNumberOfItemsReadPerTick, + upBuffer); + + // + // DOWN ... + CopyBuffer( + mHandler, + X_SSLC_DOWN_LINE, + 0, + mNumberOfItemsReadPerTick, + downBuffer); + + // + // KPI ... + CopyBuffer( + mHandler, + X_SSLC_KPI_LINE, + 0, + mNumberOfItemsReadPerTick, + kpiBuffer); + } + + // + // START Tools Functions ... + // + + // + // Check Up Buffer Crossed Over Down ... + bool IsUpCrossedOverDown( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + upBuffer[bar_index] > downBuffer[bar_index] && + upBuffer[bar_index + 1] <= downBuffer[bar_index + 1] + // + ; + + // + return result; + } + + // + // Check Up Buffer Crossed Under Down ... + bool IsUpCrossedUnderDown( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + upBuffer[bar_index] < downBuffer[bar_index] && + upBuffer[bar_index + 1] >= downBuffer[bar_index + 1] + // + ; + + // + return result; + } + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + // MARKET ... + + // + // Length ... + int mLength; + + // + // CALCULATION ... + + // + // Method ... + ENUM_MA_METHOD mMethod; + + // + // Up Applied To + ENUM_APPLIED_PRICE mUpAppliedTo; + + // + // Down Applied To + ENUM_APPLIED_PRICE mDownAppliedTo; + + // + string mTag; + + // + int mHandler; + + // + bool IsValidArraySize(int bar_index) + { + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(upBuffer); + result = rCount > bar_index + 1; + + // + return result; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xtrnd.helper.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xtrnd.helper.mq5 new file mode 100644 index 0000000..c4ecfd2 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Helpers/x-saherelm.x121.xtrnd.helper.mq5 @@ -0,0 +1,469 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XTRND Indicator Provider +// Description: Trend Finder ... +// +// +// 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 Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// XPeaksAndVales Exported Buffers ... +enum ENUM_X_XTRND_BUFFERS +{ + // + X_TRND_UP_LINE = 0, + X_TRND_UP_STATE_LINE = 1, + // + X_TRND_DOWN_LINE = 2, + X_TRND_DOWN_STATE_LINE = 3, +}; + +// +// Trend State at unique Bar ... +enum ENUM_X_XTRND_STATE +{ + X_TRND_STATE_RANGE = 0, + X_TRND_STATE_CONSOLIDATION = 1, + X_TRND_STATE_UP = 2, + X_TRND_STATE_DOWN = 3, +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +class XSCXTRNDHelper +{ + // +public: + // + // Properties ... + double upBuffer[]; + double upStateBuffer[]; + double downBuffer[]; + double downStateBuffer[]; + + // + // Constructor ... + void XSCXTRNDHelper() + { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCXTRNDHelper( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period, + // + // Buffer Reading ... + int numberOfItemsReadPerTick = 52, + // + // MARKET ... + int cycleLength = 2, // Cycle Length to Check + int numberOfVerifications = 2, // Number of Verifications + // + // CALCULATION ... + ENUM_SERIESMODE hhMode = MODE_HIGH, // Detect Up + ENUM_SERIESMODE llMode = MODE_LOW // Detect Low + // + ) + { + // + // Setting Requirements ... + + // + // Symbol ... + mSymbol = symbol; + + // + // Period ... + mPeriod = period; + + // + // Number of Reading Buffer Items per Tick ... + mNumberOfItemsReadPerTick = numberOfItemsReadPerTick; + + // + // MARKET ... + mCycleLength = cycleLength; + mNumberOfVerifications = numberOfVerifications; + + // + // CALCULATIONS ... + mHHMode = hhMode; + mLLMode = llMode; + + // + mTag = "XTRND " + mSymbol + ", " + ToString(mPeriod); + + // + // Initial Handler ... + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xtrnd", + // + // Inputs ... + // + // MARKET ... + "", + mCycleLength, + mNumberOfVerifications, + // + // CALCULATIONS ... + "", + mHHMode, + mLLMode, + // + // PRESENTATION ... + "", + false, + false + // + ); + if (mHandler == INVALID_HANDLE) + { + LogMessage("failed to Initialize Indicator: " + (string)GetLastError()); + } + + // + ArraySetAsSeries(upBuffer, true); + ArraySetAsSeries(upStateBuffer, true); + ArraySetAsSeries(downBuffer, true); + ArraySetAsSeries(downStateBuffer, true); + } + + // + // DeConstructor ... + void ~XSCXTRNDHelper() + { + // + // Release Indicators ... + IndicatorRelease(mHandler); + } + + // + // Reading Buffers ... + void ReadBuffers() + { + // + // UP ... + CopyBuffer( + mHandler, + X_TRND_UP_LINE, + 0, + mNumberOfItemsReadPerTick, + upBuffer); + + // + // UP STATE ... + CopyBuffer( + mHandler, + X_TRND_UP_STATE_LINE, + 0, + mNumberOfItemsReadPerTick, + upStateBuffer); + + // + // DOWN ... + CopyBuffer( + mHandler, + X_TRND_DOWN_LINE, + 0, + mNumberOfItemsReadPerTick, + downBuffer); + + // + // DOWN STATE ... + CopyBuffer( + mHandler, + X_TRND_DOWN_STATE_LINE, + 0, + mNumberOfItemsReadPerTick, + downStateBuffer); + } + + // + // START Tools Functions ... + // + + // + // Detect Trend Up ... + bool IsTrendBullish( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + upStateBuffer[bar_index] == X_TRND_STATE_UP && + downStateBuffer[bar_index] == X_TRND_STATE_UP + // + ; + + // + return result; + } + + // + // Detect Trend Switched Up ... + bool IsTrendSwitchedBullish( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + IsTrendBullish(bar_index) && + !IsTrendBullish(bar_index + 1) + // + ; + + // + return result; + } + + // + // Detect Trend Down ... + bool IsTrendBearish( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + upStateBuffer[bar_index] == X_TRND_STATE_DOWN && + downStateBuffer[bar_index] == X_TRND_STATE_DOWN + // + ; + + // + return result; + } + + // + // Detect Trend Switched Down ... + bool IsTrendSwitchedBearish( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + IsTrendBearish(bar_index) && + !IsTrendBearish(bar_index + 1) + // + ; + + // + return result; + } + + // + // Detect Trend Consolidation ... + bool IsTrendConsolidation( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index)) + { + return result; + } + + // + result = + // + (upStateBuffer[bar_index] == X_TRND_STATE_RANGE || + upStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + && + // + (downStateBuffer[bar_index] == X_TRND_STATE_RANGE || + downStateBuffer[bar_index] == X_TRND_STATE_CONSOLIDATION) + // + ; + + // + return result; + } + + // + // Detect Trend Switched Consolidation ... + bool IsTrendSwitchedConsolidation( + int bar_index // Bar Index ... + ) + { + // + bool result = false; + + // + if (!IsValidArraySize(bar_index + 1)) + { + return result; + } + + // + result = + // + IsTrendConsolidation(bar_index) && + !IsTrendConsolidation(bar_index + 1) + // + ; + + // + return result; + } + + // + // END Tools Functions ... + // + + // +protected: + // +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Buffer Reading ... + int mNumberOfItemsReadPerTick; + + // + string mTag; + + // + int mHandler; + + // + // INPUTS ... + + // + // MARKET ... + + // + // Cycle Length to Check ... + int mCycleLength; + + // + // Number of Verifications ... + int mNumberOfVerifications; + + // + // CALCULATIONS ... + + // + // Detect Up ... + ENUM_SERIESMODE mHHMode; + + // + // Detect Low ... + ENUM_SERIESMODE mLLMode; + + // + bool IsValidArraySize(int bar_index) + { + // + bool result = false; + + // + if (bar_index < 0) + { + return result; + } + + // + int rCount = ArraySize(upBuffer); + result = rCount > bar_index + 1; + + // + return result; + } +}; \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xama.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xama.mq5 new file mode 100644 index 0000000..ce62a15 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xama.mq5 @@ -0,0 +1,367 @@ +/////////////////////////////////////////////////////// +// +// 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 group "Makret"; +input int length = 52; // 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_LOW; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// 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() +{ + // + ENUM_DRAW_TYPE drawType = showLine ? DRAW_COLOR_LINE : DRAW_NONE; + + // + string maBufferLabel = "XAMA " + "(" + (string)length + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showLine); + + // + // 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/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xatrsl.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xatrsl.mq5 new file mode 100644 index 0000000..e58e7da --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xatrsl.mq5 @@ -0,0 +1,765 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_ATRSL ATR Indicator +// --------------------------------------------------- +// Name: X121_ATRSL +// Description: ATR StopLoss Finer +// 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 X121_ATRSL Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_ATRSL" + +// +// Available Smoothing Methods ... +enum X_XATRSL_SMOOTHING_METHOD +{ + X_ATRSL_SMOOTHING_RMA = 0, // RMA + X_ATRSL_SMOOTHING_SMA = 1, // SMA + X_ATRSL_SMOOTHING_EMA = 2, // EMA + X_ATRSL_SMOOTHING_WMA = 3, // WMA +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 14; // Length +input double step = 0.02; // Increment Step +input double maximum = 0.2; // Maximum +input ENUM_APPLIED_PRICE highAppliedTo = PRICE_HIGH; // High Line Applied To +input ENUM_APPLIED_PRICE lowAppliedTo = PRICE_LOW; // Low Line Applied To + +// +input group "Presentation"; +input bool showHigh = true; // Show High +input bool showLow = true; // Show Low +input bool showSar = true; // Show PSar + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 3 + +// +// PLOTTED Buffers ... + +// +// HIGH ... +#define highBufferIndex 0 +double highBuffer[]; + +// +#property indicator_label1 "X121_ATRSL H" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLightGray +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// LOW ... +#define lowBufferIndex 1 +double lowBuffer[]; + +// +#property indicator_label2 "X121_ATRSL L" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrLightGray +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// SAR ... +#define sarBufferIndex 2 +double sarBuffer[]; + +// +#property indicator_label3 "X121_ATRSL SAR" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// DATA Buffers ... + +// +// RMA ... +#define rmaBufferIndex 3 +double rmaBuffer[]; + +// +// WMA ... +#define wmaBufferIndex 4 +double wmaBuffer[]; + +// +// WMA CALCULATIONS ... + +// +// MA 1 ... +#define ma1BufferIndex 5 +double ma1Buffer[]; + +// +// MA P ... +#define maPBufferIndex 6 +double maPBuffer[]; + +// +// EMA P ... +#define emaPBufferIndex 7 +double emaPBuffer[]; + +// +// ATR ... +#define atrBufferIndex 8 +double atrBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double smoothFactor; + +// +// WMA ... +int ma1Handler = INVALID_HANDLE; +int maPHandler = INVALID_HANDLE; +ENUM_APPLIED_PRICE wmaAppliedTo = PRICE_CLOSE; + +// +// EMA ... +int emaPHandler = INVALID_HANDLE; + +// +// ATR ... +int atrHandler = INVALID_HANDLE; + +// +// SAR ... +int sarHandler = 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; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Calculate RMA and WMA Smooth Factoir ... + smoothFactor = 1.0 / length; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Initialize Handlers ... + if (!InitialHandlers()) + { + return INIT_FAILED; + } + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(sarHandler); + IndicatorRelease(atrHandler); + IndicatorRelease(ma1Handler); + IndicatorRelease(maPHandler); + IndicatorRelease(emaPHandler); +} + +// +// 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; + + // + // Check Calculated Bars ... + int sarCalculatedBars = BarsCalculated(sarHandler); + int atrCalculatedBars = BarsCalculated(atrHandler); + int ma1CalculatedBars = BarsCalculated(ma1Handler); + int maPCalculatedBars = BarsCalculated(maPHandler); + int emaPCalculatedBars = BarsCalculated(emaPHandler); + if (sarCalculatedBars < maxLength || + atrCalculatedBars < maxLength || + ma1CalculatedBars < maxLength || + maPCalculatedBars < maxLength || + emaPCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedSars = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); + int copiedAtrs = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer); + int copiedMa1s = CopyBuffer(ma1Handler, 0, 0, limit, ma1Buffer); + int copiedMaPs = CopyBuffer(maPHandler, 0, 0, limit, maPBuffer); + int copiedEMaPs = CopyBuffer(emaPHandler, 0, 0, limit, emaPBuffer); + if (copiedSars <= 0 || + copiedAtrs <= 0 || + copiedMa1s <= 0 || + copiedMaPs <= 0 || + copiedEMaPs <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Determines First Calculation ... + bool isFirstBar = ((limit == rates_total) && + i == rates_total - 1); + + // + CalculateBuffers( + i, + isFirstBar, + limit, + rates_total, + prev_calculated, + open, + high, + low, + close + // + ); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + // Validate Inputs ... + (length > 2 && + step > 0 && + maximum > step) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Max ... + result = MathMax(result, length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // HIGH ... + ENUM_DRAW_TYPE highDrawType = showHigh ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(highBuffer, true); + SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA); + PlotIndexSetDouble(highBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(highBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(highBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(highBufferIndex, PLOT_DRAW_TYPE, highDrawType); + + // + // LOW ... + ENUM_DRAW_TYPE lowDrawType = showLow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(lowBuffer, true); + SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(lowBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(lowBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(lowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lowBufferIndex, PLOT_DRAW_TYPE, lowDrawType); + + // + // SAR ... + ENUM_DRAW_TYPE sarDrawType = showSar ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); + PlotIndexSetDouble(sarBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(sarBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(sarBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sarBufferIndex, PLOT_DRAW_TYPE, sarDrawType); + + // + // DATA Buffers ... + + // + // RMA ... + ArraySetAsSeries(rmaBuffer, true); + SetIndexBuffer(rmaBufferIndex, rmaBuffer, INDICATOR_CALCULATIONS); + + // + // MA 1 ... + ArraySetAsSeries(ma1Buffer, true); + SetIndexBuffer(ma1BufferIndex, ma1Buffer, INDICATOR_CALCULATIONS); + + // + // MA P ... + ArraySetAsSeries(maPBuffer, true); + SetIndexBuffer(maPBufferIndex, maPBuffer, INDICATOR_CALCULATIONS); + + // + // WMA ... + ArraySetAsSeries(wmaBuffer, true); + SetIndexBuffer(wmaBufferIndex, wmaBuffer, INDICATOR_DATA); + + // + // ATR ... + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); +} + +// +// Initialize WMA Required Handlers ... +bool InitialHandlers() +{ + // + bool result = false; + + // + // MA 1 ... + ma1Handler = iMA( + _Symbol, + _Period, + 1, // Lenght of MA 1 ... + 0, + MODE_SMA, + wmaAppliedTo); + + // + // MA P ... + maPHandler = iMA( + _Symbol, + _Period, + length, + 0, + MODE_SMA, + wmaAppliedTo); + + // + // EMA P ... + emaPHandler = iMA( + _Symbol, + _Period, + length, + 0, + MODE_EMA, + wmaAppliedTo); + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + length); + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + step, + maximum); + + // + result = + // + sarHandler != INVALID_HANDLE && + atrHandler != INVALID_HANDLE && + ma1Handler != INVALID_HANDLE && + maPHandler != INVALID_HANDLE && + emaPHandler != INVALID_HANDLE + // + ; + + // + // Log Error Message if Initialization Failed ... + if (!result) + { + LogMessage("Error in Initializing Indicator ..."); + } + + // + 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, // Selected Bar Index + bool isFirstBar, // Determines First Bar + const int limit, // Limit Of Calculations + const int ratesTotal, // Total Rates + const int prevCalculated, // Prev Calculated Bars + const double &open[], // Open Price Series + const double &high[], // High Price Series + const double &low[], // Low Price Series + const double &close[] // Close Price Series +) +{ + // + // RMA Calculation ... + + // + double closeValue = close[bar_index]; + double prevRMAValue = isFirstBar + ? closeValue + : rmaBuffer[bar_index + 1]; + + // + double rmaValue = (closeValue * smoothFactor) + prevRMAValue * (1.0 - smoothFactor); + + // + rmaBuffer[bar_index] = rmaValue; + + // + // WMA Calculations ... + + // + double maPValue = maPBuffer[bar_index]; + double ma1Value = ma1Buffer[bar_index]; + + // + double wmaValue; + if (isFirstBar) + { + wmaValue = maPValue; + } + else + { + wmaValue = (ma1Value - wmaBuffer[bar_index + 1]) * smoothFactor + wmaBuffer[bar_index + 1]; + } + + // + wmaBuffer[bar_index] = wmaValue; + + // + // CALCULATE Buffers ... + + // + double atrValue = atrBuffer[bar_index]; + double highSourcePrice = GetSourcePrice( + bar_index, + highAppliedTo, + open, + high, + low, + close); + double lowSourcePrice = GetSourcePrice( + bar_index, + lowAppliedTo, + open, + high, + low, + close); + + // + // Retrieve SMoothing Value ... + // double smoothingValue = GetSmoothedValue(bar_index); + + // + double smoothedATR = atrValue; + + // + // HIGH ... + double highValue = highSourcePrice + smoothedATR; + highBuffer[bar_index] = highValue; + + // + // LOW ... + double lowValue = lowSourcePrice - smoothedATR; + lowBuffer[bar_index] = lowValue; +} + +// +// Retrieve Smoothed Value based on User Choice ... +double GetSmoothedValue( + int bar_index // Bar Index +) +{ + // + double result = EMPTY_VALUE; + + // + // switch (smoothingMethod) + // { + // // + // // RMA ... + // case X_ATRSL_SMOOTHING_RMA: + // result = rmaBuffer[bar_index]; + // break; + + // // + // // WMA ... + // case X_ATRSL_SMOOTHING_WMA: + // result = wmaBuffer[bar_index]; + // break; + + // // + // // EMA ... + // case X_ATRSL_SMOOTHING_EMA: + // result = emaPBuffer[bar_index]; + // break; + + // // + // // SMA ... + // case X_ATRSL_SMOOTHING_SMA: + // result = maPBuffer[bar_index]; + // break; + + // // + // default: + // result = maPBuffer[bar_index]; + // break; + // } + + // + return result; +} + +// +// Retrive Which Price Selected By User as Source ... +double GetSourcePrice( + int bar_index, // BarIndex + ENUM_APPLIED_PRICE appliedPrice, // Selected Price Source + const double &open[], // Open Price Series + const double &high[], // High Price Series + const double &low[], // Low Price Series + const double &close[] // Close Price Series +) +{ + // + double result = EMPTY_VALUE; + + // + switch (appliedPrice) + { + // + // OPEN ... + case PRICE_OPEN: + result = open[bar_index]; + break; + + // + // HIGH ... + case PRICE_HIGH: + result = high[bar_index]; + break; + + // + // LOW ... + case PRICE_LOW: + result = low[bar_index]; + break; + + // + // CLOSE ... + default: + case PRICE_CLOSE: + result = close[bar_index]; + break; + } + + // + return result; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xcclear.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xcclear.mq5 new file mode 100644 index 0000000..6f318e0 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xcclear.mq5 @@ -0,0 +1,481 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_CC Candle Styles +// --------------------------------------------------- +// Name: X121_CC +// Description: Candle Styles ... +// 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 X121_CC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_CC" + +// +// Holds an SnapShot of Charts Configuration ... +struct XChartStyle +{ + // + // chart's ID ... + long chartId; + // + // chart's mode ... + ENUM_CHART_MODE mode; + // + // show bid line ... + bool showBidLine; + // + // show ask line ... + bool showAskLine; + // + // show grids on chart ... + bool showGrid; + // + // show volumes ... + bool showVolumes; + // + // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ... + bool showTradeLevels; + // + // chart autoscroll ... + bool autoScroll; + // + // chart quick navigation state ... + bool quickNavigation; + // + // chart's foreground color ... + color foreGroundColor; + // + // chart's background color ... + color backGroundColor; + // + // Up Color ... + color upColor; + // + // Down Color ... + color downColor; + // + // Bullish color ... + color bullishColor; + // + // Bearish color ... + color bearishColor; + // + // grid color ... + color gridColor; + // + // bid line color ... + color bidLineColor; + // + // ask line color ... + color askLineColor; + // + // line mode and doji candlestick color ... + color lineColor; + // + // Color of stop order levels (Stop Loss and Take Profit) ... + color stopColor; + // + // volumes color ... + color volumesColor; +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Chart Style"; +input color mUpColor = clrLime; // Up Color +input color mDownColor = clrRed; // Down Color +input color mLineColor = clrLime; // Line mode and Doji candlestick Color +input color mBearishColor = clrRed; // Bullish Color +input color mBullishColor = clrLime; // Bearish Color +input color mVolumesColor = clrGreen; // Volumes Color + +// +input group "Presentation"; +input bool showCandles = false; // Show Candles + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// 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" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XChartStyle chartStyle; +XChartStyle clearStyle; +bool hasChartConfig = false; + +// +// 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; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Apply Chart Style ... + ApplyCustomChartStyle(); + + // + // 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 + + // + RemoveDraws(drawPrefix); +} + +// +// 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; + + // + 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 = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ +} + +// +// 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 +) +{ +} + +// +// Apply Custom Chart Style ... +void ApplyCustomChartStyle() +{ + // + // Read Prev Applied Chart Style ans Store it ... + if (!hasChartConfig) + { + // + // Read Current Chart Config and Store it ... + ReadChartStyle(); + + // + // After Reading Current Chart Style ... + // we have to Save Configs and Change Styles ... + clearStyle = chartStyle; + + // + clearStyle.upColor = CLR_NONE; + clearStyle.downColor = CLR_NONE; + clearStyle.lineColor = CLR_NONE; + clearStyle.volumesColor = CLR_NONE; + clearStyle.bullishColor = CLR_NONE; + clearStyle.bearishColor = CLR_NONE; + } + + // + // Decide to Show or not Candles based on User Input ... + if (showCandles) + { + SetChartStyle(chartStyle); + } + else + { + SetChartStyle(clearStyle); + } +} + +// +// Read Previous Chart Style ... +void ReadChartStyle() +{ + // + if (hasChartConfig) + { + return; + } + + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + chartStyle.chartId = chartId; + + // + // Retrieve Chart Mode ... + chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); + + // + chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); + chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); + chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); + chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); + chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); + chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); + chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); + + // + chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); + chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); + chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); + chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); + chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); + chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); + chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); + chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); + chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); + chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); + chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); + chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); + + // + chartStyle.upColor = mUpColor; + chartStyle.downColor = mDownColor; + chartStyle.lineColor = mLineColor; + chartStyle.bearishColor = mBearishColor; + chartStyle.bullishColor = mBullishColor; + chartStyle.volumesColor = mVolumesColor; +} + +// +// Set Chart Style ... +void SetChartStyle( + XChartStyle &mChartStyle // Chart Style to Apply +) +{ + // + ApplyChartStyle( + mChartStyle.chartId, + mChartStyle.mode, + mChartStyle.showBidLine, + mChartStyle.showAskLine, + mChartStyle.showGrid, + mChartStyle.showVolumes, + mChartStyle.showTradeLevels, + mChartStyle.autoScroll, + mChartStyle.quickNavigation, + mChartStyle.foreGroundColor, + mChartStyle.backGroundColor, + mChartStyle.upColor, + mChartStyle.downColor, + mChartStyle.bullishColor, + mChartStyle.bearishColor, + mChartStyle.gridColor, + mChartStyle.bidLineColor, + mChartStyle.askLineColor, + mChartStyle.lineColor, + mChartStyle.stopColor, + mChartStyle.volumesColor); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xche.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xche.mq5 new file mode 100644 index 0000000..92ea4f1 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xche.mq5 @@ -0,0 +1,629 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHE Indicator +// --------------------------------------------- +// Name: XCHE +// Description: Hull Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XHull Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XCHE" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 35; // Length +input int loopback = 26; // Loopback +input double multiplier1 = 3.0; // 1st Multiplier +input double multiplier2 = 3.5; // 2nd Multiplier + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showLongExit1Line = true; // Show 1st Long Exit +input bool showShortExit1Line = true; // Show 1st Short Exit +input bool showLongExit2Line = true; // Show 2st Long Exit +input bool showShortExit2Line = true; // Show 2st Short Exit + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +// Long Exit 1 ... +#define longExit1BufferIndex 0 +double longExit1Buffer[]; + +// +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_DOT + +// +// Short Exit 1 ... +#define shortExit1BufferIndex 1 +double shortExit1Buffer[]; + +// +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color2 clrRed + +// +// Long Exit 2 ... +#define longExit2BufferIndex 2 +double longExit2Buffer[]; + +// +#property indicator_type3 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color3 clrAqua + +// +// Short Exit 2 ... +#define shortExit2BufferIndex 3 +double shortExit2Buffer[]; + +// +#property indicator_type4 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color4 clrMagenta + +// +// START Arrows ... + +// +// Long Exit 1 Start ... +#define longExit1StartBufferIndex 4 +double longExit1StartBuffer[]; + +// +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrLime + +// +// Short Exit 1 Start ... +#define shortExit1StartBufferIndex 5 +double shortExit1StartBuffer[]; + +// +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrRed + +// +// Long Exit 2 Start ... +#define longExit2StartBufferIndex 6 +double longExit2StartBuffer[]; + +// +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrAqua + +// +// Short Exit 2 Start ... +#define shortExit2StartBufferIndex 7 +double shortExit2StartBuffer[]; + +// +#property indicator_type8 DRAW_ARROW +#property indicator_color8 clrMagenta + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// Working Array ... +double work[][6]; +#define hi1Idx 0 +#define lo1Idx 1 +#define hi2Idx 2 +#define lo2Idx 3 +#define trend1Idx 4 +#define trend2Idx 5 + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart mPeriod 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 +} + +// +// 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[]) +{ + // + if (Bars(_Symbol, _Period) < rates_total) + { + return (prev_calculated); + } + + // + if (ArrayRange(work, 0) != rates_total) + { + ArrayResize(work, rates_total); + } + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + low, + close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + loopback >= 0; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(length, loopback); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + uint arrowCode = 159; + + // + // LEVEL 1 ... + + // + // Long Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit1DrawType = showLongExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit1StartDrawType = showLongExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit1BufferIndex, longExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_SHOW_DATA, showLongExit1Line); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_DRAW_TYPE, longExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit1StartBufferIndex, longExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_DRAW_TYPE, longExit1StartDrawType); + + // + // Short Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit1DrawType = showShortExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit1StartDrawType = showShortExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit1BufferIndex, shortExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_SHOW_DATA, showShortExit1Line); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_DRAW_TYPE, shortExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit1StartBufferIndex, shortExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_DRAW_TYPE, shortExit1StartDrawType); + + // + // LEVEL 2 ... + + // + // Long Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit2DrawType = showLongExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit2StartDrawType = showLongExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit2BufferIndex, longExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_SHOW_DATA, showLongExit2Line); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_DRAW_TYPE, longExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit2StartBufferIndex, longExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_DRAW_TYPE, longExit2StartDrawType); + + // + // Short Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit2DrawType = showShortExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit2StartDrawType = showShortExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit2BufferIndex, shortExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_SHOW_DATA, showShortExit2Line); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_DRAW_TYPE, shortExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit2StartBufferIndex, shortExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_DRAW_TYPE, shortExit2StartDrawType); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int prevCalculated, // Previous Calculated + int ratesTotal, // Total Rates + const double &open[], // Rates Open ... + const double &high[], // Rates High ... + const double &low[], // Rates Low ... + const double &close[] // Rates Close ... +) +{ + // + // Cleanup Buffers ... + longExit1Buffer[bar_index] = longExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index] = shortExit1StartBuffer[bar_index] = EMPTY_VALUE; + longExit2Buffer[bar_index] = longExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index] = shortExit2StartBuffer[bar_index] = EMPTY_VALUE; + + // + int start = MathMax(bar_index - loopback, 0); + + // + // Calculate ATR Value ... + double atrValue = 0; + for (int k = 1; k <= length && (bar_index - k - 1) >= 0; k++) + { + // + atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) - + MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]); + } + atrValue /= (double)length; + + // + // Retrieve Highest High and Lowest Lows ... + double loopbackMax = high[ArrayMaximum(high, start, loopback)]; + double loopbackMin = low[ArrayMinimum(low, start, loopback)]; + + // + // Fill Multi Dimesional Working Array ... + work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue; + work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue; + work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue; + work[bar_index][lo2Idx] = loopbackMin + multiplier2 * atrValue; + work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0; + work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0; + + // + if (bar_index > 0) + { + // + // Calculate Trends ... + if (close[bar_index] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][trend1Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][trend1Idx] = -1; + } + + // + if (close[bar_index] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][trend2Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][trend2Idx] = -1; + } + + // + // Calculate Exit Values ... + + // + // Exit 1 ... + + // + // Long ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == 1) + { + // + if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx]; + } + + // + longExit1Buffer[bar_index] = work[bar_index][hi1Idx]; + + // + if (longExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit1StartBuffer[bar_index] = longExit1Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == -1) + { + // + if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx]; + } + + // + shortExit1Buffer[bar_index] = work[bar_index][lo1Idx]; + + // + if (shortExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index]; + } + } + + // + // Exit 2 ... + + // + // Long ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == 1) + { + if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx]; + } + + // + longExit2Buffer[bar_index] = work[bar_index][hi2Idx]; + + // + if (longExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit2StartBuffer[bar_index] = longExit2Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == -1) + { + // + if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx]; + } + + // + shortExit2Buffer[bar_index] = work[bar_index][lo2Idx]; + + // + if (shortExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index]; + } + } + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xct.ex5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xct.ex5 new file mode 100644 index 0000000..379fc94 Binary files /dev/null and b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xct.ex5 differ diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xct.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xct.mq5 new file mode 100644 index 0000000..84e7e8f --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xct.mq5 @@ -0,0 +1,214 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCTimer Indicator +// --------------------------------------------- +// Name: XCTimer +// 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 XCTimer Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCTimer" +// +// END Constants ... +// + +// +// START Inputs ... +// +input color clr = clrYellow; +input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + CreateIndicatorObject(); + + // + // 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 + + // + // Delete Object ... + ObjectDelete(0, ShortName); +} + +// +// 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[]) +{ + // + ArraySetAsSeries(time, true); + + // + int m = int(time[0] + PeriodSeconds() - TimeCurrent()); + int s = m % 60; + m = (m - s) / 60; + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + string _sp = "", _m = "", _s = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + if (m < 10) + _m = "0"; + if (s < 10) + _s = "0"; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in " + _m + IntegerToString(m) + ":" + _s + IntegerToString(s); + + // + ObjectSetInteger(0, ShortName, OBJPROP_COLOR, clr); + ObjectSetString(0, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(0, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(0, ShortName, OBJPROP_FONT, "Courier"); + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +void CreateIndicatorObject() +{ + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, corner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (corner) + { + case CORNER_LEFT_UPPER: + Anchor = ANCHOR_LEFT_UPPER; + break; + case CORNER_RIGHT_UPPER: + Anchor = ANCHOR_RIGHT_UPPER; + break; + case CORNER_LEFT_LOWER: + Anchor = ANCHOR_LEFT_LOWER; + break; + case CORNER_RIGHT_LOWER: + Anchor = ANCHOR_RIGHT_LOWER; + break; + } + + // + ObjectSetInteger(0, ShortName, OBJPROP_ANCHOR, Anchor); +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xhk.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xhk.mq5 new file mode 100644 index 0000000..34ad3ff --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xhk.mq5 @@ -0,0 +1,500 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_HK HikenAshi Candles +// --------------------------------------------------- +// Name: X121_HK +// Description: Hiken Ashi ... +// 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 X121_HK Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_HK" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Presentation"; +input bool drawCandles = true; // Draw Hiken Ashi Candle +input bool drawCandleLines = false; // Show HikenAshi Lines + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 13 +#property indicator_plots 5 + +// +// PLOTTED Buffers ... + +// +// Open ... +#define openBufferIndex 0 +double openBuffer[]; + +// +// High ... +#define highBufferIndex 1 +double highBuffer[]; + +// +// Low ... +#define lowBufferIndex 2 +double lowBuffer[]; + +// +// Close ... +#define closeBufferIndex 3 +double closeBuffer[]; + +// +// Candle Color ... +#define candleColorBufferIndex 4 +double candleColorBuffer[]; + +// +#define candlesBufferIndex 0 + +// +#property indicator_label1 "X121_HK Open;X121_HK High;X121_HK Low;X121_HK Close" +#property indicator_type1 DRAW_COLOR_CANDLES +#property indicator_color1 clrAqua, clrMagenta, CLR_NONE + +// +#define openHKBufferIndex 5 +#define openHKColorBufferIndex 6 +double openHKBuffer[]; +double openHKColorBuffer[]; + +// +#define openHKBufferPlotIndex 1 +#property indicator_label2 "X121_HK O" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrAqua, clrMagenta, clrLightGray +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define highHKBufferIndex 7 +#define highHKColorBufferIndex 8 +double highHKBuffer[]; +double highHKColorBuffer[]; + +// +#define highHKBufferPlotIndex 2 +#property indicator_label3 "X121_HK H" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, clrMagenta, clrLightGray +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define lowHKBufferIndex 9 +#define lowHKColorBufferIndex 10 +double lowHKBuffer[]; +double lowHKColorBuffer[]; + +// +#define lowHKBufferPlotIndex 3 +#property indicator_label4 "X121_HK L" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrAqua, clrMagenta, clrLightGray +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define closeHKBufferIndex 11 +#define closeHKColorBufferIndex 12 +double closeHKBuffer[]; +double closeHKColorBuffer[]; + +// +#define closeHKBufferPlotIndex 4 +#property indicator_label5 "X121_HK C" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 clrAqua, clrMagenta, clrLightGray +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// 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; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, prev_calculated, rates_total, open, high, close, low); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Candles Color ... + ArraySetAsSeries(candleColorBuffer, true); + SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(candleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(openBuffer, true); + PlotIndexSetInteger(openBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(highBuffer, true); + SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(closeBuffer, true); + SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(lowBuffer, true); + SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open HK ... + ENUM_DRAW_TYPE openDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_DRAW_TYPE, openDrawType); + + // + ArraySetAsSeries(openHKColorBuffer, true); + SetIndexBuffer(openHKColorBufferIndex, openHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // High HK ... + ENUM_DRAW_TYPE highDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_DRAW_TYPE, highDrawType); + + // + ArraySetAsSeries(highHKColorBuffer, true); + SetIndexBuffer(highHKColorBufferIndex, highHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Low HK ... + ENUM_DRAW_TYPE lowDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_DRAW_TYPE, lowDrawType); + + // + ArraySetAsSeries(lowHKColorBuffer, true); + SetIndexBuffer(lowHKColorBufferIndex, lowHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close HK ... + ENUM_DRAW_TYPE closeDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_DRAW_TYPE, closeDrawType); + + // + ArraySetAsSeries(closeHKColorBuffer, true); + SetIndexBuffer(closeHKColorBufferIndex, closeHKColorBuffer, 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 + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[]) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = openBuffer[bar_index + 1]; + mPrevHKCloseValue = closeBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + openBuffer[bar_index] = mHKOpenValue; + highBuffer[bar_index] = mHKHighValue; + lowBuffer[bar_index] = mHKLowValue; + closeBuffer[bar_index] = mHKCloseValue; + + // + double candleColorValue = + mHKOpenValue < mHKCloseValue ? 0 : 1; + + // + candleColorBuffer[bar_index] = drawCandles ? candleColorValue : 2; + + // + openHKBuffer[bar_index] = mHKOpenValue; + openHKColorBuffer[bar_index] = candleColorValue; + + // + highHKBuffer[bar_index] = mHKHighValue; + highHKColorBuffer[bar_index] = candleColorValue; + + // + lowHKBuffer[bar_index] = mHKLowValue; + lowHKColorBuffer[bar_index] = candleColorValue; + + // + closeHKBuffer[bar_index] = mHKCloseValue; + closeHKColorBuffer[bar_index] = candleColorValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xhull.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xhull.mq5 new file mode 100644 index 0000000..d0396ca --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xhull.mq5 @@ -0,0 +1,587 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XHULL Indicator +// --------------------------------------------- +// Name: XHULL +// Description: Hull Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XHull Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "XHULL" + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init( + int mPeriod, + double mDivisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(mPeriod > 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 72; // Length +input double divisor = 2.0; // Divisor (Speed) + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showUpZone = true; // Show Up Zone +input bool showDownZone = true; // Show Down Zone + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// UP Zone ... + +// +#define upZoneBufferIndex 0 +#define upZoneColorBufferIndex 1 + +// +double upZoneBuffer[]; +double upZoneColorBuffer[]; + +// +#property indicator_label1 "XHULL Up" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLightGray, clrAqua, clrMagenta +#property indicator_width1 1 + +// +// DOWN Zone ... + +// +#define downZoneBufferIndex 2 +#define downZoneColorBufferIndex 3 + +// +double downZoneBuffer[]; +double downZoneColorBuffer[]; + +// +#property indicator_label2 "XHULL Down" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrLightGray, clrAqua, clrMagenta +#property indicator_width2 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + length, + divisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + length, + divisor); + + // + // 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 mPeriod 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 + + // + delete mUpZHull; + delete mDownZHull; +} + +// +// 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[]) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = getPrice( + upAppliedTo, + open, high, low, close, i); + + // + double downPrice = getPrice( + downAppliedTo, + open, high, low, close, i); + + // + CalculateBuffers( + i, + rates_total, + upPrice, + downPrice); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + divisor >= 0.5; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE upZoneDrawType = showUpZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(upZoneBufferIndex, upZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_SHOW_DATA, showUpZone); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_DRAW_TYPE, upZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(upZoneColorBufferIndex, upZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE downZoneDrawType = showDownZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(downZoneBufferIndex, downZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_SHOW_DATA, showDownZone); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_DRAW_TYPE, downZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(downZoneColorBufferIndex, downZoneColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + upZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (upZoneBuffer[bar_index] > upZoneBuffer[bar_index - 1]) + ? 1 + : (upZoneBuffer[bar_index] < upZoneBuffer[bar_index - 1]) + ? 2 + : upZoneColorBuffer[bar_index - 1] + : 0; + upZoneColorBuffer[bar_index] = upColorIDX; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + downZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (downZoneBuffer[bar_index] > downZoneBuffer[bar_index - 1]) + ? 1 + : (downZoneBuffer[bar_index] < downZoneBuffer[bar_index - 1]) + ? 2 + : downZoneColorBuffer[bar_index - 1] + : 0; + downZoneColorBuffer[bar_index] = downColorIDX; +} + +// +// END Functions ... +// + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xich.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xich.mq5 new file mode 100644 index 0000000..96eb522 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xich.mq5 @@ -0,0 +1,895 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_ICH Ichimoku +// ------------------------------------------------- +// Name: X121_ICH +// Description: +// 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 X121_ICH Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_ICH" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ICHIMOKU Kinko Hyo ... + +// +// TENKANSEN ... +input group "Tenkan Sen"; +input int tenkanSenLength = 9; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// KIJUNSEN ... +input group "Kijun Sen"; +input int kijunSenLength = 26; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// SENKOUSPANB ... +input group "Senkou Span B"; +input int senkouSpanBLength = 52; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// CHIKOUSPAN ... +input group "Chikou Span"; +input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type + +// +input group "Presentation"; +input bool showTenkanSen = true; // Show Tenkan Sen +input bool showKijunSen = true; // Show Kijun Sen +input bool showKijunSenPlus = false; // Show Kijun Sen + +input bool showKijunSenNegative = false; // Show Kijun Sen - +input bool showChikouSpan = true; // Show Chikou Span +input bool showSenkouSpanA = true; // Show Senkou Span A +input bool showSenkouSpanB = true; // Show Senkou Span B +input bool showKumo = true; // Show Kumo +input bool shiftKumo = true; // Shift Kumo to Future + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes 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" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 8 + +// +// PLOTTED Buffers ... + +// +// ICHIMOKU ... + +// +// TENKANSEN ... + +// +#define tenkanSenBufferIndex 0 +double tenkanSenBuffer[]; + +// +#property indicator_label1 "X121_ICH Tenkan Sen" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// KIJUNSEN ... + +// +#define kijunSenBufferIndex 1 +double kijunSenBuffer[]; + +// +#property indicator_label2 "X121_ICH Kijun Sen" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDodgerBlue +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#define kijunSenPlusBufferIndex 2 +double kijunSenPlusBuffer[]; + +// +#property indicator_label3 "X121_ICH Kijun Sen +" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMediumTurquoise +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define kijunSenNegativeBufferIndex 3 +double kijunSenNegativeBuffer[]; + +// +#property indicator_label4 "X121_ICH Kijun Sen -" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrDarkSeaGreen +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CHIKOUSPAN ... + +// +#define chikouSpanBufferIndex 4 +double chikouSpanBuffer[]; + +// +#property indicator_label5 "X121_ICH Chikou Span" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrDarkGreen +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +#define senkouABufferIndex 5 +double senkouABuffer[]; + +// +#property indicator_label6 "X121_ICH Senkou Span A" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGray +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +#define senkouBBufferIndex 6 +double senkouBBuffer[]; + +// +#property indicator_label7 "X121_ICH Senkou Span B" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// KUMO ... + +// +// SENKOUSPANA ... + +// +#define senkouSpanABufferIndex 7 +double senkouSpanABuffer[]; + +// +// SENKOUSPANB ... + +// +#define senkouSpanBBufferIndex 8 +double senkouSpanBBuffer[]; + +// +// KUMOCLOUD ... + +// +#define kumoBufferIndex 7 + +// +#property indicator_label8 "X121_ICH Kumo" +#property indicator_type8 DRAW_FILLING +#property indicator_color8 clrAqua, clrMagenta +#property indicator_style8 STYLE_SOLID +#property indicator_width8 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +ENUM_SERIESMODE mTenkanSenTopMode = NULL; +ENUM_SERIESMODE mTenkanSenBottomMode = NULL; + +// +ENUM_SERIESMODE mKijunSenTopMode = NULL; +ENUM_SERIESMODE mKijunSenBottomMode = NULL; + +// +ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; +ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + RemoveDraws(drawPrefix); +} + +// +// 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; + + // + 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 = + // + // Validate Ichimoku Kinko Hyo ... + (tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ichimoku ... + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // ICHIMOKU ... + + // + // TENKANSEN ... + + // + ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType); + + // + // KIJUNSEN ... + + // + ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenBuffer, true); + SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType); + + // + // KIJUNSEN Plus ... + + // + ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenPlusBuffer, true); + SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType); + + // + // KIJUNSEN Negative ... + + // + ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenNegativeBuffer, true); + SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType); + + // + // CHIKOUSPAN ... + + // + ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(chikouSpanBuffer, true); + SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType); + + // + // SENKOUSPAN A and B ... + int shiftSize = shiftKumo ? kijunSenLength : 0; + + // + // SENKOUSPANA ... + ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouABuffer, true); + SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); + + // + // SENKOUSPANB ... + ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouBBuffer, true); + SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); + + // + // KUMO ... + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // KUMO ... + + // + ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; + + // + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType); +} + +// +// 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 +) +{ + // + // ICHIMOKU ... + + // + double topValue; + double bottomValue; + + // + // TENKANSEN ... + + // + // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... + if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) + { + // + switch (tenkanSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mTenkanSenTopMode = MODE_HIGH; + mTenkanSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mTenkanSenTopMode = MODE_OPEN; + mTenkanSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mTenkanSenTopMode, + tenkanSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mTenkanSenBottomMode, + tenkanSenLength, + bar_index); + + // + double tenkanSenValue = (topValue + bottomValue) / 2; + tenkanSenBuffer[bar_index] = tenkanSenValue; + + // + // KIJUNSEN ... + + // + // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... + if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) + { + // + switch (kijunSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mKijunSenTopMode = MODE_HIGH; + mKijunSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mKijunSenTopMode = MODE_OPEN; + mKijunSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mKijunSenTopMode, + kijunSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mKijunSenBottomMode, + kijunSenLength, + bar_index); + + // + double kijunSenValue = (topValue + bottomValue) / 2; + kijunSenBuffer[bar_index] = kijunSenValue; + + // + kijunSenPlusBuffer[bar_index] = kijunSenValue; + kijunSenNegativeBuffer[bar_index] = kijunSenValue; + + // + // CHIKOUSPAN ... + double chikouSpanValue = GetAppliedPrice( + bar_index, + chikuoSpanAppliedTo); + chikouSpanBuffer[bar_index] = chikouSpanValue; + + // + // KUMO ... + + // + // SENKOUSPANA ... + double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; + senkouABuffer[bar_index] = senkouSpanAValue; + senkouSpanABuffer[bar_index] = senkouSpanAValue; + + // + // SENKOUSPANB ... + + // + // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... + if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) + { + // + switch (senkouSpanBMode) + { + // + case X_XICH_HH_LL_MODE: + // + mSenkouSpanBTopMode = MODE_HIGH; + mSenkouSpanBBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mSenkouSpanBTopMode = MODE_OPEN; + mSenkouSpanBBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mSenkouSpanBTopMode, + senkouSpanBLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mSenkouSpanBBottomMode, + senkouSpanBLength, + bar_index); + + // + double senkouSpanBValue = (topValue + bottomValue) / 2; + senkouBBuffer[bar_index] = senkouSpanBValue; + senkouSpanBBuffer[bar_index] = senkouSpanBValue; + + // + return; + if (ArraySize(senkouABuffer) > bar_index + kijunSenLength + 1) + { + // + // Detect Koumo Switch ... + bool isKumoSwitchBullish = + // + senkouABuffer[bar_index + kijunSenLength] > senkouBBuffer[bar_index + kijunSenLength] && + senkouABuffer[bar_index + kijunSenLength + 1] <= senkouBBuffer[bar_index + kijunSenLength + 1] + // + ; + + // + // Detect Koumo Switch ... + bool isKumoSwitchBearish = + // + senkouABuffer[bar_index + kijunSenLength] < senkouBBuffer[bar_index + kijunSenLength] && + senkouABuffer[bar_index + kijunSenLength + 1] >= senkouBBuffer[bar_index + kijunSenLength + 1] + // + ; + + // + datetime time = iTime( + _Symbol, + _Period, + bar_index); + + // + long chartID = ChartID(); + + // + if (isKumoSwitchBullish) + { + // + string vlName = "Kumo_Switch_Bullish_NOW" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + clrAqua, + STYLE_DASHDOT); + } + + // + if (isKumoSwitchBearish) + { + // + string vlName = "Kumo_Switch_Bearish_NOW" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + clrMagenta, + STYLE_DASHDOT); + } + } + + // + return; + if (ArraySize(senkouABuffer) > bar_index + 1) + { + // + // Detect Koumo Switch ... + bool isKumoSwitchBullish = + // + senkouABuffer[bar_index] > senkouBBuffer[bar_index] && + senkouABuffer[bar_index + 1] <= senkouBBuffer[bar_index + 1] + // + ; + + // + // Detect Koumo Switch ... + bool isKumoSwitchBearish = + // + senkouABuffer[bar_index] < senkouBBuffer[bar_index] && + senkouABuffer[bar_index + 1] >= senkouBBuffer[bar_index + 1] + // + ; + + // + datetime time = iTime( + _Symbol, + _Period, + bar_index); + + // + long chartID = ChartID(); + + // + if (isKumoSwitchBullish) + { + // + string vlName = "Kumo_Switch_Bullish_FUTURE" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + clrAqua, + STYLE_DASHDOT); + } + + // + if (isKumoSwitchBearish) + { + // + string vlName = "Kumo_Switch_Bearish_FUTURE" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + clrMagenta, + STYLE_DASHDOT); + } + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xmc.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xmc.mq5 new file mode 100644 index 0000000..8a4aa26 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xmc.mq5 @@ -0,0 +1,469 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_MC MA Cross Indicator +// --------------------------------------------------- +// Name: X121_MC +// Description: Moving Average Crosses +// 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 X121_MC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_MC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Fast"; +input int fastMaLength = 9; // Length +input int fastMaShift = 0; // Shift +input ENUM_MA_METHOD fastMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE fastMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Slow"; +input int slowMaLength = 18; // Length +input int slowMaShift = 0; // Shift +input ENUM_MA_METHOD slowMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE slowMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Verifier"; +input int verifierMaLength = 50; // Length +input int verifierMaShift = 0; // Shift +input ENUM_MA_METHOD verifierMaMethod = MODE_EMA; // Method +input ENUM_APPLIED_PRICE verifierMaAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showVerifierMa = true; // Show Verifier + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "X121_MC MA F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrYellow +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "X121_MC MA S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDarkOrange +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// VERIFIER ... +#define verifierMaBufferIndex 2 +double verifierMaBuffer[]; + +// +#property indicator_label3 "X121_MC MA V" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrDarkBlue +#property indicator_style3 STYLE_SOLID +#property indicator_width3 2 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fastMaHandler = INVALID_HANDLE; +int slowMaHandler = INVALID_HANDLE; +int verifierMaHandler = 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; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // MA Initialization ... + + // + // FAST ... + fastMaHandler = iMA( + _Symbol, + _Period, + fastMaLength, + fastMaShift, + fastMaMethod, + fastMaAppliedTo); + if (fastMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + return INIT_FAILED; + } + + // + // SLOW ... + slowMaHandler = iMA( + _Symbol, + _Period, + slowMaLength, + slowMaShift, + slowMaMethod, + slowMaAppliedTo); + if (slowMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + return INIT_FAILED; + } + + // + // VERIFIER ... + verifierMaHandler = iMA( + _Symbol, + _Period, + verifierMaLength, + verifierMaShift, + verifierMaMethod, + verifierMaAppliedTo); + if (verifierMaHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + 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 ... + IndicatorRelease(fastMaHandler); + IndicatorRelease(slowMaHandler); + IndicatorRelease(verifierMaHandler); +} + +// +// 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; + + // + // Check Calculated Bars ... + int fastMaCalculatedBars = BarsCalculated(fastMaHandler); + int slowMaCalculatedBars = BarsCalculated(slowMaHandler); + int verifierMaCalculatedBars = BarsCalculated(verifierMaHandler); + if (fastMaCalculatedBars < maxLength || + slowMaCalculatedBars < maxLength || + verifierMaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFastMas = CopyBuffer(fastMaHandler, 0, 0, limit, fastMaBuffer); + int copiedSlowMas = CopyBuffer(slowMaHandler, 0, 0, limit, slowMaBuffer); + int copiedVerifierMas = CopyBuffer(verifierMaHandler, 0, 0, limit, verifierMaBuffer); + if (copiedFastMas <= 0 || + copiedSlowMas <= 0 || + copiedVerifierMas <= 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 = + // + // Validate Ma ... + (fastMaLength > 2 && + slowMaLength > fastMaLength && + verifierMaLength > slowMaLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + result = MathMax(result, fastMaLength); + result = MathMax(result, slowMaLength); + result = MathMax(result, verifierMaLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // MA ... + + // + // FAST ... + ENUM_DRAW_TYPE fastMaDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastMaDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowMaDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowMaDrawType); + + // + // VERIFIER ... + ENUM_DRAW_TYPE verifierMaDrawType = showVerifierMa ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(verifierMaBuffer, true); + SetIndexBuffer(verifierMaBufferIndex, verifierMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_TYPE, verifierMaDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xmrb.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xmrb.mq5 new file mode 100644 index 0000000..be26e52 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xmrb.mq5 @@ -0,0 +1,802 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_MRB MA Ribbon Indicator +// ----------------------------------------------------- +// Name: X121_MRB +// Description: Moving Average Ribbon +// 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 X121_MRB Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_MRB" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Ribbon 1"; +input int fast1Length = 3; // Fast +input int slow1Length = 5; // Slow + +// +input group "Ribbon 2"; +input int fast2Length = 8; // Fast +input int slow2Length = 13; // Slow + +// +input group "Ribbon 3"; +input int fast3Length = 21; // Fast +input int slow3Length = 34; // Slow + +// +input group "Ribbon 4"; +input int fast4Length = 55; // Fast +input int slow4Length = 89; // Slow + +// +input group "Ribbon 5"; +input int fast5Length = 144; // Fast +input int slow5Length = 233; // Slow + +// +input group "Calculation Mode"; +input ENUM_MA_METHOD ribbonMode = MODE_EMA; // Calculation Mode +input ENUM_APPLIED_PRICE ribbonAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showRibbon = false; // Show Ribbon + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 12 +#property indicator_plots 12 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "X121_MRB F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "X121_MRB S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +// FAST ... + +// +#define fast1BufferIndex 2 +double fast1Buffer[]; + +// +#property indicator_label3 "X121_MRB 1 F" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAquamarine +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define fast2BufferIndex 3 +double fast2Buffer[]; + +// +#property indicator_label4 "X121_MRB 2 F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrAquamarine +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define fast3BufferIndex 4 +double fast3Buffer[]; + +// +#property indicator_label5 "X121_MRB 3 F" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +#define fast4BufferIndex 5 +double fast4Buffer[]; + +// +#property indicator_label6 "X121_MRB 4 F" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +#define fast5BufferIndex 6 +double fast5Buffer[]; + +// +#property indicator_label7 "X121_MRB 5 F" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrAquamarine +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// SLOW ... + +// +#define slow1BufferIndex 7 +double slow1Buffer[]; + +// +#property indicator_label8 "X121_MRB 1 S" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrPlum +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +#define slow2BufferIndex 8 +double slow2Buffer[]; + +// +#property indicator_label9 "X121_MRB 2 S" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrPlum +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define slow3BufferIndex 9 +double slow3Buffer[]; + +// +#property indicator_label10 "X121_MRB 3 S" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrPlum +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define slow4BufferIndex 10 +double slow4Buffer[]; + +// +#property indicator_label11 "X121_MRB 4 S" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrPlum +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define slow5BufferIndex 11 +double slow5Buffer[]; + +// +#property indicator_label12 "X121_MRB 5 S" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrPlum +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fast1MaHandler = INVALID_HANDLE; +int fast2MaHandler = INVALID_HANDLE; +int fast3MaHandler = INVALID_HANDLE; +int fast4MaHandler = INVALID_HANDLE; +int fast5MaHandler = INVALID_HANDLE; + +// +int slow1MaHandler = INVALID_HANDLE; +int slow2MaHandler = INVALID_HANDLE; +int slow3MaHandler = INVALID_HANDLE; +int slow4MaHandler = INVALID_HANDLE; +int slow5MaHandler = 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; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize MAs ... + if (!InitializeMas()) + { + 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 ... + + // + IndicatorRelease(fast1MaHandler); + IndicatorRelease(fast2MaHandler); + IndicatorRelease(fast3MaHandler); + IndicatorRelease(fast4MaHandler); + IndicatorRelease(fast5MaHandler); + + // + IndicatorRelease(slow1MaHandler); + IndicatorRelease(slow2MaHandler); + IndicatorRelease(slow3MaHandler); + IndicatorRelease(slow4MaHandler); + IndicatorRelease(slow5MaHandler); +} + +// +// 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; + + // + // Check Calculated Bars ... + // + int fast1MaCalculatedBars = BarsCalculated(fast1MaHandler); + int fast2MaCalculatedBars = BarsCalculated(fast2MaHandler); + int fast3MaCalculatedBars = BarsCalculated(fast3MaHandler); + int fast4MaCalculatedBars = BarsCalculated(fast4MaHandler); + int fast5MaCalculatedBars = BarsCalculated(fast5MaHandler); + // + int slow1MaCalculatedBars = BarsCalculated(slow1MaHandler); + int slow2MaCalculatedBars = BarsCalculated(slow2MaHandler); + int slow3MaCalculatedBars = BarsCalculated(slow3MaHandler); + int slow4MaCalculatedBars = BarsCalculated(slow4MaHandler); + int slow5MaCalculatedBars = BarsCalculated(slow5MaHandler); + if ( + fast1MaCalculatedBars < maxLength || + fast2MaCalculatedBars < maxLength || + fast3MaCalculatedBars < maxLength || + fast4MaCalculatedBars < maxLength || + fast5MaCalculatedBars < maxLength || + slow1MaCalculatedBars < maxLength || + slow2MaCalculatedBars < maxLength || + slow3MaCalculatedBars < maxLength || + slow4MaCalculatedBars < maxLength || + slow5MaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + // + int copiedFast1Mas = CopyBuffer(fast1MaHandler, 0, 0, limit, fast1Buffer); + int copiedFast2Mas = CopyBuffer(fast2MaHandler, 0, 0, limit, fast2Buffer); + int copiedFast3Mas = CopyBuffer(fast3MaHandler, 0, 0, limit, fast3Buffer); + int copiedFast4Mas = CopyBuffer(fast4MaHandler, 0, 0, limit, fast4Buffer); + int copiedFast5Mas = CopyBuffer(fast5MaHandler, 0, 0, limit, fast5Buffer); + // + int copiedSlow1Mas = CopyBuffer(slow1MaHandler, 0, 0, limit, slow1Buffer); + int copiedSlow2Mas = CopyBuffer(slow2MaHandler, 0, 0, limit, slow2Buffer); + int copiedSlow3Mas = CopyBuffer(slow3MaHandler, 0, 0, limit, slow3Buffer); + int copiedSlow4Mas = CopyBuffer(slow4MaHandler, 0, 0, limit, slow4Buffer); + int copiedSlow5Mas = CopyBuffer(slow5MaHandler, 0, 0, limit, slow5Buffer); + if ( + copiedFast1Mas <= 0 || + copiedFast2Mas <= 0 || + copiedFast3Mas <= 0 || + copiedFast4Mas <= 0 || + copiedFast5Mas <= 0 || + copiedSlow1Mas <= 0 || + copiedSlow2Mas <= 0 || + copiedSlow3Mas <= 0 || + copiedSlow4Mas <= 0 || + copiedSlow5Mas <= 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 = + // + // Validate Ma ... + (fast1Length > 2 && + fast2Length > fast1Length && + fast3Length > fast2Length && + fast4Length > fast3Length && + fast5Length > fast4Length && + slow1Length > fast1Length && + slow2Length > fast2Length && + slow3Length > fast3Length && + slow4Length > fast4Length && + slow5Length > fast5Length && + slow2Length > slow1Length && + slow3Length > slow2Length && + slow4Length > slow3Length && + slow5Length > slow4Length + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + + // + result = MathMax(fast1Length, fast2Length); + result = MathMax(result, fast3Length); + result = MathMax(result, fast4Length); + result = MathMax(result, fast5Length); + + // + result = MathMax(result, slow1Length); + result = MathMax(result, slow2Length); + result = MathMax(result, slow3Length); + result = MathMax(result, slow4Length); + result = MathMax(result, slow5Length); + + // + return result; +} + +// +// Initialize Ma Handlers ... +bool InitializeMas() +{ + // + bool result = false; + + // + fast1MaHandler = iMA( + _Symbol, + _Period, + fast1Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast2MaHandler = iMA( + _Symbol, + _Period, + fast2Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast3MaHandler = iMA( + _Symbol, + _Period, + fast3Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast4MaHandler = iMA( + _Symbol, + _Period, + fast4Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast5MaHandler = iMA( + _Symbol, + _Period, + fast5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + slow1MaHandler = iMA( + _Symbol, + _Period, + slow1Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow2MaHandler = iMA( + _Symbol, + _Period, + slow2Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow3MaHandler = iMA( + _Symbol, + _Period, + slow3Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow4MaHandler = iMA( + _Symbol, + _Period, + slow4Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow5MaHandler = iMA( + _Symbol, + _Period, + slow5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + result = + fast1MaHandler != INVALID_HANDLE && + fast2MaHandler != INVALID_HANDLE && + fast3MaHandler != INVALID_HANDLE && + fast4MaHandler != INVALID_HANDLE && + fast5MaHandler != INVALID_HANDLE && + slow1MaHandler != INVALID_HANDLE && + slow2MaHandler != INVALID_HANDLE && + slow3MaHandler != INVALID_HANDLE && + slow4MaHandler != INVALID_HANDLE && + slow5MaHandler != INVALID_HANDLE; + + // + if (!result) + { + // + string message = "Error Initializing Handlers ..."; + LogMessage(message); + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // FAST ... + ENUM_DRAW_TYPE fastDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, showFastMa); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, showSlowMa); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowDrawType); + + // + // DATA ... + ENUM_DRAW_TYPE ribbonDrawType = showRibbon ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(fast1Buffer, true); + SetIndexBuffer(fast1BufferIndex, fast1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast2Buffer, true); + SetIndexBuffer(fast2BufferIndex, fast2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast3Buffer, true); + SetIndexBuffer(fast3BufferIndex, fast3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast4Buffer, true); + SetIndexBuffer(fast4BufferIndex, fast4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast5Buffer, true); + SetIndexBuffer(fast5BufferIndex, fast5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow1Buffer, true); + SetIndexBuffer(slow1BufferIndex, slow1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow2Buffer, true); + SetIndexBuffer(slow2BufferIndex, slow2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow3Buffer, true); + SetIndexBuffer(slow3BufferIndex, slow3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow4Buffer, true); + SetIndexBuffer(slow4BufferIndex, slow4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow5Buffer, true); + SetIndexBuffer(slow5BufferIndex, slow5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); +} + +// +// 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 +) +{ + // + // Retireve Values ... + + // + double fast1Value = fast1Buffer[bar_index]; + double fast2Value = fast2Buffer[bar_index]; + double fast3Value = fast3Buffer[bar_index]; + double fast4Value = fast4Buffer[bar_index]; + double fast5Value = fast5Buffer[bar_index]; + + // + double slow1Value = slow1Buffer[bar_index]; + double slow2Value = slow2Buffer[bar_index]; + double slow3Value = slow3Buffer[bar_index]; + double slow4Value = slow4Buffer[bar_index]; + double slow5Value = slow5Buffer[bar_index]; + + // + double fastValue = (fast1Value + fast2Value + fast3Value + fast4Value + fast5Value) / 5; + fastMaBuffer[bar_index] = fastValue; + + // + double slowValue = (slow1Value + slow2Value + slow3Value + slow4Value + slow5Value) / 5; + slowMaBuffer[bar_index] = slowValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xppsr.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xppsr.mq5 new file mode 100644 index 0000000..e9b53df --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xppsr.mq5 @@ -0,0 +1,1214 @@ +///////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_PPSR Pivot Points Indicator +// --------------------------------------------------------- +// Name: X121_PPSR +// Description: Pivot Points +// 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 X121_PPSR Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_PPSR" + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Level 1"; +input ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l1Period = NULL; // Time Period +input ENUM_SERIESMODE l1HHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE l1LLMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Level 2"; +input ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l2Period = NULL; // Time Period +input ENUM_SERIESMODE l2HHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE l2LLMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Level 3"; +input ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l3Period = NULL; // Time Period +input ENUM_SERIESMODE l3HHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE l3LLMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Level 4"; +input ENUM_X_PERIOD_METHOD l4Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l4Period = NULL; // Time Period +input ENUM_SERIESMODE l4HHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE l4LLMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; + +// +input group "Support and Resistace Levels"; +input bool showSRLevel1 = true; // Show Level 1 +input bool showSRLevel2 = true; // Show Level 2 +input bool showSRLevel3 = true; // Show Level 3 +input bool showSRLevel4 = true; // Show Level 4 + +// +input group "Pivot Point Levels"; +input bool showPPLevel1 = true; // Show Level 1 Pivots +input bool showPPLevel2 = true; // Show Level 2 Pivots +input bool showPPLevel3 = true; // Show Level 3 Pivots +input bool showPPLevel4 = true; // Show Level 4 Pivots + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 24 +#property indicator_plots 24 + +// +// PLOTTED Buffers ... + +// +// LEVEL 1 ... + +// +// RESISTANCE ... + +// +#define l1RBufferIndex 0 +double l1RBuffer[]; + +// +#property indicator_label1 "X121_PPSR L1 R" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrGoldenrod +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +#define l1R1BufferIndex 1 +double l1R1Buffer[]; + +// +#property indicator_label2 "X121_PPSR L1 R1" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrGoldenrod +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define l1R2BufferIndex 2 +double l1R2Buffer[]; + +// +#property indicator_label3 "X121_PPSR L1 R2" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGoldenrod +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// SUPPORT ... + +// +#define l1SBufferIndex 3 +double l1SBuffer[]; + +// +#property indicator_label4 "X121_PPSR L1 S" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrLightGreen +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define l1S1BufferIndex 4 +double l1S1Buffer[]; + +// +#property indicator_label5 "X121_PPSR L1 S1" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrLightGreen +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +#define l1S2BufferIndex 5 +double l1S2Buffer[]; + +// +#property indicator_label6 "X121_PPSR L1 S2" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGreen +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +// LEVEL 2 ... + +// +// RESISTANCE ... + +// +#define l2RBufferIndex 6 +double l2RBuffer[]; + +// +#property indicator_label7 "X121_PPSR L2 R" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrGoldenrod +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +#define l2R1BufferIndex 7 +double l2R1Buffer[]; + +// +#property indicator_label8 "X121_PPSR L2 R2" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrGoldenrod +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +#define l2R2BufferIndex 8 +double l2R2Buffer[]; + +// +#property indicator_label9 "X121_PPSR L2 R2" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrGoldenrod +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +// SUPPORT ... + +// +#define l2SBufferIndex 9 +double l2SBuffer[]; + +// +#property indicator_label10 "X121_PPSR L2 S" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrLightGreen +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define l2S1BufferIndex 10 +double l2S1Buffer[]; + +// +#property indicator_label11 "X121_PPSR L2 S1" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrLightGreen +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define l2S2BufferIndex 11 +double l2S2Buffer[]; + +// +#property indicator_label12 "X121_PPSR L2 S2" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrLightGreen +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// LEVEL 3 ... + +// +// RESISTANCE ... + +// +#define l3RBufferIndex 12 +double l3RBuffer[]; + +// +#property indicator_label13 "X121_PPSR L3 R" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrGoldenrod +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define l3R1BufferIndex 13 +double l3R1Buffer[]; + +// +#property indicator_label14 "X121_PPSR L3 R1" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrGoldenrod +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define l3R2BufferIndex 14 +double l3R2Buffer[]; + +// +#property indicator_label15 "X121_PPSR L3 R2" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrGoldenrod +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +// SUPPORT ... + +// +#define l3SBufferIndex 15 +double l3SBuffer[]; + +// +#property indicator_label16 "X121_PPSR L3 S" +#property indicator_type16 DRAW_LINE +#property indicator_color16 clrLightGreen +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +#define l3S1BufferIndex 16 +double l3S1Buffer[]; + +// +#property indicator_label17 "X121_PPSR L3 S1" +#property indicator_type17 DRAW_LINE +#property indicator_color17 clrLightGreen +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +#define l3S2BufferIndex 17 +double l3S2Buffer[]; + +// +#property indicator_label18 "X121_PPSR L3 S2" +#property indicator_type18 DRAW_LINE +#property indicator_color18 clrLightGreen +#property indicator_style18 STYLE_DOT +#property indicator_width18 1 + +// +// LEVEL 4 ... + +// +// RESISTANCE ... + +// +#define l4RBufferIndex 18 +double l4RBuffer[]; + +// +#property indicator_label19 "X121_PPSR L4 R" +#property indicator_type19 DRAW_LINE +#property indicator_color19 clrGoldenrod +#property indicator_style19 STYLE_DOT +#property indicator_width19 1 + +// +#define l4R1BufferIndex 19 +double l4R1Buffer[]; + +// +#property indicator_label20 "X121_PPSR L4 R1" +#property indicator_type20 DRAW_LINE +#property indicator_color20 clrGoldenrod +#property indicator_style20 STYLE_DOT +#property indicator_width20 1 + +// +#define l4R2BufferIndex 20 +double l4R2Buffer[]; + +// +#property indicator_label21 "X121_PPSR L4 R2" +#property indicator_type21 DRAW_LINE +#property indicator_color21 clrGoldenrod +#property indicator_style21 STYLE_DOT +#property indicator_width21 1 + +// +// SUPPORT ... + +// +#define l4SBufferIndex 21 +double l4SBuffer[]; + +// +#property indicator_label22 "X121_PPSR L4 S" +#property indicator_type22 DRAW_LINE +#property indicator_color22 clrLightGreen +#property indicator_style22 STYLE_DOT +#property indicator_width22 1 + +// +#define l4S1BufferIndex 22 +double l4S1Buffer[]; + +// +#property indicator_label23 "X121_PPSR L4 S1" +#property indicator_type23 DRAW_LINE +#property indicator_color23 clrLightGreen +#property indicator_style23 STYLE_DOT +#property indicator_width23 1 + +// +#define l4S2BufferIndex 23 +double l4S2Buffer[]; + +// +#property indicator_label24 "X121_PPSR L4 S2" +#property indicator_type24 DRAW_LINE +#property indicator_color24 clrLightGreen +#property indicator_style24 STYLE_DOT +#property indicator_width24 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int currentPeriodSecconds = 0; + +// +int mL1Candles; +double mLastL1R; +double mLastL1S; +int mLastL1StartBarIndex = 0; +ENUM_SERIESMODE mL1HHMode = NULL; +ENUM_SERIESMODE mL1LLMode = NULL; +datetime mLastL1StartTime = NULL; +ENUM_TIMEFRAMES mL1Period = NULL; + +// +int mL2Candles; +double mLastL2R; +double mLastL2S; +int mLastL2StartBarIndex = 0; +ENUM_SERIESMODE mL2HHMode = NULL; +ENUM_SERIESMODE mL2LLMode = NULL; +datetime mLastL2StartTime = NULL; +ENUM_TIMEFRAMES mL2Period = NULL; + +// +int mL3Candles; +double mLastL3R; +double mLastL3S; +int mLastL3StartBarIndex = 0; +ENUM_SERIESMODE mL3HHMode = NULL; +ENUM_SERIESMODE mL3LLMode = NULL; +datetime mLastL3StartTime = NULL; +ENUM_TIMEFRAMES mL3Period = NULL; + +// +int mL4Candles; +double mLastL4R; +double mLastL4S; +int mLastL4StartBarIndex = 0; +ENUM_SERIESMODE mL4HHMode = NULL; +ENUM_SERIESMODE mL4LLMode = NULL; +datetime mLastL4StartTime = NULL; +ENUM_TIMEFRAMES mL4Period = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Do Initialization ... + + // + if (currentPeriodSecconds == 0) + { + currentPeriodSecconds = PeriodSeconds(_Period); + } + + // + // Find Level 1 Period ... + if (mL1Period == NULL) + { + // + if (l1Method == X_PERIOD_AUTO) + { + mL1Period = GetNearestTimeFrame(_Period); + } + else + { + mL1Period = l1Period; + } + + // + int level1PeriodSecconds = PeriodSeconds(mL1Period); + + // + mL1Candles = level1PeriodSecconds / currentPeriodSecconds; + + // + mL1HHMode = l1HHMode == NULL ? MODE_HIGH : l1HHMode; + mL1LLMode = l1LLMode == NULL ? MODE_LOW : l1LLMode; + } + + // + // Find Level 2 Period ... + if (mL2Period == NULL) + { + // + if (l2Method == X_PERIOD_AUTO) + { + mL2Period = GetMediestTimeFrame(_Period); + } + else + { + mL2Period = l2Period; + } + + // + int level2PeriodSecconds = PeriodSeconds(mL2Period); + + // + mL2Candles = level2PeriodSecconds / currentPeriodSecconds; + + // + mL2HHMode = l2HHMode == NULL ? MODE_HIGH : l2HHMode; + mL2LLMode = l2LLMode == NULL ? MODE_LOW : l2LLMode; + } + + // + // Find Level 3 Period ... + if (mL3Period == NULL) + { + // + if (l3Method == X_PERIOD_AUTO) + { + mL3Period = GetFarestTimeFrame(_Period); + } + else + { + mL3Period = l3Period; + } + + // + int level3PeriodSecconds = PeriodSeconds(mL3Period); + + // + mL3Candles = level3PeriodSecconds / currentPeriodSecconds; + + // + mL3HHMode = l3HHMode == NULL ? MODE_HIGH : l3HHMode; + mL3LLMode = l3LLMode == NULL ? MODE_LOW : l3LLMode; + } + + // + // Find Level 4 Period ... + if (mL4Period == NULL) + { + // + if (l4Method == X_PERIOD_AUTO) + { + mL4Period = GetHindmostTimeFrame(_Period); + } + else + { + mL4Period = l4Period; + } + + // + int level4PeriodSecconds = PeriodSeconds(mL4Period); + + // + mL4Candles = level4PeriodSecconds / currentPeriodSecconds; + + // + mL4HHMode = l4HHMode == NULL ? MODE_HIGH : l4HHMode; + mL4LLMode = l4LLMode == NULL ? MODE_LOW : l4LLMode; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + string comment = GenerateComment(); + Comment(comment); + + // + // 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 +} + +// +// 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; + + // + 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 = + // + // Validate Inputs ... + (l1Method != X_PERIOD_NOTHING && + (l1Period == NULL ? l1Method == X_PERIOD_AUTO : true)) + // + && + // + (l2Method != X_PERIOD_NOTHING && + (l2Period == NULL ? l2Method == X_PERIOD_AUTO : true)) + // + && + // + (l3Method != X_PERIOD_NOTHING && + (l3Period == NULL ? l3Method == X_PERIOD_AUTO : true)) + // + && + // + (l4Method != X_PERIOD_NOTHING && + (l4Period == NULL ? l4Method == X_PERIOD_AUTO : true)) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LEVEL 1 ... + ENUM_DRAW_TYPE l1DrawType = showSRLevel1 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE l1PPDrawType = showPPLevel1 ? DRAW_LINE : DRAW_NONE; + + // + // RESISTANCE ... + ArraySetAsSeries(l1RBuffer, true); + SetIndexBuffer(l1RBufferIndex, l1RBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l1RBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l1RBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l1RBufferIndex, PLOT_DRAW_TYPE, l1DrawType); + + ArraySetAsSeries(l1R1Buffer, true); + SetIndexBuffer(l1R1BufferIndex, l1R1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l1R1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l1R1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l1R1BufferIndex, PLOT_DRAW_TYPE, l1PPDrawType); + + ArraySetAsSeries(l1R2Buffer, true); + SetIndexBuffer(l1R2BufferIndex, l1R2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l1R2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l1R2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l1R2BufferIndex, PLOT_DRAW_TYPE, l1PPDrawType); + + // + // SUPPORT ... + ArraySetAsSeries(l1SBuffer, true); + SetIndexBuffer(l1SBufferIndex, l1SBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l1SBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l1SBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l1SBufferIndex, PLOT_DRAW_TYPE, l1DrawType); + + ArraySetAsSeries(l1S1Buffer, true); + SetIndexBuffer(l1S1BufferIndex, l1S1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l1S1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l1S1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l1S1BufferIndex, PLOT_DRAW_TYPE, l1PPDrawType); + + ArraySetAsSeries(l1S2Buffer, true); + SetIndexBuffer(l1S2BufferIndex, l1S2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l1S2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l1S2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l1S2BufferIndex, PLOT_DRAW_TYPE, l1PPDrawType); + + // + // LEVEL 2 ... + ENUM_DRAW_TYPE l2DrawType = showSRLevel2 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE l2PPDrawType = showPPLevel2 ? DRAW_LINE : DRAW_NONE; + + // + // RESISTANCE ... + ArraySetAsSeries(l2RBuffer, true); + SetIndexBuffer(l2RBufferIndex, l2RBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l2RBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l2RBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l2RBufferIndex, PLOT_DRAW_TYPE, l2DrawType); + + ArraySetAsSeries(l2R1Buffer, true); + SetIndexBuffer(l2R1BufferIndex, l2R1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l2R1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l2R1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l2R1BufferIndex, PLOT_DRAW_TYPE, l2PPDrawType); + + ArraySetAsSeries(l2R2Buffer, true); + SetIndexBuffer(l2R2BufferIndex, l2R2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l2R2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l2R2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l2R2BufferIndex, PLOT_DRAW_TYPE, l2PPDrawType); + + // + // SUPPORT ... + ArraySetAsSeries(l2SBuffer, true); + SetIndexBuffer(l2SBufferIndex, l2SBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l2SBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l2SBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l2SBufferIndex, PLOT_DRAW_TYPE, l2DrawType); + + ArraySetAsSeries(l2S1Buffer, true); + SetIndexBuffer(l2S1BufferIndex, l2S1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l2S1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l2S1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l2S1BufferIndex, PLOT_DRAW_TYPE, l2PPDrawType); + + ArraySetAsSeries(l2S2Buffer, true); + SetIndexBuffer(l2S2BufferIndex, l2S2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l2S2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l2S2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l2S2BufferIndex, PLOT_DRAW_TYPE, l2PPDrawType); + + // + // LEVEL 3 ... + ENUM_DRAW_TYPE l3DrawType = showSRLevel3 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE l3PPDrawType = showPPLevel3 ? DRAW_LINE : DRAW_NONE; + + // + // RESISTANCE ... + ArraySetAsSeries(l3RBuffer, true); + SetIndexBuffer(l3RBufferIndex, l3RBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l3RBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l3RBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l3RBufferIndex, PLOT_DRAW_TYPE, l3DrawType); + + ArraySetAsSeries(l3R1Buffer, true); + SetIndexBuffer(l3R1BufferIndex, l3R1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l3R1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l3R1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l3R1BufferIndex, PLOT_DRAW_TYPE, l3PPDrawType); + + ArraySetAsSeries(l3R2Buffer, true); + SetIndexBuffer(l3R2BufferIndex, l3R2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l3R2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l3R2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l3R2BufferIndex, PLOT_DRAW_TYPE, l3PPDrawType); + + // + // SUPPORT ... + ArraySetAsSeries(l3SBuffer, true); + SetIndexBuffer(l3SBufferIndex, l3SBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l3SBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l3SBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l3SBufferIndex, PLOT_DRAW_TYPE, l3DrawType); + + ArraySetAsSeries(l3S1Buffer, true); + SetIndexBuffer(l3S1BufferIndex, l3S1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l3S1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l3S1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l3S1BufferIndex, PLOT_DRAW_TYPE, l3PPDrawType); + + ArraySetAsSeries(l3S2Buffer, true); + SetIndexBuffer(l3S2BufferIndex, l3S2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l3S2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l3S2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l3S2BufferIndex, PLOT_DRAW_TYPE, l3PPDrawType); + + // + // LEVEL 4 ... + ENUM_DRAW_TYPE l4DrawType = showSRLevel4 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE l4PPDrawType = showPPLevel4 ? DRAW_LINE : DRAW_NONE; + + // + // RESISTANCE ... + ArraySetAsSeries(l4RBuffer, true); + SetIndexBuffer(l4RBufferIndex, l4RBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l4RBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l4RBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l4RBufferIndex, PLOT_DRAW_TYPE, l4DrawType); + + ArraySetAsSeries(l4R1Buffer, true); + SetIndexBuffer(l4R1BufferIndex, l4R1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l4R1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l4R1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l4R1BufferIndex, PLOT_DRAW_TYPE, l4PPDrawType); + + ArraySetAsSeries(l4R2Buffer, true); + SetIndexBuffer(l4R2BufferIndex, l4R2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l4R2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l4R2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l4R2BufferIndex, PLOT_DRAW_TYPE, l4PPDrawType); + + // + // SUPPORT ... + ArraySetAsSeries(l4SBuffer, true); + SetIndexBuffer(l4SBufferIndex, l4SBuffer, INDICATOR_DATA); + PlotIndexSetInteger(l4SBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l4SBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l4SBufferIndex, PLOT_DRAW_TYPE, l4DrawType); + + ArraySetAsSeries(l4S1Buffer, true); + SetIndexBuffer(l4S1BufferIndex, l4S1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l4S1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l4S1BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l4S1BufferIndex, PLOT_DRAW_TYPE, l4PPDrawType); + + ArraySetAsSeries(l4S2Buffer, true); + SetIndexBuffer(l4S2BufferIndex, l4S2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(l4S2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l4S2BufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(l4S2BufferIndex, PLOT_DRAW_TYPE, l4PPDrawType); +} + +// +// 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 +) +{ + // + XOHCL c = GetCandle(bar_index); + + // + int maxCandles = MathMax(mL1Candles, mL2Candles); + maxCandles = MathMax(maxCandles, mL3Candles); + maxCandles = MathMax(maxCandles, mL4Candles); + + // + double l1RValue = 0; + double l1SValue = 0; + double l1CloseValue = 0; + + // + double l2RValue = 0; + double l2SValue = 0; + double l2CloseValue = 0; + + // + double l3RValue = 0; + double l3SValue = 0; + double l3CloseValue = 0; + + // + double l4RValue = 0; + double l4SValue = 0; + double l4CloseValue = 0; + + // + double l1PPValue = 0; + double l1R1Value = 0; + double l1R2Value = 0; + double l1S1Value = 0; + double l1S2Value = 0; + + // + double l2PPValue = 0; + double l2R1Value = 0; + double l2R2Value = 0; + double l2S1Value = 0; + double l2S2Value = 0; + + // + double l3PPValue = 0; + double l3R1Value = 0; + double l3R2Value = 0; + double l3S1Value = 0; + double l3S2Value = 0; + + // + double l4PPValue = 0; + double l4R1Value = 0; + double l4R2Value = 0; + double l4S1Value = 0; + double l4S2Value = 0; + + // + // LEVEL 1 ... + + // + l1RValue = GetHighestHigh( + mL1Candles, + bar_index, + mL1HHMode); + l1SValue = GetLowestLow( + mL1Candles, + bar_index, + mL1LLMode); + l1CloseValue = GetLowestLow( + mL1Candles, + bar_index, + MODE_CLOSE); + + // + // Calculate Pivot Points ... + double l1Diff = MathAbs(l1RValue - l1SValue); + l1PPValue = (l1RValue + l1SValue + l1CloseValue) / 3; + + // + l1R1Value = (2 * l1PPValue) - l1SValue; + l1R2Value = l1PPValue + (l1Diff); + + // + l1S1Value = (2 * l1PPValue) - l1RValue; + l1S2Value = l1PPValue - l1Diff; + + // + // LEVEL 2 ... + + // + l2RValue = GetHighestHigh( + mL2Candles, + bar_index, + mL2HHMode); + l2SValue = GetLowestLow( + mL2Candles, + bar_index, + mL2LLMode); + l2CloseValue = GetLowestLow( + mL2Candles, + bar_index, + MODE_CLOSE); + + // + // Calculate Pivot Points ... + double l2Diff = MathAbs(l2RValue - l2SValue); + l2PPValue = (l2RValue + l2SValue + l2CloseValue) / 3; + + // + l2R1Value = (2 * l2PPValue) - l2SValue; + l2R2Value = l2PPValue + (l2Diff); + + // + l2S1Value = (2 * l2PPValue) - l2RValue; + l2S2Value = l2PPValue - l2Diff; + + // + // LEVEL 3 ... + + // + l3RValue = GetHighestHigh( + mL3Candles, + bar_index, + mL3HHMode); + l3SValue = GetLowestLow( + mL3Candles, + bar_index, + mL3LLMode); + l3CloseValue = GetLowestLow( + mL3Candles, + bar_index, + MODE_CLOSE); + + // + // Calculate Pivot Points ... + double l3Diff = MathAbs(l3RValue - l3SValue); + l3PPValue = (l3RValue + l3SValue + l3CloseValue) / 3; + + // + l3R1Value = (2 * l3PPValue) - l3SValue; + l3R2Value = l1PPValue + (l3Diff); + + // + l3S1Value = (2 * l3PPValue) - l3RValue; + l3S2Value = l3PPValue - l3Diff; + + // + // LEVEL 4 ... + + // + l4RValue = GetHighestHigh( + mL4Candles, + bar_index, + mL4HHMode); + l4SValue = GetLowestLow( + mL4Candles, + bar_index, + mL4LLMode); + l4CloseValue = GetLowestLow( + mL4Candles, + bar_index, + MODE_CLOSE); + + // + // Calculate Pivot Points ... + double l4Diff = MathAbs(l4RValue - l4SValue); + l4PPValue = (l4RValue + l4SValue + l4CloseValue) / 3; + + // + l4R1Value = (2 * l4PPValue) - l4SValue; + l4R2Value = l4PPValue + (l4Diff); + + // + l4S1Value = (2 * l4PPValue) - l4RValue; + l4S2Value = l4PPValue - l4Diff; + + // + // FILLING BUFFERS ... + + // + l1RBuffer[bar_index] = l1RValue; + l1R1Buffer[bar_index] = l1R1Value; + l1R2Buffer[bar_index] = l1R2Value; + + // + l1SBuffer[bar_index] = l1SValue; + l1S1Buffer[bar_index] = l1S1Value; + l1S2Buffer[bar_index] = l1S2Value; + + // + l2RBuffer[bar_index] = l2RValue; + l2R1Buffer[bar_index] = l2R1Value; + l2R2Buffer[bar_index] = l2R2Value; + + // + l2SBuffer[bar_index] = l2SValue; + l2S1Buffer[bar_index] = l2S1Value; + l2S2Buffer[bar_index] = l2S2Value; + + // + l3RBuffer[bar_index] = l3RValue; + l3R1Buffer[bar_index] = l3R1Value; + l3R2Buffer[bar_index] = l3R2Value; + + // + l3SBuffer[bar_index] = l3SValue; + l3S1Buffer[bar_index] = l3S1Value; + l3S2Buffer[bar_index] = l3S2Value; + + // + l4RBuffer[bar_index] = l4RValue; + l4R1Buffer[bar_index] = l4R1Value; + l4R2Buffer[bar_index] = l4R2Value; + + // + l4SBuffer[bar_index] = l4SValue; + l4S1Buffer[bar_index] = l4S1Value; + l4S2Buffer[bar_index] = l4S2Value; +} + +// +// Generate Comment String ... +string GenerateComment() +{ + // + string result = ""; + + // + result += "L1 P: " + EnumToString(mL1Period) + "\n"; + result += "L2 P: " + EnumToString(mL2Period) + "\n"; + result += "L3 P: " + EnumToString(mL3Period) + "\n"; + result += "L4 P: " + EnumToString(mL4Period); + + // + return result; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xpv.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xpv.mq5 new file mode 100644 index 0000000..c0d2a47 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xpv.mq5 @@ -0,0 +1,1124 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_PV Peaks and Vales Indicator +// ----------------------------------------------------------- +// Name: X121_PV +// Description: Market Peaks and Vales +// 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 X121_PV Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_PV" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length +input int hindLength = 35; // Hind Length + +// +input group "Trend"; +input int numOfShoulder = 10; // Number of Shoulders for Swings + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showLevels = false; // Show Levels +input bool showTrend = false; // Show Trend +input bool showSRs = false; // Show Support and Resistance + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// 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" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 14 +#property indicator_plots 12 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "X121_PV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "X121_PV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "X121_PV R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, CLR_NONE +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "X121_PV S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrMagenta, CLR_NONE +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define sHHBufferIndex 6 +#define sHHBufferPlotIndex 4 +double sHHBuffer[]; + +// +#property indicator_label5 "X121_PV SHH" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrLightGray +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +#define sLLBufferIndex 7 +#define sLLBufferPlotIndex 5 +double sLLBuffer[]; + +// +#property indicator_label6 "X121_PV SLL" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGray +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +#define mHHBufferIndex 8 +#define mHHBufferPlotIndex 6 +double mHHBuffer[]; + +// +#property indicator_label7 "X121_PV MHH" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +#define mLLBufferIndex 9 +#define mLLBufferPlotIndex 7 +double mLLBuffer[]; + +// +#property indicator_label8 "X121_PV MLL" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrLightGray +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +#define lHHBufferIndex 10 +#define lHHBufferPlotIndex 8 +double lHHBuffer[]; + +// +#property indicator_label9 "X121_PV LHH" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrLightGray +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define lLLBufferIndex 11 +#define lLLBufferPlotIndex 9 +double lLLBuffer[]; + +// +#property indicator_label10 "X121_PV LLL" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrLightGray +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define hHHBufferIndex 12 +#define hHHBufferPlotIndex 10 +double hHHBuffer[]; + +// +#property indicator_label11 "X121_PV HHH" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrLightGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define hLLBufferIndex 13 +#define hLLBufferPlotIndex 11 +double hLLBuffer[]; + +// +#property indicator_label12 "X121_PV HLL" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrLightGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +// 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; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + RemoveDraws(drawPrefix); +} + +// +// 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; + + // + 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 = + // + // Validate Peaks and Vales ... + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength && + hindLength > longLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + result = MathMax(result, hindLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + // PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW_SHIFT, -20); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + // PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW_SHIFT, 20); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + ENUM_DRAW_TYPE zoneDrawType = showLevels ? DRAW_LINE : DRAW_NONE; + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); +} + +// +// 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 ... + + // + double rColorIDX = 1; + double sColorIDX = 1; + + // + // SHORT ... + + // + // HIGH ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LOW ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HIGH ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LOW ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HIGH ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LOW ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // HIND ... + + // + // HIGH ... + int hHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + hindLength, + bar_index); + double hHHValue = GetAppliedPrice( + hHHIndex, + hhMode); + + // + hHHBuffer[bar_index] = hHHValue; + + // + // LOW ... + int hLLIndex = iLowest( + _Symbol, + _Period, + llMode, + hindLength, + bar_index); + double hLLValue = GetAppliedPrice( + hLLIndex, + llMode); + + // + hLLBuffer[bar_index] = hLLValue; + + // + // RESISTANCE SUPPORT ... + + // + // RESISTANCE ... + double rValue = (sHHValue + mHHValue + lHHValue + hHHValue) / 4; + rBuffer[bar_index] = rValue; + + // + // SUPPORT ... + double sValue = (sLLValue + mLLValue + lLLValue + hLLValue) / 4; + sBuffer[bar_index] = sValue; + + // + // PEAKS and VALES ... + + // + // PEAKS ... + bool isPeak = rValue == hHHValue && + hHHValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + // + if (isPeak && lastPeak != rValue) + { + // + if (showPeaksAndVales) + { + rColorIDX = 0; + } + + // + lastPeak = rValue; + peaksBuffer[bar_index] = lastPeak; + } + else + { + peaksBuffer[bar_index] = lastPeak; + } + + // + // VALES ... + bool isVale = sValue == hLLValue && + hLLValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + // + if (isVale && lastVale != sValue) + { + // + if (showPeaksAndVales) + { + sColorIDX = 0; + } + + // + lastVale = sValue; + valesBuffer[bar_index] = lastVale; + } + else + { + valesBuffer[bar_index] = lastVale; + } + + // + // Set Default Colors ... + + // + rColorBuffer[bar_index] = rColorIDX; + sColorBuffer[bar_index] = sColorIDX; + + // + // Find Swings ... + + // + // High ... + int hSwing1 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + bar_index + 1); + + int hSwing2 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing1 + 1); + + // + // High ... + int hSwing3 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing2 + 1); + + // int hSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_HIGH, + // numOfShoulder, + // hSwing3 + 1); + + // + // Low ... + int lSwing1 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + bar_index + 1); + + int lSwing2 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing1 + 1); + + int lSwing3 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing2 + 1); + + // int lSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_LOW, + // numOfShoulder, + // lSwing3 + 1); + + // + if (bar_index < 50) + { + + // + bool isStrongResistance = + // + hHHBuffer[bar_index + 1] == hHHBuffer[bar_index + 2] && + hHHBuffer[bar_index + 2] == hHHBuffer[bar_index + 3] && + // + lHHBuffer[bar_index + 1] == lHHBuffer[bar_index + 2] && + lHHBuffer[bar_index + 2] == lHHBuffer[bar_index + 3] && + // + mHHBuffer[bar_index + 1] == mHHBuffer[bar_index + 2] && + mHHBuffer[bar_index + 2] == mHHBuffer[bar_index + 3] && + // + sHHBuffer[bar_index + 1] == sHHBuffer[bar_index + 2] && + sHHBuffer[bar_index + 2] == sHHBuffer[bar_index + 3] + // + ; + + // + bool isStrongSupport = + // + hLLBuffer[bar_index + 1] == hLLBuffer[bar_index + 2] && + hLLBuffer[bar_index + 2] == hLLBuffer[bar_index + 3] && + // + lLLBuffer[bar_index + 1] == lLLBuffer[bar_index + 2] && + lLLBuffer[bar_index + 2] == lLLBuffer[bar_index + 3] && + // + mLLBuffer[bar_index + 1] == mLLBuffer[bar_index + 2] && + mLLBuffer[bar_index + 2] == mLLBuffer[bar_index + 3] && + // + sLLBuffer[bar_index + 1] == sLLBuffer[bar_index + 2] && + sLLBuffer[bar_index + 2] == sLLBuffer[bar_index + 3] + // + ; + + // + if (isStrongResistance && showSRs) + { + // + DrawSupportResistance( + "R", + clrRed, + sHHBuffer[bar_index + 3], + bar_index + 3); + } + + // + if (isStrongSupport && showSRs) + { + // + DrawSupportResistance( + "S", + clrGreen, + sLLBuffer[bar_index + 3], + bar_index + 3); + } + } + + // + if (showTrend && bar_index < 20) + { + // + DrawSwing( + "High1", + MODE_HIGH, + clrAqua, + hSwing1, + hSwing2); + + // + DrawSwing( + "Low1", + MODE_LOW, + clrAqua, + lSwing1, + lSwing2); + + // + DrawSwing( + "High2", + MODE_HIGH, + clrMagenta, + hSwing2, + hSwing3); + + // + DrawSwing( + "Low2", + MODE_LOW, + clrMagenta, + lSwing2, + lSwing3); + } +} + +// +void DrawSwing( + string prefix, // Prefix ... + ENUM_SERIESMODE mode, // Swing Mode ... + color swingColor, // Color ... + int index1, // Index 1 ... + int index2 // Index 2 ... +) +{ + // + if (mode != MODE_HIGH && mode != MODE_LOW) + { + return; + } + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + index1); + + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + index1); + + // + XOHCL c2 = GetCandle( + _Symbol, + _Period, + index2); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + index2); + + // + double value1 = -1; + double value2 = -1; + + // + switch (mode) + { + // + case MODE_HIGH: + value1 = c1.high; + value2 = c2.high; + break; + + // + case MODE_LOW: + value1 = c1.low; + value2 = c2.low; + break; + } + + // + if (value1 == -1 || value2 == -1) + { + return; + } + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TrendLine"; + + // // + // if (IsDrawExists(tlName)) { + // RemoveDraw(tlName); + // } + + // + DrawTrendLine( + chartId, + tlName, + 0, + time2, + value2, + time1, + value1, + swingColor, + STYLE_DOT, + 3, + false, + false, + true); +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + string prefix, // Prefix ... + color lColor, // Color ... + double price, // Support or Resistance price ... + int bar_index // Start Bar Index ... +) +{ + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + bar_index - 1); + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TL" + "_" + (string)(NormalizePrice(price, _Symbol)); + + // + DrawTrendLine( + chartId, + tlName, + 0, + time1, + price, + time2, + price, + lColor, + STYLE_DOT, + 3, + false, + false, + true); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xsslc.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xsslc.mq5 new file mode 100644 index 0000000..bdfe5b2 --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xsslc.mq5 @@ -0,0 +1,453 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_SSLC SSL Channel +// ---------------------------------------------------- +// Name: X121_SSLC +// Description: SSL Channel 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 X121_SSLC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_SSLC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 30; // Length + +// +input group "Calculation"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Applied To +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Applied To + +// +input group "Presentation"; +input bool showUp = true; // Show Up +input bool showDown = true; // Show Down + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 2 + +// +// PLOTTED Buffers ... + +// +#define upBufferIndex 0 +double upBuffer[]; + +// +#property indicator_label1 "X121_SSLC Up" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#define downBufferIndex 1 +double downBuffer[]; + +// +#property indicator_label2 "X121_SSLC Down" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +#define upMaBufferIndex 2 +double upMaBuffer[]; + +// +#define downMaBufferIndex 3 +double downMaBuffer[]; + +// +#define kpiBufferIndex 4 +double kpiBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int upHandler = INVALID_HANDLE; +int downHandler = 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; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize Requierd Handlers ... + upHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + upAppliedTo); + downHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + downAppliedTo); + if (upHandler == INVALID_HANDLE || downHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + LogMessage(msg); + + // + 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 + + // + // Release Indicators ... + IndicatorRelease(upHandler); + IndicatorRelease(downHandler); +} + +// +// 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; + + // + // Check Calculated Bars ... + int upCalculatedBars = BarsCalculated(upHandler); + int downCalculatedBars = BarsCalculated(downHandler); + if (upCalculatedBars < maxLength || + downCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedUps = CopyBuffer(upHandler, 0, 0, limit, upMaBuffer); + int copiedDowns = CopyBuffer(downHandler, 0, 0, limit, downMaBuffer); + if (copiedUps <= 0 || + copiedDowns <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, limit, rates_total, prev_calculated, close); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + // Validate Inputs ... + (length > 2) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP ... + + // + ENUM_DRAW_TYPE upDrawType = showUp ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(upBuffer, true); + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_TYPE, upDrawType); + + // + // DOWN ... + + // + ENUM_DRAW_TYPE downDrawType = showDown ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(downBuffer, true); + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_TYPE, downDrawType); + + // + // DATA Buffers ... + + // + // UP MA ... + ArraySetAsSeries(upMaBuffer, true); + SetIndexBuffer(upMaBufferIndex, upMaBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN MA ... + ArraySetAsSeries(downMaBuffer, true); + SetIndexBuffer(downMaBufferIndex, downMaBuffer, INDICATOR_CALCULATIONS); + + // + // KPI ... + ArraySetAsSeries(kpiBuffer, true); + SetIndexBuffer(kpiBufferIndex, kpiBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = upMaBuffer[bar_index]; + double downMaValue = downMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) { + kpiValue = 1; + } else if (closeValue < downMaValue) { + kpiValue = -1; + } else { + kpiValue = kpiBuffer[bar_index + 1]; + } + + // + kpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + upBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + downBuffer[bar_index] = downValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xtm.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xtm.mq5 new file mode 100644 index 0000000..427af2b --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xtm.mq5 @@ -0,0 +1,355 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_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 X121_XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "X121_XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 0, + X_XTM_BEARISH = 2, + X_XTM_NEUTURAL = 1, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int length = 35; // Length +input int shift = 0; // Shift + +// +input group "Calculations"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE appliedTo = PRICE_LOW; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 2 +#property indicator_plots 2 + +// +// maBuffer ... +#define maBufferIndex 0 +double maBuffer[]; + +#define maColorBufferIndex 1 +double maColorBuffer[]; + +// +#property indicator_label1 "X121 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 maxLength; + +// +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; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + length, + shift, + method, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + Print(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; + + // + // 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; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ENUM_DRAW_TYPE drawType = showLine ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showLine); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// 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; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xtrnd.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xtrnd.mq5 new file mode 100644 index 0000000..32e70cd --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Indicators/x-saherelm.x121.xtrnd.mq5 @@ -0,0 +1,1151 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_XTRND Trends Indicator +// ----------------------------------------------------------- +// Name: X121_XTRND +// Description: Market Trend Detector ... +// 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 X121_XTRND Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XTRND" + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int cycleLength = 2; // Cycle Length to Check +input int numberOfVerifications = 2; // Number of Verifications + +// +input group "Calculation"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Detect Up +input ENUM_SERIESMODE llMode = MODE_LOW; // Detect Low + +// +input group "Cycles"; + +// +input group "Level 1"; +input ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l1Period = NULL; // Time Period + +// +input group "Level 2"; +input ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l2Period = NULL; // Time Period + +// +input group "Level 3"; +input ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l3Period = NULL; // Time Period + +// +input group "Presentation"; +input bool showConsolidations = false; // Show Consolidations +input bool showTrend = true; // Show Trend +input bool showL1Trends = false; // Show Cycle 1 Trend +input bool showL2Trends = false; // Show Cycle 2 Trend +input bool showL3Trends = false; // Show Cycle 3 Trend + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 16 +#property indicator_plots 16 + +// +// Higher High ... +#define hhBufferIndex 0 +#define hhPlotBufferIndex 0 +double hhBuffer[]; + +#define hhColorBufferIndex 1 +double hhColorBuffer[]; + +// +#property indicator_label1 "X121_XTRND U" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Lower Low ... +#define llBufferIndex 2 +#define llPlotBufferIndex 1 +double llBuffer[]; + +#define llColorBufferIndex 3 +double llColorBuffer[]; + +// +#property indicator_label2 "X121_XTRND D" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// CYCLE 1 ... + +// +// Higher High ... +#define l1hhBufferIndex 4 +#define l1hhPlotBufferIndex 2 +double l1hhBuffer[]; + +#define l1hhColorBufferIndex 5 +double l1hhColorBuffer[]; + +// +#property indicator_label3 "X121_XTRND C1 U" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Lower Low ... +#define l1llBufferIndex 6 +#define l1llPlotBufferIndex 3 +double l1llBuffer[]; + +#define l1llColorBufferIndex 7 +double l1llColorBuffer[]; + +// +#property indicator_label4 "X121_XTRND C1 D" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CYCLE 2 ... + +// +// Higher High ... +#define l2hhBufferIndex 8 +#define l2hhPlotBufferIndex 4 +double l2hhBuffer[]; + +#define l2hhColorBufferIndex 9 +double l2hhColorBuffer[]; + +// +#property indicator_label5 "X121_XTRND C2 U" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// Lower Low ... +#define l2llBufferIndex 10 +#define l2llPlotBufferIndex 5 +double l2llBuffer[]; + +#define l2llColorBufferIndex 11 +double l2llColorBuffer[]; + +// +#property indicator_label6 "X121_XTRND C2 D" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +// CYCLE 3 ... + +// +// Higher High ... +#define l3hhBufferIndex 12 +#define l3hhPlotBufferIndex 6 +double l3hhBuffer[]; + +#define l3hhColorBufferIndex 13 +double l3hhColorBuffer[]; + +// +#property indicator_label7 "X121_XTRND C3 U" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// Lower Low ... +#define l3llBufferIndex 14 +#define l3llPlotBufferIndex 7 +double l3llBuffer[]; + +#define l3llColorBufferIndex 15 +double l3llColorBuffer[]; + +// +#property indicator_label8 "X121_XTRND C3 D" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int currentPeriodSecconds = 0; + +// +// CYCLE 1 ... +int mL1Candles; +int mL1PeriodSecconds = 0; +int mLastL1StartBarIndex = 0; +datetime mLastL1StartTime = NULL; +ENUM_TIMEFRAMES mL1Period = NULL; + +// +// CYCLE 2 ... +int mL2Candles; +int mL2PeriodSecconds = 0; +int mLastL2StartBarIndex = 0; +datetime mLastL2StartTime = NULL; +ENUM_TIMEFRAMES mL2Period = NULL; + +// +// CYCLE 3 ... +int mL3Candles; +int mL3PeriodSecconds = 0; +int mLastL3StartBarIndex = 0; +datetime mLastL3StartTime = NULL; +ENUM_TIMEFRAMES mL3Period = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initial Periods ... + InitialCycles(); + + // + // 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 +} + +// +// 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; + + // + 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 = + // + (cycleLength > 0 && + numberOfVerifications > 0) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax( + cycleLength, + numberOfVerifications); + + // + return result; +} + +// +// Initial Multi Time Frame Cycles Periods ... +void InitialCycles() +{ + // + // Calculate Current Period Secconds ... + currentPeriodSecconds = PeriodSeconds(_Period); + + // + // Nearest ... + // Calculate Cycle 1 Requirements ... + if (mL1Period == NULL) + { + // + if (l1Method == X_PERIOD_AUTO) + { + mL1Period = GetNearestTimeFrame(_Period); + } + else + { + mL1Period = l1Period; + } + + // + mL1PeriodSecconds = PeriodSeconds(mL1Period); + + // + mL1Candles = mL1PeriodSecconds / currentPeriodSecconds; + } + + // + // Mediest ... + // Calculate Cycle 2 Requirements ... + if (mL2Period == NULL) + { + // + if (l2Method == X_PERIOD_AUTO) + { + mL2Period = GetMediestTimeFrame(_Period); + } + else + { + mL2Period = l2Period; + } + + // + mL2PeriodSecconds = PeriodSeconds(mL2Period); + + // + mL2Candles = mL2PeriodSecconds / currentPeriodSecconds; + } + + // + // Farest ... + // Calculate Cycle 3 Requirements ... + if (mL3Period == NULL) + { + // + if (l3Method == X_PERIOD_AUTO) + { + mL3Period = GetFarestTimeFrame(_Period); + } + else + { + mL3Period = l3Period; + } + + // + mL3PeriodSecconds = PeriodSeconds(mL3Period); + + // + mL3Candles = mL3PeriodSecconds / currentPeriodSecconds; + } +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ENUM_DRAW_TYPE drawType = showTrend ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_DRAW_TYPE, drawType); + + // + // COLOR Buffer ... + ArraySetAsSeries(hhColorBuffer, true); + SetIndexBuffer(hhColorBufferIndex, hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(llPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(llPlotBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(llColorBuffer, true); + SetIndexBuffer(llColorBufferIndex, llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // CYCLES ... + + // + // NEAREST ... + + // + ENUM_DRAW_TYPE l1DrawType = showL1Trends ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l1hhBuffer, true); + SetIndexBuffer(l1hhBufferIndex, l1hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l1hhPlotBufferIndex, PLOT_SHOW_DATA, showL1Trends); + PlotIndexSetInteger(l1hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l1hhPlotBufferIndex, PLOT_DRAW_TYPE, l1DrawType); + + // + // COLOR Buffer ... + ArraySetAsSeries(l1hhColorBuffer, true); + SetIndexBuffer(l1hhColorBufferIndex, l1hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l1llBuffer, true); + SetIndexBuffer(l1llBufferIndex, l1llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l1llPlotBufferIndex, PLOT_SHOW_DATA, showL1Trends); + PlotIndexSetInteger(l1llPlotBufferIndex, PLOT_DRAW_TYPE, l1DrawType); + PlotIndexSetInteger(l1llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l1llColorBuffer, true); + SetIndexBuffer(l1llColorBufferIndex, l1llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIEST ... + + // + ENUM_DRAW_TYPE l2DrawType = showL2Trends ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l2hhBuffer, true); + SetIndexBuffer(l2hhBufferIndex, l2hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l2hhPlotBufferIndex, PLOT_SHOW_DATA, showL2Trends); + PlotIndexSetInteger(l2hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l2hhPlotBufferIndex, PLOT_DRAW_TYPE, l2DrawType); + + // + // COLOR Buffer ... + ArraySetAsSeries(l2hhColorBuffer, true); + SetIndexBuffer(l2hhColorBufferIndex, l2hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l2llBuffer, true); + SetIndexBuffer(l2llBufferIndex, l2llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l2llPlotBufferIndex, PLOT_SHOW_DATA, showL2Trends); + PlotIndexSetInteger(l2llPlotBufferIndex, PLOT_DRAW_TYPE, l2DrawType); + PlotIndexSetInteger(l2llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l2llColorBuffer, true); + SetIndexBuffer(l2llColorBufferIndex, l2llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FAREST ... + + // + ENUM_DRAW_TYPE l3DrawType = showL3Trends ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l3hhBuffer, true); + SetIndexBuffer(l3hhBufferIndex, l3hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l3hhPlotBufferIndex, PLOT_SHOW_DATA, showL3Trends); + PlotIndexSetInteger(l3hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(l3hhPlotBufferIndex, PLOT_DRAW_TYPE, l3DrawType); + + // + // COLOR Buffer ... + ArraySetAsSeries(l3hhColorBuffer, true); + SetIndexBuffer(l3hhColorBufferIndex, l3hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l3llBuffer, true); + SetIndexBuffer(l3llBufferIndex, l3llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l3llPlotBufferIndex, PLOT_SHOW_DATA, showL3Trends); + PlotIndexSetInteger(l3llPlotBufferIndex, PLOT_DRAW_TYPE, l3DrawType); + PlotIndexSetInteger(l3llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l3llColorBuffer, true); + SetIndexBuffer(l3llColorBufferIndex, l3llColorBuffer, 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 +) +{ + // + // HIGHER Highs ... + double hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + cycleLength, + bar_index); + + // + hhBuffer[bar_index] = hh; + + // + // LOWER Lows ... + double ll = GetLowestLow( + _Symbol, + _Period, + llMode, + cycleLength, + bar_index); + + // + llBuffer[bar_index] = ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double hhColorIDX = showConsolidations ? 1 : 0; + double llColorIDX = showConsolidations ? 1 : 0; + + // + // Calculate Cycle Changes ... + + // + int cycleCLength = cycleLength * numberOfVerifications; + bool isCycleCLengthPassed = MathAbs(ArraySize(hhBuffer) - bar_index) > cycleCLength + 1; + + // + if (isCycleCLengthPassed) + { + // + bool isLowestLowUp = true; // ll > llBuffer[bar_index + 1]; + bool isLowestLowDown = true; // ll < llBuffer[bar_index + 1]; + bool isHighsestHighUp = true; // hh > hhBuffer[bar_index + 1]; + bool isHighsestHighDown = true; // hh < hhBuffer[bar_index + 1]; + for (int i = bar_index; i < bar_index + cycleCLength; i++) + { + // + double iHH = hhBuffer[i]; + double iLL = llBuffer[i]; + + // + if (hh < iHH) + { + isHighsestHighUp = false; + } + else if (hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (ll < iLL) + { + isLowestLowUp = false; + } + else if (ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + hhColorIDX = 2; + llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + hhColorIDX = 3; + llColorIDX = 3; + } + } + + // + hhColorBuffer[bar_index] = hhColorIDX; + llColorBuffer[bar_index] = llColorIDX; + + // + // CYCLE 1 ... + + // + int l1cycleLength = cycleLength * mL1Candles; + + // + // HIGHER Highs ... + double l1hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l1cycleLength, + bar_index); + + // + l1hhBuffer[bar_index] = l1hh; + + // + // LOWER Lows ... + double l1ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l1cycleLength, + bar_index); + + // + l1llBuffer[bar_index] = l1ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l1hhColorIDX = showConsolidations && showL1Trends ? 1 : 0; + double l1llColorIDX = showConsolidations && showL1Trends ? 1 : 0; + + // + // Calculate Cycle Changes ... + + // + int l1cycleCLength = l1cycleLength * numberOfVerifications; + bool isl1CycleCLengthPassed = MathAbs(ArraySize(l1hhBuffer) - bar_index) > l1cycleCLength + 1; + + // + if (isl1CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l1cycleCLength; i++) + { + // + double iHH = l1hhBuffer[i]; + double iLL = l1llBuffer[i]; + + // + if (l1hh < iHH) + { + isHighsestHighUp = false; + } + else if (l1hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l1ll < iLL) + { + isLowestLowUp = false; + } + else if (l1ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l1hhColorIDX = 2; + l1llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l1hhColorIDX = 3; + l1llColorIDX = 3; + } + } + + // + l1hhColorBuffer[bar_index] = l1hhColorIDX; + l1llColorBuffer[bar_index] = l1llColorIDX; + + // + // CYCLE 2 ... + + // + int l2cycleLength = cycleLength * mL2Candles; + + // + // HIGHER Highs ... + double l2hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l2cycleLength, + bar_index); + + // + l2hhBuffer[bar_index] = l2hh; + + // + // LOWER Lows ... + double l2ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l2cycleLength, + bar_index); + + // + l2llBuffer[bar_index] = l2ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l2hhColorIDX = showConsolidations && showL2Trends ? 1 : 0; + double l2llColorIDX = showConsolidations && showL2Trends ? 1 : 0; + + // + // Calculate Cycle Changes ... + + // + int l2cycleCLength = l2cycleLength * numberOfVerifications; + bool isl2CycleCLengthPassed = MathAbs(ArraySize(l2hhBuffer) - bar_index) > l2cycleCLength + 1; + + // + if (isl2CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l2cycleCLength; i++) + { + // + double iHH = l2hhBuffer[i]; + double iLL = l2llBuffer[i]; + + // + if (l2hh < iHH) + { + isHighsestHighUp = false; + } + else if (l2hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l2ll < iLL) + { + isLowestLowUp = false; + } + else if (l2ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l2hhColorIDX = 2; + l2llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l2hhColorIDX = 3; + l2llColorIDX = 3; + } + } + + // + l2hhColorBuffer[bar_index] = l2hhColorIDX; + l2llColorBuffer[bar_index] = l2llColorIDX; + + // + // CYCLE 3 ... + + // + int l3cycleLength = cycleLength * mL3Candles; + + // + // HIGHER Highs ... + double l3hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l3cycleLength, + bar_index); + + // + l3hhBuffer[bar_index] = l3hh; + + // + // LOWER Lows ... + double l3ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l3cycleLength, + bar_index); + + // + l3llBuffer[bar_index] = l3ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l3hhColorIDX = showConsolidations && showL3Trends ? 1 : 0; + double l3llColorIDX = showConsolidations && showL3Trends ? 1 : 0; + + // + // Calculate Cycle Changes ... + + // + int l3cycleCLength = l3cycleLength * numberOfVerifications; + bool isl3CycleCLengthPassed = MathAbs(ArraySize(l3hhBuffer) - bar_index) > l3cycleCLength + 1; + + // + if (isl3CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l3cycleCLength; i++) + { + // + double iHH = l3hhBuffer[i]; + double iLL = l3llBuffer[i]; + + // + if (l3hh < iHH) + { + isHighsestHighUp = false; + } + else if (l3hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l3ll < iLL) + { + isLowestLowUp = false; + } + else if (l3ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l3hhColorIDX = 2; + l3llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l3hhColorIDX = 3; + l3llColorIDX = 3; + } + } + + // + l3hhColorBuffer[bar_index] = l3hhColorIDX; + l3llColorBuffer[bar_index] = l3llColorIDX; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Providers/Test/x121.test.provider.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Providers/Test/x121.test.provider.mq5 new file mode 100644 index 0000000..85b37ee --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Providers/Test/x121.test.provider.mq5 @@ -0,0 +1,917 @@ +//////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTestPRVD Signal Provider Library +// -------------------------------------------------------- +// Name: XTestPRVD +// Description: XTestPRVD Signal provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Imports/Includes ... +// + +// +// 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 "../../Helpers/Test/x121.xpv.test.helper.mq5" +#include "../../Helpers/Test/x121.xmc.test.helper.mq5" +#include "../../Helpers/Test/x121.xmrb.test.helper.mq5" +#include "../../Helpers/Test/x121.xichi.test.helper.mq5" +#include "../../Helpers/Test/x121.xtrnd.test.helper.mq5" +#include "../../Helpers/Test/x121.xatrsl.test.helper.mq5" + +// +// END Imports/Includes ... +// + +// +// START Enum/Constant Definitions ... +// + +// +// Model Market Sence ... +struct X121MarketCondition +{ + // + // XPV ... + + // + bool isPVNewPeak; + bool isPVSamePeak; + bool isPVPeakBreakedUp; + bool isPVPeakBreakedDown; + + // + bool isPVNewVale; + bool isPVSameVale; + bool isPVValeBreakedUp; + bool isPVValeBreakedDown; + + // + // SSL Channel ... + bool isSSLUpOverDown; + bool isSSLUpUnderDown; + bool isSSLUpCrossedOverDown; + bool isSSLUpCrossedUnderDown; + + // + // XICHI ... + + // + // TNKIJ ... + bool isIchiTenkanSenOverKijunSen; + bool isIchiTenkanSenUnderKijunSen; + bool isIchiTenkanSenCrossedOverKijunSen; + bool isIchiTenkanSenCrossedUnderKijunSen; + + // + // KUMO ... + bool isIchiKumoBullish; + bool isIchiKumoBearish; + bool isIchiFutureKumoBullish; + bool isIchiFutureKumoBearish; + bool isIchiKumoSwitchedToBullish; + bool isIchiKumoSwitchedToBearish; + bool isIchiFutureKumoSwitchedToBullish; + bool isIchiFutureKumoSwitchedToBearish; + + // + // TNKUMO ... + bool isIchiTenkanSenOverSenkouSpanA; + bool isIchiTenkanSenOverSenkouSpanB; + bool isIchiTenkanSenCrossedOverSenkouSpanA; + bool isIchiTenkanSenCrossedOverSenkouSpanB; + bool isIchiTenkanSenUnderSenkouSpanA; + bool isIchiTenkanSenUnderSenkouSpanB; + bool isIchiTenkanSenCrossedUnderSenkouSpanA; + bool isIchiTenkanSenCrossedUnderSenkouSpanB; + + // + // KIJUMO ... + bool isIchiKijunSenOverSenkouSpanA; + bool isIchiKijunSenOverSenkouSpanB; + bool isIchiKijunSenCrossedOverSenkouSpanA; + bool isIchiKijunSenCrossedOverSenkouSpanB; + bool isIchiKijunSenUnderSenkouSpanA; + bool isIchiKijunSenUnderSenkouSpanB; + bool isIchiKijunSenCrossedUnderSenkouSpanA; + bool isIchiKijunSenCrossedUnderSenkouSpanB; + + // + // XTRND ... + + // + // CURRENT ... + bool isTrendBullish; + bool isTrendBearish; + bool isTrendConsolidation; + bool isTrendSwitchedToBullish; + bool isTrendSwitchedToBearish; + bool isTrendSwitchedToConsolidation; + + // + // LEVEL 1 ... + bool isTrendL1Bullish; + bool isTrendL1Bearish; + bool isTrendL1Consolidation; + bool isTrendL1SwitchedToBullish; + bool isTrendL1SwitchedToBearish; + bool isTrendL1SwitchedToConsolidation; + + // + // LEVEL 2 ... + bool isTrendL2Bullish; + bool isTrendL2Bearish; + bool isTrendL2Consolidation; + bool isTrendL2SwitchedToBullish; + bool isTrendL2SwitchedToBearish; + bool isTrendL2SwitchedToConsolidation; + + // + // LEVEL 3 ... + bool isTrendL3Bullish; + bool isTrendL3Bearish; + bool isTrendL3Consolidation; + bool isTrendL3SwitchedToBullish; + bool isTrendL3SwitchedToBearish; + bool isTrendL3SwitchedToConsolidation; + + // + // XMRB ... + + // + // MRIBBON ... + bool isRibbonBullish; + bool isRibbonBearish; + bool isRibbonSwitchedToBullish; + bool isRibbonSwitchedToBearish; + + // + // RIBOON 1 ... + bool isRibbon1Bullish; + bool isRibbon1Bearish; + bool isRibbon1SwitchedToBullish; + bool isRibbon1SwitchedToBearish; + + // + // RIBOON 2 ... + bool isRibbon2Bullish; + bool isRibbon2Bearish; + bool isRibbon2SwitchedToBullish; + bool isRibbon2SwitchedToBearish; + + // + // RIBOON 3 ... + bool isRibbon3Bullish; + bool isRibbon3Bearish; + bool isRibbon3SwitchedToBullish; + bool isRibbon3SwitchedToBearish; + + // + // RIBOON 4 ... + bool isRibbon4Bullish; + bool isRibbon4Bearish; + bool isRibbon4SwitchedToBullish; + bool isRibbon4SwitchedToBearish; + + // + // RIBOON 5 ... + bool isRibbon5Bullish; + bool isRibbon5Bearish; + bool isRibbon5SwitchedToBullish; + bool isRibbon5SwitchedToBearish; + + // + // XMC ... + bool isMCFastOverSlow; + bool isMCFastUnderSlow; + bool isMCFastCrossedOverSlow; + bool isMCFastCrossedUnderSlow; + bool isMCFastOverVerifier; + bool isMCFastUnderVerifier; + bool isMCFastCrossedOverVerifier; + bool isMCFastCrossedUnderVerifier; + bool isMCSlowOverVerifier; + bool isMCSlowUnderVerifier; + bool isMCSlowCrossedOverVerifier; + bool isMCSlowCrossedUnderVerifier; + + // + // XAMA ... + bool isXAMABullish; + bool isXAMABearish; + bool isXAMANeutural; + bool isXAMAChangedToBullish; + bool isXAMAChangedToBearish; + bool isXAMAChangedToNeutural; + + // + // XTM ... + bool isXTMBullish; + bool isXTMBearish; + bool isXTMNeutural; + bool isXTMChangedToBullish; + bool isXTMChangedToBearish; + bool isXTMChangedToNeutural; +} + +// +// END Enum/Constant Definitions ... +// + +// +// START Variables ... +// + +// +int mcclearHandler = INVALID_HANDLE; + +// +// END Variables ... +// + +// +// START Signal Provider Functions ... +// + +// +bool XTestPRVDOnInit() +{ + // + bool result = false; + + // + result = XATRSLHLPOnInit(); + if (!result) + { + return result; + } + + // + result = XICHIHLPOnInit(); + if (!result) + { + return result; + } + + // + result = XMCHLPOnInit(); + if (!result) + { + return result; + } + + // + result = XMRBHLPOnInit(); + if (!result) + { + return result; + } + + // + result = XPVHLPOnInit(); + if (!result) + { + return result; + } + + // + result = XTRNDHLPOnInit(); + if (!result) + { + return result; + } + + // + // Initial CCLear Handler ... + mcclearHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xcclear", + // + // Inputs ... + // + // CHARTSTYLE ... + "", + // + // Up Color ... + clrLime, + // + // Down Color ... + clrRed, + // + // Line mode and Doji candlestick Color ... + clrLime, + // + // Bullish Color ... + clrRed, + // + // Bearish Color ... + clrLime, + // + // Volumes Color ... + clrGreen, + // + // PRESENTATION ... + "", + true + // + ); + result = mcclearHandler != INVALID_HANDLE; + + // + return result; +} + +// +void XTestPRVDOnDeInit() +{ + // + XATRSLHLPOnDeInit(); + XICHIHLPOnDeInit(); + XMCHLPOnDeInit(); + XMRBHLPOnDeInit(); + XPVHLPOnDeInit(); + XTRNDHLPOnDeInit(); +} + +// +void XTestPRVDOnTick() +{ + XATRSLHLPReadBuffers(); + XICHIHLPReadBuffers(); + XMCHLPReadBuffers(); + XMRBHLPReadBuffers(); + XPVHLPReadBuffers(); + XTRNDHLPReadBuffers(); +} + +// +bool XTestPRVDProcessSignals(XSignal &result) +{ + // + bool mResult = false; + + // + // BUY ... + + // + Clean(result); + bool hasLongSignal = XTestPRVDHasLongSignal(result); + if (hasLongSignal) + { + // + mResult = true; + return mResult; + } + + // + // SELL ... + + // + Clean(result); + bool hasShortignal = XTestPRVDHasShortSignal(result); + if (hasShortignal) + { + // + mResult = true; + return mResult; + } + + // + return mResult; +} + +// +bool XTestPRVDHasLongSignal(XSignal &result) +{ + // + bool mResult = false; + return mResult; + + // + XOHCLSupRes supRes = XPVHLPFindCandleSupprtAndResistance(1, 6); + bool hasSupport = ArraySize(supRes.sup) > 0; + bool hasResistance = ArraySize(supRes.res) > 0; + + // + double r2r = 1.2; + double riskAmount = 0.005; + double entry = GetEntry( + _Symbol, + POSITION_TYPE_BUY); + double sl = entry - + (hasSupport + ? (supRes.sup[ArrayMaximum(supRes.sup)] - supRes.sup[ArrayMinimum(supRes.sup)]) + : hasResistance + ? (supRes.res[ArrayMaximum(supRes.res)] - supRes.res[ArrayMinimum(supRes.res)]) + : PointToPrice( + _Symbol, + 10)) + // + ; + + // + bool isXTestHasSignal = XTestPRVDHasLongCondition(); + if (isXTestHasSignal) + { + // + Add( + "XTest", + result.providers); + + // + result.r2r = 1.5; + + // + result.sl = atrslDownBuffer[1]; + } + + // + bool isXTRNDHasSignal = XTRNDHasLongCondition(); + if (isXTRNDHasSignal) + { + // + Add( + "XTRND", + result.providers); + } + + // + bool isXICHIHasSignal = XICHIHasLongCondition(); + if (isXICHIHasSignal) + { + // + Add( + "XICHI", + result.providers); + } + + // + mResult = + // + isXTRNDHasSignal + // + || + // + isXICHIHasSignal + // + ; + + // + if (mResult) + { + // + result.sl = sl; + result.r2r = r2r; + result.entry = entry; + result.symbol = _Symbol; + result.period = _Period; + result.riskAmount = riskAmount; + result.type = POSITION_TYPE_BUY; + result.supportAndResistance = supRes; + } + + // + return mResult; +} + +// +bool XTestPRVDHasShortSignal(XSignal &result) +{ + // + bool mResult = false; + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + XOHCLSupRes supRes = XPVHLPFindCandleSupprtAndResistance(1, 6); + bool hasSupport = ArraySize(supRes.sup) > 0; + bool hasResistance = ArraySize(supRes.res) > 0; + + // + double r2r = 1.2; + double riskAmount = 0.005; + double entry = GetEntry( + _Symbol, + POSITION_TYPE_SELL); + double sl = entry + (supRes.res[ArrayMaximum(supRes.res)] - supRes.res[ArrayMinimum(supRes.res)]); + + // + bool isXTRNDHasSignal = XTRNDHasShortCondition(); + if (isXTRNDHasSignal) + { + // + Add( + "XTRND", + result.providers); + } + + // + bool isICHIHasSignal = XICHIHasShortCondition(); + if (isICHIHasSignal) + { + // + Add( + "XICHI", + result.providers); + } + + // + mResult = + // + isXTRNDHasSignal + // + // || + // // + // TODO: + // isICHIHasSignal + // + ; + + // + if (mResult) + { + // + result.sl = sl; + result.r2r = r2r; + result.entry = entry; + result.symbol = _Symbol; + result.period = _Period; + result.riskAmount = riskAmount; + result.type = POSITION_TYPE_SELL; + result.mode = X_ORDER_MODE_MARKET; + result.supportAndResistance = supRes; + + // + if (!hasSupport) + { + // + // When there is no any Provided Support for a Singal ... + // Place Pending Order instead of Market Order and use + // PV's LL Buffers as Supprt area ... + result.mode = X_ORDER_MODE_STOP; + double supportArea = XPVHLPGetMaxLL(1) - GetCandleShadow(c1); + result.entry = supportArea; + } + } + + // + return mResult; +} + +// +// TODO: Implement it ... +bool XTestPRVDForceCloseAllShorts() +{ + // + bool result = false; + + // // + // XOHCL c1 = GetCandle( + // _Symbol, + // _Period, + // 1); + + // // + // result = + // // + // c1.low < ichiKijunSenBuffer[1] && + // c1.high > ichiKijunSenBuffer[1] + // // + // ; + + // + return result; +} + +// +bool XTestPRVDHasLongCondition() +{ + // + bool result = false; + + // + return result; +} + +// +bool XTestPRVDHasShortCondition() +{ + // + bool result = false; + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + + // + return result; +} + +// +// XTRND .. + +// +bool XTRNDForceCloseAllLongs() +{ + // + bool result = false; + + // + return result; +} + +// +bool XTRNDForceCloseAllShorts() +{ + // + bool result = false; + + // + return result; +} + +// +bool XTRNDHasLongCondition() +{ + // + bool result = false; + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + + // + XIchiInfo ichi1 = XICHIHLPGetInfo(1); + + // + bool isTrendSwitchedToBullish = + // + ( + // + XTRNDHLPIsL3TrendSwitchedBullish(1) && + XTRNDHLPIsTrendBullish(1) && + XTRNDHLPIsL1TrendBullish(1) && + XTRNDHLPIsL2TrendBullish(1) + // + ) + // + || + // + ( + // + XTRNDHLPIsL2TrendSwitchedBullish(1) && + XTRNDHLPIsTrendBullish(1) && + XTRNDHLPIsL1TrendBullish(1) && + XTRNDHLPIsL3TrendBullish(1) + // + ) + // + || + // + ( + // + XTRNDHLPIsL1TrendSwitchedBullish(1) && + XTRNDHLPIsTrendBullish(1) && + XTRNDHLPIsL2TrendBullish(1) && + XTRNDHLPIsL3TrendBullish(1) + // + ) + // + ; + + // + bool signal1 = + // + isTrendSwitchedToBullish + // + ; + + // + result = + // + signal1 + // + ; + + // + return result; +} + +// +bool XTRNDHasShortCondition() +{ + // + bool result = false; + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + + // + bool isTrendSwitchedToBearish = + // + ( + // + XTRNDHLPIsL3TrendSwitchedBearish(1) && + XTRNDHLPIsTrendBearish(1) && + XTRNDHLPIsL1TrendBearish(1) && + XTRNDHLPIsL2TrendBearish(1) + // + ) + // + || + // + ( + // + XTRNDHLPIsL2TrendSwitchedBearish(1) && + XTRNDHLPIsTrendBearish(1) && + XTRNDHLPIsL1TrendBearish(1) && + XTRNDHLPIsL3TrendBearish(1) && + XTRNDHLPIsTrendBearish(2) && + XTRNDHLPIsL1TrendBearish(2) && + XTRNDHLPIsL3TrendBearish(2) + // + ) + // + || + // + ( + // + XTRNDHLPIsL1TrendSwitchedBearish(1) && + XTRNDHLPIsTrendBearish(1) && + XTRNDHLPIsL2TrendBearish(1) && + XTRNDHLPIsL3TrendBearish(1) && + XTRNDHLPIsTrendBearish(2) && + XTRNDHLPIsL2TrendBearish(2) && + XTRNDHLPIsL3TrendBearish(2) && + XTRNDHLPIsTrendBearish(3) && + XTRNDHLPIsL2TrendBearish(3) && + XTRNDHLPIsL3TrendBearish(3) + // + ) + // + ; + + // + bool signal1 = + // + isTrendSwitchedToBearish + // + ; + + // + result = + // + signal1 + // + ; + + // + return result; +} + +// +// XICHI ... + +// +bool XICHIForceCloseAllShorts() +{ + // + bool result = false; + + // + return result; +} + +// +bool XICHIForceCloseAllLongs() +{ + // + bool result = false; + + // + return result; +} + +// +bool XICHIHasLongCondition() +{ + // + bool result = false; + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + XIchiInfo info1 = XICHIHLPGetInfo(1); + + // + bool isKumoSwitchedToBullish = + // + XICHIHLPIsKumoSwitchedToBullish(1) + // + ; + + // + bool signal1 = + // + isKumoSwitchedToBullish && + c1.low > info1.tenkanSen && + info1.tenkanSen > info1.kijunSen && + info1.kijunSen > MathMax(info1.senkouSpanA, info1.senkouSpanB) + // + ; + + // + result = + // + signal1 + // + ; + + // + return result; +} + +// +bool XICHIHasShortCondition() +{ + // + bool result = false; + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + XIchiInfo info1 = XICHIHLPGetInfo(1); + + // + bool isKumoSwitchedToBearish = + // + XICHIHLPIsKumoSwitchedToBearish(1) + // + ; + + // + bool signal1 = + // + isKumoSwitchedToBearish && + c1.high < info1.tenkanSen && + info1.tenkanSen < info1.kijunSen && + info1.kijunSen < MathMin(info1.senkouSpanA, info1.senkouSpanB) + // + ; + + // + result = + // + signal1 + // + ; + + // + return result; +} + +// +// END Signal Provider Functions ... +// \ No newline at end of file diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Providers/x.saherelm.x121.provider.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Providers/x.saherelm.x121.provider.mq5 new file mode 100644 index 0000000..6da98ed --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Providers/x.saherelm.x121.provider.mq5 @@ -0,0 +1,1590 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Class Library +// ---------------------------------------------- +// Name: XSCX121P +// Description: X121 Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Helpers/x-saherelm.x121.xpv.helper.mq5" +#include "../Helpers/x-saherelm.x121.xhk.helper.mq5" +#include "../Helpers/x-saherelm.x121.xmc.helper.mq5" +#include "../Helpers/x-saherelm.x121.xich.helper.mq5" +#include "../Helpers/x-saherelm.x121.xmrb.helper.mq5" +#include "../Helpers/x-saherelm.x121.xppsr.helper.mq5" +#include "../Helpers/x-saherelm.x121.xsslc.helper.mq5" +#include "../Helpers/x-saherelm.x121.xtrnd.helper.mq5" +#include "../Helpers/x-saherelm.x121.xatrsl.helper.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCX121Provider : public XSCEABaseProvider +{ + // + // Public ... +public: + // + // Props ... + // + // Define Helpers ... + + // + // MC ... + XSCXMCHelper mMCHelper; + + // + // PV ... + XSCXPVHelper mPVHelper; + + // + // HKENASHI ... + XSCXHKHelper mHKHelper; + + // + // MRB ... + XSCXMRBHelper mMRBHelper; + + // + // ICHIMOKU ... + XSCXICHHelper mIchiHelper; + + // + // SSLC ... + XSCXSSLCHelper mSSLCHelper; + + // + // PPSR ... + XSCXPPSRHelper mPPSRHelper; + + // + // TRND ... + XSCXTRNDHelper mTRNDHelper; + + // + // ATRSL ... + XSCXATRSLHelper mATRSLHelper; + + // + // Constructor ... + void XSCX121Provider() : XSCEABaseProvider(){}; + void XSCX121Provider( + // + // Symbol ... + string symbol, + // + // Period ... + ENUM_TIMEFRAMES period + // + ) : XSCEABaseProvider(symbol, period) + { + // + mTag = "X121_Provider_" + mSymbol + "_" + ToString(mPeriod); + + // + mCTimerHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xct", + // + // Inputs ... + clrYellow, + CORNER_RIGHT_LOWER + // + ); + + // // + // ArraySetAsSeries(mEMA200Buffer, true); + // mEMA200Handler = iMA( + // mSymbol, + // mPeriod, + // 200, + // 0, + // MODE_EMA, + // PRICE_CLOSE); + + // // + // ArraySetAsSeries(mRSIBuffer, true); + // mRSIHandler = iRSI( + // mSymbol, + // mPeriod, + // 14, + // PRICE_CLOSE); + + // + // CCI Initialization ... + ArraySetAsSeries(mCCIBuffer, true); + mCCIHandler = iCCI( + mSymbol, + mPeriod, + 14, + PRICE_TYPICAL); + + // + // Instance Helpers ... + + // + // MC ... + mMCHelper = new XSCXMCHelper( + mSymbol, + mPeriod); + + // + // PV ... + mPVHelper = new XSCXPVHelper( + mSymbol, + mPeriod); + + // + // HIKENASHI ... + mHKHelper = new XSCXHKHelper( + mSymbol, + mPeriod); + + // + // MRB ... + mMRBHelper = new XSCXMRBHelper( + mSymbol, + mPeriod); + + // + // ICHIMOKU ... + mIchiHelper = new XSCXICHHelper( + mSymbol, + mPeriod); + + // + // SSLC ... + mSSLCHelper = new XSCXSSLCHelper( + mSymbol, + mPeriod); + + // + // PPSR ... + mPPSRHelper = new XSCXPPSRHelper( + mSymbol, + mPeriod); + + // + // TRND ... + mTRNDHelper = new XSCXTRNDHelper( + mSymbol, + mPeriod); + + // + // ATRSL ... + mATRSLHelper = new XSCXATRSLHelper( + mSymbol, + mPeriod); + } + + // + // Deconstructor ... + void ~XSCX121Provider() + { + // + IndicatorRelease(mCCIHandler); + IndicatorRelease(mCTimerHandler); + // IndicatorRelease(mRSIHandler); + // IndicatorRelease(mIchimokuHandler); + // IndicatorRelease(mEMA200Handler); + + // + // De construct Helpers ... + } + + // + virtual void ProcessBuffers() + { + // + mMCHelper.ReadBuffers(); + mPVHelper.ReadBuffers(); + mHKHelper.ReadBuffers(); + mMRBHelper.ReadBuffers(); + mSSLCHelper.ReadBuffers(); + mIchiHelper.ReadBuffers(); + mPPSRHelper.ReadBuffers(); + mTRNDHelper.ReadBuffers(); + mATRSLHelper.ReadBuffers(); + + // // + // /// EMA 200 ... + // CopyBuffer(mEMA200Handler, 0, 0, 10, mEMA200Buffer); + + // // + // /// RSI 14 ... + // CopyBuffer(mRSIHandler, 0, 0, 10, mRSIBuffer); + + // + // CCI 14 ... + CopyBuffer(mCCIHandler, 0, 0, 10, mCCIBuffer); + } + + // + virtual void ProcessTick() + { + ProcessSignals(); + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // CCandle Timer ... + int mCTimerHandler; + + // // + // // EMA 200 ... + // int mEMA200Handler; + // double mEMA200Buffer[]; + + // // + // // RSI ... + // int mRSIHandler; + // double mRSIBuffer[]; + + // + // CCI ... + int mCCIHandler; + double mCCIBuffer[]; + + // + // Here we are Capture Conditions and Check Signals ... + // The Signals Must be Unique for each providers ... + void ProcessSignals() + { + // + XSignalInfo signal; + + // + // BUY ... + + // + Clean(signal); + bool hasLongSignal = HasLongSignal(signal); + if (hasLongSignal) + { + // + NotifyOnSignalEvent( + signal); + mWaitUntilNewCandle = true; + return; + } + + // + // SELL ... + + // + Clean(signal); + bool hasShortignal = HasShortSignal(signal); + if (hasShortignal) + { + // + NotifyOnSignalEvent( + signal); + mWaitUntilNewCandle = true; + return; + } + } + + // + // START Providers Signals ... + // + + // + // Check has Long Signal on Each Strategies ... + bool HasLongSignal(XSignalInfo &info) + { + // + bool result = false; + + // + double entry = GetEntry(POSITION_TYPE_BUY); + + // + bool isXMRBHasSignal = false; // XMRBHasLongCondition(); + if (isXMRBHasSignal) + { + // + Add( + "XMRB", + info.providers); + + // + info.r2r = 1.5; + + // + // info.sl = mATRSLHelper.downBuffer[1]; + } + + // + bool isXPVHasSignal = false; // XPVHasLongCondition(); + if (isXPVHasSignal) + { + // + Add( + "XPV", + info.providers); + + // + info.r2r = 1.4; + + // + double slValue = mPVHelper.sLLBuffer[1]; + // slValue -= PointToPrice( + // mSymbol, + // 5 + // ); + // info.sl = slValue; + info.sl = mATRSLHelper.downBuffer[1]; + } + + // + bool isXICHIHasSignal1 = false; // XICHIHasLongCondition1(); + if (isXICHIHasSignal1) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1.5; + + // + double llValue = GetLowestLow( + mSymbol, + mPeriod, + 3, + 0); + llValue -= PointToPrice( + mSymbol, + 5); + + // + info.sl = llValue; + } + + // + bool isXICHIHasSignal2 = false; // XICHIHasLongCondition2(); + if (isXICHIHasSignal2) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1; + + // + double llValue = GetLowestLow( + mSymbol, + mPeriod, + 3, + 0); + llValue -= PointToPrice( + mSymbol, + 5); + + // + info.sl = llValue; + } + + // + bool isXICHIHasSignal3 = false; // XICHIHasLongCondition3(); + if (isXICHIHasSignal3) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1.5; + + // + double llValue = GetLowestLow( + mSymbol, + mPeriod, + 3, + 0); + llValue -= PointToPrice( + mSymbol, + 5); + + // + info.sl = llValue; + } + + // + bool isXICHIHasSignal4 = XICHIHasLongCondition4(); + if (isXICHIHasSignal4) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1.5; + + // + double slValue = mATRSLHelper.downBuffer[1]; + slValue -= PointToPrice( + mSymbol, + 5); + + // + info.sl = slValue; + } + + // + result = + // + isXMRBHasSignal + // + || + // + isXPVHasSignal + // + || + // + isXICHIHasSignal1 + // + || + // + isXICHIHasSignal2 + // + || + // + isXICHIHasSignal3 + // + || + // + isXICHIHasSignal4 + // + ; + + // + if (result) + { + // + info.entry = entry; + info.symbol = mSymbol; + info.period = mPeriod; + info.type = POSITION_TYPE_BUY; + } + + // + return result; + } + + // + // Check has Short Signal on Each Strategies ... + bool HasShortSignal(XSignalInfo &info) + { + // + bool result = false; + + // + double entry = GetEntry(POSITION_TYPE_SELL); + + // + bool isXMRBHasSignal = false; // XMRBHasShortCondition(); + if (isXMRBHasSignal) + { + // + Add( + "XMRB", + info.providers); + + // + info.r2r = 1.5; + + // + // info.sl = mATRSLHelper.upBuffer[1]; + } + + // + bool isXPVHasSignal = false; // XPVHasShortCondition(); + if (isXPVHasSignal) + { + // + Add( + "XPV", + info.providers); + + // + info.r2r = 1.4; + + // + double slValue = mPVHelper.sHHBuffer[1]; + // slValue -= PointToPrice( + // mSymbol, + // 5 + // ); + // info.sl = slValue; + info.sl = mATRSLHelper.upBuffer[1]; + } + + // + bool isXICHIHasSignal1 = false; // XICHIHasShortCondition1(); + if (isXICHIHasSignal1) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1.5; + + // + double hhValue = GetHighestHigh( + mSymbol, + mPeriod, + 3, + 0); + hhValue += PointToPrice( + mSymbol, + 5); + + // + info.sl = hhValue; + } + + // + bool isXICHIHasSignal2 = false; // XICHIHasShortCondition2(); + if (isXICHIHasSignal2) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1; + + // + double hhValue = GetHighestHigh( + mSymbol, + mPeriod, + 3, + 0); + hhValue += PointToPrice( + mSymbol, + 5); + + // + info.sl = hhValue; + } + + // + bool isXICHIHasSignal3 = false; // XICHIHasShortCondition3(); + if (isXICHIHasSignal3) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1.5; + + // + double hhValue = GetHighestHigh( + mSymbol, + mPeriod, + 3, + 0); + hhValue += PointToPrice( + mSymbol, + 5); + + // + info.sl = hhValue; + } + + // + bool isXICHIHasSignal4 = XICHIHasShortCondition4(); + if (isXICHIHasSignal4) + { + // + Add( + "XICHI", + info.providers); + + // + info.r2r = 1.5; + + // + double slValue = mATRSLHelper.upBuffer[1]; + slValue += PointToPrice( + mSymbol, + 5); + + // + info.sl = slValue; + } + + // + result = + // + isXMRBHasSignal + // + || + // + isXPVHasSignal + // + || + // + isXICHIHasSignal1 + // + || + // + isXICHIHasSignal2 + // + || + // + isXICHIHasSignal3 + // + || + // + isXICHIHasSignal4 + // + ; + + // + if (result) + { + // + info.entry = entry; + info.symbol = mSymbol; + info.period = mPeriod; + info.type = POSITION_TYPE_SELL; + } + + // + return result; + } + + // + // START XMRB ... + + // + bool XMRBHasLongCondition() + { + // + bool result = false; + + // // + // XOHCL c1 = GetCandle( + // mSymbol, + // mPeriod, + // 1); + + // // + // XOHCL c2 = GetCandle( + // mSymbol, + // mPeriod, + // 2); + + // // + // double hhValue = GetHighestHigh( + // mSymbol, + // mPeriod, + // 5, + // 1); + // double llValue = GetLowestLow( + // mSymbol, + // mPeriod, + // 5, + // 1); + + // // + // // Find Fast Cross Over Slow ... + // bool isFastCrossOverSlow = + // mMRBHelper.fastBuffer[1] > mMRBHelper.slowBuffer[1] && + // mMRBHelper.fastBuffer[2] <= mMRBHelper.slowBuffer[2]; + + // // + // bool isTrendsUp = + // // + // // Trens by Other ... + // ( + // // + // ( + // // + // mMRBHelper.fast1Buffer[1] > mMRBHelper.slow1Buffer[1] && + // mMRBHelper.fast2Buffer[1] > mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] > mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] > mMRBHelper.slow4Buffer[1] && + // mMRBHelper.fast5Buffer[1] > mMRBHelper.slow5Buffer[1] + // // + // ) + // // + // || + // ( + // // + // mMRBHelper.fast1Buffer[1] > mMRBHelper.slow1Buffer[1] && + // mMRBHelper.fast2Buffer[1] > mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] > mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] > mMRBHelper.slow4Buffer[1] + // // + // ) + // // + // || + // ( + // // + // mMRBHelper.fast2Buffer[1] > mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] > mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] > mMRBHelper.slow4Buffer[1] && + // mMRBHelper.fast5Buffer[1] > mMRBHelper.slow5Buffer[1] + // // + // ) + // // + // ) + // // + // && + // // + // // Trends By Them ... + // ( + // // + // ( + // // + // mMRBHelper.fast2Buffer[1] > mMRBHelper.fast3Buffer[1] && + // mMRBHelper.fast3Buffer[1] > mMRBHelper.fast4Buffer[1] + // // + // ) + // // + // || + // // + // ( + // // + // mMRBHelper.fast3Buffer[1] > mMRBHelper.fast4Buffer[1] && + // mMRBHelper.fast4Buffer[1] > mMRBHelper.fast5Buffer[1] + // // + // ) + // // + // ) + // // + // ; + + // // + // bool isCyclesTrendsUp = + // ( + // // + // mMRBHelper.fast1Buffer[1] > mMRBHelper.slow1Buffer[1] && + // mMRBHelper.fast2Buffer[1] > mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] > mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] > mMRBHelper.slow4Buffer[1] && + // mMRBHelper.fast5Buffer[1] > mMRBHelper.slow5Buffer[1] + // // + // ) + // // + // && + // // + // !( + // // + // mMRBHelper.fast1Buffer[2] > mMRBHelper.slow1Buffer[2] && + // mMRBHelper.fast2Buffer[2] > mMRBHelper.slow2Buffer[2] && + // mMRBHelper.fast3Buffer[2] > mMRBHelper.slow3Buffer[2] && + // mMRBHelper.fast4Buffer[2] > mMRBHelper.slow4Buffer[2] && + // mMRBHelper.fast5Buffer[2] > mMRBHelper.slow5Buffer[2] + // // + // ) + // // + // ; + + // // + // bool candleCrossEMA200 = + // c1.open < mEMA200Buffer[1] && + // c1.close > mEMA200Buffer[1]; + + // // + // bool llCrossEMA200 = + // llValue < mEMA200Buffer[1] && + // hhValue > mEMA200Buffer[1]; + + // // + // bool candlesPullBack = + // // + // ( + // // + // mMRBHelper.fastBuffer[1] > mMRBHelper.slowBuffer[1] && + // mMRBHelper.fastBuffer[2] > mMRBHelper.slowBuffer[2] && + // mMRBHelper.fastBuffer[3] > mMRBHelper.slowBuffer[3] && + // // + // mMRBHelper.fastBuffer[1] > mMRBHelper.fastBuffer[2] && + // mMRBHelper.fastBuffer[2] > mMRBHelper.fastBuffer[3] && + // // + // c1.open < mMRBHelper.fastBuffer[1] && + // c1.close > mMRBHelper.fastBuffer[2] && + // // + // c2.open < mMRBHelper.fastBuffer[2] && + // c2.close < mMRBHelper.fastBuffer[2] && + // // + // MathMin(c1.high, c1.low) > mEMA200Buffer[1] && + // MathMin(c2.high, c2.low) > mEMA200Buffer[2] + // // + // ) + // // + // ; + + // // + // result = + // // + // (isTrendsUp && + // llCrossEMA200 && + // isFastCrossOverSlow) + // // + // || + // // + // (isTrendsUp && + // isCyclesTrendsUp && + // candleCrossEMA200) + // // + // // || + // // // + // // llCrossEMA200 + // // // + // || + // // + // candlesPullBack + // // + // ; + + // + return result; + } + + // + bool XMRBHasShortCondition() + { + // + bool result = false; + + // // + // XOHCL c1 = GetCandle( + // mSymbol, + // mPeriod, + // 1); + // XOHCL c2 = GetCandle( + // mSymbol, + // mPeriod, + // 2); + + // // + // double hhValue = GetHighestHigh( + // mSymbol, + // mPeriod, + // 5, + // 1); + // double llValue = GetLowestLow( + // mSymbol, + // mPeriod, + // 5, + // 1); + + // // + // // Find Fast Cross Under Slow ... + // bool isFastCrossUnderSlow = + // mMRBHelper.fastBuffer[1] < mMRBHelper.slowBuffer[1] && + // mMRBHelper.fastBuffer[2] >= mMRBHelper.slowBuffer[2]; + + // // + // bool isTrendsDown = + // // + // // Trens by Other ... + // ( + // // + // ( + // // + // mMRBHelper.fast1Buffer[1] < mMRBHelper.slow1Buffer[1] && + // mMRBHelper.fast2Buffer[1] < mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] < mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] < mMRBHelper.slow4Buffer[1] && + // mMRBHelper.fast5Buffer[1] < mMRBHelper.slow5Buffer[1] + // // + // ) + // // + // || + // ( + // // + // mMRBHelper.fast1Buffer[1] < mMRBHelper.slow1Buffer[1] && + // mMRBHelper.fast2Buffer[1] < mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] < mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] < mMRBHelper.slow4Buffer[1] + // // + // ) + // // + // || + // ( + // // + // mMRBHelper.fast2Buffer[1] < mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] < mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] < mMRBHelper.slow4Buffer[1] && + // mMRBHelper.fast5Buffer[1] < mMRBHelper.slow5Buffer[1] + // // + // ) + // // + // ) + // // + // && + // // + // // Trends By Them ... + // ( + // // + // ( + // // + // mMRBHelper.fast2Buffer[1] < mMRBHelper.fast3Buffer[1] && + // mMRBHelper.fast3Buffer[1] < mMRBHelper.fast4Buffer[1] + // // + // ) + // // + // || + // // + // ( + // // + // mMRBHelper.fast3Buffer[1] < mMRBHelper.fast4Buffer[1] && + // mMRBHelper.fast4Buffer[1] < mMRBHelper.fast5Buffer[1] + // // + // ) + // // + // ) + // // + // ; + + // // + // bool isCyclesTrendsDown = + // ( + // // + // mMRBHelper.fast1Buffer[1] < mMRBHelper.slow1Buffer[1] && + // mMRBHelper.fast2Buffer[1] < mMRBHelper.slow2Buffer[1] && + // mMRBHelper.fast3Buffer[1] < mMRBHelper.slow3Buffer[1] && + // mMRBHelper.fast4Buffer[1] < mMRBHelper.slow4Buffer[1] && + // mMRBHelper.fast5Buffer[1] < mMRBHelper.slow5Buffer[1] + // // + // ) + // // + // && + // // + // !( + // // + // mMRBHelper.fast1Buffer[2] < mMRBHelper.slow1Buffer[2] && + // mMRBHelper.fast2Buffer[2] < mMRBHelper.slow2Buffer[2] && + // mMRBHelper.fast3Buffer[2] < mMRBHelper.slow3Buffer[2] && + // mMRBHelper.fast4Buffer[2] < mMRBHelper.slow4Buffer[2] && + // mMRBHelper.fast5Buffer[2] < mMRBHelper.slow5Buffer[2] + // // + // ) + // // + // ; + + // // + // bool candleCrossEMA200 = + // c1.open > mEMA200Buffer[1] && + // c1.close < mEMA200Buffer[1]; + + // // + // bool hhCrossEMA200 = + // hhValue > mEMA200Buffer[1] && + // llValue < mEMA200Buffer[1]; + + // // + // bool candlesPullBack = + // // + // ( + // // + // mMRBHelper.fastBuffer[1] < mMRBHelper.slowBuffer[1] && + // mMRBHelper.fastBuffer[2] < mMRBHelper.slowBuffer[2] && + // mMRBHelper.fastBuffer[3] < mMRBHelper.slowBuffer[3] && + // // + // mMRBHelper.fastBuffer[1] < mMRBHelper.fastBuffer[2] && + // mMRBHelper.fastBuffer[2] < mMRBHelper.fastBuffer[3] && + // // + // c1.open > mMRBHelper.fastBuffer[1] && + // c1.close < mMRBHelper.fastBuffer[2] && + // // + // c2.open > mMRBHelper.slowBuffer[2] && + // c2.close > mMRBHelper.slowBuffer[2] && + // // + // MathMax(c1.high, c1.low) < mEMA200Buffer[1] && + // MathMax(c2.high, c2.low) < mEMA200Buffer[2] + // // + // ) + // // + // ; + + // // + // result = + // // + // (isTrendsDown && + // hhCrossEMA200 && + // isFastCrossUnderSlow) + // // + // || + // // + // (isTrendsDown && + // isCyclesTrendsDown && + // candleCrossEMA200) + // // + // // || + // // // + // // hhCrossEMA200 + // // // + // || + // // + // candlesPullBack + // // + // ; + + // + return result; + } + + // + // END XMRB ... + // + + // + // START XPV ... + // + + // + bool XPVHasLongCondition() + { + // + bool result = false; + + // + bool isSupportsHappens = + // + !mPVHelper.IsStrongSupport(1) && + mPVHelper.IsStrongSupport(2) && + mPVHelper.IsStrongSupport(3) + // + ; + + // + result = + // + false + // + // isSupportsHappens && + // isFeautureKumoBullish + // + ; + + // + return result; + } + + // + bool XPVHasShortCondition() + { + // + bool result = false; + + // + result = + !mPVHelper.IsStrongResistance(1) && + mPVHelper.IsStrongResistance(2) && + mPVHelper.IsStrongResistance(3); + + // + return result; + } + + // + // END XPV ... + // + + // + // START Ichimoku ... + // + + // + // CONDITION 1 ... + + // + // Long Condition 1 ... + bool XICHIHasLongCondition1() + { + // + bool result = false; + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + bool isTenkanSenCrossed = + mIchiHelper.IsTenkanSenCrossedOverKijunSen(1); + + // + XIchiInfo info = mIchiHelper.GetInfo(1); + bool isCandleClosedOverCross = + c1.close > MathMax(info.tenkanSen, info.kijunSen); + + // + double ll = GetLowestLow( + mSymbol, + mPeriod, + 6, + 1); + bool isCandlesOverKumo = + ll > MathMax(info.senkouSpanA, info.senkouSpanB); + + // + result = + // + isTenkanSenCrossed && + isCandlesOverKumo && + isCandleClosedOverCross + // + ; + + // + return result; + } + + // + // Short Condition 1 ... + bool XICHIHasShortCondition1() + { + // + bool result = false; + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + bool isTenkanSenCrossed = + mIchiHelper.IsTenkanSenCrossedUnderKijunSen(1); + + // + XIchiInfo info = mIchiHelper.GetInfo(1); + bool isCandleClosedUnderCross = + c1.close < MathMin(info.tenkanSen, info.kijunSen); + + // + double hh = GetHighestHigh( + mSymbol, + mPeriod, + 6, + 1); + bool isCandlesUnderKumo = + hh < MathMin(info.senkouSpanA, info.senkouSpanB); + + // + result = + // + isTenkanSenCrossed && + isCandlesUnderKumo && + isCandleClosedUnderCross + // + ; + + // + return result; + } + + // + // CONDITION 2 ... + + // + // Long Condition 2 ... + // Ichimoku and CCI ... + bool XICHIHasLongCondition2() + { + // + bool result = false; + + // + bool isCCICrossedOverNegative100 = + // + mCCIBuffer[1] > -100 && + mCCIBuffer[2] <= -100 + // + ; + + // + bool isTenkanSenOverKijunSen = + mIchiHelper.IsTenkanSenOverKijunSen(1); + + // + bool isKumoBullish = + mIchiHelper.IsKumoBullish(1); + + // + XIchiInfo info = mIchiHelper.GetInfo(1); + double llValue = GetLowestLow( + mSymbol, + mPeriod, + 12, + 1); + bool isPriceOverKumo = + // + llValue > MathMax(info.senkouSpanA, info.senkouSpanB) + // + ; + + // + result = + // + isKumoBullish && + isPriceOverKumo && + isTenkanSenOverKijunSen && + isCCICrossedOverNegative100 + // + ; + + // + return result; + } + + // + // Short Condition 2 ... + // Ichimoku and CCI ... + bool XICHIHasShortCondition2() + { + // + bool result = false; + + // + bool isCCICrossedUnderPositive100 = + // + mCCIBuffer[1] < 100 && + mCCIBuffer[2] >= 100 + // + ; + + // + bool isTenkanSenUnderKijunSen = + mIchiHelper.IsTenkanSenUnderKijunSen(1); + + // + bool isKumoBearish = + mIchiHelper.IsKumoBearish(1); + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + XIchiInfo info = mIchiHelper.GetInfo(1); + double hhValue = GetHighestHigh( + mSymbol, + mPeriod, + 12, + 1); + bool isPriceUnderKumo = + // + c1.high < MathMin(info.senkouSpanA, info.senkouSpanB) && + hhValue < MathMin(info.senkouSpanA, info.senkouSpanB) + // + ; + + // + result = + // + isKumoBearish && + isPriceUnderKumo && + isTenkanSenUnderKijunSen && + isCCICrossedUnderPositive100 + // + ; + + // + return result; + } + + // + // CONDITIONS 3 ... + + // + // Long Condition 3 ... + bool XICHIHasLongCondition3() + { + // + bool result = false; + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + XIchiInfo info = mIchiHelper.GetInfo(1); + + // + bool isFutureKumoSwitchedToBullish = + mIchiHelper.IsKumoSwitchedToBullish(1, true); + + // + bool isCandleClosedOverFutureKumo = + c1.close > MathMax(info.senkouSpanAFuture, info.senkouSpanBFuture); + + // + result = + // + isCandleClosedOverFutureKumo && + isFutureKumoSwitchedToBullish + // + ; + + // + return result; + } + + // + // Short Condition 3 ... + bool XICHIHasShortCondition3() + { + // + bool result = false; + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + XIchiInfo info = mIchiHelper.GetInfo(1); + + // + bool isFutureKumoSwitchedToBearish = + mIchiHelper.IsKumoSwitchedToBearish(1, true); + + // + bool isCandleClosedUnderFutureKumo = + c1.close < MathMin(info.senkouSpanAFuture, info.senkouSpanBFuture); + + // + result = + // + isCandleClosedUnderFutureKumo && + isFutureKumoSwitchedToBearish + // + ; + + // + return result; + } + + // + // CONDITIONS 4 ... + + // + // Long Condition 4 ... + bool XICHIHasLongCondition4() + { + // + bool result = false; + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + XIchiInfo info = mIchiHelper.GetInfo(1); + + // + bool isSSLUpCrossedOverDown = + mSSLCHelper.IsUpCrossedOverDown(1); + + // + bool isCandleClosedOverKumo = + c1.low > MathMax(info.senkouSpanA, info.senkouSpanB); + + // + bool isKumoBullish = + mIchiHelper.IsKumoBullish(1); + + // + result = + // + isKumoBullish && + isSSLUpCrossedOverDown && + isCandleClosedOverKumo + // + ; + + // + return result; + } + + // + // Short Condition 4 ... + bool XICHIHasShortCondition4() + { + // + bool result = false; + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + XIchiInfo info = mIchiHelper.GetInfo(1); + + // + bool isSSLUpCrossedUnderDown = + mSSLCHelper.IsUpCrossedUnderDown(1); + + // + bool isCandleClosedUnderKumo = + c1.high < MathMin(info.senkouSpanA, info.senkouSpanB); + + // + bool isKumoBearish = + mIchiHelper.IsKumoBearish(1); + + // + result = + // + isKumoBearish && + isSSLUpCrossedUnderDown && + isCandleClosedUnderKumo + // + ; + + // + return result; + } + + // + // END Ichimoku ... + // + + // + // END Providers Signals ... + // +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct X121SignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Desired Magic Number ... + ulong magicNumber; + + // + // Provider ... + XSCX121Provider provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + X121SignalProvider &item, // item want to add + X121SignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Generate Identifier Tag ... +string GenerateTag(X121SignalProvider &descriptor) +{ + // + string result = ""; + + // + result = descriptor.symbol + "_" + ToString(descriptor.period); + + // + return result; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/x-saherelm.x121.chart.tools.lib.mq5 b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/x-saherelm.x121.chart.tools.lib.mq5 new file mode 100644 index 0000000..609c74b --- /dev/null +++ b/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/x-saherelm.x121.chart.tools.lib.mq5 @@ -0,0 +1,193 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X12 Draw Library +// ------------------------------------------ +// Name: X121Draw +// Description: provides Draw Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// START Chart Tools Functions ... +// + +// +string x121ToolsButtonName = "X121TOOLS"; + +// +// Calculate Button size ... +bool CalculateButtonSize( + XSize &result, // Holds Result ... + long chartID = 0, // Specified Chart ID ... + int step = 32 // Step Divider ... +) +{ + // + bool mResult = false; + + // + mResult = GetChartSize( + result, + chartID); + if (!mResult) + { + return mResult; + } + + // + // define the step for changing the button size + int x_step = (int)result.width / step; + int y_step = (int)result.height / step; + + // + // set the button coordinates and its size + int x = (int)result.width / step; + int y = (int)result.height / step; + + // + // int width = (int)result.width * 15 / 32; + // int height = (int)result.height * 15 / 32; + int width = (int)result.width / 32; + int height = (int)result.height / 32; + + // + result.x = x; + result.y = y; + result.w = width; + result.h = height; + result.wStep = x_step; + result.hStep = y_step; + + // + return mResult; +} + +// +// Draw Tools Button On Chart ... +bool DrawToolsButton( + long chartID = 0, // Specified Chart ID ... + int subWindow = 0, // Specified Chart's SubWindow ... + ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER // Specified Corner to Draw Button ... +) +{ + // + bool result = false; + + // + XSize size; + result = CalculateButtonSize( + size, + chartID); + if (!result) + { + return result; + } + + // + result = ButtonCreate( + chartID, + x121ToolsButtonName, + 0, + size.x, + size.y, + size.w, + size.y, + corner, + "Press", + "Arial", + 10, + clrBlack, + clrLightGray, + CLR_NONE, + false, // Pressed/Released ... + false, + false, + true, + 0); + + // + return result; +} + +// +bool ToggleToolsButtonState( + long chartID = 0, // Specified Chart ID ... + int subWindow = 0 // Specified Chart's SubWindow ... +) +{ + // + bool result = false; + + // + return result; +} + +// +// Prepare Chart Requirements ... +bool DrawTools( + long chartID = 0, // Specified Chart ID ... + int subWindow = 0 // Specified Chart's SubWindow ... +) +{ + // + bool result = false; + + // + result = DrawToolsButton( + chartID, + subWindow); + + // + // redraw the chart + if (result) + { + ChartRedraw(); + } + + // + return result; +} + +// +// Parse Chart Tools Events ... +void HandleToolsChartEvent( + long chartID, // Specified Chart ID ... + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter +) +{ + // + // OnClick ... + if (id == CHARTEVENT_CLICK) + { + // + // Toolls Btton Clicked ... + if (sparam == x121ToolsButtonName) + { + LogMessage("Tools Button Clicked ..."); + } + } +} + +// +// END Chart Tools Functions ... +// diff --git a/MQLTestWorkspace/BKPS/Temp/supprot_resistance_sample.yaml b/MQLTestWorkspace/BKPS/Temp/supprot_resistance_sample.yaml new file mode 100644 index 0000000..27e265d --- /dev/null +++ b/MQLTestWorkspace/BKPS/Temp/supprot_resistance_sample.yaml @@ -0,0 +1,269 @@ +2024.04.01 06:30:00 XEA > Peaks and Vales +2024.04.01 06:30:00 XEA > Supprot and Resistance: +2024.04.01 06:30:00 R1: 1.07873 +2024.04.01 06:30:00 R2: 1.07986 +2024.04.01 06:30:00 +2024.04.01 06:30:00 S1: 1.07819 +2024.04.01 06:30:00 S2: 1.07743 +2024.04.01 06:30:00 +2024.04.01 06:30:00 +2024.04.01 06:30:00 XEA > +2024.04.01 06:30:00 XEA > Ichimoku Kinko Hyo +2024.04.01 06:30:00 XEA > Supprot and Resistance: +2024.04.01 06:30:00 R1: 1.0787149999999999 +2024.04.01 06:30:00 R2: 1.0788 +2024.04.01 06:30:00 +2024.04.01 06:30:00 S1: 0.0 +2024.04.01 06:30:00 S2: 0.0 + + +2024.04.01 15:30:00 XEA > Peaks and Vales +2024.04.01 15:30:00 XEA > Supprot and Resistance: +2024.04.01 15:30:00 R1: 1.07849 +2024.04.01 15:30:00 R2: 1.07903 +2024.04.01 15:30:00 +2024.04.01 15:30:00 S1: 0.0 +2024.04.01 15:30:00 S2: 0.0 +2024.04.01 15:30:00 +2024.04.01 15:30:00 +2024.04.01 15:30:00 XEA > +2024.04.01 15:30:00 XEA > Ichimoku Kinko Hyo +2024.04.01 15:30:00 XEA > Supprot and Resistance: +2024.04.01 15:30:00 R1: 1.0782349999999998 +2024.04.01 15:30:00 R2: 1.07844 +2024.04.01 15:30:00 +2024.04.01 15:30:00 S1: 0.0 +2024.04.01 15:30:00 S2: 0.0 + + +2024.04.01 16:20:00 XEA > Peaks and Vales +2024.04.01 16:20:00 XEA > Supprot and Resistance: +2024.04.01 16:20:00 R1: 1.07855 +2024.04.01 16:20:00 R2: 1.07903 +2024.04.01 16:20:00 +2024.04.01 16:20:00 S1: 0.0 +2024.04.01 16:20:00 S2: 0.0 +2024.04.01 16:20:00 +2024.04.01 16:20:00 +2024.04.01 16:20:00 XEA > +2024.04.01 16:20:00 XEA > Ichimoku Kinko Hyo +2024.04.01 16:20:00 XEA > Supprot and Resistance: +2024.04.01 16:20:00 R1: 1.078125 +2024.04.01 16:20:00 R2: 1.07817 +2024.04.01 16:20:00 +2024.04.01 16:20:00 S1: 0.0 +2024.04.01 16:20:00 S2: 0.0 + + + +2024.04.01 17:45:02 XEA > Peaks and Vales +2024.04.01 17:45:02 XEA > Supprot and Resistance: +2024.04.01 17:45:02 R1: 1.0781 +2024.04.01 17:45:02 R2: 1.07826 +2024.04.01 17:45:02 +2024.04.01 17:45:02 S1: 0.0 +2024.04.01 17:45:02 S2: 0.0 +2024.04.01 17:45:02 +2024.04.01 17:45:02 +2024.04.01 17:45:02 XEA > +2024.04.01 17:45:02 XEA > Ichimoku Kinko Hyo +2024.04.01 17:45:02 XEA > Supprot and Resistance: +2024.04.01 17:45:02 R1: 1.077985 +2024.04.01 17:45:02 R2: 1.078125 +2024.04.01 17:45:02 +2024.04.01 17:45:02 S1: 0.0 +2024.04.01 17:45:02 S2: 0.0 +2024.04.01 17:45:02 +2024.04.01 17:45:02 + + + +2024.04.01 18:15:00 XEA > Peaks and Vales +2024.04.01 18:15:00 XEA > Supprot and Resistance: +2024.04.01 18:15:00 R1: 1.07805 +2024.04.01 18:15:00 R2: 1.07853 +2024.04.01 18:15:00 +2024.04.01 18:15:00 S1: 0.0 +2024.04.01 18:15:00 S2: 0.0 +2024.04.01 18:15:00 +2024.04.01 18:15:00 +2024.04.01 18:15:00 XEA > +2024.04.01 18:15:00 XEA > Ichimoku Kinko Hyo +2024.04.01 18:15:00 XEA > Supprot and Resistance: +2024.04.01 18:15:00 R1: 1.07611 +2024.04.01 18:15:00 R2: 1.0763449999999999 +2024.04.01 18:15:00 +2024.04.01 18:15:00 S1: 0.0 +2024.04.01 18:15:00 S2: 0.0 +2024.04.01 18:15:00 +2024.04.01 18:15:00 + + +2024.04.01 18:25:00 XEA > Peaks and Vales +2024.04.01 18:25:00 XEA > Supprot and Resistance: +2024.04.01 18:25:00 R1: 1.07805 +2024.04.01 18:25:00 R2: 1.07853 +2024.04.01 18:25:00 +2024.04.01 18:25:00 S1: 0.0 +2024.04.01 18:25:00 S2: 0.0 +2024.04.01 18:25:00 +2024.04.01 18:25:00 +2024.04.01 18:25:00 XEA > +2024.04.01 18:25:00 XEA > Ichimoku Kinko Hyo +2024.04.01 18:25:00 XEA > Supprot and Resistance: +2024.04.01 18:25:00 R1: 1.07611 +2024.04.01 18:25:00 R2: 1.0763449999999999 +2024.04.01 18:25:00 +2024.04.01 18:25:00 S1: 0.0 +2024.04.01 18:25:00 S2: 0.0 +2024.04.01 18:25:00 +2024.04.01 18:25:00 + + +2024.04.02 01:50:02 XEA > Peaks and Vales +2024.04.02 01:50:02 XEA > Supprot and Resistance: +2024.04.02 01:50:02 R1: 1.07849 +2024.04.02 01:50:02 R2: 1.07903 +2024.04.02 01:50:02 +2024.04.02 01:50:02 S1: 1.07363 +2024.04.02 01:50:02 S2: 1.07342 +2024.04.02 01:50:02 +2024.04.02 01:50:02 +2024.04.02 01:50:02 XEA > +2024.04.02 01:50:02 XEA > Ichimoku Kinko Hyo +2024.04.02 01:50:02 XEA > Supprot and Resistance: +2024.04.02 01:50:02 R1: 1.074205 +2024.04.02 01:50:02 R2: 1.07428 +2024.04.02 01:50:02 +2024.04.02 01:50:02 S1: 1.0740675 +2024.04.02 01:50:02 S2: 1.074025 +2024.04.02 01:50:02 +2024.04.02 01:50:02 + + +2024.04.02 02:05:00 XEA > Peaks and Vales +2024.04.02 02:05:00 XEA > Supprot and Resistance: +2024.04.02 02:05:00 R1: 1.07416 +2024.04.02 02:05:00 R2: 1.0744 +2024.04.02 02:05:00 +2024.04.02 02:05:00 S1: 1.07366 +2024.04.02 02:05:00 S2: 0.0 +2024.04.02 02:05:00 +2024.04.02 02:05:00 +2024.04.02 02:05:00 XEA > +2024.04.02 02:05:00 XEA > Ichimoku Kinko Hyo +2024.04.02 02:05:00 XEA > Supprot and Resistance: +2024.04.02 02:05:00 R1: 1.074025 +2024.04.02 02:05:00 R2: 1.0740675 +2024.04.02 02:05:00 +2024.04.02 02:05:00 S1: 1.073385 +2024.04.02 02:05:00 S2: 0.0 +2024.04.02 02:05:00 +2024.04.02 02:05:00 + + +2024.04.02 03:35:00 XEA > Peaks and Vales +2024.04.02 03:35:00 XEA > Supprot and Resistance: +2024.04.02 03:35:00 R1: 1.07399 +2024.04.02 03:35:00 R2: 1.07425 +2024.04.02 03:35:00 +2024.04.02 03:35:00 S1: 0.0 +2024.04.02 03:35:00 S2: 0.0 +2024.04.02 03:35:00 +2024.04.02 03:35:00 +2024.04.02 03:35:00 XEA > +2024.04.02 03:35:00 XEA > Ichimoku Kinko Hyo +2024.04.02 03:35:00 XEA > Supprot and Resistance: +2024.04.02 03:35:00 R1: 1.073385 +2024.04.02 03:35:00 R2: 1.073705 +2024.04.02 03:35:00 +2024.04.02 03:35:00 S1: 0.0 +2024.04.02 03:35:00 S2: 0.0 +2024.04.02 03:35:00 +2024.04.02 03:35:00 + + +2024.04.02 06:25:00 XEA > Peaks and Vales +2024.04.02 06:25:00 XEA > Supprot and Resistance: +2024.04.02 06:25:00 R1: 1.07366 +2024.04.02 06:25:00 R2: 1.07512 +2024.04.02 06:25:00 +2024.04.02 06:25:00 S1: 1.07312 +2024.04.02 06:25:00 S2: 0.0 +2024.04.02 06:25:00 +2024.04.02 06:25:00 +2024.04.02 06:25:00 XEA > +2024.04.02 06:25:00 XEA > Ichimoku Kinko Hyo +2024.04.02 06:25:00 XEA > Supprot and Resistance: +2024.04.02 06:25:00 R1: 1.073485 +2024.04.02 06:25:00 R2: 1.0736249999999998 +2024.04.02 06:25:00 +2024.04.02 06:25:00 S1: 0.0 +2024.04.02 06:25:00 S2: 0.0 +2024.04.02 06:25:00 +2024.04.02 06:25:00 + + +2024.04.10 19:00:04 XEA > Peaks and Vales +2024.04.10 19:00:04 XEA > Supprot and Resistance: +2024.04.10 19:00:04 R1: 1.07795 +2024.04.10 19:00:04 R2: 1.08617 +2024.04.10 19:00:04 +2024.04.10 19:00:04 S1: 0.0 +2024.04.10 19:00:04 S2: 0.0 +2024.04.10 19:00:04 +2024.04.10 19:00:04 +2024.04.10 19:00:04 XEA > +2024.04.10 19:00:04 XEA > Ichimoku Kinko Hyo +2024.04.10 19:00:04 XEA > Supprot and Resistance: +2024.04.10 19:00:04 R1: 1.073705 +2024.04.10 19:00:04 R2: 1.07374 +2024.04.10 19:00:04 +2024.04.10 19:00:04 S1: 1.073275 +2024.04.10 19:00:04 S2: 1.0732050000000002 +2024.04.10 19:00:04 +2024.04.10 19:00:04 + + +2024.04.10 19:40:00 XEA > Peaks and Vales +2024.04.10 19:40:00 XEA > Supprot and Resistance: +2024.04.10 19:40:00 R1: 1.07742 +2024.04.10 19:40:00 R2: 1.08584 +2024.04.10 19:40:00 +2024.04.10 19:40:00 S1: 0.0 +2024.04.10 19:40:00 S2: 0.0 +2024.04.10 19:40:00 +2024.04.10 19:40:00 +2024.04.10 19:40:00 XEA > +2024.04.10 19:40:00 XEA > Ichimoku Kinko Hyo +2024.04.10 19:40:00 XEA > Supprot and Resistance: +2024.04.10 19:40:00 R1: 1.0732050000000002 +2024.04.10 19:40:00 R2: 1.073275 +2024.04.10 19:40:00 +2024.04.10 19:40:00 S1: 1.072805 +2024.04.10 19:40:00 S2: 0.0 +2024.04.10 19:40:00 +2024.04.10 19:40:00 + + +2024.04.11 03:10:00 XEA > Peaks and Vales +2024.04.11 03:10:00 XEA > Supprot and Resistance: +2024.04.11 03:10:00 R1: 1.07425 +2024.04.11 03:10:00 R2: 1.07542 +2024.04.11 03:10:00 +2024.04.11 03:10:00 S1: 0.0 +2024.04.11 03:10:00 S2: 0.0 +2024.04.11 03:10:00 +2024.04.11 03:10:00 +2024.04.11 03:10:00 XEA > +2024.04.11 03:10:00 XEA > Ichimoku Kinko Hyo +2024.04.11 03:10:00 XEA > Supprot and Resistance: +2024.04.11 03:10:00 R1: 1.074115 +2024.04.11 03:10:00 R2: 1.07416 +2024.04.11 03:10:00 +2024.04.11 03:10:00 S1: 1.0738750000000001 +2024.04.11 03:10:00 S2: 1.0738050000000001 +2024.04.11 03:10:00 +2024.04.11 03:10:00 + + diff --git a/MQLTestWorkspace/BKPS/Temp/xtm.old.mq5 b/MQLTestWorkspace/BKPS/Temp/xtm.old.mq5 new file mode 100644 index 0000000..a827587 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Temp/xtm.old.mq5 @@ -0,0 +1,361 @@ +/////////////////////////////////////////////////////// +// +// 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 group "Makret"; +input int maPeriod = 35; // Period +input int maShift = 0; // Shift +input ENUM_MA_METHOD maMethod = MODE_SMA; // Method +input ENUM_APPLIED_PRICE maAppliedTo = PRICE_LOW; // Applied To + +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// 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() +{ + // + ENUM_DRAW_TYPE drawType = showLine ? DRAW_COLOR_LINE : DRAW_NONE; + + // + string maBufferLabel = "XTM " + "(" + (string)maPeriod + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showLine); + + // + // 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/MQLTestWorkspace/BKPS/Templates/Guard Handlers.mq5 b/MQLTestWorkspace/BKPS/Templates/Guard Handlers.mq5 new file mode 100644 index 0000000..47da2b6 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/Guard Handlers.mq5 @@ -0,0 +1,227 @@ + +// +// Close All Open Positions when Profit Summary is Reached ... +void HandleGridHedge() +{ + // + int openPositionsCount = xEATrade.PositionsCount(); + if (openPositionsCount <= 1 || + xEAMinProfitPerOpenPositionForHedging <= 0) + { + return; + } + + // + double requiredProfitForHedging = xEAMinProfitPerOpenPositionForHedging * openPositionsCount; + double accountProfit = xEATrade.GetPositionsProfit(); + if (accountProfit > 0 || MathAbs(accountProfit) < requiredProfitForHedging) + { + return; + } + + // + string comment = "Close since Grid Hedging ..."; + xEATrade.CloseAllPositions(comment); + + // + string msg = "Grid Hedging in Loss: " + (string)accountProfit; + LogMessage(msg); +} + +// +// Close All Open Positions when Profit Summary is Reached ... +void HandlePyramidHedge() +{ + // + int openPositionsCount = xEATrade.PositionsCount(); + if (openPositionsCount <= 1 || + xEAMinProfitPerOpenPositionForHedging <= 0) + { + return; + } + + // + double requiredProfitForHedging = xEAMinProfitPerOpenPositionForHedging * openPositionsCount; + double accountProfit = xEATrade.GetPositionsProfit(); + if (accountProfit < requiredProfitForHedging) + { + return; + } + + // + string comment = "Close since Pyramid Hedging ..."; + xEATrade.CloseAllPositions(comment); + + // + string msg = "Pyramid Hedging in Profit: " + (string)accountProfit; + LogMessage(msg); +} + +// +// Force Close Signals ... +void HandleForceClosing() +{ + // + int positionsCount = xEATrade.PositionsCount(); + int ordersCount = xEATrade.OrdersCount(); + if (positionsCount <= 0 || ordersCount <= 0) + { + return; + } + + // + X121ForceClose results[]; + xEAProvider.CanForceCloseShortSignals(results); + int resultsCount = ArraySize(results); + if (resultsCount <= 0) + { + return; + } + + // + for (int i = 0; i < resultsCount; i++) + { + // + X121ForceClose iForceClose = results[i]; + if (!iForceClose.force) + { + continue; + } + + // + XPosition iPositions[]; + xEATrade.GetPositions( + iPositions, + iForceClose.symbol, + iForceClose.period); + int iPositionsCount = ArraySize(iPositions); + if (iPositionsCount > 0) + { + // + for (int j = 0; j < iPositionsCount; j++) + { + // + XPosition jPosition = iPositions[j]; + bool isLong = IsLong(jPosition.type); + if (isLong) + { + continue; + } + + // + ENUM_X121_SIGNAL_PROVIDERS jProvider = ExtractProvider(jPosition); + string jProviderStr = ToString(jProvider); + if (jProviderStr != iForceClose.provider) + { + continue; + } + + // + string comment = "Force Close Signals ..."; + bool isClosed = xEATrade.Close(jPosition.ticket, comment); + if (isClosed) + { + // + string msg = "Position (" + (string)jPosition.ticket + ") Closed Due Force Event ..."; + LogMessage(msg); + } + } + } + + // + XOrder iOrders[]; + xEATrade.GetOrders( + iOrders, + iForceClose.symbol, + iForceClose.period, + ORDER_STATE_PLACED); + int iOrdersCount = ArraySize(iOrders); + if (iOrdersCount > 0) + { + // + bool isCanceled = xEATrade.CancelOrders(iOrders); + if (isCanceled) + { + // + string msg = "(" + (string)ordersCount + ") Canceled due Cycle Change ..."; + + // + LogMessage(msg); + } + } + } +} + +// +// Close a Position and it's Support Due to Profit ... +void HandleHedgeSupports() +{ + // + int positionsCount = xEATrade.PositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition positions[]; + xEATrade.GetPositions( + positions); + positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool hasSupport = xEATrade.HasSupport(iPosition.ticket); + if (!hasSupport) + { + continue; + } + + // + bool isClosed = xEATrade.ClosePositionAndSupports( + iPosition.ticket); + if (isClosed) + { + // + string msg = "Position and Supports Closed ..."; + LogMessage(msg); + } + } +} + + + + // + // Delete Specific Order of Support if Exists ... + ulong positionId = deal.positionId; + + // + XOrder supports[]; + bool hasSupport = xEATrade.GetSupportOrders( + positionId, + supports, + NULL, + NULL, + ORDER_STATE_PLACED); + if (hasSupport) + { + // + bool isCanceled = xEATrade.CancelOrders(supports); + + // + if (isCanceled) + { + // + string msg = "Close all Supports of (" + (string)positionId + ") Due to it's TakeProfit Event ..."; + LogMessage(msg); + } + } diff --git a/MQLTestWorkspace/BKPS/Templates/draw.support.resistance.mql5 b/MQLTestWorkspace/BKPS/Templates/draw.support.resistance.mql5 new file mode 100644 index 0000000..a221b3e --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/draw.support.resistance.mql5 @@ -0,0 +1,124 @@ + +// +void DrawSupportResistance( + int bar_index, + XOHCLSupRes &data, + string prefix = "", + color supportColor = clrLime, + color lowSupportColor = clrGreen, + color resistanceColor = clrRed, + color highResistanceColor = clrBrown) +{ + // + datetime barTime = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime prevBarTime = GetCandleTime( + _Symbol, + _Period, + bar_index + 5); + + // + long chID = ChartID(); + int subWindiw = 0; + + // + string mPrefix = prefix + "_" + (string)barTime + "_"; + + // + // SUPPORT ... + + // + if (data.sup > 0) + { + // + string supTlName = mPrefix + "SUP_(" + (string)data.sup + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + supTlName, + subWindiw, + prevBarTime, + data.sup, + barTime, + data.sup, + supportColor, + STYLE_DOT, + 1, + true); + } + + // + if (data.lowSup > 0) + { + // + string lowSupTlName = mPrefix + "LOW-SUP_(" + (string)data.lowSup + ")"; + + // + // Draw Low Support ... + DrawTrendLine( + chID, + lowSupTlName, + subWindiw, + prevBarTime, + data.lowSup, + barTime, + data.lowSup, + lowSupportColor, + STYLE_DOT, + 1, + true); + } + + // + // RESISTANCE ... + + // + if (data.res > 0) + { + // + string resTlName = mPrefix + "RES_(" + (string)data.res + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + resTlName, + subWindiw, + prevBarTime, + data.res, + barTime, + data.res, + resistanceColor, + STYLE_DOT, + 1, + true); + } + + // + if (data.highRes > 0) + { + // + string highResTlName = mPrefix + "HIGH-RES_(" + (string)data.highRes + ")"; + + // + // Draw Low Support ... + DrawTrendLine( + chID, + highResTlName, + subWindiw, + prevBarTime, + data.highRes, + barTime, + data.highRes, + highResistanceColor, + STYLE_DOT, + 1, + true); + } +} diff --git a/MQLTestWorkspace/BKPS/Templates/how to use xtrnd helper.mq5 b/MQLTestWorkspace/BKPS/Templates/how to use xtrnd helper.mq5 new file mode 100644 index 0000000..6ad8b4e --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/how to use xtrnd helper.mq5 @@ -0,0 +1,30 @@ + + // + bool isTrendSwitchedBullish = mTRNDHelper.IsTrendSwitchedBullish(1); + if (isTrendSwitchedBullish) + { + LogMessage("isTrendSwitchedBullish"); + } + + // + bool isTrendSwitchedBearish = mTRNDHelper.IsTrendSwitchedBearish(1); + if (isTrendSwitchedBearish) + { + LogMessage("isTrendSwitchedBearish"); + } + + // + bool isTrendSwitchedConsolidation = mTRNDHelper.IsTrendSwitchedConsolidation(1); + if (isTrendSwitchedConsolidation) + { + LogMessage("isTrendSwitchedConsolidation"); + } + + // + if ( + isTrendSwitchedBullish || + isTrendSwitchedBearish || + isTrendSwitchedConsolidation) + { + LogMessage(" "); + } diff --git a/MQLTestWorkspace/BKPS/Templates/how-to-use.xichi.helper.mq5 b/MQLTestWorkspace/BKPS/Templates/how-to-use.xichi.helper.mq5 new file mode 100644 index 0000000..e5a5f6b --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/how-to-use.xichi.helper.mq5 @@ -0,0 +1,100 @@ + // + if (mIsNewCandle) + { + // + datetime barTime = iTime( + mSymbol, + mPeriod, + 0); + + // + datetime time = iTime( + mSymbol, + mPeriod, + 1); + + // + long chartID = ChartID(); + + // + int barIndex = 0; + + // // + // // Check Kumo Is Bullish On State ... + // bool isKumoBullish = + // // + // mIchiHelper.IsKumoBullish(barIndex + 1, true) + // // + // ; + + // // + // if (isKumoBullish) + // { + // // + // LogMessage("isKumoBullish"); + // LogMessage("TenkanSen: " + (string)mIchiHelper.tenkanSenBuffer[barIndex]); + // LogMessage("KijunSen: " + (string)mIchiHelper.kijunSenBuffer[barIndex]); + // LogMessage("SenkouSpan A: " + (string)mIchiHelper.senkouSpanABuffer[barIndex + 26]); + // LogMessage("SenkouSpan B: " + (string)mIchiHelper.senkouSpanBBuffer[barIndex + 26]); + // LogMessage(" "); + // } + + // // + // // Check Kumo Is Bearish On State ... + // bool isKumoBearish = + // // + // mIchiHelper.IsKumoBearish(barIndex + 1, true) + // // + // ; + + // // + // if (isKumoBearish) + // { + // // + // LogMessage("isKumoBearish"); + // LogMessage("TenkanSen: " + (string)mIchiHelper.tenkanSenBuffer[barIndex]); + // LogMessage("KijunSen: " + (string)mIchiHelper.kijunSenBuffer[barIndex]); + // LogMessage("SenkouSpan A: " + (string)mIchiHelper.senkouSpanABuffer[barIndex + 26]); + // LogMessage("SenkouSpan B: " + (string)mIchiHelper.senkouSpanBBuffer[barIndex + 26]); + // LogMessage(" "); + // } + + // // + // // Check Kumo Switched To Bullish On State ... + // bool isKumoSwitchedToBullish = + // // + // mIchiHelper.IsKumoSwitchedToBullish(barIndex + 1, true) + // // + // ; + + // // + // if (isKumoSwitchedToBullish) + // { + // // + // LogMessage("isKumoSwitchedToBullish"); + // LogMessage("TenkanSen: " + (string)mIchiHelper.tenkanSenBuffer[barIndex]); + // LogMessage("KijunSen: " + (string)mIchiHelper.kijunSenBuffer[barIndex]); + // LogMessage("SenkouSpan A: " + (string)mIchiHelper.senkouSpanABuffer[barIndex + 26]); + // LogMessage("SenkouSpan B: " + (string)mIchiHelper.senkouSpanBBuffer[barIndex + 26]); + // LogMessage(" "); + // } + + // // + // // Check Kumo Switched To Bearish On State ... + // bool isKumoSwitchedToBearish = + // // + // mIchiHelper.IsKumoSwitchedToBearish(barIndex + 1, true) + // // + // ; + + // if (isKumoSwitchedToBearish) + // { + // // + // LogMessage("isKumoSwitchedToBearish"); + // LogMessage("TenkanSen: " + (string)mIchiHelper.tenkanSenBuffer[barIndex]); + // LogMessage("KijunSen: " + (string)mIchiHelper.kijunSenBuffer[barIndex]); + // LogMessage("SenkouSpan A: " + (string)mIchiHelper.senkouSpanABuffer[barIndex + 26]); + // LogMessage("SenkouSpan B: " + (string)mIchiHelper.senkouSpanBBuffer[barIndex + 26]); + // LogMessage(" "); + // } + } diff --git a/MQLTestWorkspace/BKPS/Templates/ichimoku.test.short.signals.mq5 b/MQLTestWorkspace/BKPS/Templates/ichimoku.test.short.signals.mq5 new file mode 100644 index 0000000..42fe635 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/ichimoku.test.short.signals.mq5 @@ -0,0 +1,251 @@ +bool XTestPRVDHasShortCondition() +{ + // + bool result = false; + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + // + XOHCL c2 = GetCandle( + _Symbol, + _Period, + 2); + + // + XIchiInfo ichiInfo = XICHIHLPGetInfo(2); + + // + bool isCandleClosedUnderPsar = + // + c1.high < atrslSarBuffer[1] + // + ; + + // + bool isTrendSwitched = + // + XTRNDHLPIsTrendStronglyBearish(1) + // + ; + + // + bool isNewValeHappends = + // + XPVHLPIsVale(1) && + !XPVHLPIsVale(2) + // + ; + + // + bool isKumoBearish = + // + XICHIHLPIsKumoBearish(1) + // + ; + + // + bool isTenkanSenUnderKijunSen = + // + XICHIHLPIsTenkanSenUnderKijunSen(1) + // + ; + + // + bool isTenkanSenCrossedUnderKijunSen = + // + XICHIHLPIsTenkanSenCrossedUnderKijunSen(1) + // + ; + + // + bool isBullishKumoBreakout = + // + XICHIHLPIsKumoBullish(1) && + XICHIHLPIsKumoBullish(2) && + (c2.high > MathMax(ichiInfo.senkouSpanA, ichiInfo.senkouSpanB) && + c2.low < MathMin(ichiInfo.senkouSpanA, ichiInfo.senkouSpanB)) && + c1.high < MathMin(ichiInfo.senkouSpanA, ichiInfo.senkouSpanB) + // + ; + + // + bool isCandloClosedUnderTenkanSen = + // + c1.high < ichiInfo.tenkanSen + // + ; + + // + bool isKijunbSenUnderKumo = + // + ichiInfo.kijunSen < MathMin(ichiInfo.senkouSpanA, ichiInfo.senkouSpanB) + // + ; + + // + bool isChikouSpanFree = + // + c1.close < GetLowestLow( + _Symbol, + _Period, + 1, + 26) + // + ; + + // + bool isKumoSoFat = + // + MathAbs(ichiInfo.senkouSpanA - ichiInfo.senkouSpanB) > MathAbs(GetHighestHigh( + _Symbol, + _Period, + 1, + 17) - + GetLowestLow( + _Symbol, + _Period, + 1, + 17)) + // + ; + + // + bool isKijunSenInsideFutureKumo = + // + ichiInfo.kijunSen < MathMax(ichiInfo.senkouSpanAFuture, ichiInfo.senkouSpanBFuture) && + ichiInfo.kijunSen > MathMin(ichiInfo.senkouSpanAFuture, ichiInfo.senkouSpanBFuture) + // + ; + + // + bool isFutureKumoBearish = + // + XICHIHLPIsKumoBearish(1, true) + // && + // + // TODO: Remove this ... + // MathMax(ichiInfo.senkouSpanA, ichiInfo.senkouSpanB) < MathMax(ichiInfo.senkouSpanAFuture, ichiInfo.senkouSpanBFuture) + // + ; + + // + bool signal1 = + // + isKumoBearish && + isTrendSwitched && + isNewValeHappends && + isCandleClosedUnderPsar && + isTenkanSenUnderKijunSen + // + ; + + // + bool signal2 = + // + isKijunbSenUnderKumo && + isBullishKumoBreakout && + isTenkanSenUnderKijunSen && + isCandloClosedUnderTenkanSen + // + ; + + // + bool signal3 = + // + !isKumoSoFat && + isChikouSpanFree && + isFutureKumoBearish && + isKijunbSenUnderKumo && + !isKijunSenInsideFutureKumo && + isCandloClosedUnderTenkanSen && + isTenkanSenCrossedUnderKijunSen + // + ; + + // + result = + // + // signal1 + // // + // || + // + // signal2 + // // + // || + // + signal3 + // + ; + + // + return result; +} + + +/// + + + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + 1); + // + XOHCL c2 = GetCandle( + _Symbol, + _Period, + 2); + + // + XIchiInfo ichiInfo = XICHIHLPGetInfo(1); + + // + bool isKumoSwitchedToBeraish = + // + XICHIHLPIsKumoSwitchedToBearish(1) + // + ; + + // + double ll9Value = GetLowestLow( + _Symbol, + _Period, + 9, + 1); + double hh9Value = GetHighestHigh( + _Symbol, + _Period, + 9, + 1); + bool isChikouSpanUnderPrice = + // + ichiInfo.chikouSpan < ll9Value && + ichiInfo.chikouSpan < hh9Value + // + ; + + // + bool isTenkanSenOverKijunSen = + // + XICHIHLPIsTenkanSenOverKijunSen(1) + // + ; + // + bool isPriceUnderTenkanSen = + c1.high < ichiInfo.tenkanSen; + + // + bool signal1 = + // + isChikouSpanUnderPrice && + isKumoSwitchedToBeraish && + (isTenkanSenOverKijunSen + ? isPriceUnderTenkanSen + : true) + + // + ; diff --git a/MQLTestWorkspace/BKPS/Templates/old.long.signals.mq5 b/MQLTestWorkspace/BKPS/Templates/old.long.signals.mq5 new file mode 100644 index 0000000..d00695a --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/old.long.signals.mq5 @@ -0,0 +1,79 @@ + // + bool result = false; + + // + double entry = GetEntry( + mSymbol, + POSITION_TYPE_BUY); + + // + XOHCL c0 = GetCandle( + mSymbol, + mPeriod, + 0); + double c0AppliedPrice = MathMin(c0.low, c0.open); + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + X121MarketConditions mConditions = GetMarketConditions(1); + + // + bool signal1 = + // + mConditions.xtrndInfo.l1ll == mConditions.xtrndInfo.l2ll && + mConditions.xtrndInfo.l1ll == mConditions.xtrndInfo.l3ll && + mConditions.xtrndInfo.l1ll == mConditions.xpvInfo.vale && + // + c0AppliedPrice == mConditions.xtrndInfo.l1ll + // && + // + // mConditions.xmrbInfo.isFastUnderSlow + // + ; + + // + if (signal1) + { + // + Add( + ToString(XPVF), + mConditions.signal.providers); + + // + mConditions.signal.r2r = 1.5; + mConditions.signal.riskAmount = 0.0001; + mConditions.signal.mode = X_ORDER_MODE_STOP; + mConditions.signal.entry = mConditions.xpvInfo.fl3; + mConditions.signal.sl = mConditions.xtrndInfo.l1ll; + mConditions.signal.tp = mConditions.xpvInfo.fl1; + } + + // + result = + // + false + // signal1 + // + ; + + // + if (result) + { + // + conditions = mConditions; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_BUY; + + // + conditions.hasSignal = true; + } + + // + return result; diff --git a/MQLTestWorkspace/BKPS/Templates/old.short.signals.mq5 b/MQLTestWorkspace/BKPS/Templates/old.short.signals.mq5 new file mode 100644 index 0000000..f27cba0 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/old.short.signals.mq5 @@ -0,0 +1,130 @@ + // + // When Price going Down of Fibo 3 Level from Up ... + // Chandelier Exit Must Verify Short trade by providing Short Exit 1 and 2 ... + bool signal1 = + // + c1.close < mConditions.xpvInfo.fl3 && + // + mConditions.xcheInfo.shortExit1 > c1.open && + mConditions.xcheInfo.shortExit1 != EMPTY_VALUE && + // + mConditions.xcheInfo.shortExit2 > c1.open && + mConditions.xcheInfo.shortExit2 != EMPTY_VALUE && + // + !(mConditions.xtrndInfo.isTrendBullish || + mConditions.xtrndInfo.isL1TrendBullish || + mConditions.xtrndInfo.isL2TrendBullish || + mConditions.xtrndInfo.isL3TrendBullish) + // + ; + + + + X121MarketConditions m0Conditions = GetMarketConditions(0); + + // + bool signal1 = + // + mConditions.xtrndInfo.l1hh == mConditions.xtrndInfo.l2hh && + mConditions.xtrndInfo.l1hh == mConditions.xtrndInfo.l3hh && + mConditions.xtrndInfo.l1hh == mConditions.xpvInfo.peak && + // + c0AppliedPrice == mConditions.xtrndInfo.l1hh + // && + // + // mConditions.xmrbInfo.isFastUnderSlow + // + ; + + // + if (signal1) + { + // + Add( + ToString(XPVF), + mConditions.signal.providers); + + // + mConditions.signal.r2r = 1.5; + mConditions.signal.riskAmount = 0.0001; + mConditions.signal.mode = X_ORDER_MODE_STOP; + mConditions.signal.entry = mConditions.xpvInfo.fl1; + mConditions.signal.sl = mConditions.xtrndInfo.l1hh; + mConditions.signal.tp = mConditions.xpvInfo.fl3; + } + + // + double minVerifier = MathMin(m0Conditions.xhullInfo.up, m0Conditions.xhullInfo.down); + minVerifier = MathMin(minVerifier, m0Conditions.xmrbInfo.fast); + minVerifier = MathMin(minVerifier, m0Conditions.xmrbInfo.slow); + minVerifier = MathMin(minVerifier, m0Conditions.xsslcInfo.up); + minVerifier = MathMin(minVerifier, m0Conditions.xsslcInfo.down); + + // + bool signal2 = + // + (mConditions.xsslcInfo.isBearish && + mConditions.xmrbInfo.isFastUnderSlow && + mConditions.xhullInfo.isUpBearish && + mConditions.xhullInfo.isDownBearish) + // + && + // + !(m0Conditions.xsslcInfo.isBearish && + m0Conditions.xmrbInfo.isFastUnderSlow && + m0Conditions.xhullInfo.isUpBearish && + m0Conditions.xhullInfo.isDownBearish) + // + && + // + (mConditions.xtrndInfo.isTrendBearish && + (mConditions.xtrndInfo.isL1TrendBearish || + mConditions.xtrndInfo.isL2TrendBearish)) + // + && + // + c1.high < minVerifier + // + ; + + // + if (signal2) + { + // + Add( + ToString(XCHNL), + mConditions.signal.providers); + + // + mConditions.signal.r2r = 1.5; + mConditions.signal.riskAmount = 0.0001; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = mConditions.xpvInfo.peak; + mConditions.signal.tp = mConditions.xpvInfo.vale; + } + + // + bool signal3 = + // + mConditions.xtrndInfo.isL3TrendSwitchedToBearish + // + ; + + // + if (signal3) + { + // + Add( + ToString(XTRND), + mConditions.signal.providers); + + // + mConditions.signal.r2r = 1.5; + mConditions.signal.riskAmount = 0.0001; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = mConditions.xtrndInfo.l3hh; + mConditions.signal.tp = mConditions.xtrndInfo.l3ll; + } + diff --git a/MQLTestWorkspace/BKPS/Templates/open.support.positions.old.ea.mq5 b/MQLTestWorkspace/BKPS/Templates/open.support.positions.old.ea.mq5 new file mode 100644 index 0000000..96335e8 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/open.support.positions.old.ea.mq5 @@ -0,0 +1,181 @@ + +// +// Find Reversal Position Type ... +ENUM_POSITION_TYPE GetSupportPositionType(ENUM_POSITION_TYPE type) +{ + // + ENUM_POSITION_TYPE result = POSITION_TYPE_BUY; + + // + if (type == POSITION_TYPE_BUY) + { + result = POSITION_TYPE_SELL; + } + else + { + result = POSITION_TYPE_BUY; + } + + // + return result; +} + +// +// Check a Position Has Supportable or not ... +bool IsSupportablePosition(XPosition &position) +{ + // + bool result = false; + + // + if (StringLen(position.comment) <= 0) + { + return result; + } + + // + int supStrPos = StringFind( + position.comment, + mSupportPrefix + "("); + + // + result = supStrPos < 0; + + // + return result; +} + +// +// Check a Position has Support Position or not ... +bool HasSupportPosition(XPosition &position) +{ + // + bool result = false; + + // + int positionsCount = xEATrade.PositionsCount(); + + // + if (positionsCount <= 0 || + position.ticket == 0 || + StringLen(position.comment) <= 0) + { + return result; + } + + // + string supCommentStr = mSupportPrefix + "(" + (string)position.ticket + ")"; + + // + XPosition positions[]; + xEATrade.GetPositions(positions); + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + int supCommentPos = StringFind( + iPosition.comment, + supCommentStr); + + // + result = supCommentPos >= 0; + if (result) + { + break; + } + } + + // + return result; +} + +// +// Open a Support Position based on Exists ... +void OpenSupportPosition(XPosition &position) +{ + // + bool isSupportable = IsSupportablePosition(position); + if (!isSupportable) + { + return; + } + + // + bool hasSupport = HasSupportPosition(position); + if (hasSupport) + { + return; + } + + // + ENUM_POSITION_TYPE type = GetSupportPositionType(position.type); + double entry = GetEntry( + position.symbol, + type); + + // + bool isLong = IsLong(type); + + // + double tpPrice = PipsToPrice( + position.symbol, + 10); + double slPrice = PipsToPrice( + position.symbol, + 5); + + // + double tp = 0; + // isLong + // ? entry + tpPrice + // : entry - tpPrice; + + // + double sl = 0; + // isLong + // ? entry - slPrice + // : entry + slPrice; + + // + string comment = mSupportPrefix + "(" + (string)position.ticket + ")"; + + // + bool isPositionOpen = false; + // + // Open Signal Position ... + if (isLong) + { + // + isPositionOpen = xEATrade.Buy( + position.symbol, + position.period, + position.volume, + entry, + sl, + tp, + comment); + } + else + { + // + isPositionOpen = xEATrade.Sell( + position.symbol, + position.period, + position.volume, + entry, + sl, + tp, + comment); + } + + // + if (isPositionOpen) + { + // + LogMessage("Open Support Psition for: " + position.comment); + } +} diff --git a/MQLTestWorkspace/BKPS/Templates/short.sl.calc.test.mql5 b/MQLTestWorkspace/BKPS/Templates/short.sl.calc.test.mql5 new file mode 100644 index 0000000..f6d7a20 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/short.sl.calc.test.mql5 @@ -0,0 +1,62 @@ + + // // + // int prevBearish = + // XTRNDHLPFindNextTrendSwitchedBearish(1); + // XOHCL cPrevBearish = GetCandle( + // _Symbol, + // _Period, + // prevBearish); + + // // + // int prevBullish = + // XTRNDHLPFindNextTrendSwitchedBearish(1); + // XOHCL cPrevBullish = GetCandle( + // _Symbol, + // _Period, + // prevBullish); + + // // + // double changeRate = XATRSLHLPGetChangeRate(1); + // double rangeChangeRate = XATRSLHLPGetRangeChangeRate(2); + // double atrValue = atrslUpBuffer[1]; + // if (changeRate > rangeChangeRate) + // { + // atrValue = atrslUpBuffer[2]; + // } + + // + // double hhValue = GetHighestHigh( + // _Symbol, + // _Period, + // 3, + // 1); + + // + // double mrbValue = MathMax(mrbFastBuffer[1], mrbSlowBuffer[1]); + + // + // atrslUpBuffer[1]; + // ichiKijunSenBuffer[1]; + // MathMin(cPrevBullish.high, cPrevBearish.high); + // double hh9Value = + // GetHighestHigh( + // _Symbol, + // _Period, + // 1, + // 9); + + // + // int prevSwingHigh = FindSwing( + // _Symbol, + // _Period, + // MODE_HIGH, + // 5, + // 1); + + // // + // double s1 = XPVHLPGetLastStrongSupport(1); + // double s2 = XPVHLPGetLastStrongSupport(2); + + // // + // double r1 = XPVHLPGetLastStrongResistance(1); + // double r2 = XPVHLPGetLastStrongResistance(2); diff --git a/MQLTestWorkspace/BKPS/Templates/static.indicator.helper.library.mql5 b/MQLTestWorkspace/BKPS/Templates/static.indicator.helper.library.mql5 new file mode 100644 index 0000000..a86246a --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/static.indicator.helper.library.mql5 @@ -0,0 +1,83 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XHLP 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 + +// +// START Includes ... +// + +// +// Includes ... +#include "../../Libraries/x-saherelm.alert.lib.mq5" +#include "../../Libraries/x-saherelm.models.lib.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes ... +// + +// +// START Constants/Enums ... +// + +// +// END Constants/Enums ... +// + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +bool XHLPOnInit() { + // + bool result = false; + + // + return result; +} + +// +void XHLPOnDeInit() { + // + // Release Indicators ... +} + +// +void XHLPReadBuffers() { + // +} + +// +// END Handler Functions ... +// + +// +// START Helper Functions ... +// + +// +// END Helper Functions ... +// diff --git a/MQLTestWorkspace/BKPS/Templates/trader.generate.support.signals.mq5 b/MQLTestWorkspace/BKPS/Templates/trader.generate.support.signals.mq5 new file mode 100644 index 0000000..0b2d946 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/trader.generate.support.signals.mq5 @@ -0,0 +1,129 @@ + + // + // Support Signals ... + void GenerateSupportSignals( + XSignal &result[], // Hold Result ... + const XSignal &source // Source Signal to Use for Generation ... + ) + { + // + // Here we must Prepare all Signals ... + + // + Clean(result); + + // + if (source.entry <= 0 || + (ArraySize(source.supportAndResistance.sup) == 0 && + ArraySize(source.supportAndResistance.res) == 0)) + { + return; + } + + // + double priceOf10Points = PointToPrice( + source.symbol, + 10); + + // + double tmpSupRes[]; + int supResCount = ArraySize(source.supportAndResistance.sup) + + ArraySize(source.supportAndResistance.res); + ArrayResize( + tmpSupRes, + supResCount); + ArrayCopy( + tmpSupRes, + source.supportAndResistance.sup); + ArrayCopy( + tmpSupRes, + source.supportAndResistance.res, + 0, + ArraySize(source.supportAndResistance.sup) - 1); + + // + bool isLong = IsLong(source.type); + + // + ENUM_POSITION_TYPE signalReverseType = isLong + ? POSITION_TYPE_SELL + : POSITION_TYPE_BUY; + + // + // Template Variables ... + double sl; + double tp; + double entry; + ENUM_POSITION_TYPE type; + ENUM_X_ORDER_MODES mode; + double r2r = 1.5; + double volume = NormalizeVolume( + source.volume, // * 1.5, + source.symbol); + string symbol = source.symbol; + ENUM_TIMEFRAMES period = source.period; + double riskAmount = source.riskAmount; // * 1.5; + + // + XSignal tmpSignal; + Clean(tmpSignal); + + // + // since SL is Lower Sup or Higher Res ... + // we have to add a Reversal Support for SL ... + if (source.sl > 0) + { + // + // Sl Type Signals are Reversal ... + type = signalReverseType; + + // + // Finding Entry Price ... + entry = source.sl - priceOf10Points; + sl = !isLong + ? FindLesserThanValue(entry, tmpSupRes) + : FindBiggerThanValue(entry, tmpSupRes); + double riskPrice = sl > 0 + ? MathAbs(entry - sl) + : MathAbs(entry - priceOf10Points); + double riskPoint = PriceToPoint( + symbol, + riskPrice); + double rewardPoint = r2r * riskPoint; + double rewardPrice = PointToPrice( + symbol, + rewardPoint); + tp = !isLong + ? entry + rewardPrice + : entry - rewardPrice; + + // + mode = X_ORDER_MODE_STOP; + + // + // Fill ... + tmpSignal.sl = sl; + tmpSignal.tp = tp; + tmpSignal.r2r = r2r; + tmpSignal.type = type; + tmpSignal.mode = mode; + tmpSignal.entry = entry; + tmpSignal.symbol = symbol; + tmpSignal.volume = volume; + tmpSignal.period = period; + tmpSignal.riskAmount = riskAmount; + + // + Add( + tmpSignal, + result); + Clean(tmpSignal); + } + + // + // add MidTerm Support Signal ... + // TODO: + + // + // TODO: Implement another Support Scenarios ... + } diff --git a/MQLTestWorkspace/BKPS/Templates/x-121.indicator.template.mq5 b/MQLTestWorkspace/BKPS/Templates/x-121.indicator.template.mq5 new file mode 100644 index 0000000..d9183a6 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/x-121.indicator.template.mq5 @@ -0,0 +1,253 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XHULL Indicator +// --------------------------------------------- +// Name: XHULL +// Description: Hull Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XHull Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XHull" +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// 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; + + // + 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 = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/Templates/x-saherelm.chart_drawing.template.ex5 b/MQLTestWorkspace/BKPS/Templates/x-saherelm.chart_drawing.template.ex5 new file mode 100644 index 0000000..20a8c83 Binary files /dev/null and b/MQLTestWorkspace/BKPS/Templates/x-saherelm.chart_drawing.template.ex5 differ diff --git a/MQLTestWorkspace/BKPS/Templates/x-saherelm.chart_drawing.template.mq5 b/MQLTestWorkspace/BKPS/Templates/x-saherelm.chart_drawing.template.mq5 new file mode 100644 index 0000000..e660058 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/x-saherelm.chart_drawing.template.mq5 @@ -0,0 +1,164 @@ +////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X121_ICH Ichimoku Time Teory +// ------------------------------------------------------ +// Name: X121_ICH_ +// Description: +// 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 X121_ICH Timing" + +// +#property strict +#property indicator_chart_window + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_ICH_T" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// END Constants ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// Indicator Chart ID ... +string mIndicatorId; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Assign a hopefully-unique ID to the indicator so that it can later remove itself + mIndicatorId = ShortName + "." + IntegerToString(GetMicrosecondCount()); + IndicatorSetString(INDICATOR_SHORTNAME, mIndicatorId); + + // + // 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 +} + +// +// Calculations ... +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[]) +{ + return rates_total; +} + +// +// Handle Chart Events ... +void OnChartEvent( + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter +) +{ +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Remove Indicator From Chart ... +void RemoveIndicator() +{ + ChartIndicatorDelete(0, 0, mIndicatorId); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/Templates/x-saherelm.xxhelper.indicator.template.mq5 b/MQLTestWorkspace/BKPS/Templates/x-saherelm.xxhelper.indicator.template.mq5 new file mode 100644 index 0000000..2ecba4c --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/x-saherelm.xxhelper.indicator.template.mq5 @@ -0,0 +1,151 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCBaseHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + // + } + + // + // Deconstructor ... + void ~XSCHelper() + { + } + + // + // START Properties ... + // + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Tag ... + string GetTag() + { + return mTag; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Initial Indicator Handler ... + virtual bool Init(); + + // + // Reading Buffers based on Given Bar Index ... + virtual void ReadBuffers( + int barIndex // Given Bar Index + ); + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Indicator Handler ... + int mHandler; + + // + // Tag Identifier ... + string mTag; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/Templates/x.helper.implementation.class.template.mq5 b/MQLTestWorkspace/BKPS/Templates/x.helper.implementation.class.template.mq5 new file mode 100644 index 0000000..852dc0e --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/x.helper.implementation.class.template.mq5 @@ -0,0 +1,435 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXPVHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Index of Lines ... +enum ENUM_XPV_BUFFERS +{ + // + // Main Requirements ... + XPV_PEAKS_LINE = 0, + XPV_VALES_LINE = 1, +}; + +// +// Retrieve Info Model ... +struct XPVInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Peak Value ... + double peak; + + // + // Vales Value ... + double vale; + + // + // Conditions ... + + // + // Determines New Peaks Happens ... + bool isNewPeak; + + // + // Determines New Vales Happens ... + bool isNewVale; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXPVHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double peaksBuffer[]; + double valesBuffer[]; + + // + // Constructor ... + void XSCXPVHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + // + // Indicator Properties ... + // + // Market ... + // + // Short Length ... + int shortLength = 9, + // + // Medium Length + int mediumLength = 17, + // + // Long Length ... + int longLength = 26, + // + // Hind Length ... + int hindLength = 35, + // + // Detection Mode ... + // + // Highest High Calculation Method ... + ENUM_SERIESMODE hhMode = MODE_HIGH, + // + // Lowest Low Calculation Method ... + ENUM_SERIESMODE llMode = MODE_LOW, + // + // Presentations ... + // + // Show Peaks and Vales ... + bool showPeaksAndVales = false, + // + // Show Levels ... + bool showLevels = false + // + ) : XSCBaseHelper(symbol, period) + { + // + // Indicator Properties ... + mHHMode = hhMode; + mLLMode = llMode; + mLongLength = longLength; + mHindLength = hindLength; + mShowLevels = showLevels; + mShortLength = shortLength; + mMediumLength = mediumLength; + mShowPeaksAndVales = showPeaksAndVales; + + // + Init(); + } + + // + // Deconstructor ... + void ~XSCXPVHelper() + { + } + + // + // START Properties ... + // + + // + // Show Levels ... + bool ShowLevels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowLevels == show) + { + return true; + } + + // + mShowLevels = show; + result = Init(); + + // + return result; + } + + // + // Show Peaks and Vales ... + bool ShowPeaksAnVales( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowPeaksAndVales == show) + { + return true; + } + + // + mShowPeaksAndVales = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + void PrepareTag() + { + mTag = "" + GetTagPrefix(); + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mShortLength > 2 && + mMediumLength > mShortLength && + mLongLength > mMediumLength && + mHindLength > mLongLength) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xpv", + // + // Inputs ... + // + // Market ... + "", + // + // Short Length ... + mShortLength, + // + // Medium Length + mMediumLength, + // + // Long Length ... + mLongLength, + // + // Hind Length ... + mHindLength, + // + // Detection Mode ... + "", + // + // Highest High Calculation Method ... + mHHMode, + // + // Lowest Low Calculation Method ... + mLLMode, + // + // Presentations ... + "", + // + // Show Peaks and Vales ... + mShowPeaksAndVales, + // + // Show Levels ... + mShowLevels + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + void Calculate( + int barIndex // Given Bar Index + ) + { + // + // PEAKS ... + CopyBuffer( + mHandler, + XPV_PEAKS_LINE, + barIndex, + mLoopbackBars, + peaksBuffer); + + // + // VALES ... + CopyBuffer( + mHandler, + XPV_VALES_LINE, + barIndex, + mLoopbackBars, + valesBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XPVInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XPVInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex + ); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime;; + result.barIndex = barIndex; + + // + result.peak = peaksBuffer[barIndex]; + result.vale = valesBuffer[barIndex]; + + // + result.isNewPeak = + peaksBuffer[barIndex] != peaksBuffer[barIndex + 1]; + result.isNewVale = + valesBuffer[barIndex] != valesBuffer[barIndex + 1]; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Short Length ... + int mShortLength; + // + // Medium Length + int mMediumLength; + // + // Long Length ... + int mLongLength; + // + // Hind Length ... + int mHindLength; + // + // Detection Mode ... + // + // Highest High Calculation Method ... + ENUM_SERIESMODE mHHMode; + // + // Lowest Low Calculation Method ... + ENUM_SERIESMODE mLLMode; + // + // Presentations ... + // + // Show Peaks and Vales ... + bool mShowPeaksAndVales; + // + // Show Levels ... + bool mShowLevels; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/Templates/xpv.find.supres.old.mq5 b/MQLTestWorkspace/BKPS/Templates/xpv.find.supres.old.mq5 new file mode 100644 index 0000000..8b174ad --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/xpv.find.supres.old.mq5 @@ -0,0 +1,310 @@ + +// +XOHCLSupRes XPVHLPFindCandleSupprtAndResistance( + int bar_index, // Bar Index ... + int verifications = 4 // Number of Verifications ... +) +{ + // + XOHCLSupRes result = {}; + result.res = 0; + result.highRes = 0; + result.sup = 0; + result.lowSup = 0; + + // + XOHCL cBar = GetCandle( + _Symbol, + _Period, + bar_index); + + // + int tries = 0; + int lastBar = bar_index; + while ( + result.res == 0 || + result.highRes == 0 || + result.sup == 0 || + result.lowSup == 0) + { + // + int bar = XPVHLPFindSupportBar(lastBar); + double val = XPVHLPFindSupportValue(lastBar); + + // + int bar1 = XPVHLPFindResistanceBar(lastBar); + double val1 = XPVHLPFindResistanceValue(lastBar); + + // + if (result.res == 0 && result.highRes == 0 && val > cBar.high && val1 > cBar.high) + { + // + result.res = MathMin(val, val1); + result.highRes = MathMax(val, val1); + } + else if (result.sup == 0 && result.lowSup == 0 && val < cBar.low && val1 < cBar.low) + { + // + result.sup = MathMax(val, val1); + result.lowSup = MathMin(val, val1); + } + else if (val > cBar.high) + { + // + if (result.res == 0 || result.highRes == 0) + { + // + if (result.res == 0) + { + result.res = val; + } + else if (val > result.res) + { + result.highRes = val; + } + else if (val < result.res) + { + // + result.highRes = result.res; + result.res = val; + } + } + } + else if (val < cBar.low) + { + // + if (result.sup == 0 || result.lowSup == 0) + { + // + if (result.sup == 0) + { + result.sup = val; + } + else if (val < result.sup) + { + result.lowSup = val; + } + else if (val > result.sup) + { + // + result.lowSup = result.sup; + result.sup = val; + } + } + } + else if (val1 > cBar.high) + { + // + if (result.res == 0 || result.highRes == 0) + { + // + if (result.res == 0) + { + result.res = val1; + } + else if (val1 > result.res) + { + result.highRes = val1; + } + else if (val1 < result.res) + { + // + result.highRes = result.res; + result.res = val1; + } + } + } + else if (val1 < cBar.low) + { + // + if (result.sup == 0 || result.lowSup == 0) + { + // + if (result.sup == 0) + { + result.sup = val1; + } + else if (val1 < result.sup) + { + result.lowSup = val1; + } + else if (val1 > result.sup) + { + // + result.lowSup = result.sup; + result.sup = val1; + } + } + } + + // + if (tries >= verifications) + { + break; + } + + // + lastBar = MathMin(bar, bar1); + tries++; + } + + // + return result; +} + + + + +// +int XPVHLPFindSupportBar( + int bar_index, // Bar Index ... + int verifications = 4 // Number of Verifications ... +) +{ + // + int result = -1; + + // + int mVerified = 0; + int idx = bar_index; + bool founded = false; + double lastValue = 0; + while (!founded) + { + // + XPVHLPReadBuffers(idx); + bool isSupport = XPVHLPIsStrongSupport(idx); + if (isSupport) + { + // + if (lastValue != pvLLLBuffer[idx]) + { + // + lastValue = pvLLLBuffer[idx]; + mVerified = 0; + } + else if (lastValue == pvLLLBuffer[idx]) + { + mVerified++; + } + } + else + { + mVerified = 0; + } + + // + idx++; + + // + founded = mVerified >= verifications; + if (founded) + { + result = idx; + break; + } + } + + // + return result; +} + +// +double XPVHLPFindSupportValue( + int bar_index, // Bar Index ... + int verifications = 4 // Number of Verifications ... +) +{ + // + double result = 0; + + // + int supportBar = XPVHLPFindSupportBar(bar_index, verifications); + if (supportBar < -1) + { + return result; + } + + // + return pvSLLBuffer[bar_index]; + + // + return result; +} + +// +int XPVHLPFindResistanceBar( + int bar_index, // Bar Index ... + int verifications = 4 // Number of Verifications ... +) +{ + // + int result = -1; + + // + int mVerified = 0; + int idx = bar_index; + bool founded = false; + double lastValue = 0; + while (!founded) + { + // + XPVHLPReadBuffers(idx); + bool isSupport = XPVHLPIsStrongResistance(idx); + if (isSupport) + { + // + if (lastValue != pvLHHBuffer[idx]) + { + // + lastValue = pvLHHBuffer[idx]; + mVerified = 0; + } + else if (lastValue == pvLHHBuffer[idx]) + { + mVerified++; + } + } + else + { + mVerified = 0; + } + + // + idx++; + + // + founded = mVerified >= verifications; + if (founded) + { + result = idx; + break; + } + } + + // + return result; +} + +// +double XPVHLPFindResistanceValue( + int bar_index, // Bar Index ... + int verifications = 4 // Number of Verifications ... +) +{ + // + double result = 0; + + // + int supportBar = XPVHLPFindResistanceBar(bar_index, verifications); + if (supportBar < -1) + { + return result; + } + + // + return pvSHHBuffer[bar_index]; + + // + return result; +} diff --git a/MQLTestWorkspace/BKPS/Templates/xpv.helper.test.tools.mq5 b/MQLTestWorkspace/BKPS/Templates/xpv.helper.test.tools.mq5 new file mode 100644 index 0000000..99784e7 --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/xpv.helper.test.tools.mq5 @@ -0,0 +1,164 @@ + +// +// Find Last Strong Support ... +double XPVHLPGetLastStrongSupport( + int bar_index, // Bar Index ... + int length // LoopBack ... +) +{ + // + double result = 0; + + // + bool isBarIndexSupport = XPVHLPIsStrongSupport(bar_index); + if (isBarIndexSupport) + { + length += bar_index; + } + + // + if (!XPVHLPIsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (XPVHLPIsStrongSupport(i)) + { + // + result = mpvSLLBuffer[i]; + break; + } + } + + // + return result; +} + +// +// Find Last Strong Resistance ... +double XPVHLPGetLastStrongResistance( + int bar_index, // Bar Index ... + int length // LoopBack ... +) +{ + // + double result = 0; + + // + bool isBarIndexResistance = XPVHLPIsStrongResistance(bar_index); + if (isBarIndexResistance) + { + length += bar_index; + } + + // + if (!XPVHLPIsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (XPVHLPIsStrongResistance(i)) + { + // + result = mpvSHHBuffer[i]; + break; + } + } + + // + return result; +} + +// +// Find Strong Support Break Stop ... +bool XPVHLPIsSupportBreakedStop( + int bar_index, // Bar Index ... + int length // LoopBack ... +) +{ + // + bool result = false; + + // + bool isBaIndexSupport = XPVHLPIsStrongSupport(bar_index); + if (isBaIndexSupport) + { + return result; + } + + // + if (!XPVHLPIsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + bool isAllStrongSupport = true; + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (!XPVHLPIsStrongSupport(i) && isAllStrongSupport) + { + // + isAllStrongSupport = false; + break; + } + } + + // + result = !isBaIndexSupport && isAllStrongSupport; + + // + return result; +} + +// +// Find Strong Resistance Break Stop ... +bool XPVHLPIsResistanceBreakedStop( + int bar_index, // Bar Index ... + int length // LoopBack ... +) +{ + // + bool result = false; + + // + bool isBaIndexResistance = XPVHLPIsStrongResistance(bar_index); + if (isBaIndexResistance) + { + return result; + } + + // + if (!XPVHLPIsValidArraySize(bar_index + length + 1)) + { + return result; + } + + // + bool isAllStrongResistance = true; + for (int i = bar_index; i < bar_index + length; i++) + { + // + if (!XPVHLPIsStrongResistance(i) && isAllStrongResistance) + { + // + isAllStrongResistance = false; + break; + } + } + + // + result = !isBaIndexResistance && isAllStrongResistance; + + // + return result; +} diff --git a/MQLTestWorkspace/Classes/x-saherelm.http.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.http.class.mq5 new file mode 100644 index 0000000..e28342d --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.http.class.mq5 @@ -0,0 +1,385 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCHttp +// Description: provides all HTTP requirements ... +// +// +// 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 Definitions ... +// + +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; + +// +// 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; +} + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Manage Account ... +class XSCHttp +{ + // + // Public ... +public: + // + // Constructor ... + void XSCHttp() + { + XSCHttp("", 10000); + } + void XSCHttp( + string path, // Base Folder to Store Data + int timeout // base timeout for Requests + ) + { + // + Path(path); + Timeout(timeout); + } + + // + // Deconstructor ... + void ~XSCHttp() + { + } + + // + // START Getter(s)/Setter(s) ... + // + + // + // Path ... + void Path(string value) + { + mPath = value; + } + + string Path() + { + return mPath; + } + + // + // Timeout ... + void Timeout(int value) + { + mTimeout = value; + } + + // + int Timeout() + { + return mTimeout; + } + + // + // Error ... + int Error() + { + return mError; + } + + // + // Response ... + string Response() + { + return mResponse; + } + + // + // END Getter(s)/Setter(s) ... + // + + // + // START Provided Functions ... + // + + // + // 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; + } + + // + // Reset State ... + ResetState(); + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders); + + // + if (result < 0) + { + mError = GetLastError(); + } + else + { + mResponse = CharArrayToString(response); + } + + // + 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; + } + + // + // Handle Download Specific URL Content to Specific Path and File Name ... + bool Download( + string url, // the URL address which going to download + string fileName // Specify Destination file name to Store Response + ) + { + // + bool result = false; + + // + string filePath = GetFilePath(fileName); + string cookie = NULL; + string referer = NULL; + int timeout = Timeout(); + + // + char payload[]; + string headers; + char response[]; + string responseHeaders; + + // + // Send Request ... + int requestResult = GetRequest( + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + // Define File Handler ... + int mFileHandler = FileOpen( + filePath, + FILE_WRITE | FILE_BIN); + if (mFileHandler == INVALID_HANDLE) + { + // + mError = GetLastError(); + return result; + } + + // + // Write Response to File ... + uint writed = FileWriteArray( + mFileHandler, + response, + 0, + ArraySize(response)); + FileFlush(mFileHandler); + FileClose(mFileHandler); + + // + result = writed > 0; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Destintion Folder Path ... + string mPath; + + // + // WEB Request Timeout Value ... + int mTimeout; + + // + // WEB Request's Response ... + string mResponse; + + // + // Error Value ... + int mError; + + // + // Private ... +private: + // + // Reset Errors State ... + void ResetState() + { + // + // Reset Errors ... + mError = -1; + mResponse = ""; + ResetLastError(); + } + + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.x121.provider.class.ex5 b/MQLTestWorkspace/Classes/x-saherelm.x121.provider.class.ex5 new file mode 100644 index 0000000..86ed200 Binary files /dev/null and b/MQLTestWorkspace/Classes/x-saherelm.x121.provider.class.ex5 differ diff --git a/MQLTestWorkspace/Classes/x-saherelm.x121.provider.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.x121.provider.class.mq5 new file mode 100644 index 0000000..4a423b0 --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.x121.provider.class.mq5 @@ -0,0 +1,1788 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121Provider +// Description: X121 Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Helpers/x-saherelm.x121.xct.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xcc.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xhk.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xtm.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xpv.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xama.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xmrb.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xche.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xich.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xtrnd.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xsslc.helper.class.mq5" +#include "../Helpers/x-saherelm.x121.xhull.helper.class.mq5" + +// +// Seriallizer Library ... +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// Here we Have to Define an Input Structure Model +// for Provider Class to Handle Helpers Definitions ... +struct X121ProviderInputs +{ + // + // XCT ... + // Candle Timer ... + XCTInputs xctConfig; + + // + // XCC ... + // Candle Styling ... + XCCInputs xccConfig; + + // + // XHK ... + // HikenAshi Candle Representing ... + XHKInputs xhkConfig; + + // + // XTM ... + // Trend Magic ... + XTMInputs xtmConfig; + + // + // XPV ... + // Peaks And Vales ... + XPVInputs xpvConfig; + + // + // XAMA ... + // Adaptive Moving Average ... + XAMAInputs xamaConfig; + + // + // XMRB ... + // Moving Average Ribbon ... + XMRBInputs xmrbConfig; + + // + // XCHE ... + // Chandelier Exit Points ... + XCHEInputs xcheConfig; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + XICHInputs xichConfig; + + // + // XTRND ... + // Trend Detector ... + XTRNDInputs xtrndConfig; + + // + // XSSLC ... + // SSL Channel ... + XSSLCInputs xsslcConfig; + + // + // XHULL ... + // Hull Trend Detection Channel ... + XHULLInputs xhullConfig; +}; + +// +// Model Market Sense based On Current Captured conditions ... +struct X121MarketConditions +{ + // + // Commonly Used Info ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + XCandleRemains barRemains; + + // + // Bar Index ... + int barIndex; + + // + // Check Current Market Condition has Signal or not ... + bool hasSignal; + + // + // If has any Signal, Models it's related info here ... + XSignal signal; + + // + // Support and Resistances ... + // if provides Signal ... + XOHCLSupRes supportResistances; + + // + // Change Price Steps ... + double momentumStep; + + // + // INDICATORS Market Sense ... + + // + // XCT ... + // there is not any Info provided here ... + + // + // XCC ... + // there is not any Info provided here ... + + // + // XHK ... + XHKInfo xhkInfo; + + // + // XTM ... + XTMInfo xtmInfo; + + // + // XPV ... + XPVInfo xpvInfo; + + // + // XAMA ... + XAMAInfo xamaInfo; + + // + // XMRB ... + XMRBInfo xmrbInfo; + + // + // XCHE ... + XCHEInfo xcheInfo; + + // + // XICH ... + XICHInfo xichInfo; + + // + // XTRND ... + XTRNDInfo xtrndInfo; + + // + // XSSLC ... + XSSLCInfo xsslcInfo; + + // + // XHULL ... + XHULLInfo xhullInfo; +}; + +// +// Notified a Signal was Appears ... +typedef void (*TOnSignalConditions)( + X121MarketConditions &info); + +// +// All Available Signal Types ... +enum ENUM_X121_SIGNAL_PROVIDERS +{ + NONE, // NONE ... + XPVF, // Peakse and Vales Using Fibo ... + XCHNL, // SSL Channel and MRB Signals ... + XTRND, // Trend Base ... +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCX121Provider : public XSCEABaseProvider +{ + // + // Public ... +public: + // + // Props ... + X121ProviderInputs providedConfig; + X121ProviderInputs currentConfig; + X121ProviderInputs cleanConfig; + + // + // Indicator Helper Classes Instance ... + + // + // XCT ... + XSCXCTHelper *mXCTHelper; + + // + // XCC ... + XSCXCCHelper *mXCCHelper; + + // + // XHK ... + XSCXHKHelper *mXHKHelper; + + // + // XTM ... + XSCXTMHelper *mXTMHelper; + + // + // XPV ... + XSCXPVHelper *mXPVHelper; + + // + // XAMA ... + XSCXAMAHelper *mXAMAHelper; + + // + // XMRB ... + XSCXMRBHelper *mXMRBHelper; + + // + // XCHE ... + XSCXCHEHelper *mXCHEHelper; + + // + // XICH ... + XSCXICHHelper *mXICHHelper; + + // + // XTRND ... + XSCXTRNDHelper *mXTRNDHelper; + + // + // XSSLC ... + XSCXSSLCHelper *mXSSLCHelper; + + // + // XHULL ... + XSCXHULLHelper *mXHULLHelper; + + // + // Hull Pivot Points ... + double upZonePivots[]; + double downZonePivots[]; + + // + // Peaks and Vales Verifications Number ... + double peaksPivots[]; + double valesPivots[]; + + // + double ichPivots[]; + + // + double fiboPivots[]; + + // + int pvConsequences; + + // + // Constructor ... + void XSCX121Provider( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Time Frame ... + ) + { + // + mMinPivots = 100; + pvConsequences = 26; + mDisableXPVFShort = false; + mDisableXPVFLong = false; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCX121Provider() + { + // + IndicatorRelease(mCTimerHandler); + + // + // De construct Helpers ... + delete mXCTHelper; + delete mXCCHelper; + delete mXHKHelper; + delete mXTMHelper; + delete mXPVHelper; + delete mXAMAHelper; + delete mXMRBHelper; + delete mXCHEHelper; + delete mXICHHelper; + delete mXTRNDHelper; + delete mXSSLCHelper; + delete mXHULLHelper; + } + + // + int GetMinPivots() { + return mMinPivots; + } + + // + virtual void PrepareTag() + { + mTag = "X121Provider((" + mSymbol + ")(" + ToString(mPeriod) + ")"; + } + + // + virtual bool Init() + { + // + bool result = false; + + // + // Instantiate all Indicators Helper Classes ... + + // + // XCT ... + mXCTHelper = new XSCXCTHelper( + mSymbol, + mPeriod); + result = mXCTHelper.SetConfig(currentConfig.xctConfig); + if (!result) + { + return result; + } + + // + // XCC ... + mXCCHelper = new XSCXCCHelper( + mSymbol, + mPeriod); + result = mXCCHelper.SetConfig(currentConfig.xccConfig); + if (!result) + { + return result; + } + + // + // XHK ... + mXHKHelper = new XSCXHKHelper( + mSymbol, + mPeriod); + result = mXHKHelper.SetConfig(currentConfig.xhkConfig); + if (!result) + { + return result; + }; + + // + // XTM ... + mXTMHelper = new XSCXTMHelper( + mSymbol, + mPeriod); + result = mXTMHelper.SetConfig(currentConfig.xtmConfig); + if (!result) + { + return result; + }; + + // + // XPV ... + mXPVHelper = new XSCXPVHelper( + mSymbol, + mPeriod); + result = mXPVHelper.SetConfig(currentConfig.xpvConfig); + if (!result) + { + return result; + }; + + // + // XAMA ... + mXAMAHelper = new XSCXAMAHelper( + mSymbol, + mPeriod); + result = mXAMAHelper.SetConfig(currentConfig.xamaConfig); + if (!result) + { + return result; + }; + + // + // XMRB ... + mXMRBHelper = new XSCXMRBHelper( + mSymbol, + mPeriod); + result = mXMRBHelper.SetConfig(currentConfig.xmrbConfig); + if (!result) + { + return result; + }; + + // + // XCHE ... + mXCHEHelper = new XSCXCHEHelper( + mSymbol, + mPeriod); + result = mXCHEHelper.SetConfig(currentConfig.xcheConfig); + if (!result) + { + return result; + }; + + // + // XICH ... + mXICHHelper = new XSCXICHHelper( + mSymbol, + mPeriod); + result = mXICHHelper.SetConfig(currentConfig.xichConfig); + if (!result) + { + return result; + }; + + // + // XTRND ... + mXTRNDHelper = new XSCXTRNDHelper( + mSymbol, + mPeriod); + result = mXTRNDHelper.SetConfig(currentConfig.xtrndConfig); + if (!result) + { + return result; + }; + + // + // XSSLC ... + mXSSLCHelper = new XSCXSSLCHelper( + mSymbol, + mPeriod); + result = mXSSLCHelper.SetConfig(currentConfig.xsslcConfig); + if (!result) + { + return result; + }; + + // + // XHULL ... + mXHULLHelper = new XSCXHULLHelper( + mSymbol, + mPeriod); + result = mXHULLHelper.SetConfig(currentConfig.xhullConfig); + if (!result) + { + return result; + }; + + // + return result; + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(result, mXCTHelper.GetMaxLength()); + result = MathMax(result, mXCCHelper.GetMaxLength()); + result = MathMax(result, mXHKHelper.GetMaxLength()); + result = MathMax(result, mXTMHelper.GetMaxLength()); + result = MathMax(result, mXPVHelper.GetMaxLength()); + result = MathMax(result, mXAMAHelper.GetMaxLength()); + result = MathMax(result, mXMRBHelper.GetMaxLength()); + result = MathMax(result, mXCHEHelper.GetMaxLength()); + result = MathMax(result, mXICHHelper.GetMaxLength()); + result = MathMax(result, mXTRNDHelper.GetMaxLength()); + result = MathMax(result, mXSSLCHelper.GetMaxLength()); + result = MathMax(result, mXHULLHelper.GetMaxLength()); + + // + return result; + } + + // + virtual int GetCalculatedBars() + { + // + int result = -1; + + // + int mXCTBars = mXCTHelper.GetCalculatedBars(); + int mXCCBars = mXCCHelper.GetCalculatedBars(); + int mXHKBars = mXHKHelper.GetCalculatedBars(); + int mXTMBars = mXTMHelper.GetCalculatedBars(); + int mXPVBars = mXPVHelper.GetCalculatedBars(); + int mXAMABars = mXAMAHelper.GetCalculatedBars(); + int mXMRBBars = mXMRBHelper.GetCalculatedBars(); + int mXCHEBars = mXCHEHelper.GetCalculatedBars(); + int mXICHBars = mXICHHelper.GetCalculatedBars(); + int mXTRNDBars = mXTRNDHelper.GetCalculatedBars(); + int mXSSLCBars = mXSSLCHelper.GetCalculatedBars(); + int mXHULLBars = mXHULLHelper.GetCalculatedBars(); + + // + int min = MathMin(mXCTBars, mXCCBars); + min = MathMin(min, mXHKBars); + min = MathMin(min, mXTMBars); + min = MathMin(min, mXPVBars); + min = MathMin(min, mXAMABars); + min = MathMin(min, mXMRBBars); + min = MathMin(min, mXCHEBars); + min = MathMin(min, mXICHBars); + min = MathMin(min, mXTRNDBars); + min = MathMin(min, mXSSLCBars); + min = MathMin(min, mXHULLBars); + + // + int max = MathMax(mXCTBars, mXCCBars); + max = MathMax(max, mXHKBars); + max = MathMax(max, mXTMBars); + max = MathMax(max, mXPVBars); + max = MathMax(max, mXAMABars); + max = MathMax(max, mXMRBBars); + max = MathMax(max, mXCHEBars); + max = MathMax(max, mXICHBars); + max = MathMax(max, mXTRNDBars); + max = MathMax(max, mXSSLCBars); + max = MathMax(max, mXHULLBars); + + // + result = min; + + // + return result; + } + + // + virtual void ProcessBuffers() + { + UpdatePivotPoints(); + } + + // + virtual bool ProcessTick(X121MarketConditions &conditions) + { + // + if (CanIgnoreTick()) { + return false; + } + + // + return ProcessSignals(conditions); + } + + // + X121ProviderInputs GetConfig() + { + // + X121ProviderInputs result; + + // + result = currentConfig; + + // + return result; + } + + // + bool SetConfig(X121ProviderInputs &config) + { + // + bool result = false; + + // + PrepareConfig(config); + + // + result = Init(); + + // + return result; + } + + // + bool ResetDefaultConfig() + { + // + bool result = SetConfig(providedConfig); + + // + return result; + } + + // + bool ShowCleanConfig() + { + // + currentConfig = cleanConfig; + + // + bool result = Init(); + + // + return result; + } + + // + bool ShowDefaultConfig() + { + // + currentConfig = providedConfig; + + // + bool result = Init(); + + // + return result; + } + + // + // Generate Market Sense ... + X121MarketConditions GetMarketConditions( + int barIndex // Specified Bar Index + ) + { + // + X121MarketConditions result; + + // + // Fill Common Data ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barIndex = barIndex; + + // + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + result.barTime = barTime; + + // + int remainedCandle = barIndex > 0 + ? barIndex - 1 + : barIndex; + GetCandleRemainsTime( + result.barRemains, + mSymbol, + mPeriod, + remainedCandle); + + // + result.xhkInfo = mXHKHelper.GetInfo(barIndex); + result.xtmInfo = mXTMHelper.GetInfo(barIndex); + result.xpvInfo = mXPVHelper.GetInfo(barIndex); + result.xamaInfo = mXAMAHelper.GetInfo(barIndex); + result.xmrbInfo = mXMRBHelper.GetInfo(barIndex); + result.xcheInfo = mXCHEHelper.GetInfo(barIndex); + result.xichInfo = mXICHHelper.GetInfo(barIndex); + result.xtrndInfo = mXTRNDHelper.GetInfo(barIndex); + result.xsslcInfo = mXSSLCHelper.GetInfo(barIndex); + result.xhullInfo = mXHULLHelper.GetInfo(barIndex); + + // + return result; + } + + // + // TODO: Complete this ... + XOHCLSupRes GetSupportsAndResistances( + XSignal &signal, // Signal + int requirements = 10) + { + // + XOHCLSupRes result; + + // + int totalBars = Bars( + mSymbol, + mPeriod); + + // + int idx = 0; + + // + while ( + idx < totalBars - 17 || + ArraySize(result.sup) < requirements || + ArraySize(result.res) < requirements) + { + // + // Here we Try to Find Support and Resistances ... + + // + idx++; + } + + // + return result; + } + + // + bool GuardCheck(XGuard &guards[]) + { + // + bool result = false; + + // + Clean(guards); + + // + // Implement Guards Check ... + + // + return result; + } + + // + // Add Specific On SignalConditions Event Handler ... + int AddOnSignalConditionEventHandler(TOnSignalConditions handler) + { + // + ArrayResize( + mSignalConditionsEventHandlers, + ArraySize(mSignalConditionsEventHandlers) + 1); + + // + int result = ArraySize(mSignalConditionsEventHandlers) - 1; + mSignalConditionsEventHandlers[result] = handler; + + // + return result; + } + + // + // Remove All On Signal Event Handler ... + void ReoveOnSignalEventHandlers() + { + // + ArrayFree(mSignalConditionsEventHandlers); + } + + // + // Notify a Signal Found on all Event Listeners ... + void NotifyOnSignalConditionsEvent(X121MarketConditions &info) + { + // + int listenerCount = ArraySize(mSignalConditionsEventHandlers); + if (listenerCount <= 0) + { + return; + } + + // + // Loop Through Listeners ... + for (int i = 0; i < listenerCount; i++) + { + // + TOnSignalConditions listener = mSignalConditionsEventHandlers[i]; + + // + listener(info); + } + } + + // + void ProccessPivotPoints() + { + // + if (mStartPivotScan) + { + return; + } + + // + mStartPivotScan = true; + + // + int maxLength = GetMaxLength(); + int cBars = GetCalculatedBars(); + int scanSize = cBars - maxLength - 1; + for (int i = 1; i < scanSize; i++) + { + // + UpdatePivotPoints(i); + + // + int pivotsCount = CountPivots(); + if (pivotsCount >= mMinPivots) + { + break; + } + } + } + + // + int CountPivots() + { + // + int pivotSizes[]; + int upZoneCount = ArraySize(upZonePivots); + if (upZoneCount > 0) + { + // + Add( + upZoneCount, + pivotSizes); + } + + // + int downZoneCount = ArraySize(downZonePivots); + if (downZoneCount > 0) + { + // + Add( + downZoneCount, + pivotSizes); + } + + // + int peaksCount = ArraySize(peaksPivots); + if (peaksCount > 0) + { + // + Add( + peaksCount, + pivotSizes); + } + + // + int valesCount = ArraySize(valesPivots); + if (valesCount > 0) + { + // + Add( + valesCount, + pivotSizes); + } + + // + int fibsCount = ArraySize(fiboPivots); + if (fibsCount > 0) + { + // + Add( + fibsCount, + pivotSizes); + } + + // + int ichsCount = ArraySize(ichPivots); + if (ichsCount > 0) + { + // + Add( + ichsCount, + pivotSizes); + } + + // + int result = ArraySize(pivotSizes) > 0 + ? pivotSizes[ArrayMaximum(pivotSizes)] + : 0; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // CCandle Timer ... + int mCTimerHandler; + + // + // Signal Event Handlers ... + TOnSignalConditions mSignalConditionsEventHandlers[]; + + // + // Make Provided Config in Clean Style ... + void PrepareConfig(X121ProviderInputs &config) + { + // + cleanConfig = config; + + // + // XCT ... + // Candle Timing ... + cleanConfig.xctConfig.showCandleTime = false; + + // + // XCC ... + // Candle Styling ... + cleanConfig.xccConfig.showCandles = true; + + // + // XHK ... + // HikenAshi Candle Representing ... + cleanConfig.xhkConfig.drawCandles = false; + cleanConfig.xhkConfig.drawCandleLines = false; + + // + // XTM ... + // Trend Magic ... + cleanConfig.xtmConfig.showLine = false; + + // + // XPV ... + // Peaks And Vales ... + cleanConfig.xpvConfig.showPeaksAndVales = false; + cleanConfig.xpvConfig.showLevels = false; + cleanConfig.xpvConfig.showFibo1Levels = false; + cleanConfig.xpvConfig.showFibo2Levels = false; + cleanConfig.xpvConfig.showFibo3Levels = false; + + // + // XAMA ... + // Adaptive Moving Average ... + cleanConfig.xamaConfig.showLine = false; + + // + // XMRB ... + // Moving Average Ribbon ... + cleanConfig.xmrbConfig.showFastMa = false; + cleanConfig.xmrbConfig.showSlowMa = false; + cleanConfig.xmrbConfig.showRibbon = false; + + // + // XCHE ... + // Chandelier Exit Points ... + cleanConfig.xcheConfig.showLongExit1Line = false; + cleanConfig.xcheConfig.showShortExit1Line = false; + cleanConfig.xcheConfig.showLongExit2Line = false; + cleanConfig.xcheConfig.showShortExit2Line = false; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + cleanConfig.xichConfig.showTenkanSen = false; + cleanConfig.xichConfig.showKijunSen = false; + cleanConfig.xichConfig.showKijunSenPlus = false; + cleanConfig.xichConfig.showKijunSenNegative = false; + cleanConfig.xichConfig.showChikouSpan = false; + cleanConfig.xichConfig.showSenkouSpanA = false; + cleanConfig.xichConfig.showSenkouSpanB = false; + cleanConfig.xichConfig.showKumo = false; + + // + // XTRND ... + // Trend Detector ... + cleanConfig.xtrndConfig.showConsolidations = false; + cleanConfig.xtrndConfig.showTrend = false; + cleanConfig.xtrndConfig.showL1Trend = false; + cleanConfig.xtrndConfig.showL2Trend = false; + cleanConfig.xtrndConfig.showL3Trend = false; + + // + // XSSLC ... + // SSL Channel ... + cleanConfig.xsslcConfig.showUp = false; + cleanConfig.xsslcConfig.showDown = false; + + // + // XHULL ... + // Hull Trend Detection Channel ... + cleanConfig.xhullConfig.showUpZone = false; + cleanConfig.xhullConfig.showDownZone = false; + + // + providedConfig = config; + currentConfig = config; + } + + // + int mMinPivots; + bool mStartPivotScan; + bool mDisableXPVFLong; + bool mDisableXPVFShort; + double mLastMomentumStep; + + // + // Find Required Pivots for Support and Resistance ... + void UpdatePivotPoints( + int barIndex = 1 // Specified Candle ... + ) + { + // + mXCTHelper.Calculate(barIndex); + mXCCHelper.Calculate(barIndex); + mXHKHelper.Calculate(barIndex); + mXTMHelper.Calculate(barIndex); + mXPVHelper.Calculate(barIndex); + mXAMAHelper.Calculate(barIndex); + mXMRBHelper.Calculate(barIndex); + mXCHEHelper.Calculate(barIndex); + mXICHHelper.Calculate(barIndex); + mXTRNDHelper.Calculate(barIndex); + mXSSLCHelper.Calculate(barIndex); + mXHULLHelper.Calculate(barIndex); + + // + // Detect Peask and Vales Pivots ... + + // + // Detect Hull Pivots ... + // find Hull Trend Changes ... + int idx = 1; + bool isHullUpChanged = + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx] == XHULL_STATE_BULLISH && + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx + 1] != XHULL_STATE_BULLISH + // + ) + // + || + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx] == XHULL_STATE_BEARISH && + (XHULL_ZONE_STATES)mXHULLHelper.upStateBuffer[idx + 1] != XHULL_STATE_BEARISH + // + ) + // + ; + + // + bool isHullDownChanged = + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx] == XHULL_STATE_BULLISH && + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx + 1] != XHULL_STATE_BULLISH + // + ) + // + || + // + ( + // + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx] == XHULL_STATE_BEARISH && + (XHULL_ZONE_STATES)mXHULLHelper.downStateBuffer[idx + 1] != XHULL_STATE_BEARISH + // + ) + // + ; + + // + // Find Change State ... + if (isHullUpChanged || + isHullDownChanged) + { + // + AddIfNotExists( + mXHULLHelper.upBuffer[idx], + upZonePivots); + + // + AddIfNotExists( + mXHULLHelper.downBuffer[idx], + downZonePivots); + } + + // + // Find Momentom Step ... + if (isHullUpChanged && + isHullDownChanged) + { + // + mLastMomentumStep = MathAbs(mXHULLHelper.upBuffer[idx] - mXHULLHelper.downBuffer[idx]); + mLastMomentumStep = NormalizePrice( + mLastMomentumStep, + mSymbol); + } + + // + // Find Peaks and Vales ... + double selectedFib1 = mXPVHelper.fl1Buffer[idx]; + double selectedFib2 = mXPVHelper.fl2Buffer[idx]; + double selectedFib3 = mXPVHelper.fl3Buffer[idx]; + double selectedPeak = mXPVHelper.peaksBuffer[idx]; + double selectedVale = mXPVHelper.valesBuffer[idx]; + + // + double selectedTenkanSen = mXICHHelper.tenkanSenBuffer[idx]; + double selectedKijunSen = mXICHHelper.kijunSenBuffer[idx]; + + // + int fib1Verified = 0; + int fib2Verified = 0; + int fib3Verified = 0; + int peaksVerified = 0; + int valesVerified = 0; + int kijunSenVerified = 0; + int tenkanSenVerified = 0; + int senkouSpanAVerified = 0; + int senkouSpanBVerified = 0; + for (int i = barIndex + 1; i < pvConsequences + barIndex + 1; i++) + { + // + int idx = i - barIndex; + + // + // PEAKS and VALES ... + + // + if (selectedPeak == mXPVHelper.peaksBuffer[idx]) + { + peaksVerified++; + } + else + { + peaksVerified = 0; + } + + // + if (selectedVale == mXPVHelper.valesBuffer[idx]) + { + valesVerified++; + } + else + { + valesVerified = 0; + } + + // + if (selectedFib1 == mXPVHelper.fl1Buffer[idx]) + { + fib1Verified++; + } + else + { + fib1Verified = 0; + } + + // + if (selectedFib2 == mXPVHelper.fl2Buffer[idx]) + { + fib2Verified++; + } + else + { + fib2Verified = 0; + } + + // + if (selectedFib3 == mXPVHelper.fl3Buffer[idx]) + { + fib3Verified++; + } + else + { + fib3Verified = 0; + } + + // + // ICHIMOKU Kinko Hyo ... + + // + if (selectedTenkanSen == mXICHHelper.tenkanSenBuffer[idx]) + { + tenkanSenVerified++; + } + else + { + tenkanSenVerified = 0; + } + + // + if (selectedKijunSen == mXICHHelper.kijunSenBuffer[idx]) + { + kijunSenVerified++; + } + else + { + kijunSenVerified++; + } + } + + // + if (peaksVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedPeak, + peaksPivots); + } + + // + if (valesVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedVale, + valesPivots); + } + + // + if (fib1Verified >= pvConsequences) + { + // + AddIfNotExists( + selectedFib1, + fiboPivots); + } + + // + if (fib2Verified >= pvConsequences) + { + // + AddIfNotExists( + selectedFib2, + fiboPivots); + } + + // + if (fib3Verified >= pvConsequences) + { + // + AddIfNotExists( + selectedFib3, + fiboPivots); + } + + // + if (tenkanSenVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedTenkanSen, + ichPivots); + } + + // + if (kijunSenVerified >= pvConsequences) + { + // + AddIfNotExists( + selectedKijunSen, + ichPivots); + } + + // // + // if (senkouSpanAVerified >= pvConsequences) + // { + // // + // AddIfNotExists( + // selectedSenkouSpanA, + // ichPivots); + // } + + // // + // if (senkouSpanBVerified >= pvConsequences) + // { + // // + // AddIfNotExists( + // selectedSenkouSpanB, + // ichPivots); + // } + } + + // + void FillPivotPoints( + double &result[]) + { + // + Clean(result); + + // + int pCount = CountPivots(); + if (pCount <= 0) + { + return; + } + + // + AddsIfNotExists( + upZonePivots, + result); + + // + AddsIfNotExists( + downZonePivots, + result); + + // + AddsIfNotExists( + peaksPivots, + result); + + // + AddsIfNotExists( + valesPivots, + result); + + // + AddsIfNotExists( + fiboPivots, + result); + + // + AddsIfNotExists( + ichPivots, + result); + } + + // + // Here we are Capture Conditions and Check Signals ... + // The Signals Must be Unique for each providers ... + bool ProcessSignals(X121MarketConditions &conditions) + { + // + X121MarketConditions mConditions = GetMarketConditions(1); + + // + // BUY ... + + // + Clean(mConditions.signal); + bool hasLongSignal = HasLongSignal(mConditions); + if (hasLongSignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + // SELL ... + + // + Clean(mConditions.signal); + bool hasShortignal = HasShortSignal(mConditions); + if (hasShortignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + return false; + } + + // + // Check has Long Signal on Each Strategies ... + bool HasLongSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + double entry = GetEntry( + mSymbol, + POSITION_TYPE_BUY); + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + 1, + pivots, + 15); + X121MarketConditions mConditions = GetMarketConditions(1); + + // + mXPVHelper.Calculate(1); + + // + Clean(mConditions.signal); + + // + // XPVF Signal Provider ... + bool xPVFSignal = false; + if (!mDisableXPVFLong) + { + // + xPVFSignal = + // + mConditions.xpvInfo.isNewPeak && + mXPVHelper.peaksBuffer[0] < mXPVHelper.peaksBuffer[1] && + mXPVHelper.valesBuffer[0] == mXPVHelper.valesBuffer[1] + // + ; + + // + if (xPVFSignal) + { + // + Add( + ToString(XPVF), + mConditions.signal.providers); + + // + mConditions.signal.r2r = 1.5; + mConditions.signal.riskAmount = 0.005; + mConditions.signal.mode = X_ORDER_MODE_MARKET; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; // mXCHEHelper.longExit2[1]; + mConditions.signal.tp = 0; + + // + // mConditions.signal.calculateTP = true; + // mConditions.signal.useRiskAmountAsVolume = false; + // mConditions.signal.useSupportAndResistance = true; + + // + // mDisableXPVFLong = true; + // mDisableXPVFShort = false; + } + } + + // + result = + // + xPVFSignal + // + ; + + // + if (result) + { + // + conditions = mConditions; + + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_BUY; + + // + conditions.hasSignal = true; + } + + // + return result; + } + + // + // Check has Short Signal on Each Strategies ... + bool HasShortSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + double entry = GetEntry( + mSymbol, + POSITION_TYPE_SELL); + + // + XOHCL c1 = GetCandle( + mSymbol, + mPeriod, + 1); + + // + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + 1, + pivots, + 15); + + // + X121MarketConditions mConditions = GetMarketConditions(1); + + // + mXPVHelper.Calculate(1); + + // + Clean(mConditions.signal); + + // + // XPVF Signal Provider ... + bool xPVFSignal = false; + if (!mDisableXPVFShort) + { + // + xPVFSignal = + // + mConditions.xpvInfo.isNewVale && + mXPVHelper.valesBuffer[0] > mXPVHelper.valesBuffer[1] && + mXPVHelper.peaksBuffer[0] == mXPVHelper.peaksBuffer[1] + // + ; + + // + if (xPVFSignal) + { + // + Add( + ToString(XPVF), + mConditions.signal.providers); + + // + mConditions.signal.r2r = 1.5; + mConditions.signal.riskAmount = 0.005; + mConditions.signal.mode = X_ORDER_MODE_STOP; + mConditions.signal.entry = entry; + mConditions.signal.sl = 0; + mConditions.signal.tp = mXPVHelper.valesBuffer[1]; + + // + mConditions.signal.calculateTP = true; + mConditions.signal.useRiskAmountAsVolume = false; + mConditions.signal.useSupportAndResistance = true; + + // + // mDisableXPVFShort = true; + // mDisableXPVFLong = false; + } + } + + // + result = + // + xPVFSignal + // + ; + + // + if (result) + { + // + conditions = mConditions; + + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_SELL; + + // + conditions.hasSignal = true; + } + + // + return result; + } +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct X121SignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Desired Magic Number ... + ulong magicNumber; + + // + // Provider ... + XSCX121Provider *provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + X121SignalProvider &item, // item want to add + X121SignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Generate Identifier Tag ... +string GenerateTag(X121SignalProvider &descriptor) +{ + // + string result = ""; + + // + result = descriptor.symbol + "," + ToString(descriptor.period); + + // + return result; +} + +// +// Converts a Signal provider to String ... +string ToString(ENUM_X121_SIGNAL_PROVIDERS provider) +{ + return EnumToString(provider); +} + +// +// convert an String to Signal provider ... +ENUM_X121_SIGNAL_PROVIDERS ToProvider(string provider) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + if (ToString(NONE) == provider) + { + result = NONE; + } + else if (ToString(XPVF) == provider) + { + result = XPVF; + } + else if (ToString(XCHNL) == provider) + { + result = XCHNL; + } + else if (ToString(XTRND) == provider) + { + result = XTRND; + } + + // + return result; +} + +// +// Extract Provider Type from Signal Commnet ... +ENUM_X121_SIGNAL_PROVIDERS ExtractPositionProvider(XPosition &position) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + string providerStr = + ExtractString( + position.comment, + XProviderToken + "(", + ")"); + if (StringLen(providerStr) <= 0) + { + return result; + } + + // + result = ToProvider(providerStr); + + // + return result; +} + +// +// Generate Provider String for Using in Positions Comment ... +// NOTE: if there is more than One Provider, it takes first +// provider as main and the others used to increase volume ... +string GenerateProvidersString(XSignal &signal) +{ + // + string result = ""; + + // + int providersCount = ArraySize(signal.providers); + if (providersCount <= 0) + { + return result; + } + + // + result = XProviderToken + "(" + signal.providers[0] + ")"; + + // + return result; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.x121.xea.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.x121.xea.class.mq5 new file mode 100644 index 0000000..a9926c5 --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.x121.xea.class.mq5 @@ -0,0 +1,443 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121EA +// Description: an Expert Class which +// used X121 Setup ... +// +// +// 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 Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xea.class.mq5" +#include "../Libraries/x-saherelm.x121.draw.lib.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// an Expert Advisor Class by X121Provider ... +class XSCX121EA : public XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + XSCX121Provider *mProvider; + + // + // Constructor ... + void XSCX121EA( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + ulong magic, // Magic Number + int slippage, // Slippgae + OnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + OnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + OnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + OnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + OnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + OnTradeStateChanged onTradeStateChangedHandler = NULL, // On Trade State Changed Event Handler + TOnSignalConditions onSignalConditions = NULL // On SignalConditions Event Handler + ) : XSCBaseEA(symbol, + period, + magic, + slippage, + onStopLossTriggered, + onTakeProfitTriggered, + onDealsChangedHandler, + onOrdersChangedHandler, + onPositionsChangedHandler, + onTradeStateChangedHandler) + { + // + mOnSignalConditions = onSignalConditions; + + // + InitProvider(); + } + + // + // DeConstructor ... + void ~XSCX121EA() + { + delete mProvider; + } + + // + // START Inheritance Functions ... + // + + // + void PrepareTag() + { + mTag = "X121EA:" + mSymbol + "," + ToString(mPeriod) + (string)mMagic; + } + + // + bool CheckGuard(XGuard &guards[]) + { + return mProvider.GuardCheck(guards); + } + + // + bool SignalCheck(XSignal &signals[]) + { + // + // Detect Pivot Points ... + int foundedPivots = mProvider.CountPivots(); + int reuiredPivots = mProvider.GetMinPivots(); + if (foundedPivots < reuiredPivots) + { + // + mProvider.ProccessPivotPoints(); + + // + LogMessage("Founding Pivots: " + ToString(foundedPivots) + "/" + ToString(reuiredPivots)); + return false; + } + + // + X121MarketConditions conditions; + bool result = mProvider.ProcessTick(conditions); + + // + if (result) + { + // + // TODO: Here we Do all Signal Preparations such as TP/SL Calculations + // or Support and Resistance usage or Volume Calculations ... + // then pass prepared Signal to Execution ... + + // + ulong mTicket = MathRand() * 100000; + + // + DrawSignal( + mTicket, + conditions.signal); + + // + DrawSupportResistance( + 0, + conditions.supportResistances, + conditions.signal.providers[0]); + + // + // IGNORE SIGNAL EXECUTTION ... + return false; + + // + Add( + conditions.signal, + signals); + } + + // + return result; + } + + // + // END Inheritance Functions ... + // + + // + // START Provided Actions ... + // + + // + // END Provided Actions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + X121ProviderInputs mProviderConfig; + TOnSignalConditions mOnSignalConditions; + + // + // Actions ... + + // + // Prepare Default Configurations for X121Provider Setup ... + void PrepareProviderConfig() + { + // + // XCT ... + // Candle Timing ... + mProviderConfig.xctConfig.clr = clrBlueViolet; + mProviderConfig.xctConfig.corner = CORNER_RIGHT_UPPER; + mProviderConfig.xctConfig.showCandleTime = true; + + // + // XCC ... + // Candle Styling ... + mProviderConfig.xccConfig.upColor = clrLime; + mProviderConfig.xccConfig.downColor = clrRed; + mProviderConfig.xccConfig.lineColor = clrLime; + mProviderConfig.xccConfig.bearishColor = clrRed; + mProviderConfig.xccConfig.bullishColor = clrLime; + mProviderConfig.xccConfig.volumesColor = clrGreen; + mProviderConfig.xccConfig.showCandles = true; + + // + // XHK ... + // HikenAshi Candle Representing ... + mProviderConfig.xhkConfig.drawCandleLines = false; + + // + // XTM ... + // Trend Magic ... + mProviderConfig.xtmConfig.length = 35; + mProviderConfig.xtmConfig.shift = 0; + mProviderConfig.xtmConfig.method = MODE_SMA; + mProviderConfig.xtmConfig.appliedTo = PRICE_LOW; + mProviderConfig.xtmConfig.showLine = false; + + // + // XPV ... + // Peaks And Vales ... + mProviderConfig.xpvConfig.shortLength = 9; + mProviderConfig.xpvConfig.mediumLength = 17; + mProviderConfig.xpvConfig.longLength = 26; + mProviderConfig.xpvConfig.hindLength = 35; + mProviderConfig.xpvConfig.fiboLevel1 = 0.382; + mProviderConfig.xpvConfig.fiboLevel2 = 0.5; + mProviderConfig.xpvConfig.fiboLevel3 = 0.618; + mProviderConfig.xpvConfig.hhMode = MODE_HIGH; + mProviderConfig.xpvConfig.llMode = MODE_LOW; + mProviderConfig.xpvConfig.showPeaksAndVales = false; + mProviderConfig.xpvConfig.showLevels = false; + mProviderConfig.xpvConfig.showFibo1Levels = false; + mProviderConfig.xpvConfig.showFibo2Levels = false; + mProviderConfig.xpvConfig.showFibo3Levels = false; + + // + // XAMA ... + // Adaptive Moving Average ... + mProviderConfig.xamaConfig.length = 52; + mProviderConfig.xamaConfig.fastEMA = 2; + mProviderConfig.xamaConfig.slowEMA = 30; + mProviderConfig.xamaConfig.maShift = 0; + mProviderConfig.xamaConfig.appliedTo = PRICE_LOW; + mProviderConfig.xamaConfig.showLine = false; + + // + // XMRB ... + // Moving Average Ribbon ... + mProviderConfig.xmrbConfig.fast1Length = 3; + mProviderConfig.xmrbConfig.slow1Length = 5; + mProviderConfig.xmrbConfig.fast2Length = 8; + mProviderConfig.xmrbConfig.slow2Length = 13; + mProviderConfig.xmrbConfig.fast3Length = 21; + mProviderConfig.xmrbConfig.slow3Length = 34; + mProviderConfig.xmrbConfig.fast4Length = 55; + mProviderConfig.xmrbConfig.slow4Length = 89; + mProviderConfig.xmrbConfig.fast5Length = 144; + mProviderConfig.xmrbConfig.slow5Length = 233; + mProviderConfig.xmrbConfig.ribbonMode = MODE_EMA; + mProviderConfig.xmrbConfig.ribbonAppliedTo = PRICE_CLOSE; + mProviderConfig.xmrbConfig.showFastMa = false; + mProviderConfig.xmrbConfig.showSlowMa = false; + mProviderConfig.xmrbConfig.showRibbon = false; + + // + // XCHE ... + // Chandelier Exit Points ... + mProviderConfig.xcheConfig.length = 35; + mProviderConfig.xcheConfig.loopback = 26; + mProviderConfig.xcheConfig.multiplier1 = 3; + mProviderConfig.xcheConfig.multiplier2 = 3.5; + mProviderConfig.xcheConfig.upAppliedTo = PRICE_HIGH; + mProviderConfig.xcheConfig.downAppliedTo = PRICE_LOW; + mProviderConfig.xcheConfig.showLongExit1Line = false; + mProviderConfig.xcheConfig.showShortExit1Line = false; + mProviderConfig.xcheConfig.showLongExit2Line = false; + mProviderConfig.xcheConfig.showShortExit2Line = false; + + // + // XICH ... + // Ichimopku Kinko Hyo ... + mProviderConfig.xichConfig.tenkanSenLength = 9; + mProviderConfig.xichConfig.tenkanSenMode = X_XICH_HH_LL_MODE; + mProviderConfig.xichConfig.kijunSenLength = 26; + mProviderConfig.xichConfig.kijunSenMode = X_XICH_HH_LL_MODE; + mProviderConfig.xichConfig.senkouSpanBLength = 52; + mProviderConfig.xichConfig.senkouSpanBMode = X_XICH_HH_LL_MODE; + mProviderConfig.xichConfig.chikuoSpanAppliedTo = PRICE_CLOSE; + mProviderConfig.xichConfig.showTenkanSen = false; + mProviderConfig.xichConfig.showKijunSen = false; + mProviderConfig.xichConfig.showKijunSenPlus = false; + mProviderConfig.xichConfig.showKijunSenNegative = false; + mProviderConfig.xichConfig.showChikouSpan = false; + mProviderConfig.xichConfig.showSenkouSpanA = false; + mProviderConfig.xichConfig.showSenkouSpanB = false; + mProviderConfig.xichConfig.showKumo = false; + mProviderConfig.xichConfig.shiftKumo = true; + + // + // XTRND ... + // Trend Detector ... + mProviderConfig.xtrndConfig.cycleLength = 2; + mProviderConfig.xtrndConfig.numberOfVerifications = 2; + mProviderConfig.xtrndConfig.hhMode = MODE_HIGH; + mProviderConfig.xtrndConfig.llMode = MODE_LOW; + mProviderConfig.xtrndConfig.l1Method = X_PERIOD_AUTO; + mProviderConfig.xtrndConfig.l1Period = NULL; + mProviderConfig.xtrndConfig.l2Method = X_PERIOD_AUTO; + mProviderConfig.xtrndConfig.l2Period = NULL; + mProviderConfig.xtrndConfig.l3Method = X_PERIOD_AUTO; + mProviderConfig.xtrndConfig.l3Period = NULL; + mProviderConfig.xtrndConfig.showConsolidations = false; + mProviderConfig.xtrndConfig.showTrend = false; + mProviderConfig.xtrndConfig.showL1Trend = false; + mProviderConfig.xtrndConfig.showL2Trend = false; + mProviderConfig.xtrndConfig.showL3Trend = false; + + // + // XSSLC ... + // SSL Channel ... + mProviderConfig.xsslcConfig.length = 36; + mProviderConfig.xsslcConfig.method = MODE_SMA; + mProviderConfig.xsslcConfig.upAppliedTo = PRICE_HIGH; + mProviderConfig.xsslcConfig.downAppliedTo = PRICE_LOW; + mProviderConfig.xsslcConfig.showUp = false; + mProviderConfig.xsslcConfig.showDown = false; + + // + // XHULL ... + // Hull Trend Detection Channel ... + mProviderConfig.xhullConfig.length = 72; + mProviderConfig.xhullConfig.divisor = 2; + mProviderConfig.xhullConfig.upAppliedTo = PRICE_HIGH; + mProviderConfig.xhullConfig.downAppliedTo = PRICE_LOW; + mProviderConfig.xhullConfig.showUpZone = false; + mProviderConfig.xhullConfig.showDownZone = false; + + // + // Default Configs For Different States ... + bool showPV = true; + bool showHK = true; + bool showCHE = true; + bool showTRND = true; + bool simpleIchi = true; + + // + if (showHK) + { + // + // Hiken Ashi ... + mProviderConfig.xccConfig.showCandles = false; + mProviderConfig.xhkConfig.drawCandles = true; + } + if (showPV) + { + // + // Peaks and Vales ... + mProviderConfig.xpvConfig.showFibo1Levels = true; + mProviderConfig.xpvConfig.showFibo2Levels = true; + mProviderConfig.xpvConfig.showFibo3Levels = true; + mProviderConfig.xpvConfig.showPeaksAndVales = true; + } + if (simpleIchi) + { + // + // Simple Ichimoku Kinko Hyo ... + mProviderConfig.xichConfig.showKijunSen = true; + mProviderConfig.xichConfig.showTenkanSen = true; + mProviderConfig.xichConfig.showSenkouSpanA = true; + mProviderConfig.xichConfig.showSenkouSpanB = true; + } + if (showCHE) + { + // + // Chandelier Exit ... + mProviderConfig.xcheConfig.showLongExit1Line = true; + mProviderConfig.xcheConfig.showLongExit2Line = true; + mProviderConfig.xcheConfig.showShortExit1Line = true; + mProviderConfig.xcheConfig.showShortExit2Line = true; + } + if (showTRND) + { + // + // Show Trend ... + mProviderConfig.xtrndConfig.showL1Trend = true; + mProviderConfig.xtrndConfig.showL2Trend = true; + mProviderConfig.xtrndConfig.showL3Trend = true; + } + } + + // + // Initialize X121Provider ... + void InitProvider() + { + // + PrepareProviderConfig(); + + // + mProvider = new XSCX121Provider( + mSymbol, + mPeriod); + + // + if (mOnSignalConditions != NULL) + { + // + // Attach Event Handlers ... + mProvider.AddOnSignalConditionEventHandler(mOnSignalConditions); + } + + // + // Initialize Provider ... + mProvider.SetConfig(mProviderConfig); + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.xaccount.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.xaccount.class.mq5 new file mode 100644 index 0000000..4425f0b --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.xaccount.class.mq5 @@ -0,0 +1,398 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCAccount +// Description: provides all Account requirements ... +// +// +// 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 Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Manage Account ... +class XSCAccount +{ + // + // Public ... +public: + // + // Constructor ... + void XSCAccount() + { + // + mAccountInfo = new CAccountInfo(); + } + + // + // Deconstructor ... + void ~XSCAccount() + { + } + + // + // START Provided Functions ... + // + + // + // 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 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; + } + + // + // Calculate Point Value for Given Symbol based on Account ... + double GetPointValue( + string symbol // trading symbol + ) + { + // + double result = 0; + + // + double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); + double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); + double point = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + double ticksPerPoint = tickSize / point; + + // + result = tickValue / ticksPerPoint; + + // + return result; + } + + // + // Calculate Risk Amount based on account Currency by Providing: + // Points and Volume ... + double CalculateRiskAmount( + string symbol, // trading symbol + double points, // amount of Risk Points + double volume // position Volume + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = pointValue * volume * points; + + // + return result; + } + + // + // Calculate Risk Points based on account Currency by Providing: + // Volume and Amount ... + double CalculateRiskPoints( + string symbol, // trading symbol + double volume, // position Volume + double amount // amount of Risk based on Account Currency + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * volume); + + // + return result; + } + + // + // Calculate Volume based on account Currency by Providing: + // Amount and Risk Points ... + double CalculateVolume( + string symbol, // trading symbol + double amount, // amount of Risk based on Account Currency + double points // amount of Risk Points + ) + { + // + double result = 0; + + // + points = + points <= 0 + ? 10 + : points; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * points); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.xdatacollector.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.xdatacollector.class.mq5 new file mode 100644 index 0000000..f24164d --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.xdatacollector.class.mq5 @@ -0,0 +1,1582 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCDataCollector +// Description: provides all Data Collection requirements ... +// +// +// 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 Definitions ... +// + +// +// Supported Data Types ... +enum ENUM_X_XDATACOLLECTOR_TYPES +{ + X_DATA_COLLECTOR_SIGNAL, + X_DATA_COLLECTOR_SUPRES, + X_DATA_COLLECTOR_POSITION, + X_DATA_COLLECTOR_DEAL, + X_DATA_COLLECTOR_LOG, +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "x-saherelm.xtrade.class.mq5" +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class Definition ... +class XSCDataCollector +{ + // + // Public ... +public: + // + // Constructor ... + void XSCDataCollector() + { + // + XSCDataCollector("XDataCollector"); + + // + DefineTokens(); + } + void XSCDataCollector( + string path // Base Folder to Store Data + ) + { + // + // Set Properties ... + + // + Path(path); + + // + DefineTokens(); + } + + // + // Deconstructor ... + void ~XSCDataCollector() + { + } + + // + // START Getter(s)/Setter(s) ... + // + + // + // Path ... + void Path(string value) + { + mPath = value; + } + + string Path() + { + return mPath; + } + + // + // END Getter(s)/Setter(s) ... + // + + // + // START Provided Functions ... + // + + // + // Clean Exists Collected Data ... + void CleanStore() + { + // + ENUM_X_XDATACOLLECTOR_TYPES types[]; + RetrieveAllAvailableTypes(types); + int typesCount = ArraySize(types); + if (typesCount <= 0) + { + return; + } + + // + ResetLastError(); + + // + for (int i = 0; i < typesCount; i++) + { + // + ENUM_X_XDATACOLLECTOR_TYPES iType = types[i]; + string typeFilePath = GenerateTypeFilePath(iType); + + // + bool isExist = FileIsExist(typeFilePath); + if (isExist) + { + FileDelete(typeFilePath); + } + } + } + + // + // Add Specific Deal ... + void CollectDeal(const XDeal &deal) + { + // + string content = ToStringFormat(deal); + if (StringLen(content) <= 0) + { + return; + } + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_DEAL); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + return; + } + + // + FileSeek(mFileHandler, 0, SEEK_END); + FileWrite(mFileHandler, content); + FileFlush(mFileHandler); + FileClose(mFileHandler); + } + + // + // Extract Collected Deals ... + void ExtreactDeals(XDeal &result[]) + { + // + Clean(result); + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_DEAL); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + return; + } + + // + while (!FileIsEnding(mFileHandler)) + { + // + string content = FileReadString(mFileHandler); + + // + XDeal deal = ToDeal(content); + + // + Add( + deal, + result); + } + + // + FileClose(mFileHandler); + } + + // + // Add Specific Signal ... + void CollectSignal(const XSignal &signal) + { + // + string content = ToStringFormat(signal); + if (StringLen(content) <= 0) + { + return; + } + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_SIGNAL); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + LogMessage("Error: " + (string)GetLastError()); + return; + } + + // + FileSeek(mFileHandler, 0, SEEK_END); + FileWrite(mFileHandler, content); + FileFlush(mFileHandler); + FileClose(mFileHandler); + } + + // + // Extract Collected Signals ... + void ExtreactSignals(XSignal &result[]) + { + // + Clean(result); + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_SIGNAL); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + return; + } + + // + while (!FileIsEnding(mFileHandler)) + { + // + string content = FileReadString(mFileHandler); + + // + XSignal signal = ToSignal(content); + + // + Add( + signal, + result); + } + + // + FileClose(mFileHandler); + } + + // + // Add Specific Position ... + void CollectPosition(const XPosition &position) + { + // + string content = ToStringFormat(position); + if (StringLen(content) <= 0) + { + return; + } + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_POSITION); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + return; + } + + // + FileSeek(mFileHandler, 0, SEEK_END); + FileWrite(mFileHandler, content); + FileFlush(mFileHandler); + FileClose(mFileHandler); + } + + // + // Extract Collected Positions ... + void ExtreacPositions(XPosition &result[]) + { + // + Clean(result); + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_POSITION); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + return; + } + + // + while (!FileIsEnding(mFileHandler)) + { + // + string content = FileReadString(mFileHandler); + + // + XPosition position = ToPosition(content); + + // + Add( + position, + result); + } + + // + FileClose(mFileHandler); + } + + // + // SUPPORT and RESISTANCE ... + void CollectSupRes(const XOHCLSupRes &item) + { + } + + // + void ExtractSupReses(XOHCLSupRes &result[]) + { + } + + // + // Add Specific Log ... + void CollectLog(string log) + { + // + if (StringLen(log) <= 0) + { + return; + } + + // + string content = ExtractTypePath(X_DATA_COLLECTOR_LOG) + + "[" + log + "]"; + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_LOG); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + return; + } + + // + FileSeek(mFileHandler, 0, SEEK_END); + FileWrite(mFileHandler, content); + FileFlush(mFileHandler); + FileClose(mFileHandler); + } + + // + // Extract Collected Logs ... + void ExtractLogs(string &result[]) + { + // + Clean(result); + + // + string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_LOG); + string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_LOG); + int mFileHandler = FileOpen( + filePath, + FILE_READ | FILE_TXT); + if (mFileHandler == INVALID_HANDLE) + { + return; + } + + // + while (!FileIsEnding(mFileHandler)) + { + // + string content = FileReadString(mFileHandler); + + // + string log = ExtractString( + content, + typeIdentifier + "[", + "]"); + + // + if (StringLen(log) > 0) + { + // + Add( + log, + result); + } + } + + // + FileClose(mFileHandler); + } + + // + // TYPE Specific Casting Functions ... + + // + // Signal ... + + // + // Convert to it's String Representation ... + string ToStringFormat(const XSignal &signal) + { + // + string result = ""; + + // + DefineTokens(); + + // + result += + ExtractTypePath(X_DATA_COLLECTOR_SIGNAL) + + "[" + + mProvidersToken + "(" + ToString(signal.providers) + ")" + + mSymbolToken + "(" + signal.symbol + ")" + + mPeriodToken + "(" + ToString(signal.period) + ")" + + mTypeToken + "(" + (string)((int)signal.type) + ")" + + mModeToken + "(" + (string)((int)signal.mode) + ")" + + mEntryToken + "(" + (string)signal.entry + ")" + + mRiskAmountToken + "(" + (string)signal.riskAmount + ")" + + mTPToken + "(" + (string)signal.tp + ")" + + mSLToken + "(" + (string)signal.sl + ")" + + mR2rToken + "(" + (string)signal.r2r + ")" + + mVolumeToken + "(" + (string)signal.volume + ")" + + mSupportResistanceToken + "(" + ToStringFormat(signal.supportAndResistance) + ")" + + "]"; + + // + return result; + } + + // + // Converts an string to XSignal ... + XSignal ToSignal(string content) + { + // + XSignal result; + + // + DefineTokens(); + + // + string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_SIGNAL); + + // + if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) + { + return result; + } + + // + string signalContent = ExtractString( + content, + typeIdentifier + "[", + "]"); + if (StringLen(signalContent) == 0) + { + return result; + } + + // + // Providers ... + string providersStr = ExtractString( + signalContent, + mProvidersToken + "(", + ")"); + if (StringLen(providersStr) > 0) + { + // + string providers[]; + StringSplit( + providersStr, + StringGetCharacter(",", 0), + providers); + + // + ArrayCopy( + result.providers, + providers); + } + + // + // Symbol ... + string symbolStr = ExtractString( + signalContent, + mSymbolToken + "(", + ")"); + if (StringLen(symbolStr) > 0) + { + result.symbol = symbolStr; + } + + // + // Period ... + string periodStr = ExtractString( + signalContent, + mPeriodToken + "(", + ")"); + if (StringLen(periodStr) > 0) + { + // + ENUM_TIMEFRAMES period = ToPeriod(periodStr); + + // + result.period = period; + } + + // + // Type ... + string typeStr = ExtractString( + signalContent, + mTypeToken + "(", + ")"); + if (StringLen(typeStr) > 0) + { + // + ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)((int)typeStr); + + // + result.type = type; + } + + // + // Mode ... + string modeStr = ExtractString( + signalContent, + mModeToken + "(", + ")"); + if (StringLen(modeStr) > 0) + { + // + ENUM_X_ORDER_MODES mode = (ENUM_X_ORDER_MODES)((int)modeStr); + + // + result.mode = mode; + } + + // + // Entry ... + string entryStr = ExtractString( + signalContent, + mEntryToken + "(", + ")"); + if (StringLen(entryStr) > 0) + { + // + double entry = (double)entryStr; + + // + result.entry = entry; + } + + // + // RiskAmount ... + string raStr = ExtractString( + signalContent, + mRiskAmountToken + "(", + ")"); + if (StringLen(raStr) > 0) + { + // + double ra = (double)raStr; + + // + result.riskAmount = ra; + } + + // + // TP ... + string tpStr = ExtractString( + signalContent, + mTPToken + "(", + ")"); + if (StringLen(tpStr) > 0) + { + // + double tp = (double)tpStr; + + // + result.tp = tp; + } + + // + // SL ... + string slStr = ExtractString( + signalContent, + mSLToken + "(", + ")"); + if (StringLen(slStr) > 0) + { + // + double sl = (double)slStr; + + // + result.sl = sl; + } + + // + // R2R ... + string r2rStr = ExtractString( + signalContent, + mR2rToken + "(", + ")"); + if (StringLen(r2rStr) > 0) + { + // + double r2r = (double)r2rStr; + + // + result.r2r = r2r; + } + + // + // Volume ... + string volumeStr = ExtractString( + signalContent, + mVolumeToken + "(", + ")"); + if (StringLen(volumeStr) > 0) + { + // + double volume = (double)volumeStr; + + // + result.volume = volume; + } + + // + // SupportResistance ... + string supportResistanceStr = ExtractString( + signalContent, + mSupportResistanceToken + "(", + ")"); + if (StringLen(supportResistanceStr) > 0) + { + // + XOHCLSupRes supRes = ToSupRes(supportResistanceStr); + + // + result.supportAndResistance = supRes; + } + + // + return result; + } + + // + // Deal ... + + // + // Convert to it's String Representation ... + string ToStringFormat(const XDeal &deal) + { + // + string result = ""; + + // + DefineTokens(); + + // + result += + ExtractTypePath(X_DATA_COLLECTOR_DEAL) + + "[" + + mMagicToken + "(" + (string)deal.magic + ")" + + mPositionIDToken + "(" + (string)deal.positionId + ")" + + mTicketToken + "(" + (string)deal.ticket + ")" + + mSymbolToken + "(" + (string)deal.symbol + ")" + + mOrderToken + "(" + (string)deal.order + ")" + + mTimeToken + "(" + (string)deal.time + ")" + + mPriceToken + "(" + (string)deal.price + ")" + + mProfitToken + "(" + (string)deal.profit + ")" + + mSwapToken + "(" + (string)deal.swap + ")" + + mCommissionToken + "(" + (string)deal.commission + ")" + + mVolumeToken + "(" + (string)deal.volume + ")" + + mCommentToken + "(" + (string)deal.comment + ")" + + mTypeToken + "(" + (string)((int)deal.type) + ")" + + mEntryToken + "(" + (string)((int)deal.entry) + ")" + + mReasonToken + "(" + (string)((int)deal.reason) + ")" + + "]"; + + // + return result; + } + + // + // Converts an string to XDeal ... + XDeal ToDeal(string content) + { + // + XDeal result; + + // + DefineTokens(); + + // + string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_DEAL); + + // + if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) + { + return result; + } + + // + string dealContent = ExtractString( + content, + typeIdentifier + "[", + "]"); + if (StringLen(dealContent) == 0) + { + return result; + } + + // + // Magic ... + string magicStr = ExtractString( + dealContent, + mMagicToken + "(", + ")"); + if (StringLen(magicStr) > 0) + { + // + ulong magic = (ulong)magicStr; + + // + result.magic = magic; + } + + // + // PositionID ... + string posIDStr = ExtractString( + dealContent, + mPositionIDToken + "(", + ")"); + if (StringLen(posIDStr) > 0) + { + // + ulong posID = (ulong)posIDStr; + + // + result.positionId = posID; + } + + // + // Ticket ... + string ticketStr = ExtractString( + dealContent, + mTicketToken + "(", + ")"); + if (StringLen(ticketStr) > 0) + { + // + ulong ticket = (ulong)ticketStr; + + // + result.ticket = ticket; + } + + // + // Symbol ... + string symbolStr = ExtractString( + dealContent, + mSymbolToken + "(", + ")"); + if (StringLen(symbolStr) > 0) + { + result.symbol = symbolStr; + } + + // + // Order ... + string orderStr = ExtractString( + dealContent, + mOrderToken + "(", + ")"); + if (StringLen(orderStr) > 0) + { + // + ulong order = (ulong)orderStr; + + // + result.order = order; + } + + // + // Time ... + string timeStr = ExtractString( + dealContent, + mTimeToken + "(", + ")"); + if (StringLen(timeStr) > 0) + { + // + datetime time = StringToTime(timeStr); + + // + result.time = time; + } + + // + // Price ... + string priceStr = ExtractString( + dealContent, + mPriceToken + "(", + ")"); + if (StringLen(priceStr) > 0) + { + // + double price = (double)priceStr; + + // + result.price = price; + } + + // + // Profit ... + string profitStr = ExtractString( + dealContent, + mProfitToken + "(", + ")"); + if (StringLen(profitStr) > 0) + { + // + double profit = (double)profitStr; + + // + result.profit = profit; + } + + // + // Swap ... + string swapStr = ExtractString( + dealContent, + mSwapToken + "(", + ")"); + if (StringLen(swapStr) > 0) + { + // + double swap = (double)swapStr; + + // + result.swap = swap; + } + + // + // Commission ... + string commissionStr = ExtractString( + dealContent, + mCommissionToken + "(", + ")"); + if (StringLen(commissionStr) > 0) + { + // + double commission = (double)commissionStr; + + // + result.commission = commission; + } + + // + // Volume ... + string volumeStr = ExtractString( + dealContent, + mVolumeToken + "(", + ")"); + if (StringLen(volumeStr) > 0) + { + // + double volume = (double)volumeStr; + + // + result.volume = volume; + } + + // + // Comment ... + string commentStr = ExtractString( + dealContent, + mCommentToken + "(", + ")"); + if (StringLen(commentStr) > 0) + { + result.comment = commentStr; + } + + // + // Type ... + string typeStr = ExtractString( + dealContent, + mTypeToken + "(", + ")"); + if (StringLen(typeStr) > 0) + { + // + ENUM_DEAL_TYPE type = (ENUM_DEAL_TYPE)((int)typeStr); + + // + result.type = type; + } + + // + // Entry ... + string entryStr = ExtractString( + dealContent, + mEntryToken + "(", + ")"); + if (StringLen(entryStr) > 0) + { + // + ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)((int)entryStr); + + // + result.entry = entry; + } + + // + // Reason ... + string reasonStr = ExtractString( + dealContent, + mReasonToken + "(", + ")"); + if (StringLen(reasonStr) > 0) + { + // + ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)((int)reasonStr); + + // + result.reason = reason; + } + + // + return result; + } + + // + // SUPPORT and RESISTANCES ... + string ToStringFormat(const XOHCLSupRes &item) + { + // + string result = ""; + + // + DefineTokens(); + + // + result += + ExtractTypePath(X_DATA_COLLECTOR_SUPRES) + + "[" + + mResToken + "(" + ToString(item.res) + ")" + + mSupToken + "(" + ToString(item.sup) + ")" + + "]"; + + // + return result; + } + + // + XOHCLSupRes ToSupRes(string content) + { + // + XOHCLSupRes result; + + // + DefineTokens(); + + // + string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_SUPRES); + + // + if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) + { + return result; + } + + // + string mainContent = ExtractString( + content, + typeIdentifier + "[", + "]"); + if (StringLen(mainContent) == 0) + { + return result; + } + + // + // Res ... + string resStr = ExtractString( + mainContent, + mResToken + "(", + ")"); + if (StringLen(resStr) > 0) + { + // + double res[]; + string parts[]; + StringSplit( + resStr, + StringGetCharacter(",", 0), + parts); + + // + int partsCount = ArraySize(parts); + if (partsCount > 0) + { + // + for (int i = 0; i < partsCount; i++) + { + // + string iPart = parts[i]; + + // + Add( + double(iPart), + result.res); + } + } + } + + // + // Sup ... + string supStr = ExtractString( + mainContent, + mSupToken + "(", + ")"); + if (StringLen(supStr) > 0) + { + // + double sup[]; + string parts[]; + StringSplit( + supStr, + StringGetCharacter(",", 0), + parts); + + // + int partsCount = ArraySize(parts); + if (partsCount > 0) + { + // + for (int i = 0; i < partsCount; i++) + { + // + string iPart = parts[i]; + + // + Add( + double(iPart), + result.sup); + } + } + } + + // + return result; + } + + // + // Position ... + + // + // Convert to it's String Representation ... + string ToStringFormat(const XPosition &position) + { + // + string result = ""; + + // + DefineTokens(); + + // + result += + ExtractTypePath(X_DATA_COLLECTOR_POSITION) + + "[" + + mMagicToken + "(" + (string)position.magic + ")" + + mTicketToken + "(" + (string)position.ticket + ")" + + mSymbolToken + "(" + (string)position.symbol + ")" + + mPeriodToken + "(" + (string)((int)position.period) + ")" + + mTypeToken + "(" + (string)((int)position.type) + ")" + + mTPToken + "(" + (string)position.tp + ")" + + mSLToken + "(" + (string)position.sl + ")" + + mProfitToken + "(" + (string)position.profit + ")" + + mEntryToken + "(" + (string)position.entry + ")" + + mPriceToken + "(" + (string)position.price + ")" + + mSwapToken + "(" + (string)position.swap + ")" + + mCommissionToken + "(" + (string)position.commission + ")" + + mVolumeToken + "(" + (string)position.volume + ")" + + mOpenAtToken + "(" + (string)position.openAt + ")" + + mCommentToken + "(" + (string)position.comment + ")" + + "]"; + + // + return result; + } + + // + // Converts an string to XPosition ... + XPosition ToPosition(string content) + { + // + XPosition result; + + // + DefineTokens(); + + // + string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_POSITION); + + // + if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) + { + return result; + } + + // + string positionContent = ExtractString( + content, + typeIdentifier + "[", + "]"); + if (StringLen(positionContent) == 0) + { + return result; + } + + // + // Magic ... + string magicStr = ExtractString( + positionContent, + mMagicToken + "(", + ")"); + if (StringLen(magicStr) > 0) + { + // + ulong magic = (ulong)magicStr; + + // + result.magic = magic; + } + + // + // Ticket ... + string ticketStr = ExtractString( + positionContent, + mTicketToken + "(", + ")"); + if (StringLen(ticketStr) > 0) + { + // + ulong ticket = (ulong)ticketStr; + + // + result.ticket = ticket; + } + + // + // Symbol ... + string symbolStr = ExtractString( + positionContent, + mSymbolToken + "(", + ")"); + if (StringLen(symbolStr) > 0) + { + result.symbol = symbolStr; + } + + // + // Period ... + string periodStr = ExtractString( + positionContent, + mPeriodToken + "(", + ")"); + if (StringLen(periodStr) > 0) + { + // + ENUM_TIMEFRAMES period = ToPeriod(periodStr); + + // + result.period = period; + } + + // + // Type ... + string typeStr = ExtractString( + positionContent, + mTypeToken + "(", + ")"); + if (StringLen(typeStr) > 0) + { + // + ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)((int)typeStr); + + // + result.type = type; + } + + // + // TP ... + string tpStr = ExtractString( + positionContent, + mTPToken + "(", + ")"); + if (StringLen(tpStr) > 0) + { + // + double tp = (double)tpStr; + + // + result.tp = tp; + } + + // + // SL ... + string slStr = ExtractString( + positionContent, + mSLToken + "(", + ")"); + if (StringLen(slStr) > 0) + { + // + double sl = (double)slStr; + + // + result.sl = sl; + } + + // + // Profit ... + string profitStr = ExtractString( + positionContent, + mProfitToken + "(", + ")"); + if (StringLen(profitStr) > 0) + { + // + double profit = (double)profitStr; + + // + result.profit = profit; + } + + // + // Entry ... + string entryStr = ExtractString( + positionContent, + mEntryToken + "(", + ")"); + if (StringLen(entryStr) > 0) + { + // + double entry = (double)entryStr; + + // + result.entry = entry; + } + + // + // Price ... + string priceStr = ExtractString( + positionContent, + mPriceToken + "(", + ")"); + if (StringLen(priceStr) > 0) + { + // + double price = (double)priceStr; + + // + result.price = price; + } + + // + // Swap ... + string swapStr = ExtractString( + positionContent, + mSwapToken + "(", + ")"); + if (StringLen(swapStr) > 0) + { + // + double swap = (double)swapStr; + + // + result.swap = swap; + } + + // + // Commission ... + string commissionStr = ExtractString( + positionContent, + mCommissionToken + "(", + ")"); + if (StringLen(commissionStr) > 0) + { + // + double commission = (double)commissionStr; + + // + result.commission = commission; + } + + // + // Volume ... + string volumeStr = ExtractString( + positionContent, + mVolumeToken + "(", + ")"); + if (StringLen(volumeStr) > 0) + { + // + double volume = (double)volumeStr; + + // + result.volume = volume; + } + + // + // OpenAt ... + string openAtStr = ExtractString( + positionContent, + mOpenAtToken + "(", + ")"); + if (StringLen(openAtStr) > 0) + { + // + datetime openAt = StringToTime(openAtStr); + + // + result.openAt = openAt; + } + + // + // Comment ... + string commentStr = ExtractString( + positionContent, + mCommentToken + "(", + ")"); + if (StringLen(commentStr) > 0) + { + result.comment = commentStr; + } + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Destintion Folder Path ... + string mPath; + + // + void DefineTokens() + { + + // + // Define Required Variables ... + + // + // Define Some Modifier Tokens for Type Castings ... + mProvidersToken = "PVS"; + mSymbolToken = "SBL"; + mPeriodToken = "PR"; + mTypeToken = "TYP"; + mModeToken = "MD"; + mEntryToken = "EN"; + mRiskAmountToken = "RA"; + mTPToken = "TP"; + mSLToken = "SL"; + mR2rToken = "RR"; + mVolumeToken = "VL"; + + // + mMagicToken = "MGK"; + mTicketToken = "TK"; + mProfitToken = "PFT"; + mPriceToken = "CPR"; + mSwapToken = "SWP"; + mCommissionToken = "CMS"; + mOpenAtToken = "ODT"; + mCommentToken = "CMN"; + + // + mPositionIDToken = "PID"; + mOrderToken = "ORD"; + mTimeToken = "TDT"; + mReasonToken = "RSN"; + + // + mResToken = "RES"; + mSupToken = "SUP"; + mSupportResistanceToken = "SUPRES"; + } + + // + // Private ... +private: + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } + + // + // Extract Each Type Specific File Name ... + string ExtractTypePath(ENUM_X_XDATACOLLECTOR_TYPES type) + { + // + string typeStr = EnumToString(type); + + // + string typeParts[]; + StringSplit( + typeStr, + StringGetCharacter("_", 0), + typeParts); + + // + string result = typeParts[ArraySize(typeParts) - 1]; + + // + return result; + } + + // + string GenerateTypeFilePath(ENUM_X_XDATACOLLECTOR_TYPES type) + { + // + string name = ExtractTypePath(type) + ".txt"; + + // + string result = GetFilePath(name); + + // + return result; + } + + // + // Retrieve all available data types ... + void RetrieveAllAvailableTypes(ENUM_X_XDATACOLLECTOR_TYPES &result[]) + { + // + ArrayFree(result); + ArrayResize(result, 0); + + // + Add( + X_DATA_COLLECTOR_LOG, + result); + + // + Add( + X_DATA_COLLECTOR_DEAL, + result); + + // + Add( + X_DATA_COLLECTOR_SIGNAL, + result); + + // + Add( + X_DATA_COLLECTOR_SUPRES, + result); + + // + Add( + X_DATA_COLLECTOR_POSITION, + result); + } + + // + // Define Some Modifier Tokens for Type Castings ... + string mProvidersToken; + string mSymbolToken; + string mPeriodToken; + string mTypeToken; + string mModeToken; + string mEntryToken; + string mRiskAmountToken; + string mTPToken; + string mSLToken; + string mR2rToken; + string mVolumeToken; + + // + string mMagicToken; + string mTicketToken; + string mProfitToken; + string mPriceToken; + string mSwapToken; + string mCommissionToken; + string mOpenAtToken; + string mCommentToken; + + // + string mPositionIDToken; + string mOrderToken; + string mTimeToken; + string mReasonToken; + + // + string mResToken; + string mSupToken; + string mSupportResistanceToken; +}; + +// +// START Usefull Functions ... +// +void Add(ENUM_X_XDATACOLLECTOR_TYPES type, + ENUM_X_XDATACOLLECTOR_TYPES &types[]) +{ + // + ArrayResize( + types, + ArraySize(types) + 1); + + // + types[ArraySize(types) - 1] = type; +} +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.xea.class.ex5 b/MQLTestWorkspace/Classes/x-saherelm.xea.class.ex5 new file mode 100644 index 0000000..a52c19f Binary files /dev/null and b/MQLTestWorkspace/Classes/x-saherelm.xea.class.ex5 differ diff --git a/MQLTestWorkspace/Classes/x-saherelm.xea.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.xea.class.mq5 new file mode 100644 index 0000000..92dbc7f --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.xea.class.mq5 @@ -0,0 +1,814 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseEA +// Description: provides all Base EA requirements ... +// +// +// 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 Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.alert.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Classes/x-saherelm.xaccount.class.mq5" +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + XSCTrade *mTrader; + XSCAccount *mAccount; + + // + bool isNewHour; + bool isNewDay; + bool isNewWeek; + bool isNewMonth; + bool isNewCandle; + + // + bool isInTestMode; + + // + bool mWaitsUntilNewCandle; + + // + // Constructor ... + void XSCBaseEA( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Time Frame + ulong magic, // Magic Number + int slippage, // Slippgae + OnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + OnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + OnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + OnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + OnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + OnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler + ) + { + // + mSymbol = symbol; + mPeriod = period; + + // + mMagic = magic; + mSlippage = slippage; + + // + mOnStopLossTriggered = onStopLossTriggered; + mOnTakeProfitTriggered = onTakeProfitTriggered; + mOnDealsChangedHandler = onDealsChangedHandler; + mOnOrdersChangedHandler = onOrdersChangedHandler; + mOnPositionsChangedHandler = onPositionsChangedHandler; + mOnTradeStateChangedHandler = onTradeStateChangedHandler; + + // + // Reset Timings ... + ResetTiming(); + + // + InitRequirements(); + } + + // + // Deconstructor ... + void ~XSCBaseEA() + { + // + delete mTrader; + delete mAccount; + } + + // + // START Properties ... + // + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Tag ... + string GetTag() + { + return mTag; + } + + // + ulong GetMagic() + { + return mMagic; + } + + // + int GetSlippage() + { + return mSlippage; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XEA" + mSymbol + "," + ToString(mPeriod) + (string)mMagic; + } + + // + // Handle Chart Events ... + virtual void OnChartEvent( + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter + ) + { + } + + // + // Check any Registered Providers Signalling ... + virtual bool SignalCheck(XSignal &signals[]) { + return false; + } + + // + // Check for any Custom Guard Actions Guard Actions ... + virtual bool CheckGuard(XGuard &guards[]) { + return false; + } + + // + // NOTE: you have to call these Functions on Static Classes to Handle Works ... + + // + // Handle StopLoss Event ... + virtual void OnStopLossTriggered(const XDeal &deal) {} + + // + // Handle TakeProfit Event ... + virtual void OnTakeProfitTriggered(const XDeal &deal) {} + + // + // Handle Deals Changed Event ... + virtual void OnDealsChangedHandler(int count) {} + + // + // Handle Order Changed Event ... + virtual void OnOrdersChangedHandler(int count) {} + + // + // Handle Position Changed Event ... + virtual void OnPositionsChangedHandler(int count) {} + + // + // Handle Trade State Changed ... + virtual void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) {} + + // + // Implemented Actions ... + + // + // OnTick Handler ... + void OnTick() + { + // + // First Check Guards .... + XGuard guards[]; + bool hasGuard = CheckGuard(guards); + if (hasGuard) { + DoGuards(guards); + } + + // + XSignal signals[]; + bool hasSignal = SignalCheck(signals); + if (hasSignal) { + mTrader.ExecuteSignals(signals); + } + } + + // + // Handle On Trade ... + void OnTrade() + { + // + XOnTradeHandlerState state = mTrader.HandleOnTrade(); + + // + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + OnTradeStateChangedHandler(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + OnDealsChangedHandler(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + mTrader.GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + OnTakeProfitTriggered(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + OnStopLossTriggered(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + OnOrdersChangedHandler(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + OnPositionsChangedHandler(state.newPositions); + } + } + + // + // Retrieve Dept Of Market ... + void OnBookEvent(const string &symbol) + { + // + // TODO: Implement this ... + } + + // + // TOOLS ... + // + void GetPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL // Trading Period ... + ) + { + // + Clean(result); + + // + int positionsCount = mTrader.PositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition positions[]; + mTrader.GetPositions( + positions, + symbol, + period); + positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + if (type == NULL) + { + // + ArrayResize( + result, + ArraySize(positions)); + + // + for (int i = 0; i < positionsCount; i++) + { + // + Add( + positions[i], + result); + } + + // + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + if (type == NULL || iPosition.type == type) + { + // + Add( + iPosition, + result); + } + } + } + void GetPositions( + XPosition &result[], // Hold Result ... + string symbol = NULL, // Trading Symbol ... + ENUM_POSITION_TYPE type = NULL, // Trading Type ... + ENUM_TIMEFRAMES period = NULL, // Trading Period ... + string provider = NULL // Signal Provider ... + ) + { + // + Clean(result); + + // + bool hasSymbol = !(symbol == NULL || StringLen(symbol) == 0); + bool hasProvider = !(provider == NULL || StringLen(provider) == 0); + + // + int positionsCount = mTrader.PositionsCount(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition positions[]; + mTrader.GetPositions( + positions, + symbol, + period); + positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + if (!hasProvider && type == NULL) + { + // + ArrayResize( + result, + ArraySize(positions)); + + // + for (int i = 0; i < positionsCount; i++) + { + // + Add( + positions[i], + result); + } + + // + return; + } + + // + if (type == NULL) + { + // + ArrayResize( + result, + ArraySize(positions)); + + // + for (int i = 0; i < positionsCount; i++) + { + // + Add( + positions[i], + result); + } + + // + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string iProvider = ExtractProvider(iPosition.comment); + if (hasProvider && iProvider != provider) + { + continue; + } + + // + if (type == NULL || iPosition.type == type) + { + // + Add( + iPosition, + result); + } + } + } + + // + // GUARD Handlers ... + + // + // Parse Recievd Guards and Do them ... + void DoGuards(XGuard &guards[]) + { + int guardsCount = ArraySize(guards); + if (guardsCount <= 0) + { + return; + } + + // + for (int i = 0; i < guardsCount; i++) + { + // + XGuard iGuard = guards[i]; + + // + switch (iGuard.action) + { + // + // Hedge In Profit Specified Positions ... + case X_GUARD_ACTION_HEDGE: + HandleGuardHedgeAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Trail Stop Loss in Specified Positions ... + case X_GUARD_ACTION_TRAIL_STOP: + HandleGuardTrailingStopAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period, + iGuard.dblPayLoad); + break; + + // + // Force Close Specified Positions ... + case X_GUARD_ACTION_FORCE_CLOSE: + HandleGuardForceCloseAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Generate and Place Support Signals ... + case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL: + HandleGuardAddSupportPositionAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Delete All Placed Pending Orders ... + case X_GUARD_ACTION_CANCEL_PENDING_ORDERS: + HandleGuardCancelPendingOrdersAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + } + } + } + + // + // Close All Specified Provider's Positions in Profit Summary ... + void HandleGuardHedgeAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double minProfitForHedging = 1 // Specified Profit for Hedge ... + ) + { + // + } + + // + // Force Close Specified Set Of Position ... + void HandleGuardForceCloseAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ulong ticket = 0 // Specific Ticket + ) + { + // + string comment = ""; + + // + // Close All Positions ... + if (ticket == 0) + { + // + XPosition positions[]; + GetPositions( + positions, + symbol, + type, + period, + provider); + if (ArraySize(positions) <= 0) + { + return; + } + + // + comment = provider + " Force Close Guard ..."; + + // + mTrader.ClosePositions( + positions, + comment); + } + // + // Close Specific Position ... + else + { + // + XPosition position; + bool hasPosition = mTrader.GetPosition( + position, + ticket); + + // + if (hasPosition) + { + // + comment = provider + "(" + ToString(ticket) + ")" + " Force Close Guard ..."; + + // + mTrader.Close( + ticket, + comment); + } + } + + // + if (StringLen(comment) > 0) + { + LogMessage(comment); + } + } + + // + // Trailing Specified Set Of Positions Stop Losses ... + void HandleGuardTrailingStopAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double sl // Desired SL Value ... + ) + { + // + // TODO: Implement this ... + } + + // + // Add Support Signal for Specified Positions ... + void HandleGuardAddSupportPositionAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + // TODO: Implement this ... + } + + // + // Cancel all Placed Orders ... + void HandleGuardCancelPendingOrdersAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_POSITION_TYPE type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + // TODO: Implement this ... + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + string GetTagPrefix() + { + // + string result = "(" + mSymbol + ")(" + ToString(mPeriod) + ")"; + + // + return result; + } + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // ExpertAdviser MAgic Number ... + ulong mMagic; + + // + // Slipppage ... + int mSlippage; + + // + // Tag Identifier ... + string mTag; + + // + // Private ... +private: + // + // Define Requirements ... + + // + // XSCTrade Event Handlers ... + OnStopLoss mOnStopLossTriggered; + OnTakeProfit mOnTakeProfitTriggered; + OnDealsChanged mOnDealsChangedHandler; + OnOrdersChanged mOnOrdersChangedHandler; + OnPositionsChanged mOnPositionsChangedHandler; + OnTradeStateChanged mOnTradeStateChangedHandler; + + // + // Initi Requirements ... + void InitRequirements() + { + // + // Account Manager ... + mAccount = new XSCAccount(); + + // + // Trader ... + mTrader = new XSCTrade( + mSlippage, + mMagic); + + // + // Attach Event Handlers ... + + // + if (mOnStopLossTriggered != NULL) + { + mTrader.AddOnStopLossEventHandler(mOnStopLossTriggered); + } + + // + if (mOnTakeProfitTriggered != NULL) + { + mTrader.AddOnTakeProfitEventHandler(mOnTakeProfitTriggered); + } + + // + if (mOnDealsChangedHandler != NULL) + { + mTrader.AddOnDealsChangedEventHandler(mOnDealsChangedHandler); + } + + // + if (mOnOrdersChangedHandler != NULL) + { + mTrader.AddOnOrdersChangedEventHandler(mOnOrdersChangedHandler); + } + + // + if (mOnPositionsChangedHandler != NULL) + { + mTrader.AddOnPositionsChangedEventHandler(mOnPositionsChangedHandler); + } + + // + if (mOnTradeStateChangedHandler != NULL) + { + mTrader.AddOnTradeStateChangedEventHandler(mOnTradeStateChangedHandler); + } + } +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.xhelper.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.xhelper.class.mq5 new file mode 100644 index 0000000..d9cea8b --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.xhelper.class.mq5 @@ -0,0 +1,209 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseHelper +// Description: provides all Base Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCBaseHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) + { + // + mSymbol = symbol; + mPeriod = period; + + // + LoopBack(52); + } + + // + // Deconstructor ... + void ~XSCBaseHelper() + { + IndicatorRelease(mHandler); + } + + // + // START Properties ... + // + + // + // Loopback Bars ... + void LoopBack(int value) + { + mLoopbackBars = value; + } + + int Loopback() + { + return mLoopbackBars; + } + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Tag ... + string GetTag() + { + return mTag; + } + + // + // Retrieve Bars ... + int GetBars() + { + // + int result = + Bars( + mSymbol, + mPeriod); + + // + return result; + } + + // + int GetCalculatedBars() + { + return BarsCalculated(mHandler); + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() {} + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ); + + // + // Retrieve MAx Required Length for Calculations ... + virtual int GetMaxLength(); + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + string GetTagPrefix() + { + // + string result = "(" + mSymbol + ")(" + ToString(mPeriod) + ")"; + + // + return result; + } + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Indicator Handler ... + int mHandler; + + // + // Number Of Items Read Per Tick ... + int mLoopbackBars; + + // + // Tag Identifier ... + string mTag; + + // + // Private ... +private: + // +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.xnotifier.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.xnotifier.class.mq5 new file mode 100644 index 0000000..0c653eb --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.xnotifier.class.mq5 @@ -0,0 +1,295 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCNotifier +// Description: provides all Base Notification requirements ... +// +// +// 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 Definitions ... +// + +// +// a Notification Model ... +typedef void (*OnMessage)( + string, // action ... + string // payload ... +); + +// +struct XNotifierEventListener +{ + string action; + OnMessage listeners[]; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCNotifier +{ + // + // Public ... +public: + // + // Constructor ... + void XSCNotifier() + { + } + + // + // Deconstructor ... + void ~XSCNotifier() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + bool AddEventListener( + string action, // Specific Action ... + OnMessage listener // Specific Listener ... + ) + { + // + bool result = false; + + // + int aIndex = FindActionIndex(action); + if (aIndex < 0) + { + // + // Create a New Structure ... + XNotifierEventListener model; + + // + model.action = action; + + // + Add( + listener, + model.listeners); + + // + Add( + model, + mEventListeners); + + // + result = true; + } + else + { + // + // Just Add Listener to Exists model ... + Add( + listener, + mEventListeners[aIndex].listeners); + + // + result = true; + } + + // + return result; + } + + // + bool NotifyEvent( + string action, // action ... + string payload // payload ... + ) + { + // + bool result = false; + + // + int actionIndex = FindActionIndex(action); + result = actionIndex >= 0; + if (!result) + { + return result; + } + + // + int aListenersCount = ArraySize(mEventListeners[actionIndex].listeners); + result = aListenersCount > 0; + if (!result) + { + return result; + } + + // + for (int i = 0; i < aListenersCount; i++) + { + // + OnMessage iListener = mEventListeners[actionIndex].listeners[i]; + + // + // Call Listener ... + iListener( + action, + payload); + } + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + + // + // Private ... +private: + // + XNotifierEventListener mEventListeners[]; + + // + // Find Specific Actions Index in Registered Event Listeners ... + int FindActionIndex(string action) + { + // + int result = -1; + + // + int listenersCount = ArraySize(mEventListeners); + if (listenersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < listenersCount; i++) + { + // + XNotifierEventListener iModel = mEventListeners[i]; + + // + if (iModel.action == action) + { + // + result = i; + break; + } + } + + // + return result; + } +}; + +// +// START Usefull Functions ... +// + +// +void Clean( + OnMessage &buffer[] // Buffer ... +) +{ + // + ArrayFree(buffer); + + // + ArrayResize( + buffer, + 0); +} +void Clean( + XNotifierEventListener &buffer[] // Buffer ... +) +{ + // + ArrayFree(buffer); + + // + ArrayResize( + buffer, + 0); +} + +// +void Add( + OnMessage item, // Item ... + OnMessage &buffer[] // Buffer ... +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XNotifierEventListener &item, // Item ... + XNotifierEventListener &buffer[] // Buffer ... +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.xprovider.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.xprovider.class.mq5 new file mode 100644 index 0000000..e60bb27 --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.xprovider.class.mq5 @@ -0,0 +1,304 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCEABaseProvider +// Description: provides base requirements for +// Specific Sgnal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Definitions ... +// + +// +// Notified a Signal was Appears ... +typedef void (*OnSignal)( + XSignal &signal); + +// +// Notified a Guard Appears ... +typedef void (*OnGuard)(XGuard &guard); + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCEABaseProvider +{ + // + // Public ... +public: + // + // Constructor ... + void XSCEABaseProvider() + { + mSymbol = _Symbol; + mPeriod = _Period; + } + void XSCEABaseProvider( + string symbol, + ENUM_TIMEFRAMES period) + { + // + mSymbol = symbol; + mPeriod = period; + + // + mTag = mSymbol + "," + ToString(mPeriod); + + // + mIsInTestMode = IsRunningOnTestMode(); + } + + // + // Deconstructor ... + void ~XSCEABaseProvider() + { + } + + // + bool CanIgnoreTick() { + // + mIsNewCandle = IsNewCandle( + mSymbol, + mPeriod); + bool result = mIsInTestMode + ? !mIsNewCandle + : !mIsNewCandle && mWaitUntilNewCandle; + + // + return result; + } + + // + // Prepare State ... + void OnTick() + { + // + mIsNewCandle = IsNewCandle( + mSymbol, + mPeriod); + mCanIgnoreTick = mIsInTestMode + ? !mIsNewCandle + : !mIsNewCandle && mWaitUntilNewCandle; + + // + ProcessBuffers(); + + // + if (mCanIgnoreTick) + { + return; + } + + // + mWaitUntilNewCandle = false; + + // + ProcessTick(); + } + + // + virtual void PrepareTag(); + + // + // Initialize Indicators and Requirements ... + virtual bool Init(); + + // + virtual int GetMaxLength(); + + // + virtual int GetCalculatedBars(); + + // + // Handle Update Buffers ... + virtual void ProcessBuffers() + { + return; + } + + // + // Handle On Tick Event ... + virtual void ProcessTick() + { + return; + } + + // + // Check for Guards ... + virtual bool GuardCheck(XGuard &guards[]); + + // + // Add Specific On Signal Event Handler ... + int AddOnSignalEventHandler(OnSignal handler) + { + // + ArrayResize( + mSignalEventHandlers, + ArraySize(mSignalEventHandlers) + 1); + + // + int result = ArraySize(mSignalEventHandlers) - 1; + mSignalEventHandlers[result] = handler; + + // + return result; + } + + // + // Remove All On Signal Event Handler ... + void ReoveOnSignalEventHandlers() + { + // + ArrayFree(mSignalEventHandlers); + } + + // + // Notify a Signal Found on all Event Listeners ... + void NotifyOnSignalEvent(XSignal &info) + { + // + int listenerCount = ArraySize(mSignalEventHandlers); + if (listenerCount <= 0) + { + return; + } + + // + // Loop Through Listeners ... + for (int i = 0; i < listenerCount; i++) + { + // + OnSignal listener = mSignalEventHandlers[i]; + + // + listener(info); + } + } + + // + // Protected ... +protected: + // + string mSymbol; + + // + ENUM_TIMEFRAMES mPeriod; + + // + string mTag; + + // + bool mIsNewCandle; + bool mIsInTestMode; + bool mCanIgnoreTick; + bool mWaitUntilNewCandle; + + // + // Private ... +private: + // + // Signal Event Handlers ... + OnSignal mSignalEventHandlers[]; +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct XBaseSignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Desired Magic Number ... + ulong magicNumber; +}; + +// +struct XLastSignal +{ + datetime at; + string provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + XBaseSignalProvider &item, // item want to add + XBaseSignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Classes/x-saherelm.xtrade.class.mq5 b/MQLTestWorkspace/Classes/x-saherelm.xtrade.class.mq5 new file mode 100644 index 0000000..87694fa --- /dev/null +++ b/MQLTestWorkspace/Classes/x-saherelm.xtrade.class.mq5 @@ -0,0 +1,4111 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCTrade +// Description: provides all Trade requirements ... +// +// +// 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 Definitions ... +// + +// +// Model an Open Position ... +struct XPosition +{ + // + // Magic Number ... + ulong magic; + + // + // Ticket ID ... + ulong ticket; + + // + // Tradinng Symbol ... + string symbol; + + // + // Trading Period ... + ENUM_TIMEFRAMES period; + + // + // Position Type ... + ENUM_POSITION_TYPE type; + + // + // Take Profit ... + double tp; + + // + // Stop Loss ... + double sl; + + // + // Position Current Profit ... + double profit; + + // + // Position Open Price ... + double entry; + + // + // Current Symbol Price ... + double price; + + // + // Position Swap ... + double swap; + + // + // Position Commission ... + double commission; + + // + // Volume ... + double volume; + + // + // Position Open Time ... + datetime openAt; + + // + // Position Comment ... + string comment; +}; + +// +// Model an Order ... +struct XOrder +{ + // + // Time of order placement ... + datetime setupAt; + + // + // Time of order expiration ... + datetime expiredAt; + + // + // Time of order execution or cancellation ... + datetime executedAt; + + // + // Order type ... + ENUM_ORDER_TYPE type; + + // + // Order state ... + ENUM_ORDER_STATE state; + + // + // Type of execution by remainder ... + ENUM_ORDER_TYPE_FILLING filling; + + // + // Order lifetime ... + ENUM_ORDER_TYPE_TIME lifetime; + + // + // Order ticket ... + ulong ticket; + + // + // Magic Number ... + long magic; + + // + // Position id, that is placed on order, + // when it is executed. Each executed order invokes a + // deal, that opens new or changes existing + // position. Id of that position is placed on + // executed order in this moment. + long pocitionID; + + // + // Initial volume on order placement ... + double initialVolume; + + // + // Unfilled volume ... + double currentVolume; + + // + // Price, specified in the order ... + double openPrice; + + // + // Current price by order symbol ... + double currentPrice; + + // + // Price of placing Limit order when StopLimit order is triggered ... + double stopLimitPrice; + + // + // Take Profit level ... + double tp; + + // + // Stop Loss level ... + double sl; + + // + // Trading Symbol ... + string smybol; + + // + // Order Comment ... + string comment; +}; + +// +// Model a 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 OnTrade Event Handler Result on XCTrade Class ... +struct XOnTradeHandlerState +{ + // + bool hasNewDeal; + int newDeals; + + // + bool hasNewOrder; + int newOrders; + + // + bool hasNewPosition; + int newPositions; + + // + bool hasNewHistoryOrder; + int newHistoryOrders; +}; + +// +typedef void (*OnDealsChanged)(int count); + +// +typedef void (*OnOrdersChanged)(int count); + +// +typedef void (*OnPositionsChanged)(int count); + +// +typedef void (*OnStopLoss)(const XDeal &deal); +typedef void (*OnTakeProfit)(const XDeal &deal); + +// +typedef void (*OnTradeStateChanged)(const XOnTradeHandlerState &state); + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// XCTrade Base Class ... +class XSCTradeBase : 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 ... +// + +// +// a Class for Manage Trades ... +class XSCTrade +{ + // + // Public ... +public: + // + // Constructor ... + void XSCTrade( + int slippage, // Specify Slippage + ulong magicNumber // Specify Magic Number + ) + { + // + mSlippage = slippage; + mMagicNumber = magicNumber; + + // + mPeriodPrefix = "PR"; + + // + mTrader = new XSCTradeBase(); + + // + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + // Prepare Trade Event Materials ... + // + mDaysForRead = 1; + mScanStarted = false; + + // + // Reset On Trade Counter ... + ResetOnTradeContext(); + + // + // Init On Trade Context ... + InitOnTradeContext(); + } + + // + // Deconstructor ... + void ~XSCTrade() + { + } + + // + // START Event Processing ... + // + + // + // This Must be Called Every time OnTrade Event Happening ... + XOnTradeHandlerState HandleOnTrade() + { + // + // Handle OnTrade Event ... + XOnTradeHandlerState state = {}; + HandleOnTradeEvent(state); + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return state; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + NotifyTradeStateChangeEvent(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + NotifyDealsChangeEvent(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + NotifyTakeProfitEvent(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + NotifyStopLossEvent(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + NotifyOrdersChangeEvent(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + NotifyPositionsChangeEvent(state.newPositions); + } + + // + return state; + } + + // + // Process On Trade Requirement + void HandleOnTradeEvent( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + if (mScanStarted) + { + ProcessOnTradeContext(result); + } + else + { + InitOnTradeContext(); + } + } + + // + // Event Emitters ... + + // + // STATE Changed ... + + // + // Clear Trade State Changed Event Handlers ... + void ClearOnTradeStateChangedEventHandlers() + { + // + ArrayFree(mTradeStateChangedEventHandlers); + + // + ArrayResize(mTradeStateChangedEventHandlers, 0); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnTradeStateChangedEventHandler(OnTradeStateChanged handler) + { + // + ArrayResize( + mTradeStateChangedEventHandlers, + ArraySize(mTradeStateChangedEventHandlers) + 1); + + // + mTradeStateChangedEventHandlers[ArraySize(mTradeStateChangedEventHandlers) - 1] = handler; + } + + // + // DEALS ... + + // + // Clear Deals Changed Event Handlers ... + void ClearOnDealsChangedEventHandlers() + { + // + ArrayFree(mDealsChangedEventHandlers); + + // + ArrayResize(mDealsChangedEventHandlers, 0); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnDealsChangedEventHandler(OnDealsChanged handler) + { + // + ArrayResize( + mDealsChangedEventHandlers, + ArraySize(mDealsChangedEventHandlers) + 1); + + // + mDealsChangedEventHandlers[ArraySize(mDealsChangedEventHandlers) - 1] = handler; + } + + // + // ORDERS ... + + // + // Clear Orders Changed Event Handlers ... + void ClearOnOrdersChangedEventHandlers() + { + // + ArrayFree(mOrdersChangedEventHandlers); + + // + ArrayResize(mOrdersChangedEventHandlers, 0); + } + + // + // Add New Orders Changed Event Handler ... + void AddOnOrdersChangedEventHandler(OnOrdersChanged handler) + { + // + ArrayResize( + mOrdersChangedEventHandlers, + ArraySize(mOrdersChangedEventHandlers) + 1); + + // + mOrdersChangedEventHandlers[ArraySize(mOrdersChangedEventHandlers) - 1] = handler; + } + + // + // POSITIONS ... + + // + // Clear Positions Changed Event Handlers ... + void ClearOnPositionsChangedEventHandlers() + { + // + ArrayFree(mPositionsChangedEventHandlers); + + // + ArrayResize(mPositionsChangedEventHandlers, 0); + } + + // + // Add New Positions Changed Event Handler ... + void AddOnPositionsChangedEventHandler(OnPositionsChanged handler) + { + // + ArrayResize( + mPositionsChangedEventHandlers, + ArraySize(mPositionsChangedEventHandlers) + 1); + + // + mPositionsChangedEventHandlers[ArraySize(mPositionsChangedEventHandlers) - 1] = handler; + } + + // + // TPSL ... + + // + // Clear Stop Loss Event Handlers ... + void ClearOnStopLossEventHandlers() + { + // + ArrayFree(mStopLossEventHandlers); + + // + ArrayResize(mStopLossEventHandlers, 0); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnStopLossEventHandler(OnStopLoss handler) + { + // + ArrayResize( + mStopLossEventHandlers, + ArraySize(mStopLossEventHandlers) + 1); + + // + mStopLossEventHandlers[ArraySize(mStopLossEventHandlers) - 1] = handler; + } + + // + // Clear Take Profit Event Handlers ... + void ClearOnTakeProfitEventHandlers() + { + // + ArrayFree(mTakeProfitEventHandlers); + + // + ArrayResize(mTakeProfitEventHandlers, 0); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnTakeProfitEventHandler(OnTakeProfit handler) + { + // + ArrayResize( + mTakeProfitEventHandlers, + ArraySize(mTakeProfitEventHandlers) + 1); + + // + mTakeProfitEventHandlers[ArraySize(mTakeProfitEventHandlers) - 1] = handler; + } + + // + // END Event Processing ... + // + + // + // START Provided Functions ... + // + + // + // Count Currently Open Positions ... + int PositionsCount( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + int result = 0; + + // + int allPositions = 0; + int longPositions = 0; + int shortPositions = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + allPositions++; + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + allPositions++; + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + longPositions++; + } + else + { + shortPositions++; + } + + // + continue; + } + } + } + + // + // Specify Result ... + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + result = allPositions; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions++; + } + } + else if (StringLen(symbol) > 0) + { + // + result = allPositions; + } + else if (type != NULL) + { + // + if (type == POSITION_TYPE_BUY) + { + result = longPositions; + } + else + { + result = shortPositions; + } + } + + // + return result; + } + + // + // Retrieve Max In Profit Position Ticket ... + ulong GetMaxInProfitPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit <= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Max In DrawDown Position Ticket ... + ulong GetMaxInDrawDownPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = -1; + + // + double profit = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + else + { + // + if (profit < positionAbsProfit) + { + // + result = positionTicket; + profit = positionAbsProfit; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Retrieve Specific Position's Profit ... + double GetPositionProfit( + const ulong ticket // Specified Position Ticket + ) + { + // + double result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Profit(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's OpenDate ... + datetime GetPositionOpenDate( + const ulong ticket // Specified Position Ticket + ) + { + // + datetime result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Time(); + break; + } + + // + return result; + } + + // + // Retrieve Specific Position's Comment ... + string GetPositionComment( + const ulong ticket // Specified Position Ticket + ) + { + // + string result = ""; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + result = mPositionInfo.Comment(); + break; + } + + // + return result; + } + + // + // Retrieve All Open Positions Profit ... + double GetPositionsProfit( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + double result = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + result += positionProfit; + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + result += positionProfit; + } + else + { + result += positionProfit; + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + result += positionProfit; + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + result += positionProfit; + } + else + { + result += positionProfit; + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Find Oldes Position ... + ulong GetOldestPosition( + string symbol = "", // Specified Symbol + ENUM_POSITION_TYPE type = NULL // Specified Type + ) + { + // + ulong result = 0; + + // + int age = 0; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + + // + string positionSymbol = mPositionInfo.Symbol(); + + // + double positionProfit = mPositionInfo.Profit(); + double positionAbsProfit = MathAbs(positionProfit); + if (positionProfit >= 0) + { + continue; + } + + // + ENUM_POSITION_TYPE positionType = mPositionInfo.PositionType(); + + // + string positionComment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(positionComment); + + // + // Calculate Position's Age ... + datetime positionOpenTime = mPositionInfo.Time(); + + // + // Retrieve Trade Open Bar Index based on Current Period ... + int positionOpenBarIndex = iBarShift( + positionSymbol, + positionPeriod, + positionOpenTime); + + // + // Calculate Trade Life ... + int positionAge = MathAbs(0 - positionOpenBarIndex); + + // + if ( + type == NULL && + StringLen(symbol) <= 0) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + else if ( + type != NULL && + StringLen(symbol) > 0) + { + // + if (type == positionType && + symbol == positionSymbol) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + else if (StringLen(symbol) > 0) + { + // + if (positionSymbol == symbol) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + + // + continue; + } + } + else if (type != NULL) + { + // + if (type == positionType) + { + // + if (type == POSITION_TYPE_BUY) + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + else + { + // + if (age < positionAge) + { + // + age = positionAge; + result = positionTicket; + } + } + + // + continue; + } + } + } + + // + return result; + } + + // + // Force Open a Buy/Long Position ... + bool Buy( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Buy( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.BuyStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Force Open a Sell/Short Position ... + bool Sell( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = "" // comment + ) + { + // + bool result = false; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.Sell( + volume, + symbol, + price, + sl, + tp, + comment); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + 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; + + // + string mPeriodStr = GeneratePositionPeriodComment(period); + + // + comment += mPeriodStr; + + // + result = mTrader.SellStop( + volume, + price, + symbol, + 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 + string comment = "" // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + if (tp <= 0 && sl <= 0) + { + result = false; + return result; + } + + // + // Use Position Comment when there isn't new One ... + if (StringLen(comment) == 0) + { + comment = GetPositionComment(ticket); + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment); + + // + 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); + + // + return result; + } + + // + // Close All Positions ... + void CloseAllPositions( + string comment = "" // Close Position By Specific Comment + ) + { + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + Close( + positionTicket, + comment); + } + } + + // + // 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); + + // + return result; + } + + // + // Find Position Open Bar Index ... + int GetPositionOpenBarIndex( + const ulong ticket // position ticket + ) + { + // + int result = -1; + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong positionTicket = mPositionInfo.Ticket(); + if (positionTicket != ticket) + { + continue; + } + + // + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + string comment = mPositionInfo.Comment(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + result = iBarShift( + symbol, + period, + openAt); + } + + // + return result; + } + + // + bool GetPosition( + XPosition &position, // Holds result ... + ulong ticket // Required Position Ticket ... + ) + { + // + bool result = false; + + // + XPosition positions[]; + GetPositions(positions); + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + result = iPosition.ticket == ticket; + if (!result) + { + continue; + } + + // + position = iPosition; + break; + } + + // + return result; + } + + // + // Retrieve Positions as an Array ... + void GetPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + if (!mPositionInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mPositionInfo.Magic() != mMagicNumber) + { + continue; + } + + // + ulong magic = mPositionInfo.Magic(); + ulong ticket = mPositionInfo.Ticket(); + string symbol = mPositionInfo.Symbol(); + datetime openAt = mPositionInfo.Time(); + double swap = mPositionInfo.Swap(); + double sl = mPositionInfo.StopLoss(); + double tp = mPositionInfo.TakeProfit(); + double profit = mPositionInfo.Profit(); + double volume = mPositionInfo.Volume(); + string comment = mPositionInfo.Comment(); + double entry = mPositionInfo.PriceOpen(); + double price = mPositionInfo.PriceCurrent(); + double commission = mPositionInfo.Commission(); + ENUM_POSITION_TYPE type = mPositionInfo.PositionType(); + ENUM_TIMEFRAMES period = ExtractPositionPeriod(comment); + + // + XPosition iPosition = {}; + + // + iPosition.tp = tp; + iPosition.sl = sl; + iPosition.swap = swap; + iPosition.type = type; + iPosition.magic = magic; + iPosition.entry = entry; + iPosition.price = price; + iPosition.ticket = ticket; + iPosition.symbol = symbol; + iPosition.period = period; + iPosition.volume = volume; + iPosition.openAt = openAt; + iPosition.profit = profit; + iPosition.comment = comment; + iPosition.commission = commission; + + // + Add( + iPosition, + result); + } + } + + // + void GetPositions( + XPosition &result[], // Hold Result ... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Period ... + ) + { + // + Clean(result); + + // + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return; + } + + // + XPosition allPositions[]; + GetPositions(allPositions); + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (symbol != iPosition.symbol) + { + continue; + } + + // + ENUM_TIMEFRAMES positionPeriod = ExtractPositionPeriod(iPosition.comment); + if (period != positionPeriod) + { + continue; + } + + // + Add( + iPosition, + result); + } + } + + // + // Execute a Signal ... + bool ExecuteSignal( + XSignal &signal, // Signal ... + string comment = "", // Position Comment ... + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime ... + datetime expiration = 0 // order expiration time + ) + + { + // + bool result = false; + + // + double currentEntry = GetEntry( + signal.symbol, + signal.type); + bool isLong = IsLong(signal.type); + + // + ResetLastError(); + + // + if (signal.mode == X_ORDER_MODE_MARKET) + { + // + // Execute MArket Orders ... + if (isLong) + { + // + result = Buy( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + comment); + } + else + { + // + result = Sell( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + comment); + } + } + else if (signal.mode == X_ORDER_MODE_LIMIT) + { + // + // Execute Limit Orders ... + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? signal.entry < currentEntry + : signal.entry > currentEntry; + if (!result) + { + return result; + } + + // + // Check Expiration Date ... + result = (lifetime == ORDER_TIME_SPECIFIED || lifetime == ORDER_TIME_SPECIFIED_DAY) + ? expiration > 0 + : true; + if (!result) + { + return result; + } + + // + if (isLong) + { + // + result = BuyLimit( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + else + { + // + result = SellLimit( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + } + else if (signal.mode == X_ORDER_MODE_STOP) + { + // + // Execute Stop Orders ... + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? signal.entry > currentEntry + : signal.entry < currentEntry; + if (!result) + { + return result; + } + + // + // Check Expiration Date ... + result = (lifetime == ORDER_TIME_SPECIFIED || lifetime == ORDER_TIME_SPECIFIED_DAY) + ? expiration > 0 + : true; + if (!result) + { + return result; + } + + // + if (isLong) + { + // + result = BuyStop( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + else + { + // + result = SellStop( + signal.symbol, + signal.period, + signal.volume, + signal.entry, + signal.sl, + signal.tp, + lifetime, + expiration, + comment); + } + } + + // + if (!result) + { + // + LogMessage("Error: " + (string)GetLastError() + ", " + GetErrorDescription(GetLastError())); + } + + // + return result; + } + + // + // Execute a Collection of Signals ... + int ExecuteSignals( + const XSignal &signals[], // an Array of Signals ... + string comment = "", // Position Comment ... + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime ... + datetime expiration = 0 // order expiration time + ) + { + // + int result = 0; + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + bool isExecuted = ExecuteSignal( + iSignal, + comment, + lifetime, + expiration); + + // + if (isExecuted) + { + result++; + } + } + + // + return result; + } + + // + // Retrieve in Profit Positions ... + void GetInProfitPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit > 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Retrieve in Drawdown Positions ... + void GetInDrawdownPositions( + XPosition &result[] // Hold Result ... + ) + { + // + Clean(result); + + // + XPosition allPositions[]; + GetPositions(allPositions); + int positionsCount = ArraySize(allPositions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = allPositions[i]; + + // + if (iPosition.profit < 0) + { + Add( + iPosition, + result); + } + } + } + + // + // Close a Collection Of Positions ... + void ClosePositions( + XPosition &positions[], // Positions to Close ... + string comment = "" // Specified Comment ... + ) + { + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + Close( + iPosition.ticket, + comment); + } + } + + // + // Retrieve All Orders ... + void GetOrders( + XOrder &result[], // Holdes Result .... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading TimeFrame ... + ENUM_ORDER_STATE state = NULL // Order State ... + ) + { + // + Clean(result); + + // + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return; + } + + // + // Since Orders may be so more than positions ... + // start Orders Collectiong Loops reverse ... + for (int i = ordersCount - 1; i >= 0; i--) + { + // + if (!mOrderInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mOrderInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + long magic = mOrderInfo.Magic(); + double sl = mOrderInfo.StopLoss(); + ulong ticket = mOrderInfo.Ticket(); + double tp = mOrderInfo.TakeProfit(); + string oSymbol = mOrderInfo.Symbol(); + string comment = mOrderInfo.Comment(); + long pocitionID = mOrderInfo.PositionId(); + double openPrice = mOrderInfo.PriceOpen(); + datetime setupAt = mOrderInfo.TimeSetup(); + datetime executedAt = mOrderInfo.TimeDone(); + ENUM_ORDER_STATE oState = mOrderInfo.State(); + ENUM_ORDER_TYPE type = mOrderInfo.OrderType(); + double currentPrice = mOrderInfo.PriceCurrent(); + datetime expiredAt = mOrderInfo.TimeExpiration(); + double initialVolume = mOrderInfo.VolumeInitial(); + double currentVolume = mOrderInfo.VolumeCurrent(); + double stopLimitPrice = mOrderInfo.PriceStopLimit(); + ENUM_ORDER_TYPE_TIME lifetime = mOrderInfo.TypeTime(); + ENUM_ORDER_TYPE_FILLING filling = mOrderInfo.TypeFilling(); + + // + if (StringLen(symbol) > 0 && symbol != oSymbol) + { + continue; + } + + // + ENUM_TIMEFRAMES oPeriod = ExtractPositionPeriod(comment); + if (period != NULL && period != oPeriod) + { + continue; + } + + // + if (state != NULL && oState != state) + { + continue; + } + + // + // Now Create an instance of XOrder struct and fill it by + // retrieved data, and add it to results ... + XOrder iOrder = {}; + + // + iOrder.sl = sl; + iOrder.tp = tp; + iOrder.type = type; + iOrder.magic = magic; + iOrder.state = oState; + iOrder.ticket = ticket; + iOrder.smybol = oSymbol; + iOrder.setupAt = setupAt; + iOrder.comment = comment; + iOrder.filling = filling; + iOrder.lifetime = lifetime; + iOrder.expiredAt = expiredAt; + iOrder.openPrice = openPrice; + iOrder.pocitionID = pocitionID; + iOrder.executedAt = executedAt; + iOrder.currentPrice = currentPrice; + iOrder.initialVolume = initialVolume; + iOrder.currentVolume = currentVolume; + iOrder.stopLimitPrice = stopLimitPrice; + + // + Add( + iOrder, + result); + } + } + + // + int OrdersCount() + { + return OrdersTotal(); + } + + // + // Cancel Specific Orders ... + bool CancelOrders( + XOrder &orders[]) + { + // + bool result = false; + + // + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + bool isDeleted = mTrader.OrderDelete(iOrder.ticket); + if (isDeleted && !result) + { + result = isDeleted; + } + } + + // + return result; + } + + // + // Retrieve All Deals ... + void GetDeals(XDeal &result[]) + { + // + Clean(result); + + // + int dealsCount = HistoryDealsTotal(); + if (dealsCount <= 0) + { + return; + } + + // + for (int i = dealsCount - 1; i >= 0; i--) + { + // + if (!mDealInfo.SelectByIndex(i)) + { + continue; + } + + // + if (mDealInfo.Magic() != mMagicNumber) + { + continue; + } + + // + // Reading Order Info ... + double swap = mDealInfo.Swap(); + ulong magic = mDealInfo.Magic(); + ulong order = mDealInfo.Order(); + ulong ticket = mDealInfo.Ticket(); + datetime time = mDealInfo.Time(); + double price = mDealInfo.Price(); + string symbol = mDealInfo.Symbol(); + double profit = mDealInfo.Profit(); + double volume = mDealInfo.Volume(); + string comment = mDealInfo.Comment(); + ulong positionId = mDealInfo.PositionId(); + ENUM_DEAL_ENTRY entry = mDealInfo.Entry(); + double commission = mDealInfo.Commission(); + ENUM_DEAL_TYPE type = mDealInfo.DealType(); + ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( + ticket, + DEAL_REASON); + + // + XDeal iDeal = {}; + + // + iDeal.swap = swap; + iDeal.time = time; + iDeal.type = type; + iDeal.magic = magic; + iDeal.entry = entry; + iDeal.order = order; + iDeal.price = price; + iDeal.ticket = ticket; + iDeal.symbol = symbol; + iDeal.profit = profit; + iDeal.volume = volume; + iDeal.reason = reason; + iDeal.comment = comment; + iDeal.positionId = positionId; + iDeal.commission = commission; + + // + Add( + iDeal, + result); + } + } + + // + // Generate String Representation Of Position's Time Frame ... + string GeneratePositionPeriodComment(ENUM_TIMEFRAMES period) + { + // + string result = mPeriodPrefix + "(" + ToString(period) + ")"; + + // + return result; + } + + // + // Extract Position Time Frame From it's Comment ... + ENUM_TIMEFRAMES ExtractPositionPeriod(string comment) + { + // + ENUM_TIMEFRAMES result = _Period; + + // + if (StringLen(comment) <= 0) + { + return result; + } + + // + string periodStr = ExtractString( + comment, + mPeriodPrefix + "(", + ")"); + if (StringLen(periodStr) <= 0) + { + return result; + } + + // + result = ToPeriod(periodStr); + + // + return result; + } + + // + // Retrieve Last Open Position Ticket ... + ulong GetLastOpenPositionTicket() + { + // + ulong result = 0; + + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + result = PositionGetTicket(PositionsTotal() - 1); + + // + return result; + } + + // + // Retrieve Last Placed Order Ticket ... + ulong GetLastPlacedOrderTicket() + { + // + ulong result = 0; + + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + if (mOrderInfo.SelectByIndex(ordersCount - 1)) + { + result = mOrderInfo.Ticket(); + } + + // + return result; + } + + // + // SUPPORT Signals ... + + // + // Find an Specific Position Has Support Signal Or not ... + bool HasSupport(ulong ticket) + { + // + bool result = false; + + // + int count = PositionsCount(); + if (count <= 1) + { + return result; + } + + // + XPosition position; + result = GetPosition( + position, + ticket); + if (!result) + { + return result; + } + + // + XPosition positions[]; + GetPositions(positions); + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = positions[i]; + + // + string supportTicketStr = ExtractParentTicketOfSupport(iPosition.comment); + if (StringLen(supportTicketStr) == 0) + { + continue; + } + + // + ulong parentTicket = (ulong)supportTicketStr; + + // + result = + parentTicket == ticket && + iPosition.ticket != parentTicket; + if (result) + { + break; + } + } + + // + return result; + } + + // + // Get All Support Positions for Specific Position ... + bool GetSupportPositions( + ulong ticket, // Parent Position Ticket + XPosition &supports[] // Holds Result ... + ) + { + // + bool result = false; + + // + Clean(supports); + + // + int count = PositionsCount(); + if (count <= 0) + { + return result; + } + + // + XPosition parentPosition; + bool positionExist = GetPosition( + parentPosition, + ticket); + if (!positionExist) + { + return result; + } + + // + bool hasSupport = HasSupport(ticket); + if (!hasSupport) + { + return result; + } + + // + XPosition positions[]; + GetPositions(positions); + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = positions[i]; + + // + if (iPosition.ticket == ticket) + { + continue; + } + + // + string pTicketStr = ExtractParentTicketOfSupport(iPosition.comment); + if (StringLen(pTicketStr) <= 0) + { + continue; + } + + // + ulong pTicket = (ulong)pTicketStr; + if (pTicket != ticket) + { + continue; + } + + // + Add( + iPosition, + supports); + } + + // + result = ArraySize(supports) > 0; + + // + return result; + } + + // + bool GetSupportOrders( + ulong ticket, // Parent Position Ticket + XOrder &supports[], // Holds Result ... + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period, // Trading TimeFrame ... + ENUM_ORDER_STATE state = NULL // Order State ... + ) + { + // + bool result = false; + + // + Clean(supports); + + // + XOrder orders[]; + GetOrders( + orders, + symbol, + period, + state); + int ordersCount = ArraySize(orders); + result = ordersCount > 0; + if (!result) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + string pTicketStr = ExtractParentTicketOfSupport(iOrder.comment); + if (StringLen(pTicketStr) == 0) + { + continue; + } + + // + ulong pTicket = (ulong)pTicketStr; + if (pTicket != ticket) + { + continue; + } + + // + Add( + iOrder, + supports); + } + + // + result = ArraySize(supports) > 0; + + // + return result; + } + + // + // Generate SL Support Signal ... + bool GenerateSLSupportSignal( + XSignal &signal, // Holds Result .... + ulong ticket, // Specific Position Ticket ... + double slGapPoint = 10, // Which Distance to SL for Enabling Signal ... + double volumeMultiplier = 2 // Support Signals Volume Multiplier ... + ) + { + // + bool result = false; + + // + int count = PositionsCount(); + if (count <= 0) + { + return result; + } + + // + bool hasSupport = HasSupport(ticket); + if (hasSupport) + { + return result; + } + + // + XPosition position; + result = GetPosition( + position, + ticket); + if (!result) + { + return result; + } + + // + bool isLong = + IsLong(position.type); + + // + string symbol = position.symbol; + ENUM_TIMEFRAMES period = ExtractPositionPeriod(position.comment); + double volume = position.volume * volumeMultiplier; + volume = NormalizeVolume( + volume, + symbol); + + ENUM_POSITION_TYPE type = isLong + ? POSITION_TYPE_SELL + : POSITION_TYPE_BUY; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_STOP; + + // + double slGapPrice = PointToPrice( + symbol, + slGapPoint); + double riskPrice = MathAbs(position.entry - position.sl); + + // + double entry = + isLong + ? position.sl + slGapPrice + : position.sl - slGapPrice; + entry = NormalizePrice(entry, symbol); + + // + double sl = + isLong + ? entry + riskPrice + : entry - riskPrice; + sl = NormalizePrice(sl, symbol); + + // + double tp = + isLong + ? entry - riskPrice + : entry + riskPrice; + tp = NormalizePrice(tp, symbol); + + // + signal.sl = sl; + signal.tp = tp; + signal.type = type; + signal.mode = mode; + signal.entry = entry; + signal.volume = volume; + signal.symbol = symbol; + signal.period = period; + + // + return result; + } + + // + // Close a Position and it's Supports on a Profit ... + bool ClosePositionAndSupports( + ulong ticket, // Position Ticket + double minProfit = 4 // Minimum Profit For Closing + ) + { + // + bool result = false; + + // + if (minProfit <= 0) + { + return result; + } + + // + int count = PositionsCount(); + if (count <= 0) + { + return result; + } + + // + XPosition position; + bool isExist = GetPosition( + position, + ticket); + if (!isExist) + { + return result; + } + + // + bool hasSupport = HasSupport(ticket); + if (!hasSupport) + { + return result; + } + + // + XPosition supports[]; + hasSupport = GetSupportPositions( + ticket, + supports); + int supportsCount = ArraySize(supports); + if (!hasSupport || supportsCount <= 0) + { + return result; + } + + // + double profitSummary = 0; + for (int i = 0; i < supportsCount; i++) + { + // + XPosition iSupport = supports[i]; + + // + profitSummary += iSupport.profit; + } + + // + result = profitSummary > 0 && profitSummary >= minProfit; + if (!result) + { + return result; + } + + // + Add( + position, + supports); + + // + string comment = "Close Position (" + (string)ticket + ") and it's Supports in Profit: " + (string)profitSummary + " ..."; + ClosePositions( + supports, + comment); + + // + if (result) + { + LogMessage(comment); + } + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... + + // + // EVENTS Handlers Notifiers ... + + // + // STATE ... + void NotifyTradeStateChangeEvent(const XOnTradeHandlerState &state) + { + // + int count = ArraySize(mTradeStateChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + OnTradeStateChanged iHandler = mTradeStateChangedEventHandlers[i]; + iHandler(state); + } + } + + // + // DEALS ... + void NotifyDealsChangeEvent(int changes) + { + // + int count = ArraySize(mDealsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + OnDealsChanged iHandler = mDealsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // ORDERS ... + void NotifyOrdersChangeEvent(int changes) + { + // + int count = ArraySize(mOrdersChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + OnOrdersChanged iHandler = mOrdersChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // POSITIONS ... + void NotifyPositionsChangeEvent(int changes) + { + // + int count = ArraySize(mPositionsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + OnPositionsChanged iHandler = mPositionsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // TPSL ... + + // + void NotifyStopLossEvent(const XDeal &deal) + { + // + int count = ArraySize(mStopLossEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + OnStopLoss iHandler = mStopLossEventHandlers[i]; + iHandler(deal); + } + } + + // + void NotifyTakeProfitEvent(const XDeal &deal) + { + // + int count = ArraySize(mTakeProfitEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + OnTakeProfit iHandler = mTakeProfitEventHandlers[i]; + iHandler(deal); + } + } + +private: + // + // using deviation, it must be in Point ... + int mSlippage; + + // + // using magic number ... + ulong mMagicNumber; + + // + // using CTrade instance ... + XSCTradeBase mTrader; + + // + // Deals Info ... + CDealInfo mDealInfo; + + // + // Order Info ... + COrderInfo mOrderInfo; + + // + // using PositionInfo instance ... + CPositionInfo mPositionInfo; + + // + // ADDITIONAL Data ... + + // + string mPeriodPrefix; + + // + // START Trade Processing ... + // + + // + 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( + XOnTradeHandlerState &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) + { + 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(); + + // + mOrdersCount = OrdersTotal(); + mPositionsCount = PositionsTotal(); + + // + // load history ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current value ... + mDealsCount = HistoryDealsTotal(); + mHistoryOrdersCount = HistoryOrdersTotal(); + + // + mScanStarted = true; + } + + // + // Deals Changed Event Handlers ... + OnDealsChanged mDealsChangedEventHandlers[]; + + // + // Orders Changed Event Handlers ... + OnOrdersChanged mOrdersChangedEventHandlers[]; + + // + // Positions Changed Event Handlers ... + OnPositionsChanged mPositionsChangedEventHandlers[]; + + // + // Trade State Changed Event Handlers ... + OnTradeStateChanged mTradeStateChangedEventHandlers[]; + + // + // TPSL ... + OnStopLoss mStopLossEventHandlers[]; + OnTakeProfit mTakeProfitEventHandlers[]; + + // + // END Trade Processing ... + // +}; + +// +// START Usefull Functions ... +// + +// +// Add Specific XPosition to Specified Array ... +void Add( + XDeal &item, + XDeal &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOrder &item, + XOrder &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XPosition &item, + XPosition &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Clear All Items Inside Array ... +void Clean(XDeal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(XOrder &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(XPosition &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// Generate Identifier Tag ... +string GenerateTag(XSignal &info) +{ + // + string result = ""; + + // + result = info.symbol + "," + ToString(info.period); + + // + return result; +} + +// +// Convert Position to Signal ... +XSignal ToSignalInfo( + XPosition &position) +{ + // + XSignal result; + + // + result.tp = position.tp; + result.sl = position.sl; + result.type = position.type; + result.entry = position.entry; + result.symbol = position.symbol; + result.period = position.period; + result.volume = position.volume; + + // + return result; +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Experts/x-saherelm.xea.ex5 b/MQLTestWorkspace/Experts/x-saherelm.xea.ex5 new file mode 100644 index 0000000..009ab5f Binary files /dev/null and b/MQLTestWorkspace/Experts/x-saherelm.xea.ex5 differ diff --git a/MQLTestWorkspace/Experts/x-saherelm.xea.mq5 b/MQLTestWorkspace/Experts/x-saherelm.xea.mq5 new file mode 100644 index 0000000..381c710 --- /dev/null +++ b/MQLTestWorkspace/Experts/x-saherelm.xea.mq5 @@ -0,0 +1,262 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: X121EA +// 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 X121EA" +#property strict + +// +// START Definitions ... +// + +// +// Common Library ... +#include "../Classes/x-saherelm.x121.xea.class.mq5" + +// +#define ShortName "X121EA" + +// +// END Definitions ... +// + +// +// START Inputs ... +// + +// +// EA ... +input group "Common"; +input bool xEAEnable = true; // Enable EA +input int xEASlippage = 10; // Slippgae +input ulong xEAMagicNumber = 1604056; // Magic Number + +// +// Signals ... +input group "Signals"; +input bool xEAEnableLongs = true; // Enable Long Trades +input bool xEAEnableShorts = true; // Enable Short Trades + +// +// Risk Management ... +input group "Risk Management"; +input int xEAMaxOpenPositions = 15; // Max Allowed Open Positions +input double xEAMaxAllowedDrawDownFactor = 0.15; // Max Allowed Drawdown Factor + +// +// Alerts ... +input group "Alerts"; +input bool xEAEnableAlerts = true; // Enable Events Alert +input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day +input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week +input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XSCX121EA *mX121EA; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = ShortName; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + InitEAInstance(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XEA Providers ... + delete mX121EA; +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Prevent Going Forward if user Disable it ... + if (xEAEnable) + { + mX121EA.OnTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + mX121EA.OnTrade(); +} + +// +// Handle Signal Event ... +void OnSignalConditionsRecieved(X121MarketConditions &info) +{ +} + +// +// Handle StopLoss Event ... +void OnStopLossTriggered(const XDeal &deal) +{ +} + +// +// Handle TakeProfit Event ... +void OnTakeProfitTriggered(const XDeal &deal) +{ +} + +// +// Handle Deals Changed Event ... +void OnDealsChangedHandler(int count) +{ +} + +// +// Handle Order Changed Event ... +void OnOrdersChangedHandler(int count) +{ +} + +// +// Handle Position Changed Event ... +void OnPositionsChangedHandler(int count) +{ +} + +// +// Handle Trade State Changed ... +void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) +{ +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + // Validate Args ... + result = + // + xEASlippage > 0 && + xEAMagicNumber > 0 + // + // TODO: add new validations here ... + // + ; + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +// +// Initialize X121EA Class Instances ... +void InitEAInstance() +{ + // + mX121EA = new XSCX121EA( + _Symbol, + _Period, + xEAMagicNumber, + xEASlippage, + OnStopLossTriggered, + OnTakeProfitTriggered, + OnDealsChangedHandler, + OnOrdersChangedHandler, + OnPositionsChangedHandler, + OnTradeStateChangedHandler, + OnSignalConditionsRecieved); +} +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xama.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xama.helper.class.ex5 new file mode 100644 index 0000000..ef90b9c Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xama.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xama.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xama.helper.class.mq5 new file mode 100644 index 0000000..86c445a --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xama.helper.class.mq5 @@ -0,0 +1,438 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXAMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XAMAInputs +{ + // + // Makret ... + int length; // Length + int fastEMA; // Fast EMA Length + int slowEMA; // Slow EMA Length + int maShift; // Shift + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + bool showLine; // Show Line +}; + +// +// Index of Lines ... +enum ENUM_XAMA_BUFFERS +{ + // + // Main Requirements ... + XAMA_LINE = 0, + XAMA_STATE_LINE = 1, +}; + +// +// XAMA Indicator States ... +enum ENUM_XAMA_STATES +{ + X_XAMA_BULLISH = 0, + X_XAMA_BEARISH = 2, + X_XAMA_NEUTURAL = 1, +}; + +// +// Retrieve Info Model ... +struct XAMAInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double value; + + // + // State ... + ENUM_XAMA_STATES state; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; + + // + // Detect Trend is Neutural or not ... + bool isNeutural; + + // + // Detect Trend is Switched to Neutural Or not ... + bool isSwitchedNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXAMAHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double valueBuffer[]; + double stateBuffer[]; + + // + // Constructor ... + void XSCXAMAHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXAMAHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XAMA" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xama", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mLength, + // + // Fast EMA Length ... + mFastEMA, + // + // Slow EMA Length ... + mSlowEMA, + // + // Shift ... + mMaShift, + // + // Applied To ... + mAppliedTo, + // + // Presentation ... + "", + // + // Show Line ... + mShowLine + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XAMAInputs GetConfig() + { + // + XAMAInputs result; + + // + result.length = mLength; + result.fastEMA = mFastEMA; + result.slowEMA = mSlowEMA; + result.maShift = mMaShift; + result.appliedTo = mAppliedTo; + result.showLine = mShowLine; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XAMAInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mFastEMA = config.fastEMA; + mSlowEMA = config.slowEMA; + mMaShift = config.maShift; + mAppliedTo = config.appliedTo; + mShowLine = config.showLine; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // VALUE ... + ArraySetAsSeries(valueBuffer, true); + CopyBuffer( + mHandler, + XAMA_LINE, + barIndex, + mLoopbackBars, + valueBuffer); + + // + // STATE ... + ArraySetAsSeries(stateBuffer, true); + CopyBuffer( + mHandler, + XAMA_STATE_LINE, + barIndex, + mLoopbackBars, + stateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XAMAInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XAMAInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.value = valueBuffer[barIndex]; + + // + ENUM_XAMA_STATES state = (ENUM_XAMA_STATES)stateBuffer[barIndex]; + ENUM_XAMA_STATES prevState = (ENUM_XAMA_STATES)stateBuffer[barIndex + 1]; + result.state = state; + + // + result.isBullish = state == X_XAMA_BULLISH; + result.isBearish = state == X_XAMA_BEARISH; + result.isNeutural = state == X_XAMA_NEUTURAL; + + // + result.isSwitchedBullish = + state == X_XAMA_BULLISH && prevState != X_XAMA_BULLISH; + result.isSwitchedBearish = + state == X_XAMA_BEARISH && prevState != X_XAMA_BEARISH; + result.isSwitchedNeutural = + state == X_XAMA_NEUTURAL && prevState != X_XAMA_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Fast EMA Length ... + int mFastEMA; + // + // Slow EMA Length ... + int mSlowEMA; + // + // Shift ... + int mMaShift; + // + // Applied To ... + ENUM_APPLIED_PRICE mAppliedTo; + // + // Presentation ... + // + // Show Line ... + bool mShowLine; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xcc.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xcc.helper.class.ex5 new file mode 100644 index 0000000..7f6fce1 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xcc.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xcc.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xcc.helper.class.mq5 new file mode 100644 index 0000000..414a604 --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xcc.helper.class.mq5 @@ -0,0 +1,293 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +struct XCCInputs +{ + // + // Chart Style ... + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + + // + // Presentation ... + bool showCandles; // Show Candles +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCXCCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCCHelper() + { + } + + // + // START Properties ... + // + + // + // Show Candles ... + bool ShowCandles( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowCandles == show) + { + return true; + } + + // + mShowCandles = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCC" + GetTagPrefix(); + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) {} + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = 2; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xcc", + // + // Inputs ... + // + // Chart Style ... + "", + // + // Up Color ... + mUpColor, + // + // Down Color ... + mDownColor, + // + // Line mode and Doji candlestick Color ... + mLineColor, + // + // Bullish Color ... + mBearishColor, + // + // Bearish Color ... + mBullishColor, + // + // Volumes Color ... + mVolumesColor, + // + // Presentation ... + "", + // + // Show Candles ... + mShowCandles + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCCInputs GetConfig() + { + // + XCCInputs result; + + // + result.upColor = mUpColor; + result.downColor = mDownColor; + result.lineColor = mLineColor; + result.bearishColor = mBearishColor; + result.bullishColor = mBullishColor; + result.volumesColor = mVolumesColor; + result.showCandles = mShowCandles; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCCInputs &config) + { + // + bool result = false; + + // + mUpColor = config.upColor; + mDownColor = config.downColor; + mLineColor = config.lineColor; + mBearishColor = config.bearishColor; + mBullishColor = config.bullishColor; + mVolumesColor = config.volumesColor; + mShowCandles = config.showCandles; + + // + result = Init(); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Chart Style ... + // + // Up Color ... + color mUpColor; + // + // Down Color ... + color mDownColor; + // + // Line mode and Doji candlestick Color ... + color mLineColor; + // + // Bullish Color ... + color mBearishColor; + // + // Bearish Color ... + color mBullishColor; + // + // Volumes Color ... + color mVolumesColor; + + // + // Presentation ... + // + // Show Candles ... + bool mShowCandles; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xche.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xche.helper.class.ex5 new file mode 100644 index 0000000..e6c2a36 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xche.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xche.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xche.helper.class.mq5 new file mode 100644 index 0000000..d3a651f --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xche.helper.class.mq5 @@ -0,0 +1,594 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHEHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XCHEInputs +{ + // + // Market ... + int length; // Length + int loopback; // Loopback + double multiplier1; // 1st Multiplier + double multiplier2; // 2nd Multiplier + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied to + + // + // Presentation ... + bool showLongExit1Line; // Show 1st Long Exit + bool showShortExit1Line; // Show 1st Short Exit + bool showLongExit2Line; // Show 2st Long Exit + bool showShortExit2Line; // Show 2st Short Exit +}; + +// +// Index of Lines ... +enum ENUM_XCHE_BUFFERS +{ + // + // Main Requirements ... + XCHE_1ST_LONG_EXIT_LINE = 0, + XCHE_1ST_SHORT_EXIT_LINE = 1, + XCHE_2ND_LONG_EXIT_LINE = 2, + XCHE_2ND_SHORT_EXIT_LINE = 3, +}; + +// +// Retrieve Info Model ... +struct XCHEInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double longExit1; + double longExit2; + double shortExit1; + double shortExit2; + + // + // Conditions ... + // + bool isLongExit1Start; + bool isShortExit1Start; + + // + bool isLongExit2Start; + bool isShortExit2Start; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCHEHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double longExit1Buffer[]; + double shortExit1Buffer[]; + double longExit2Buffer[]; + double shortExit2Buffer[]; + + // + // Constructor ... + void XSCXCHEHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCHEHelper() + { + } + + // + // START Properties ... + // + + // + // Show 1st Long Exit ... + bool ShowLongExit1Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowLongExit1Line == show) + { + return true; + } + + // + mShowLongExit1Line = show; + result = Init(); + + // + return result; + } + + // + // Show 1st Short Exit ... + bool ShowShortExit1Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowShortExit1Line == show) + { + return true; + } + + // + mShowShortExit1Line = show; + result = Init(); + + // + return result; + } + + // + // Show 2st Long Exit ... + bool ShowLongExit2Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowLongExit2Line == show) + { + return true; + } + + // + mShowLongExit2Line = show; + result = Init(); + + // + return result; + } + + // + // Show 2st Short Exit ... + bool ShowShortExit2Line( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowShortExit1Line == show) + { + return true; + } + + // + mShowShortExit1Line = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCHE" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(mLength, mLoopback); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + // + result = + mLength >= 9 && + mLoopback >= 0; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Loopback ... + mLoopback, + // + // 1st Multiplier ... + mMultiplier1, + // + // 2nd Multiplier ... + mMultiplier2, + // + // Calculation ... + "", + // + // Up Zone Applied to ... + mUpAppliedTo, + // + // Down Zone Applied to ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show 1st Long Exit ... + mShowLongExit1Line, + // + // Show 1st Short Exit ... + mShowShortExit1Line, + // + // Show 2st Long Exit ... + mShowLongExit2Line, + // + // Show 2st Short Exit ... + mShowShortExit2Line + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCHEInputs GetConfig() + { + // + XCHEInputs result; + + // + result.length = mLength; + result.loopback = mLoopback; + result.multiplier1 = mMultiplier1; + result.multiplier2 = mMultiplier2; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showLongExit1Line = mShowLongExit1Line; + result.showShortExit1Line = mShowShortExit1Line; + result.showLongExit2Line = mShowLongExit2Line; + result.showShortExit2Line = mShowShortExit2Line; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCHEInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mLoopback = config.loopback; + mMultiplier1 = config.multiplier1; + mMultiplier2 = config.multiplier2; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowLongExit1Line = config.showLongExit1Line; + mShowShortExit1Line = config.showShortExit1Line; + mShowLongExit2Line = config.showLongExit2Line; + mShowShortExit2Line = config.showShortExit2Line; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // LEVEL 1 .. + + // + // LONG Exit ... + ArraySetAsSeries(longExit1Buffer, true); + CopyBuffer( + mHandler, + XCHE_1ST_LONG_EXIT_LINE, + barIndex, + mLoopbackBars, + longExit1Buffer); + + // + // SHORT Exit ... + ArraySetAsSeries(shortExit1Buffer, true); + CopyBuffer( + mHandler, + XCHE_1ST_SHORT_EXIT_LINE, + barIndex, + mLoopbackBars, + shortExit1Buffer); + + // + // LEVEL 2 .. + + // + // LONG Exit ... + ArraySetAsSeries(longExit2Buffer, true); + CopyBuffer( + mHandler, + XCHE_2ND_LONG_EXIT_LINE, + barIndex, + mLoopbackBars, + longExit2Buffer); + + // + // SHORT Exit ... + ArraySetAsSeries(shortExit2Buffer, true); + CopyBuffer( + mHandler, + XCHE_2ND_SHORT_EXIT_LINE, + barIndex, + mLoopbackBars, + shortExit2Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XCHEInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XCHEInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double longExit1 = longExit1Buffer[barIndex]; + double longExit1Prev = longExit1Buffer[barIndex + 1]; + double shortExit1 = shortExit1Buffer[barIndex]; + double shortExit1Prev = shortExit1Buffer[barIndex + 1]; + + // + double longExit2 = longExit2Buffer[barIndex]; + double longExit2Prev = longExit2Buffer[barIndex + 1]; + double shortExit2 = shortExit2Buffer[barIndex]; + double shortExit2Prev = shortExit2Buffer[barIndex + 1]; + + // + result.longExit1 = longExit1; + result.shortExit1 = shortExit1; + result.longExit2 = longExit2; + result.shortExit2 = shortExit2; + + // + result.isLongExit1Start = + longExit1 != EMPTY_VALUE && + longExit1Prev == EMPTY_VALUE; + + // + result.isShortExit1Start = + shortExit1 != EMPTY_VALUE && + shortExit1Prev == EMPTY_VALUE; + + // + result.isLongExit2Start = + longExit2 != EMPTY_VALUE && + longExit2Prev == EMPTY_VALUE; + + // + result.isShortExit2Start = + shortExit2 != EMPTY_VALUE && + shortExit2Prev == EMPTY_VALUE; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Loopback ... + int mLoopback; + // + // 1st Multiplier ... + double mMultiplier1; + // + // 2nd Multiplier ... + double mMultiplier2; + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show 1st Long Exit ... + bool mShowLongExit1Line; + // + // Show 1st Short Exit ... + bool mShowShortExit1Line; + // + // Show 2st Long Exit ... + bool mShowLongExit2Line; + // + // Show 2st Short Exit ... + bool mShowShortExit2Line; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xct.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xct.helper.class.ex5 new file mode 100644 index 0000000..9e72044 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xct.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xct.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xct.helper.class.mq5 new file mode 100644 index 0000000..c448ef7 --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xct.helper.class.mq5 @@ -0,0 +1,248 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCTHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +struct XCTInputs +{ + // + color clr; + ENUM_BASE_CORNER corner; + + // + // Presentation ... + bool showCandleTime; // Show Candle Time +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXCTHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Constructor ... + void XSCXCTHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXCTHelper() + { + } + + // + // START Properties ... + // + + // + // Show Candles ... + bool ShowCandleTime( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowCandleTime == show) + { + return true; + } + + // + mShowCandleTime = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XCT" + GetTagPrefix(); + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = 1; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xct", + // + // Inputs ... + mClr, + mCorner, + // + // Presentation ... + "", + mShowCandleTime + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XCTInputs GetConfig() + { + // + XCTInputs result; + + // + result.clr = mClr; + result.corner = mCorner; + result.showCandleTime = mShowCandleTime; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XCTInputs &config) + { + // + bool result = false; + + // + mClr = config.clr; + mCorner = config.corner; + mShowCandleTime = config.showCandleTime; + + // + result = Init(); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + + // + // Text Color ... + color mClr; + // + // Text Position ... + ENUM_BASE_CORNER mCorner; + + // + // Presentation ... + // + // Show Candles ... + bool mShowCandleTime; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xhk.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhk.helper.class.ex5 new file mode 100644 index 0000000..9348c47 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhk.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xhk.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhk.helper.class.mq5 new file mode 100644 index 0000000..ff6bdd2 --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhk.helper.class.mq5 @@ -0,0 +1,427 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHKHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XHKInputs +{ + // + // Presentation ... + bool drawCandles; // Draw Hiken Ashi Candle + bool drawCandleLines; // Show HikenAshi Lines +}; + +// +// Index of Lines ... +enum ENUM_XHK_BUFFERS +{ + // + // Main Requirements ... + XHK_OPEN_LINE = 0, + XHK_HIGH_LINE = 1, + XHK_LOW_LINE = 2, + XHK_CLOSE_LINE = 3, +}; + +// +// Retrieve Info Model ... +struct XHKInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double open; + double high; + double low; + double close; + + // + // Conditions ... + + // + // Detect Candle is Bullish or not ... + bool isBullish; + + // + // Detect Candle is Bearish or not ... + bool isBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXHKHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double openBuffer[]; + double highBuffer[]; + double lowBuffer[]; + double closeBuffer[]; + + // + // Constructor ... + void XSCXHKHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + // + // Indicator Properties ... + // + // Presentation ... + // + // Draw Hiken Ashi Candle ... + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXHKHelper() + { + } + + // + // START Properties ... + // + + // + // Draw Candles ... + bool DrawCandles( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mDrawCandles == show) + { + return true; + } + + // + mDrawCandles = show; + result = Init(); + + // + return result; + } + + // + // Show HikenAshi Lines ... + bool DrawCandleLines( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mDrawCandleLines == show) + { + return true; + } + + // + mDrawCandleLines = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XHK" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = 2; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xhk", + // + // Inputs ... + // + // Presentation ... + "", + // + // Draw Hiken Ashi Candle ... + mDrawCandles, + // + // Show HikenAshi Lines ... + mDrawCandleLines + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XHKInputs GetConfig() + { + // + XHKInputs result; + + // + result.drawCandles = mDrawCandles; + result.drawCandleLines = mDrawCandleLines; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XHKInputs &config) + { + // + bool result = false; + + // + mDrawCandles = config.drawCandles; + mDrawCandleLines = config.drawCandleLines; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // OPEN ... + ArraySetAsSeries(openBuffer, true); + CopyBuffer( + mHandler, + XHK_OPEN_LINE, + barIndex, + mLoopbackBars, + openBuffer); + + // + // HIGH ... + ArraySetAsSeries(highBuffer, true); + CopyBuffer( + mHandler, + XHK_HIGH_LINE, + barIndex, + mLoopbackBars, + highBuffer); + + // + // LOW ... + ArraySetAsSeries(lowBuffer, true); + CopyBuffer( + mHandler, + XHK_LOW_LINE, + barIndex, + mLoopbackBars, + lowBuffer); + + // + // CLOSE ... + ArraySetAsSeries(closeBuffer, true); + CopyBuffer( + mHandler, + XHK_CLOSE_LINE, + barIndex, + mLoopbackBars, + closeBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XHKInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XHKInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double open = openBuffer[barIndex]; + double high = highBuffer[barIndex]; + double low = lowBuffer[barIndex]; + double close = closeBuffer[barIndex]; + + // + result.open = open; + result.high = high; + result.low = low; + result.close = close; + + // + result.isBullish = open < close; + result.isBearish = open >= close; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Presentation ... + // + // Draw Hiken Ashi Candle ... + bool mDrawCandles; + // + // Show HikenAshi Lines ... + bool mDrawCandleLines; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xhull.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhull.helper.class.ex5 new file mode 100644 index 0000000..fd2a794 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhull.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xhull.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhull.helper.class.mq5 new file mode 100644 index 0000000..63de5c3 --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xhull.helper.class.mq5 @@ -0,0 +1,530 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXHULLHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XHULLInputs +{ + // + // Market ... + int length; // Length + double divisor; // Divisor (Speed) + + // + // Calculation ... + ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied to + + // + // Presentation ... + bool showUpZone; // Show Up Zone + bool showDownZone; // Show Down Zone +}; + +// +// Index of Lines ... +enum ENUM_XHULL_BUFFERS +{ + // + // Main Requirements ... + XHULL_UP_ZONE_LINE = 0, + XHULL_UP_ZONE_STATE_LINE = 1, + XHULL_DOWN_ZONE_LINE = 2, + XHULL_DOWN_ZONE_STATE_LINE = 3, +}; + +// +// Hull States ... +enum XHULL_ZONE_STATES +{ + XHULL_STATE_NEUTURAL = 0, + XHULL_STATE_BULLISH = 1, + XHULL_STATE_BEARISH = 2 +}; + +// +// Retrieve Info Model ... +struct XHULLInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double up; + XHULL_ZONE_STATES upState; + double down; + XHULL_ZONE_STATES downState; + + // + // Conditions ... + + // + bool isUpBullish; + bool isUpNeutural; + bool isUpBearish; + + // + bool isUpSwitchedToBullish; + bool isUpSwitchedToBearish; + bool isUpSwitchedToNeutural; + + // + bool isDownBullish; + bool isDownBearish; + bool isDownNeutural; + + // + bool isDownSwitchedToBullish; + bool isDownSwitchedToBearish; + bool isDownSwitchedToNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXHULLHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double upBuffer[]; + double upStateBuffer[]; + double downBuffer[]; + double downStateBuffer[]; + + // + // Constructor ... + void XSCXHULLHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXHULLHelper() + { + } + + // + // START Properties ... + // + + // + // Show Up Zone ... + bool ShowUpZone( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowUpZone == show) + { + return true; + } + + // + mShowUpZone = show; + result = Init(); + + // + return result; + } + + // + // Show Down Zone ... + bool ShowDownZone( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowDownZone == show) + { + return true; + } + + // + mShowDownZone = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XHULL" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + result = + mLength >= 9 && + mDivisor >= 0.5; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xhull", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Divisor (Speed) ... + mDivisor, + // + // Calculation ... + "", + // + // Up Zone Applied to ... + mUpAppliedTo, + // + // Down Zone Applied to ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show Up Zone ... + mShowUpZone, + // + // Show Down Zone ... + mShowDownZone + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XHULLInputs GetConfig() + { + // + XHULLInputs result; + + // + result.length = mLength; + result.divisor = mDivisor; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showUpZone = mShowUpZone; + result.showDownZone = mShowDownZone; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XHULLInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mDivisor = config.divisor; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowUpZone = config.showUpZone; + mShowDownZone = config.showDownZone; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // UP ... + ArraySetAsSeries(upBuffer, true); + CopyBuffer( + mHandler, + XHULL_UP_ZONE_LINE, + barIndex, + mLoopbackBars, + upBuffer); + + // + // UP State ... + ArraySetAsSeries(upStateBuffer, true); + CopyBuffer( + mHandler, + XHULL_UP_ZONE_STATE_LINE, + barIndex, + mLoopbackBars, + upStateBuffer); + + // + // DOWN ... + ArraySetAsSeries(downBuffer, true); + CopyBuffer( + mHandler, + XHULL_DOWN_ZONE_LINE, + barIndex, + mLoopbackBars, + downBuffer); + + // + // DOWN State ... + ArraySetAsSeries(downStateBuffer, true); + CopyBuffer( + mHandler, + XHULL_DOWN_ZONE_STATE_LINE, + barIndex, + mLoopbackBars, + downStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XHULLInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XHULLInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double up = upBuffer[barIndex]; + XHULL_ZONE_STATES upState = (XHULL_ZONE_STATES)upStateBuffer[barIndex]; + XHULL_ZONE_STATES upStatePrev = (XHULL_ZONE_STATES)upStateBuffer[barIndex + 1]; + + // + double down = downBuffer[barIndex]; + XHULL_ZONE_STATES downState = (XHULL_ZONE_STATES)downStateBuffer[barIndex]; + XHULL_ZONE_STATES downStatePrev = (XHULL_ZONE_STATES)downStateBuffer[barIndex + 1]; + + // + result.up = up; + result.upState = upState; + result.down = down; + result.downState = downState; + + // + result.isUpBullish = upState = XHULL_STATE_BULLISH; + result.isUpBearish = upState = XHULL_STATE_BEARISH; + result.isUpNeutural = upState = XHULL_STATE_NEUTURAL; + + // + result.isUpSwitchedToBullish = upState == XHULL_STATE_BULLISH && + upStatePrev != XHULL_STATE_BULLISH; + result.isUpSwitchedToBearish = upState == XHULL_STATE_BEARISH && + upStatePrev != XHULL_STATE_BEARISH; + result.isUpSwitchedToNeutural = upState == XHULL_STATE_NEUTURAL && + upStatePrev != XHULL_STATE_NEUTURAL; + + // + result.isDownBullish = downState = XHULL_STATE_BULLISH; + result.isDownBearish = downState = XHULL_STATE_BEARISH; + result.isDownNeutural = downState = XHULL_STATE_NEUTURAL; + + // + result.isDownSwitchedToBullish = downState == XHULL_STATE_BULLISH && + downStatePrev != XHULL_STATE_BULLISH; + result.isDownSwitchedToBearish = downState == XHULL_STATE_BEARISH && + downStatePrev != XHULL_STATE_BEARISH; + result.isDownSwitchedToNeutural = downState == XHULL_STATE_NEUTURAL && + downStatePrev != XHULL_STATE_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Divisor (Speed) ... + double mDivisor; + // + // Calculation ... + // + // Up Zone Applied to ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Zone Applied to ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show Up Zone ... + bool mShowUpZone; + // + // Show Down Zone ... + bool mShowDownZone; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xich.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xich.helper.class.ex5 new file mode 100644 index 0000000..c783122 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xich.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xich.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xich.helper.class.mq5 new file mode 100644 index 0000000..ec79b08 --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xich.helper.class.mq5 @@ -0,0 +1,965 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXICHHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// Inputs ... +struct XICHInputs +{ + // + // TENKANSEN ... + // Tenkan Sen ... + int tenkanSenLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode; // Calculation Mode + + // + // KIJUNSEN ... + // Kijun Sen ... + int kijunSenLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode; // Calculation Mode + + // + // SENKOUSPANB ... + // Senkou Span B ... + int senkouSpanBLength; // Length + ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode; // Calculation Mode + + // + // CHIKOUSPAN ... + // Chikou Span ... + ENUM_APPLIED_PRICE chikuoSpanAppliedTo; // Price Type + + // + // Presentation ... + bool showTenkanSen; // Show Tenkan Sen + bool showKijunSen; // Show Kijun Sen + bool showKijunSenPlus; // Show Kijun Sen + + bool showKijunSenNegative; // Show Kijun Sen - + bool showChikouSpan; // Show Chikou Span + bool showSenkouSpanA; // Show Senkou Span A + bool showSenkouSpanB; // Show Senkou Span B + bool showKumo; // Show Kumo + bool shiftKumo; // Shift Kumo to Future +}; + +// +// Index of Lines ... +enum ENUM_XICH_BUFFERS +{ + // + // Main Requirements ... + XICH_TEANKANSEN_LINE = 0, + XICH_KIJUNSEN_LINE = 1, + XICH_CHIKOUSPAN_LINE = 4, + XICH_SENKOUSPANA_LINE = 5, + XICH_SENKOUSPANB_LINE = 6, +}; + +// +// Retrieve Info Model ... +struct XICHInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double tenkanSen; + double kijunSen; + double chikouSpan; + double senkouSpanA; + double senkouSpanB; + double senkouSpanAFuture; + double senkouSpanBFuture; + + // + // Conditions ... + + // + bool isTenkanSenOverKijunSen; + bool isTenkanSenUnderKijunSen; + bool isTenkanSenCrossedOverKijunSen; + bool isTenkanSenCrossedUnderKijunSen; + + // + bool isKumoBullish; + bool isKumoBearish; + bool isFutureKumoBullish; + bool isFutureKumoBearish; + bool isKumoSwitchedToBullish; + bool isKumoSwitchedToBearish; + bool isFutureKumoSwitchedToBullish; + bool isFutureKumoSwitchedToBearish; + + // + bool isTenkanSenOverSenkouSpanA; + bool isTenkanSenUnderSenkouSpanA; + bool isTenkanSenOverFutureSenkouSpanA; + bool isTenkanSenUnderFutureSenkouSpanA; + bool isTenkanSenCrossedOverSenkouSpanA; + bool isTenkanSenCrossedUnderSenkouSpanA; + bool isTenkanSenCrossedOverFutureSenkouSpanA; + bool isTenkanSenCrossedUnderFutureSenkouSpanA; + + // + bool isTenkanSenOverSenkouSpanB; + bool isTenkanSenUnderSenkouSpanB; + bool isTenkanSenOverFutureSenkouSpanB; + bool isTenkanSenUnderFutureSenkouSpanB; + bool isTenkanSenCrossedOverSenkouSpanB; + bool isTenkanSenCrossedUnderSenkouSpanB; + bool isTenkanSenCrossedOverFutureSenkouSpanB; + bool isTenkanSenCrossedUnderFutureSenkouSpanB; + + // + bool isKijunSenOverSenkouSpanA; + bool isKijunSenUnderSenkouSpanA; + bool isKijunSenOverFutureSenkouSpanA; + bool isKijunSenUnderFutureSenkouSpanA; + bool isKijunSenCrossedOverSenkouSpanA; + bool isKijunSenCrossedUnderSenkouSpanA; + bool isKijunSenCrossedOverFutureSenkouSpanA; + bool isKijunSenCrossedUnderFutureSenkouSpanA; + + // + bool isKijunSenOverSenkouSpanB; + bool isKijunSenUnderSenkouSpanB; + bool isKijunSenOverFutureSenkouSpanB; + bool isKijunSenUnderFutureSenkouSpanB; + bool isKijunSenCrossedOverSenkouSpanB; + bool isKijunSenCrossedUnderSenkouSpanB; + bool isKijunSenCrossedOverFutureSenkouSpanB; + bool isKijunSenCrossedUnderFutureSenkouSpanB; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXICHHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double tenkanSenBuffer[]; + double kijunSenBuffer[]; + double chikouSpanBuffer[]; + double senkouSpanABuffer[]; + double senkouSpanBBuffer[]; + + // + // Constructor ... + void XSCXICHHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXICHHelper() + { + } + + // + // START Properties ... + // + + // + // Show Tenkan Sen ... + bool ShowTenkanSen( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowTenkanSen == show) + { + return true; + } + + // + mShowTenkanSen = show; + result = Init(); + + // + return result; + } + + // + // Show Kijun Sen ... + bool ShowKijunSen( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowKijunSen == show) + { + return true; + } + + // + mShowKijunSen = show; + result = Init(); + + // + return result; + } + + // + // Show Chikou Span ... + bool ShowChikouSpan( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowChikouSpan == show) + { + return true; + } + + // + mShowChikouSpan = show; + result = Init(); + + // + return result; + } + + // + // Show Senkou Span A ... + bool ShowSenkouSpanA( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSenkouSpanA == show) + { + return true; + } + + // + mShowSenkouSpanA = show; + result = Init(); + + // + return result; + } + + // + // Show Senkou Span B ... + bool ShowSenkouSpanB( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSenkouSpanB == show) + { + return true; + } + + // + mShowSenkouSpanB = show; + result = Init(); + + // + return result; + } + + // + // Show Kumo ... + bool ShowKumo( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowKumo == show) + { + return true; + } + + // + mShowKumo = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XICH" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + // + result = MathMax(result, mTenkanSenLength); + result = MathMax(result, mKijunSenLength); + result = MathMax(result, mSenkouSpanBLength); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + result = + (mTenkanSenLength > 2 && + mKijunSenLength > mTenkanSenLength && + mSenkouSpanBLength > mKijunSenLength); + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xich", + // + // Inputs ... + // + // TENKANSEN ... + "", + // + // Length ... + mTenkanSenLength, + // + // Calculation Mode ... + mTenkanSenMode, + // + // KIJUNSEN ... + "", + // + // Length ... + mKijunSenLength, + // + // Calculation Mode ... + mKijunSenMode, + // + // SENKOUSPANA ... + "", + // + // Length ... + mSenkouSpanBLength, + // + // Calculation Mode ... + mSenkouSpanBMode, + // + // CHIKOUSPAN ... + "", + // + // Price Type ... + mChikuoSpanAppliedTo, + // + // PRESENTATION ... + "", + // + // Show Tenkan Sen ... + mShowTenkanSen, + // + // Show Kijun Sen ... + mShowKijunSen, + // + // Show Kijun Sen + ... + mShowKijunSenPlus, + // + // Show Kijun Sen - ... + mShowKijunSenNegative, + // + // Show Chikou Span ... + mShowChikouSpan, + // + // Show Senkou Span A ... + mShowSenkouSpanA, + // + // Show Senkou Span B ... + mShowSenkouSpanB, + // + // Show Kumo ... + mShowKumo, + // + // Shift Kumo to Future ... + mShiftKumo + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XICHInputs GetConfig() + { + // + XICHInputs result; + + // + result.tenkanSenLength = mTenkanSenLength; + result.tenkanSenMode = mTenkanSenMode; + result.kijunSenLength = mKijunSenLength; + result.kijunSenMode = mKijunSenMode; + result.senkouSpanBLength = mSenkouSpanBLength; + result.senkouSpanBMode = mSenkouSpanBMode; + result.chikuoSpanAppliedTo = mChikuoSpanAppliedTo; + result.showTenkanSen = mShowTenkanSen; + result.showKijunSen = mShowKijunSen; + result.showKijunSenPlus = mShowKijunSenPlus; + result.showKijunSenNegative = mShowKijunSenNegative; + result.showChikouSpan = mShowChikouSpan; + result.showSenkouSpanA = mShowSenkouSpanA; + result.showSenkouSpanB = mShowSenkouSpanB; + result.showKumo = mShowKumo; + result.shiftKumo = mShiftKumo; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XICHInputs &config) + { + // + bool result = false; + + // + mTenkanSenLength = config.tenkanSenLength; + mTenkanSenMode = config.tenkanSenMode; + mKijunSenLength = config.kijunSenLength; + mKijunSenMode = config.kijunSenMode; + mSenkouSpanBLength = config.senkouSpanBLength; + mSenkouSpanBMode = config.senkouSpanBMode; + mChikuoSpanAppliedTo = config.chikuoSpanAppliedTo; + mShowTenkanSen = config.showTenkanSen; + mShowKijunSen = config.showKijunSen; + mShowKijunSenPlus = config.showKijunSenPlus; + mShowKijunSenNegative = config.showKijunSenNegative; + mShowChikouSpan = config.showChikouSpan; + mShowSenkouSpanA = config.showSenkouSpanA; + mShowSenkouSpanB = config.showSenkouSpanB; + mShowKumo = config.showKumo; + mShiftKumo = config.shiftKumo; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // Since Ichimoku Has Some Issues ... + mLoopbackBars = 52; + + // + // TENKANSEN ... + ArraySetAsSeries(tenkanSenBuffer, true); + CopyBuffer( + mHandler, + XICH_TEANKANSEN_LINE, + barIndex, + mLoopbackBars, + tenkanSenBuffer); + + // + // KIJUNSEN ... + ArraySetAsSeries(kijunSenBuffer, true); + CopyBuffer( + mHandler, + XICH_KIJUNSEN_LINE, + barIndex, + mLoopbackBars, + kijunSenBuffer); + + // + // CHIKOUSPAN ... + ArraySetAsSeries(chikouSpanBuffer, true); + CopyBuffer( + mHandler, + XICH_CHIKOUSPAN_LINE, + barIndex + mKijunSenLength + 1, + mLoopbackBars, + chikouSpanBuffer); + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + CopyBuffer( + mHandler, + XICH_SENKOUSPANA_LINE, + -1 * (barIndex + mKijunSenLength), + mLoopbackBars, + senkouSpanABuffer); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + CopyBuffer( + mHandler, + XICH_SENKOUSPANB_LINE, + -1 * (barIndex + mKijunSenLength), + mLoopbackBars, + senkouSpanBBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XICHInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XICHInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double tenkanSen = tenkanSenBuffer[barIndex]; + double tenkanSenPrev = tenkanSenBuffer[barIndex + 1]; + + // + double kijunSen = kijunSenBuffer[barIndex]; + double kijunSenPrev = kijunSenBuffer[barIndex + 1]; + + // + double chikouSpan = chikouSpanBuffer[barIndex + mKijunSenLength]; + double chikouSpanPrev = chikouSpanBuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanA = senkouSpanABuffer[barIndex + mKijunSenLength]; + double senkouSpanAPrev = senkouSpanABuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanB = senkouSpanBBuffer[barIndex + mKijunSenLength]; + double senkouSpanBPrev = senkouSpanBBuffer[barIndex + mKijunSenLength + 1]; + + // + double senkouSpanAFuture = senkouSpanABuffer[barIndex]; + double senkouSpanAFuturePrev = senkouSpanABuffer[barIndex + 1]; + + // + double senkouSpanBFuture = senkouSpanBBuffer[barIndex]; + double senkouSpanBFuturePrev = senkouSpanBBuffer[barIndex + 1]; + + // + bool isTenkanSenOverKijunSen = + tenkanSen > kijunSen; + bool isTenkanSenUnderKijunSen = + tenkanSen < kijunSen; + bool isTenkanSenCrossedOverKijunSen = + tenkanSen > kijunSen && + tenkanSenPrev <= kijunSenPrev; + bool isTenkanSenCrossedUnderKijunSen = + tenkanSen < kijunSen && + tenkanSenPrev >= kijunSenPrev; + + // + bool isKumoBullish = + senkouSpanA > senkouSpanB; + bool isKumoBearish = + senkouSpanA < senkouSpanB; + bool isFutureKumoBullish = + senkouSpanAFuture > senkouSpanBFuture; + bool isFutureKumoBearish = + senkouSpanAFuture < senkouSpanBFuture; + bool isKumoSwitchedToBullish = + senkouSpanA > senkouSpanB && + senkouSpanAPrev <= senkouSpanBPrev; + bool isKumoSwitchedToBearish = + senkouSpanA < senkouSpanB && + senkouSpanAPrev >= senkouSpanBPrev; + bool isFutureKumoSwitchedToBullish = + senkouSpanAFuture > senkouSpanBFuture && + senkouSpanAFuturePrev <= senkouSpanBFuturePrev; + bool isFutureKumoSwitchedToBearish = + senkouSpanAFuture < senkouSpanBFuture && + senkouSpanAFuturePrev >= senkouSpanBFuturePrev; + + // + bool isTenkanSenOverSenkouSpanA = + tenkanSen > senkouSpanA; + bool isTenkanSenUnderSenkouSpanA = + tenkanSen < senkouSpanA; + bool isTenkanSenOverFutureSenkouSpanA = + tenkanSen > senkouSpanAFuture; + bool isTenkanSenUnderFutureSenkouSpanA = + tenkanSen < senkouSpanAFuture; + bool isTenkanSenCrossedOverSenkouSpanA = + tenkanSen > senkouSpanA && + tenkanSenPrev <= senkouSpanAPrev; + bool isTenkanSenCrossedUnderSenkouSpanA = + tenkanSen < senkouSpanA && + tenkanSenPrev >= senkouSpanAPrev; + bool isTenkanSenCrossedOverFutureSenkouSpanA = + tenkanSen > senkouSpanAFuture && + tenkanSenPrev <= senkouSpanAFuturePrev; + bool isTenkanSenCrossedUnderFutureSenkouSpanA = + tenkanSen < senkouSpanAFuture && + tenkanSenPrev >= senkouSpanAFuturePrev; + + // + bool isTenkanSenOverSenkouSpanB = + tenkanSen > senkouSpanB; + bool isTenkanSenUnderSenkouSpanB = + tenkanSen < senkouSpanB; + bool isTenkanSenOverFutureSenkouSpanB = + tenkanSen > senkouSpanBFuture; + bool isTenkanSenUnderFutureSenkouSpanB = + tenkanSen < senkouSpanBFuture; + bool isTenkanSenCrossedOverSenkouSpanB = + tenkanSen > senkouSpanB && + tenkanSenPrev <= senkouSpanBPrev; + bool isTenkanSenCrossedUnderSenkouSpanB = + tenkanSen < senkouSpanB && + tenkanSenPrev >= senkouSpanBPrev; + bool isTenkanSenCrossedOverFutureSenkouSpanB = + tenkanSen > senkouSpanBFuture && + tenkanSenPrev <= senkouSpanBFuturePrev; + bool isTenkanSenCrossedUnderFutureSenkouSpanB = + tenkanSen < senkouSpanBFuture && + tenkanSenPrev >= senkouSpanBFuturePrev; + + // + bool isKijunSenOverSenkouSpanA = + kijunSen > senkouSpanA; + bool isKijunSenUnderSenkouSpanA = + kijunSen < senkouSpanA; + bool isKijunSenOverFutureSenkouSpanA = + kijunSen > senkouSpanAFuture; + bool isKijunSenUnderFutureSenkouSpanA = + kijunSen < senkouSpanAFuture; + bool isKijunSenCrossedOverSenkouSpanA = + kijunSen > senkouSpanA && + kijunSenPrev <= senkouSpanAPrev; + bool isKijunSenCrossedUnderSenkouSpanA = + kijunSen < senkouSpanA && + kijunSenPrev >= senkouSpanAPrev; + bool isKijunSenCrossedOverFutureSenkouSpanA = + kijunSen > senkouSpanAFuture && + kijunSenPrev <= senkouSpanAFuturePrev; + bool isKijunSenCrossedUnderFutureSenkouSpanA = + kijunSen < senkouSpanAFuture && + kijunSenPrev >= senkouSpanAFuturePrev; + + // + bool isKijunSenOverSenkouSpanB = + kijunSen > senkouSpanB; + bool isKijunSenUnderSenkouSpanB = + kijunSen < senkouSpanB; + bool isKijunSenOverFutureSenkouSpanB = + kijunSen > senkouSpanBFuture; + bool isKijunSenUnderFutureSenkouSpanB = + kijunSen < senkouSpanBFuture; + bool isKijunSenCrossedOverSenkouSpanB = + kijunSen > senkouSpanB && + kijunSenPrev <= senkouSpanB; + bool isKijunSenCrossedUnderSenkouSpanB = + kijunSen < senkouSpanB && + kijunSenPrev >= senkouSpanB; + bool isKijunSenCrossedOverFutureSenkouSpanB = + kijunSen > senkouSpanBFuture && + kijunSenPrev <= senkouSpanBFuturePrev; + bool isKijunSenCrossedUnderFutureSenkouSpanB = + kijunSen < senkouSpanBFuture && + kijunSenPrev >= senkouSpanBFuturePrev; + + // + result.tenkanSen = tenkanSen; + result.kijunSen = kijunSen; + result.chikouSpan = chikouSpan; + result.senkouSpanA = senkouSpanA; + result.senkouSpanB = senkouSpanB; + result.senkouSpanAFuture = senkouSpanAFuture; + result.senkouSpanBFuture = senkouSpanBFuture; + + // + result.isTenkanSenOverKijunSen = isTenkanSenOverKijunSen; + result.isTenkanSenUnderKijunSen = isTenkanSenUnderKijunSen; + result.isTenkanSenCrossedOverKijunSen = isTenkanSenCrossedOverKijunSen; + result.isTenkanSenCrossedUnderKijunSen = isTenkanSenCrossedUnderKijunSen; + + // + result.isKumoBullish = isKumoBullish; + result.isKumoBearish = isKumoBearish; + result.isFutureKumoBullish = isFutureKumoBullish; + result.isFutureKumoBearish = isFutureKumoBearish; + result.isKumoSwitchedToBullish = isKumoSwitchedToBullish; + result.isKumoSwitchedToBearish = isKumoSwitchedToBearish; + result.isFutureKumoSwitchedToBullish = isFutureKumoSwitchedToBullish; + result.isFutureKumoSwitchedToBearish = isFutureKumoSwitchedToBearish; + + // + result.isTenkanSenOverSenkouSpanA = isTenkanSenOverSenkouSpanA; + result.isTenkanSenUnderSenkouSpanA = isTenkanSenUnderSenkouSpanA; + result.isTenkanSenOverFutureSenkouSpanA = isTenkanSenOverFutureSenkouSpanA; + result.isTenkanSenUnderFutureSenkouSpanA = isTenkanSenUnderFutureSenkouSpanA; + result.isTenkanSenCrossedOverSenkouSpanA = isTenkanSenCrossedOverSenkouSpanA; + result.isTenkanSenCrossedUnderSenkouSpanA = isTenkanSenCrossedUnderSenkouSpanA; + result.isTenkanSenCrossedOverFutureSenkouSpanA = isTenkanSenCrossedOverFutureSenkouSpanA; + result.isTenkanSenCrossedUnderFutureSenkouSpanA = isTenkanSenCrossedUnderFutureSenkouSpanA; + + // + result.isTenkanSenOverSenkouSpanB = isTenkanSenOverSenkouSpanB; + result.isTenkanSenUnderSenkouSpanB = isTenkanSenUnderSenkouSpanB; + result.isTenkanSenOverFutureSenkouSpanB = isTenkanSenOverFutureSenkouSpanB; + result.isTenkanSenUnderFutureSenkouSpanB = isTenkanSenUnderFutureSenkouSpanB; + result.isTenkanSenCrossedOverSenkouSpanB = isTenkanSenCrossedOverSenkouSpanB; + result.isTenkanSenCrossedUnderSenkouSpanB = isTenkanSenCrossedUnderSenkouSpanB; + result.isTenkanSenCrossedOverFutureSenkouSpanB = isTenkanSenCrossedOverFutureSenkouSpanB; + result.isTenkanSenCrossedUnderFutureSenkouSpanB = isTenkanSenCrossedUnderFutureSenkouSpanB; + + // + result.isKijunSenOverSenkouSpanA = isKijunSenOverSenkouSpanA; + result.isKijunSenUnderSenkouSpanA = isKijunSenUnderSenkouSpanA; + result.isKijunSenOverFutureSenkouSpanA = isKijunSenOverFutureSenkouSpanA; + result.isKijunSenUnderFutureSenkouSpanA = isKijunSenUnderFutureSenkouSpanA; + result.isKijunSenCrossedOverSenkouSpanA = isKijunSenCrossedOverSenkouSpanA; + result.isKijunSenCrossedUnderSenkouSpanA = isKijunSenCrossedUnderSenkouSpanA; + result.isKijunSenCrossedOverFutureSenkouSpanA = isKijunSenCrossedOverFutureSenkouSpanA; + result.isKijunSenCrossedUnderFutureSenkouSpanA = isKijunSenCrossedUnderFutureSenkouSpanA; + + // + result.isKijunSenOverSenkouSpanB = isKijunSenOverSenkouSpanB; + result.isKijunSenUnderSenkouSpanB = isKijunSenUnderSenkouSpanB; + result.isKijunSenOverFutureSenkouSpanB = isKijunSenOverFutureSenkouSpanB; + result.isKijunSenUnderFutureSenkouSpanB = isKijunSenUnderFutureSenkouSpanB; + result.isKijunSenCrossedOverSenkouSpanB = isKijunSenCrossedOverSenkouSpanB; + result.isKijunSenCrossedUnderSenkouSpanB = isKijunSenCrossedUnderSenkouSpanB; + result.isKijunSenCrossedOverFutureSenkouSpanB = isKijunSenCrossedOverFutureSenkouSpanB; + result.isKijunSenCrossedUnderFutureSenkouSpanB = isKijunSenCrossedUnderFutureSenkouSpanB; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // TENKANSEN ... + // + // Length ... + int mTenkanSenLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mTenkanSenMode; + // + // KIJUNSEN ... + // + // Length ... + int mKijunSenLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mKijunSenMode; + // + // SENKOUSPANB ... + // + // Length ... + int mSenkouSpanBLength; + // + // Calculation Mode ... + ENUM_X_ICHIMOKU_CALCULATION_MODE mSenkouSpanBMode; + // + // CHIKOUSPAN ... + // + // Price Type ... + ENUM_APPLIED_PRICE mChikuoSpanAppliedTo; + // + // Presentation ... + // + // Show Tenkan Sen ... + bool mShowTenkanSen; + // + // Show Kijun Sen ... + bool mShowKijunSen; + // + // Show Kijun Sen + ... + bool mShowKijunSenPlus; + // + // Show Kijun Sen - ... + bool mShowKijunSenNegative; + // + // Show Chikou Span ... + bool mShowChikouSpan; + // + // Show Senkou Span A ... + bool mShowSenkouSpanA; + // + // Show Senkou Span B ... + bool mShowSenkouSpanB; + // + // Show Kumo ... + bool mShowKumo; + // + // Shift Kumo to Future ... + bool mShiftKumo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 new file mode 100644 index 0000000..5ca9f84 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xmrb.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 new file mode 100644 index 0000000..e36b74d --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xmrb.helper.class.mq5 @@ -0,0 +1,849 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMRBHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XMRBInputs +{ + // + // Ribbon 1 ... + int fast1Length; // Fast + int slow1Length; // Slow + + // + // Ribbon 2 ... + int fast2Length; // Fast + int slow2Length; // Slow + + // + // Ribbon 3 ... + int fast3Length; // Fast + int slow3Length; // Slow + + // + // Ribbon 4 ... + int fast4Length; // Fast + int slow4Length; // Slow + + // + // Ribbon 5 ... + int fast5Length; // Fast + int slow5Length; // Slow + + // + // Calculation ... + ENUM_MA_METHOD ribbonMode; // Mode + ENUM_APPLIED_PRICE ribbonAppliedTo; // Applied To + + // + // Presentation ... + bool showFastMa; // Show Fast + bool showSlowMa; // Show Slow + bool showRibbon; // Show Ribbon +}; + +// +// Index of Lines ... +enum ENUM_XMRB_BUFFERS +{ + // + // Main Requirements ... + XMRB_FAST_LINE = 0, + XMRB_SLOW_LINE = 1, + // + // RIBBON 1 ... + XMRB_R1_FAST_LINE = 2, + XMRB_R1_SLOW_LINE = 3, + // + // RIBBON 2 ... + XMRB_R2_FAST_LINE = 4, + XMRB_R2_SLOW_LINE = 5, + // + // RIBBON 3 ... + XMRB_R3_FAST_LINE = 6, + XMRB_R3_SLOW_LINE = 7, + // + // RIBBON 4 ... + XMRB_R4_FAST_LINE = 8, + XMRB_R4_SLOW_LINE = 9, + // + // RIBBON 5 ... + XMRB_R5_FAST_LINE = 10, + XMRB_R5_SLOW_LINE = 11, +}; + +// +// Retrieve Info Model ... +struct XMRBInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double fast; + double slow; + double fastR1; + double slowR1; + double fastR2; + double slowR2; + double fastR3; + double slowR3; + double fastR4; + double slowR4; + double fastR5; + double slowR5; + + // + // Conditions ... + + // + bool isFastOverSlow; + bool isFastCrossedOverSlow; + bool isFastUnderSlow; + bool isFastCrossedUnderSlow; + + // + bool isR1FastOverSlow; + bool isR1FastCrossedOverSlow; + bool isR1FastUnderSlow; + bool isR1FastCrossedUnderSlow; + + // + bool isR2FastOverSlow; + bool isR2FastCrossedOverSlow; + bool isR2FastUnderSlow; + bool isR2FastCrossedUnderSlow; + + // + bool isR3FastOverSlow; + bool isR3FastCrossedOverSlow; + bool isR3FastUnderSlow; + bool isR3FastCrossedUnderSlow; + + // + bool isR4FastOverSlow; + bool isR4FastCrossedOverSlow; + bool isR4FastUnderSlow; + bool isR4FastCrossedUnderSlow; + + // + bool isR5FastOverSlow; + bool isR5FastCrossedOverSlow; + bool isR5FastUnderSlow; + bool isR5FastCrossedUnderSlow; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXMRBHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double fastBuffer[]; + double slowBuffer[]; + double fastR1Buffer[]; + double slowR1Buffer[]; + double fastR2Buffer[]; + double slowR2Buffer[]; + double fastR3Buffer[]; + double slowR3Buffer[]; + double fastR4Buffer[]; + double slowR4Buffer[]; + double fastR5Buffer[]; + double slowR5Buffer[]; + + // + // Constructor ... + void XSCXMRBHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXMRBHelper() + { + } + + // + // START Properties ... + // + + // + // Show Fast ... + bool ShowFast( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowFastMa == show) + { + return true; + } + + // + mShowFastMa = show; + result = Init(); + + // + return result; + } + + // + // Show Slow ... + bool ShowSlow( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowSlowMa == show) + { + return true; + } + + // + mShowSlowMa = show; + result = Init(); + + // + return result; + } + + // + // Show Ribbon ... + bool ShowRibbon( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowRibbon == show) + { + return true; + } + + // + mShowRibbon = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XMRB" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(mFast1Length, mFast2Length); + result = MathMax(result, mFast3Length); + result = MathMax(result, mFast4Length); + result = MathMax(result, mFast5Length); + + // + result = MathMax(result, mSlow1Length); + result = MathMax(result, mSlow2Length); + result = MathMax(result, mSlow3Length); + result = MathMax(result, mSlow4Length); + result = MathMax(result, mSlow5Length); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + result = + // + (mFast1Length > 2 && + mFast2Length > mFast1Length && + mFast3Length > mFast2Length && + mFast4Length > mFast3Length && + mFast5Length > mFast4Length && + mSlow1Length > mFast1Length && + mSlow2Length > mFast2Length && + mSlow3Length > mFast3Length && + mSlow4Length > mFast4Length && + mSlow5Length > mFast5Length && + mSlow2Length > mSlow1Length && + mSlow3Length > mSlow2Length && + mSlow4Length > mSlow3Length && + mSlow5Length > mSlow4Length + // + ) + // + ; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xmrb", + // + // Inputs ... + // + // Ribbon 1 ... + "", + mFast1Length, + mSlow1Length, + // + // Ribbon 2 ... + "", + mFast2Length, + mSlow2Length, + // + // Ribbon 3 ... + "", + mFast3Length, + mSlow3Length, + // + // Ribbon 4 ... + "", + mFast4Length, + mSlow4Length, + // + // Ribbon 5 ... + "", + mFast5Length, + mSlow5Length, + // + // Calculation ... + "", + // + // Mode ... + mRibbonMode, + // + // Applied To ... + mRibbonAppliedTo, + // + // Presentation ... + "", + // + // Show Fast ... + mShowFastMa, + // + // Show Slow ... + mShowSlowMa, + // + // Show Ribbon ... + mShowRibbon + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XMRBInputs GetConfig() + { + // + XMRBInputs result; + + // + result.fast1Length = mFast1Length; + result.slow1Length = mSlow1Length; + result.fast2Length = mFast2Length; + result.slow2Length = mSlow2Length; + result.fast3Length = mFast3Length; + result.slow3Length = mSlow3Length; + result.fast4Length = mFast4Length; + result.slow4Length = mSlow4Length; + result.fast5Length = mFast5Length; + result.slow5Length = mSlow5Length; + result.ribbonMode = mRibbonMode; + result.ribbonAppliedTo = mRibbonAppliedTo; + result.showFastMa = mShowFastMa; + result.showSlowMa = mShowSlowMa; + result.showRibbon = mShowRibbon; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XMRBInputs &config) + { + // + bool result = false; + + // + mFast1Length = config.fast1Length; + mSlow1Length = config.slow1Length; + mFast2Length = config.fast2Length; + mSlow2Length = config.slow2Length; + mFast3Length = config.fast3Length; + mSlow3Length = config.slow3Length; + mFast4Length = config.fast4Length; + mSlow4Length = config.slow4Length; + mFast5Length = config.fast5Length; + mSlow5Length = config.slow5Length; + mRibbonMode = config.ribbonMode; + mRibbonAppliedTo = config.ribbonAppliedTo; + mShowFastMa = config.showFastMa; + mShowSlowMa = config.showSlowMa; + mShowRibbon = config.showRibbon; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // FAST ... + ArraySetAsSeries(fastBuffer, true); + CopyBuffer( + mHandler, + XMRB_FAST_LINE, + barIndex, + mLoopbackBars, + fastBuffer); + + // + // SLOW ... + ArraySetAsSeries(slowBuffer, true); + CopyBuffer( + mHandler, + XMRB_SLOW_LINE, + barIndex, + mLoopbackBars, + slowBuffer); + + // + // RIBBON 1 ... + + // + // FAST ... + ArraySetAsSeries(fastR1Buffer, true); + CopyBuffer( + mHandler, + XMRB_R1_FAST_LINE, + barIndex, + mLoopbackBars, + fastR1Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR1Buffer, true); + CopyBuffer( + mHandler, + XMRB_R1_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR1Buffer); + + // + // RIBBON 2 ... + + // + // FAST ... + ArraySetAsSeries(fastR2Buffer, true); + CopyBuffer( + mHandler, + XMRB_R2_FAST_LINE, + barIndex, + mLoopbackBars, + fastR2Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR2Buffer, true); + CopyBuffer( + mHandler, + XMRB_R2_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR2Buffer); + + // + // RIBBON 3 ... + + // + // FAST ... + ArraySetAsSeries(fastR3Buffer, true); + CopyBuffer( + mHandler, + XMRB_R3_FAST_LINE, + barIndex, + mLoopbackBars, + fastR3Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR3Buffer, true); + CopyBuffer( + mHandler, + XMRB_R3_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR3Buffer); + + // + // RIBBON 4 ... + + // + // FAST ... + ArraySetAsSeries(fastR4Buffer, true); + CopyBuffer( + mHandler, + XMRB_R4_FAST_LINE, + barIndex, + mLoopbackBars, + fastR4Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR4Buffer, true); + CopyBuffer( + mHandler, + XMRB_R4_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR4Buffer); + + // + // RIBBON 5 ... + + // + // FAST ... + ArraySetAsSeries(fastR5Buffer, true); + CopyBuffer( + mHandler, + XMRB_R5_FAST_LINE, + barIndex, + mLoopbackBars, + fastR5Buffer); + + // + // SLOW ... + ArraySetAsSeries(slowR5Buffer, true); + CopyBuffer( + mHandler, + XMRB_R5_SLOW_LINE, + barIndex, + mLoopbackBars, + slowR5Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XMRBInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XMRBInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double fast = fastBuffer[barIndex]; + double fastPrev = fastBuffer[barIndex + 1]; + double slow = slowBuffer[barIndex]; + double slowPrev = slowBuffer[barIndex + 1]; + double fastR1 = fastR1Buffer[barIndex]; + double fastR1Prev = fastR1Buffer[barIndex + 1]; + double slowR1 = slowR1Buffer[barIndex]; + double slowR1Prev = slowR1Buffer[barIndex + 1]; + double fastR2 = fastR2Buffer[barIndex]; + double fastR2Prev = fastR2Buffer[barIndex + 1]; + double slowR2 = slowR2Buffer[barIndex]; + double slowR2Prev = slowR2Buffer[barIndex + 1]; + double fastR3 = fastR3Buffer[barIndex]; + double fastR3Prev = fastR3Buffer[barIndex + 1]; + double slowR3 = slowR3Buffer[barIndex]; + double slowR3Prev = slowR3Buffer[barIndex + 1]; + double fastR4 = fastR4Buffer[barIndex]; + double fastR4Prev = fastR4Buffer[barIndex + 1]; + double slowR4 = slowR4Buffer[barIndex]; + double slowR4Prev = slowR4Buffer[barIndex + 1]; + double fastR5 = fastR5Buffer[barIndex]; + double fastR5Prev = fastR5Buffer[barIndex + 1]; + double slowR5 = slowR5Buffer[barIndex]; + double slowR5Prev = slowR5Buffer[barIndex + 1]; + + // + result.fast = fast; + result.slow = slow; + result.fastR1 = fastR1; + result.slowR1 = slowR1; + result.fastR2 = fastR2; + result.slowR2 = slowR2; + result.fastR3 = fastR3; + result.slowR3 = slowR3; + result.fastR4 = fastR4; + result.slowR4 = slowR4; + result.fastR5 = fastR5; + result.slowR5 = slowR5; + + // + result.isFastOverSlow = + fast > slow; + result.isFastCrossedOverSlow = + fast > slow && fastPrev <= slowPrev; + result.isFastUnderSlow = + fast < slow; + result.isFastCrossedUnderSlow = + fast < slow && fastPrev >= slowPrev; + + // + result.isR1FastOverSlow = + fastR1 > slowR1; + result.isR1FastCrossedOverSlow = + fastR1 > slowR1 && fastR1Prev <= slowR1Prev; + result.isR1FastUnderSlow = + fastR1 < slowR1; + result.isR1FastCrossedUnderSlow = + fastR1 < slowR1 && fastR1Prev >= slowR1Prev; + + // + result.isR2FastOverSlow = + fastR2 > slowR2; + result.isR2FastCrossedOverSlow = + fastR2 > slowR2 && fastR2Prev <= slowR2Prev; + result.isR2FastUnderSlow = + fastR2 < slowR2; + result.isR2FastCrossedUnderSlow = + fastR2 < slowR2 && fastR2Prev >= slowR2Prev; + + // + result.isR3FastOverSlow = + fastR3 > slowR3; + result.isR3FastCrossedOverSlow = + fastR3 > slowR3 && fastR3Prev <= slowR3Prev; + result.isR3FastUnderSlow = + fastR3 < slowR3; + result.isR3FastCrossedUnderSlow = + fastR3 < slowR3 && fastR3Prev >= slowR3Prev; + + // + result.isR4FastOverSlow = + fastR4 > slowR4; + result.isR4FastCrossedOverSlow = + fastR4 > slowR4 && fastR4Prev <= slowR4Prev; + result.isR4FastUnderSlow = + fastR4 < slowR4; + result.isR4FastCrossedUnderSlow = + fastR4 < slowR4 && fastR4Prev >= slowR4Prev; + + // + result.isR5FastOverSlow = + fastR5 > slowR5; + result.isR5FastCrossedOverSlow = + fastR5 > slowR5 && fastR5Prev <= slowR5Prev; + result.isR5FastUnderSlow = + fastR5 < slowR5; + result.isR5FastCrossedUnderSlow = + fastR5 < slowR5 && fastR5Prev >= slowR5Prev; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Ribbon 1 ... + int mFast1Length; + int mSlow1Length; + // + // Ribbon 2 ... + int mFast2Length; + int mSlow2Length; + // + // Ribbon 3 ... + int mFast3Length; + int mSlow3Length; + // + // Ribbon 4 ... + int mFast4Length; + int mSlow4Length; + // + // Ribbon 5 ... + int mFast5Length; + int mSlow5Length; + // + // Calculation ... + // + // Mode ... + ENUM_MA_METHOD mRibbonMode; + // + // Applied To ... + ENUM_APPLIED_PRICE mRibbonAppliedTo; + // + // Presentation ... + // + // Show Fast ... + bool mShowFastMa; + // + // Show Slow ... + bool mShowSlowMa; + // + // Show Ribbon ... + bool mShowRibbon; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xpv.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xpv.helper.class.ex5 new file mode 100644 index 0000000..51d7a2d Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xpv.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xpv.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xpv.helper.class.mq5 new file mode 100644 index 0000000..84bf965 --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xpv.helper.class.mq5 @@ -0,0 +1,644 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXPVHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XPVInputs +{ + // + // Makret Cycles ... + int shortLength; // Short Length + int mediumLength; // Medium Length + int longLength; // Long Length + int hindLength; // Hind Length + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + + // + // Detection Modes ... + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Presentation ... + bool showPeaksAndVales; // Show Peaks and Vales + bool showLevels; // Show Levels + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level +}; + +// +// Index of Lines ... +enum ENUM_XPV_BUFFERS +{ + // + // Main Requirements ... + XPV_PEAKS_LINE = 0, + XPV_VALES_LINE = 1, + XPV_FL1_LINE = 6, + XPV_FL2_LINE = 8, + XPV_FL3_LINE = 10, +}; + +// +// Retrieve Info Model ... +struct XPVInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double peak; + double vale; + double fl1; + double fl2; + double fl3; + + // + // Conditions ... + + // + // Determines New Peaks Happens ... + bool isNewPeak; + + // + // Determines New Vales Happens ... + bool isNewVale; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXPVHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double peaksBuffer[]; + double valesBuffer[]; + double fl1Buffer[]; + double fl2Buffer[]; + double fl3Buffer[]; + + // + // Constructor ... + void XSCXPVHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXPVHelper() + { + } + + // + // START Properties ... + // + + // + // Show Levels ... + bool ShowLevels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowLevels == show) + { + return true; + } + + // + mShowLevels = show; + result = Init(); + + // + return result; + } + + // + // Show Peaks and Vales ... + bool ShowPeaksAnVales( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowPeaksAndVales == show) + { + return true; + } + + // + mShowPeaksAndVales = show; + result = Init(); + + // + return result; + } + + // + // Show Fibo 1st Level ... + bool ShowFibo1Levels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowFibo1Levels == show) + { + return true; + } + + // + mShowFibo1Levels = show; + result = Init(); + + // + return result; + } + + // + // Show Fibo 2nd Level ... + bool ShowFibo2Levels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowFibo2Levels == show) + { + return true; + } + + // + mShowFibo2Levels = show; + result = Init(); + + // + return result; + } + + // + // Show Fibo 3rd Level ... + bool ShowFibo3Levels( + bool show // Show or Hide Levels + ) + { + // + bool result = false; + + // + if (mShowFibo3Levels == show) + { + return true; + } + + // + mShowFibo3Levels = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XPV" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(mShortLength, mMediumLength); + result = MathMax(result, mLongLength); + result = MathMax(result, mHindLength); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mShortLength > 2 && + mMediumLength > mShortLength && + mLongLength > mMediumLength && + mHindLength > mLongLength) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xpv", + // + // Inputs ... + // + // Market ... + "", + // + // Short Length ... + mShortLength, + // + // Medium Length + mMediumLength, + // + // Long Length ... + mLongLength, + // + // Hind Length ... + mHindLength, + // + // Fibio 1st Level ... + mFiboLevel1, + // + // Fibio 2st Level ... + mFiboLevel2, + // + // Fibio 3rd Level ... + mFiboLevel3, + // + // Detection Mode ... + "", + // + // Highest High Calculation Method ... + mHHMode, + // + // Lowest Low Calculation Method ... + mLLMode, + // + // Presentations ... + "", + // + // Show Peaks and Vales ... + mShowPeaksAndVales, + // + // Show Levels ... + mShowLevels, + // + // Show Fibo 1st Level ... + mShowFibo1Levels, + // + // Show Fibo 2nd Level ... + mShowFibo2Levels, + // + // Show Fibo 3rd Level ... + mShowFibo3Levels + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XPVInputs GetConfig() + { + // + XPVInputs result; + + // + result.shortLength = mShortLength; + result.mediumLength = mMediumLength; + result.longLength = mLongLength; + result.hindLength = mHindLength; + result.fiboLevel1 = mFiboLevel1; + result.fiboLevel2 = mFiboLevel2; + result.fiboLevel3 = mFiboLevel3; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.showPeaksAndVales = mShowPeaksAndVales; + result.showLevels = mShowLevels; + result.showFibo1Levels = mShowFibo1Levels; + result.showFibo2Levels = mShowFibo2Levels; + result.showFibo3Levels = mShowFibo3Levels; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XPVInputs &config) + { + // + bool result = false; + + // + mShortLength = config.shortLength; + mMediumLength = config.mediumLength; + mLongLength = config.longLength; + mHindLength = config.hindLength; + mFiboLevel1 = config.fiboLevel1; + mFiboLevel2 = config.fiboLevel2; + mFiboLevel3 = config.fiboLevel3; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mShowPeaksAndVales = config.showPeaksAndVales; + mShowLevels = config.showLevels; + mShowFibo1Levels = config.showFibo1Levels; + mShowFibo2Levels = config.showFibo2Levels; + mShowFibo3Levels = config.showFibo3Levels; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + CopyBuffer( + mHandler, + XPV_PEAKS_LINE, + barIndex, + mLoopbackBars, + peaksBuffer); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + CopyBuffer( + mHandler, + XPV_VALES_LINE, + barIndex, + mLoopbackBars, + valesBuffer); + + // + // FIBBO LEVELS ... + + // + // LEVEL 1 ... + ArraySetAsSeries(fl1Buffer, true); + CopyBuffer( + mHandler, + XPV_FL1_LINE, + barIndex, + mLoopbackBars, + fl1Buffer); + + // + // LEVEL 2 ... + ArraySetAsSeries(fl2Buffer, true); + CopyBuffer( + mHandler, + XPV_FL2_LINE, + barIndex, + mLoopbackBars, + fl2Buffer); + + // + // LEVEL 3 ... + ArraySetAsSeries(fl3Buffer, true); + CopyBuffer( + mHandler, + XPV_FL3_LINE, + barIndex, + mLoopbackBars, + fl3Buffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XPVInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XPVInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.peak = peaksBuffer[barIndex]; + result.vale = valesBuffer[barIndex]; + result.fl1 = fl1Buffer[barIndex]; + result.fl2 = fl2Buffer[barIndex]; + result.fl3 = fl3Buffer[barIndex]; + + // + result.isNewPeak = + peaksBuffer[barIndex] != peaksBuffer[barIndex + 1]; + result.isNewVale = + valesBuffer[barIndex] != valesBuffer[barIndex + 1]; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Short Length ... + int mShortLength; + // + // Medium Length + int mMediumLength; + // + // Long Length ... + int mLongLength; + // + // Hind Length ... + int mHindLength; + // + // Fibio 1st Level ... + double mFiboLevel1; + // + // Fibio 2st Level ... + double mFiboLevel2; + // + // Fibio 3rd Level ... + double mFiboLevel3; + // + // Detection Mode ... + // + // Highest High Calculation Method ... + ENUM_SERIESMODE mHHMode; + // + // Lowest Low Calculation Method ... + ENUM_SERIESMODE mLLMode; + // + // Presentations ... + // + // Show Peaks and Vales ... + bool mShowPeaksAndVales; + // + // Show Levels ... + bool mShowLevels; + // + // Show Fibo 1st Level ... + bool mShowFibo1Levels; + // + // Show Fibo 2nd Level ... + bool mShowFibo2Levels; + // + // Show Fibo 3rd Level ... + bool mShowFibo3Levels; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 new file mode 100644 index 0000000..f008b68 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xsslc.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 new file mode 100644 index 0000000..53631dc --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xsslc.helper.class.mq5 @@ -0,0 +1,473 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXSSLCHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XSSLCInputs +{ + // + // Market ... + int length; // Length + + // + // Calculation ... + ENUM_MA_METHOD method; // Method + ENUM_APPLIED_PRICE upAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE downAppliedTo; // Down Applied To + + // + // Presentation ... + bool showUp; // Show Up + bool showDown; // Show Down +}; + +// +// Index of Lines ... +enum ENUM_XSSLC_BUFFERS +{ + // + // Main Requirements ... + XSSLC_UP_LINE = 0, + XSSLC_DOWN_LINE = 1, +}; + +// +// Retrieve Info Model ... +struct XSSLCInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double up; + double down; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXSSLCHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double upBuffer[]; + double downBuffer[]; + + // + // Constructor ... + void XSCXSSLCHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXSSLCHelper() + { + } + + // + // START Properties ... + // + + // + // Show Up ... + bool ShowUp( + bool show // Show or Hide Line + ) + { + // + bool result = false; + + // + if (mShowUp == show) + { + return true; + } + + // + mShowUp = show; + result = Init(); + + // + return result; + } + + // + // Show Down ... + bool ShowDown( + bool show // Show or Hide Line + ) + { + // + bool result = false; + + // + if (mShowDown == show) + { + return true; + } + + // + mShowDown = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XSSLC" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xsslc", + // + // Inputs ... + // + // Market ... + "", + // + // Length ... + mLength, + // + // Calculation ... + "", + // + // Method ... + mMethod, + // + // Up Applied To ... + mUpAppliedTo, + // + // Down Applied To ... + mDownAppliedTo, + // + // Presentation ... + "", + // + // Show Up ... + mShowUp, + // + // Show Down ... + mShowDown + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XSSLCInputs GetConfig() + { + // + XSSLCInputs result; + + // + result.length = mLength; + result.method = mMethod; + result.upAppliedTo = mUpAppliedTo; + result.downAppliedTo = mDownAppliedTo; + result.showUp = mShowUp; + result.showDown = mShowDown; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XSSLCInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mMethod = config.method; + mUpAppliedTo = config.upAppliedTo; + mDownAppliedTo = config.downAppliedTo; + mShowUp = config.showUp; + mShowDown = config.showDown; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // UP ... + ArraySetAsSeries(upBuffer, true); + CopyBuffer( + mHandler, + XSSLC_UP_LINE, + barIndex, + mLoopbackBars, + upBuffer); + + // + // DOWN ... + ArraySetAsSeries(downBuffer, true); + CopyBuffer( + mHandler, + XSSLC_DOWN_LINE, + barIndex, + mLoopbackBars, + downBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XSSLCInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XSSLCInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double up = upBuffer[barIndex]; + double upPrev = upBuffer[barIndex + 1]; + double down = downBuffer[barIndex]; + double downPrev = downBuffer[barIndex + 1]; + + // + result.up = up; + result.down = down; + + // + result.isBullish = up > down; + result.isBearish = up < down; + + // + result.isSwitchedBullish = + up > down && + upPrev <= downPrev; + result.isSwitchedBearish = + up < down && + upPrev >= downPrev; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Length ... + int mLength; + // + // Calculation ... + // + // Method ... + ENUM_MA_METHOD mMethod; + // + // Up Applied To ... + ENUM_APPLIED_PRICE mUpAppliedTo; + // + // Down Applied To ... + ENUM_APPLIED_PRICE mDownAppliedTo; + // + // Presentation ... + // + // Show Up ... + bool mShowUp; + // + // Show Down ... + bool mShowDown; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xtm.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtm.helper.class.ex5 new file mode 100644 index 0000000..ffd3df0 Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtm.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xtm.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtm.helper.class.mq5 new file mode 100644 index 0000000..2039b6e --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtm.helper.class.mq5 @@ -0,0 +1,439 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTMHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// Inputs ... +struct XTMInputs +{ + // + // Makret ... + int length; // Length + int shift; // Shift + + // + // Calculations ... + ENUM_MA_METHOD method; // Method + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Presentation ... + bool showLine; // Show Line +}; + +// +// Index of Lines ... +enum ENUM_XTM_BUFFERS +{ + // + // Main Requirements ... + XTM_LINE = 0, + XTM_STATE_LINE = 1, +}; + +// +// XTM Indicator States ... +enum ENUM_XTM_STATES +{ + X_XTM_BULLISH = 0, + X_XTM_BEARISH = 2, + X_XTM_NEUTURAL = 1, +}; + +// +// Retrieve Info Model ... +struct XTMInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double value; + + // + // State ... + ENUM_XTM_STATES state; + + // + // Conditions ... + + // + // Detect Trend is Bullish or not ... + bool isBullish; + + // + // Detect Trend is Switched to Bullish Or not ... + bool isSwitchedBullish; + + // + // Detect Trend is Bearish or not ... + bool isBearish; + + // + // Detect Trend is Switched to Bearish Or not ... + bool isSwitchedBearish; + + // + // Detect Trend is Neutural or not ... + bool isNeutural; + + // + // Detect Trend is Switched to Neutural Or not ... + bool isSwitchedNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXTMHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double valueBuffer[]; + double stateBuffer[]; + + // + // Constructor ... + void XSCXTMHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXTMHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XTM" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = mLength; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + (mLength >= 2) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xtm", + // + // Inputs ... + // + // Makret ... + "", + // + // Length ... + mLength, + // + // Shift ... + mShift, + // + // Calculations ... + "", + // + // Method ... + mMethod, + // + // Applied To ... + mAppliedTo, + // + // Presentation ... + "", + // + // Show Line ... + mShowLine + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XTMInputs GetConfig() + { + // + XTMInputs result; + + // + result.length = mLength; + result.shift = mShift; + result.method = mMethod; + result.appliedTo = mAppliedTo; + result.showLine = mShowLine; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XTMInputs &config) + { + // + bool result = false; + + // + mLength = config.length; + mShift = config.shift; + mMethod = config.method; + mAppliedTo = config.appliedTo; + mShowLine = config.showLine; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // VALUE ... + ArraySetAsSeries(valueBuffer, true); + CopyBuffer( + mHandler, + XTM_LINE, + barIndex, + mLoopbackBars, + valueBuffer); + + // + // STATE ... + ArraySetAsSeries(stateBuffer, true); + CopyBuffer( + mHandler, + XTM_STATE_LINE, + barIndex, + mLoopbackBars, + stateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XTMInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XTMInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + result.value = valueBuffer[barIndex]; + + // + ENUM_XTM_STATES state = (ENUM_XTM_STATES)stateBuffer[barIndex]; + ENUM_XTM_STATES prevState = (ENUM_XTM_STATES)stateBuffer[barIndex + 1]; + result.state = state; + + // + result.isBullish = state == X_XTM_BULLISH; + result.isBearish = state == X_XTM_BEARISH; + result.isNeutural = state == X_XTM_NEUTURAL; + + // + result.isSwitchedBullish = + state == X_XTM_BULLISH && prevState != X_XTM_BULLISH; + result.isSwitchedBearish = + state == X_XTM_BEARISH && prevState != X_XTM_BEARISH; + result.isSwitchedNeutural = + state == X_XTM_NEUTURAL && prevState != X_XTM_NEUTURAL; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Makret ... + // + // Length ... + int mLength; + // + // Shift ... + int mShift; + + // + // Calculations ... + // + // Method ... + ENUM_MA_METHOD mMethod; + // + // Applied To ... + ENUM_APPLIED_PRICE mAppliedTo; + + // + // Presentation ... + // + // Show Line ... + bool mShowLine; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 new file mode 100644 index 0000000..9e613de Binary files /dev/null and b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtrnd.helper.class.ex5 differ diff --git a/MQLTestWorkspace/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 new file mode 100644 index 0000000..5aa9c24 --- /dev/null +++ b/MQLTestWorkspace/Helpers/x-saherelm.x121.xtrnd.helper.class.mq5 @@ -0,0 +1,1074 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXTRNDHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// 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 Definitions ... +// + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// Inputs ... +struct XTRNDInputs +{ + // + // Makret ... + int cycleLength; // Cycle Length to Check + int numberOfVerifications; // Number of Verifications + + // + // Calculation ... + ENUM_SERIESMODE hhMode; // Detect Up + ENUM_SERIESMODE llMode; // Detect Low + + // + // Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period + + // + // Presentation ... + bool showConsolidations; // Show Consolidations + bool showTrend; // Show Trend + bool showL1Trend; // Show Cycle 1 Trend + bool showL2Trend; // Show Cycle 2 Trend + bool showL3Trend; // Show Cycle 3 Trend +}; + +// +// Index of Lines ... +enum ENUM_XTRND_BUFFERS +{ + // + // Main Requirements ... + XTRND_UP_LINE = 0, + XTRND_UP_STATE_LINE = 16, + XTRND_DOWN_LINE = 2, + XTRND_DOWN_STATE_LINE = 17, + // + // LEVEL 1 ... + XTRND_L1_UP_LINE = 4, + XTRND_L1_UP_STATE_LINE = 18, + XTRND_L1_DOWN_LINE = 6, + XTRND_L1_DOWN_STATE_LINE = 19, + // + // LEVEL 2 ... + XTRND_L2_UP_LINE = 8, + XTRND_L2_UP_STATE_LINE = 20, + XTRND_L2_DOWN_LINE = 10, + XTRND_L2_DOWN_STATE_LINE = 21, + // + // LEVEL 3 ... + XTRND_L3_UP_LINE = 12, + XTRND_L3_UP_STATE_LINE = 22, + XTRND_L3_DOWN_LINE = 14, + XTRND_L3_DOWN_STATE_LINE = 23, +}; + +// +enum ENUM_XTRND_STATES +{ + XTRND_STATE_BULLISH = 1, + XTRND_STATE_BEARISH = 2, + XTRND_STATE_CONSOLIDATION = 0, +}; + +// +// Retrieve Info Model ... +struct XTRNDInfo +{ + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // Values ... + double hh; + ENUM_XTRND_STATES hhState; + double ll; + double llState; + double l1hh; + ENUM_XTRND_STATES l1hhState; + double l1ll; + ENUM_XTRND_STATES l1llState; + double l2hh; + ENUM_XTRND_STATES l2hhState; + double l2ll; + ENUM_XTRND_STATES l2llState; + double l3hh; + ENUM_XTRND_STATES l3hhState; + double l3ll; + ENUM_XTRND_STATES l3llState; + + // + // Conditions ... + // + bool isTrendBullish; + bool isTrendSwitchedToBullish; + bool isTrendBearish; + bool isTrendSwitchedToBearish; + bool isTrendConsolidation; + bool isTrendSwitchedToConsolidation; + + // + bool isL1TrendBullish; + bool isL1TrendSwitchedToBullish; + bool isL1TrendBearish; + bool isL1TrendSwitchedToBearish; + bool isL1TrendConsolidation; + bool isL1TrendSwitchedToConsolidation; + + // + bool isL2TrendBullish; + bool isL2TrendSwitchedToBullish; + bool isL2TrendBearish; + bool isL2TrendSwitchedToBearish; + bool isL2TrendConsolidation; + bool isL2TrendSwitchedToConsolidation; + + // + bool isL3TrendBullish; + bool isL3TrendSwitchedToBullish; + bool isL3TrendBearish; + bool isL3TrendSwitchedToBearish; + bool isL3TrendConsolidation; + bool isL3TrendSwitchedToConsolidation; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Helping Indicators Requirements ... +class XSCXTRNDHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Buffers ... + double hhBuffer[]; + double hhStateBuffer[]; + double llBuffer[]; + double llStateBuffer[]; + double l1hhBuffer[]; + double l1hhStateBuffer[]; + double l1llBuffer[]; + double l1llStateBuffer[]; + double l2hhBuffer[]; + double l2hhStateBuffer[]; + double l2llBuffer[]; + double l2llStateBuffer[]; + double l3hhBuffer[]; + double l3hhStateBuffer[]; + double l3llBuffer[]; + double l3llStateBuffer[]; + + // + // Constructor ... + void XSCXTRNDHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXTRNDHelper() + { + } + + // + // START Properties ... + // + + // + // Show Trend ... + bool ShowTrend( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowTrend == show) + { + return true; + } + + // + mShowTrend = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 1 Trend ... + bool ShowL1Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL1Trends == show) + { + return true; + } + + // + mShowL1Trends = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 2 Trend ... + bool ShowL2Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL2Trends == show) + { + return true; + } + + // + mShowL2Trends = show; + result = Init(); + + // + return result; + } + + // + // Show Cycle 3 Trend ... + bool ShowL3Trends( + bool show // Show or Hide + ) + { + // + bool result = false; + + // + if (mShowL3Trends == show) + { + return true; + } + + // + mShowL3Trends = show; + result = Init(); + + // + return result; + } + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XTRND" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax( + mCycleLength, + mNumberOfVerifications); + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Inputs ... + // + // + result = + // + (mCycleLength > 0 && + mNumberOfVerifications > 0) + // + ; + if (!result) + { + return result; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xtrnd", + // + // Inputs ... + // + // Market ... + "", + // + // Cycle Length to Check ... + mCycleLength, + // + // Number of Verifications ... + mNumberOfVerifications, + // + // Calculations ... + "", + // + // Detect Up ... + mHHMode, + // + // Detect Low ... + mLLMode, + // + // Cycles ... + "", + // + // LEVEL 1 ... + "", + // + // How to Find Period ... + mLLMethod, + // + // Time Period ... + mL1Period, + // + // LEVEL 2 ... + "", + // + // How to Find Period ... + mL2Method, + // + // Time Period ... + mL2Period, + // + // LEVEL 3 ... + "", + // + // How to Find Period ... + mL3Method, + // + // Time Period ... + mL3Period, + // + // Presentation ... + "", + // + // Show Consolidations ... + mShowConsolidations, + // + // Show Trend ... + mShowTrend, + // + // Show Cycle 1 Trend ... + mShowL1Trends, + // + // Show Cycle 2 Trend ... + mShowL2Trends, + // + // Show Cycle 3 Trend ... + mShowL3Trends + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XTRNDInputs GetConfig() + { + // + XTRNDInputs result; + + // + result.cycleLength = mCycleLength; + result.numberOfVerifications = mNumberOfVerifications; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.l1Method = mLLMethod; + result.l1Period = mL1Period; + result.l2Method = mL2Method; + result.l2Period = mL2Period; + result.l3Method = mL3Method; + result.l3Period = mL3Period; + result.showConsolidations = mShowConsolidations; + result.showTrend = mShowTrend; + result.showL1Trend = mShowL1Trends; + result.showL2Trend = mShowL2Trends; + result.showL3Trend = mShowL3Trends; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XTRNDInputs &config) + { + // + bool result = false; + + // + mCycleLength = config.cycleLength; + mNumberOfVerifications = config.numberOfVerifications; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mLLMethod = config.l1Method; + mL1Period = config.l1Period; + mL2Method = config.l2Method; + mL2Period = config.l2Period; + mL3Method = config.l3Method; + mL3Period = config.l3Period; + mShowConsolidations = config.showConsolidations; + mShowTrend = config.showTrend; + mShowL1Trends = config.showL1Trend; + mShowL2Trends = config.showL2Trend; + mShowL3Trends = config.showL3Trend; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // HH ... + ArraySetAsSeries(hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_UP_LINE, + barIndex, + mLoopbackBars, + hhBuffer); + + // + // HH State ... + ArraySetAsSeries(hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_UP_STATE_LINE, + barIndex, + mLoopbackBars, + hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(llBuffer, true); + CopyBuffer( + mHandler, + XTRND_DOWN_LINE, + barIndex, + mLoopbackBars, + llBuffer); + + // + // LL State ... + ArraySetAsSeries(llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + llStateBuffer); + + // + // CYCLES ... + + // + // LEVEL 1 ... + + // + // HH ... + ArraySetAsSeries(l1hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_UP_LINE, + barIndex, + mLoopbackBars, + l1hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l1hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l1hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l1llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_DOWN_LINE, + barIndex, + mLoopbackBars, + l1llBuffer); + + // + // LL State ... + ArraySetAsSeries(l1llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L1_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l1llStateBuffer); + + // + // LEVEL 2 ... + + // + // HH ... + ArraySetAsSeries(l2hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_UP_LINE, + barIndex, + mLoopbackBars, + l2hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l2hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l2hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l2llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_DOWN_LINE, + barIndex, + mLoopbackBars, + l2llBuffer); + + // + // LL State ... + ArraySetAsSeries(l2llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L2_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l2llStateBuffer); + + // + // LEVEL 3 ... + + // + // HH ... + ArraySetAsSeries(l3hhBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_UP_LINE, + barIndex, + mLoopbackBars, + l3hhBuffer); + + // + // HH State ... + ArraySetAsSeries(l3hhStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_UP_STATE_LINE, + barIndex, + mLoopbackBars, + l3hhStateBuffer); + + // + // LL ... + ArraySetAsSeries(l3llBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_DOWN_LINE, + barIndex, + mLoopbackBars, + l3llBuffer); + + // + // LL State ... + ArraySetAsSeries(l3llStateBuffer, true); + CopyBuffer( + mHandler, + XTRND_L3_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + l3llStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XTRNDInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XTRNDInfo result; + + // + if (barIndex < 0) + { + return result; + } + + // + barIndex--; + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + double hh = hhBuffer[barIndex]; + ENUM_XTRND_STATES hhState = (ENUM_XTRND_STATES)hhStateBuffer[barIndex]; + ENUM_XTRND_STATES hhStatePrev = (ENUM_XTRND_STATES)hhStateBuffer[barIndex + 1]; + + // + double ll = llBuffer[barIndex]; + ENUM_XTRND_STATES llState = (ENUM_XTRND_STATES)llStateBuffer[barIndex]; + ENUM_XTRND_STATES llStatePrev = (ENUM_XTRND_STATES)llStateBuffer[barIndex + 1]; + + // + double l1hh = l1hhBuffer[barIndex]; + ENUM_XTRND_STATES l1hhState = (ENUM_XTRND_STATES)l1hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l1hhStatePrev = (ENUM_XTRND_STATES)l1hhStateBuffer[barIndex + 1]; + + // + double l1ll = l1llBuffer[barIndex]; + ENUM_XTRND_STATES l1llState = (ENUM_XTRND_STATES)l1llStateBuffer[barIndex]; + ENUM_XTRND_STATES l1llStatePrev = (ENUM_XTRND_STATES)l1llStateBuffer[barIndex + 1]; + + // + double l2hh = l2hhBuffer[barIndex]; + ENUM_XTRND_STATES l2hhState = (ENUM_XTRND_STATES)l2hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l2hhStatePrev = (ENUM_XTRND_STATES)l2hhStateBuffer[barIndex + 1]; + + // + double l2ll = l2llBuffer[barIndex]; + ENUM_XTRND_STATES l2llState = (ENUM_XTRND_STATES)l2llStateBuffer[barIndex]; + ENUM_XTRND_STATES l2llStatePrev = (ENUM_XTRND_STATES)l2llStateBuffer[barIndex + 1]; + + // + double l3hh = l3hhBuffer[barIndex]; + ENUM_XTRND_STATES l3hhState = (ENUM_XTRND_STATES)l3hhStateBuffer[barIndex]; + ENUM_XTRND_STATES l3hhStatePrev = (ENUM_XTRND_STATES)l3hhStateBuffer[barIndex + 1]; + + // + double l3ll = l3llBuffer[barIndex]; + ENUM_XTRND_STATES l3llState = (ENUM_XTRND_STATES)l3llStateBuffer[barIndex]; + ENUM_XTRND_STATES l3llStatePrev = (ENUM_XTRND_STATES)l3llStateBuffer[barIndex + 1]; + + // + bool isTrendBullish = + hhState == XTRND_STATE_BULLISH && + llState == XTRND_STATE_BULLISH; + bool isPrevTrendBullish = + hhStatePrev == XTRND_STATE_BULLISH && + llStatePrev == XTRND_STATE_BULLISH; + bool isTrendBearish = + hhState == XTRND_STATE_BEARISH && + llState == XTRND_STATE_BEARISH; + bool isPrevTrendBearish = + hhStatePrev == XTRND_STATE_BEARISH && + llStatePrev == XTRND_STATE_BEARISH; + bool isTrendConsolidation = + hhState == XTRND_STATE_CONSOLIDATION && + llState == XTRND_STATE_CONSOLIDATION; + bool isPrevTrendConsolidation = + hhStatePrev == XTRND_STATE_CONSOLIDATION && + llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isTrendSwitchedToBullish = + isTrendBullish && + !isPrevTrendBullish; + bool isTrendSwitchedToBearish = + isTrendBearish && + !isPrevTrendBearish; + bool isTrendSwitchedToConsolidation = + isTrendConsolidation && + !isPrevTrendConsolidation; + + // + bool isL1TrendBullish = + l1hhState == XTRND_STATE_BULLISH && + l1llState == XTRND_STATE_BULLISH; + bool isL1PrevTrendBullish = + l1hhStatePrev == XTRND_STATE_BULLISH && + l1llStatePrev == XTRND_STATE_BULLISH; + bool isL1TrendBearish = + l1hhState == XTRND_STATE_BEARISH && + l1llState == XTRND_STATE_BEARISH; + bool isL1PrevTrendBearish = + l1hhStatePrev == XTRND_STATE_BEARISH && + l1llStatePrev == XTRND_STATE_BEARISH; + bool isL1TrendConsolidation = + l1hhState == XTRND_STATE_CONSOLIDATION && + l1llState == XTRND_STATE_CONSOLIDATION; + bool isL1PrevTrendConsolidation = + l1hhStatePrev == XTRND_STATE_CONSOLIDATION && + l1llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL1TrendSwitchedToBullish = + isL1TrendBullish && + !isL1PrevTrendBullish; + bool isL1TrendSwitchedToBearish = + isL1TrendBearish && + !isL1PrevTrendBearish; + bool isL1TrendSwitchedToConsolidation = + isL1TrendConsolidation && + !isL1PrevTrendConsolidation; + + // + bool isL2TrendBullish = + l2hhState == XTRND_STATE_BULLISH && + l2llState == XTRND_STATE_BULLISH; + bool isL2PrevTrendBullish = + l2hhStatePrev == XTRND_STATE_BULLISH && + l2llStatePrev == XTRND_STATE_BULLISH; + bool isL2TrendBearish = + l2hhState == XTRND_STATE_BEARISH && + l2llState == XTRND_STATE_BEARISH; + bool isL2PrevTrendBearish = + l2hhStatePrev == XTRND_STATE_BEARISH && + l2llStatePrev == XTRND_STATE_BEARISH; + bool isL2TrendConsolidation = + l2hhState == XTRND_STATE_CONSOLIDATION && + l2llState == XTRND_STATE_CONSOLIDATION; + bool isL2PrevTrendConsolidation = + l2hhStatePrev == XTRND_STATE_CONSOLIDATION && + l2llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL2TrendSwitchedToBullish = + isL2TrendBullish && + !isL2PrevTrendBullish; + bool isL2TrendSwitchedToBearish = + isL2TrendBearish && + !isL2PrevTrendBearish; + bool isL2TrendSwitchedToConsolidation = + isL2TrendConsolidation && + !isL2PrevTrendConsolidation; + + // + bool isL3TrendBullish = + l3hhState == XTRND_STATE_BULLISH && + l3llState == XTRND_STATE_BULLISH; + bool isL3PrevTrendBullish = + l3hhStatePrev == XTRND_STATE_BULLISH && + l3llStatePrev == XTRND_STATE_BULLISH; + bool isL3TrendBearish = + l3hhState == XTRND_STATE_BEARISH && + l3llState == XTRND_STATE_BEARISH; + bool isL3PrevTrendBearish = + l3hhStatePrev == XTRND_STATE_BEARISH && + l3llStatePrev == XTRND_STATE_BEARISH; + bool isL3TrendConsolidation = + l3hhState == XTRND_STATE_CONSOLIDATION && + l3llState == XTRND_STATE_CONSOLIDATION; + bool isL3PrevTrendConsolidation = + l3hhStatePrev == XTRND_STATE_CONSOLIDATION && + l3llStatePrev == XTRND_STATE_CONSOLIDATION; + + // + bool isL3TrendSwitchedToBullish = + isL3TrendBullish && + !isL3PrevTrendBullish; + bool isL3TrendSwitchedToBearish = + isL3TrendBearish && + !isL3PrevTrendBearish; + bool isL3TrendSwitchedToConsolidation = + isL3TrendConsolidation && + !isL3PrevTrendConsolidation; + + // + result.hh = hh; + result.hhState = hhState; + result.ll = ll; + result.llState = llState; + result.l1hh = l1hh; + result.l1hhState = l1hhState; + result.l1ll = l1ll; + result.l1llState = l1llState; + result.l2hh = l2hh; + result.l2hhState = l2hhState; + result.l2ll = l2ll; + result.l2llState = l2llState; + result.l3hh = l3hh; + result.l3hhState = l3hhState; + result.l3ll = l3ll; + result.l3llState = l3llState; + + // + result.isTrendBullish = isTrendBullish; + result.isTrendBearish = isTrendBearish; + result.isTrendConsolidation = isTrendConsolidation; + + // + result.isTrendSwitchedToBullish = isTrendSwitchedToBullish; + result.isTrendSwitchedToBearish = isTrendSwitchedToBearish; + result.isTrendSwitchedToConsolidation = isTrendSwitchedToConsolidation; + + // + result.isL1TrendBullish = isL1TrendBullish; + result.isL1TrendBearish = isL1TrendBearish; + result.isL1TrendConsolidation = isL1TrendConsolidation; + + // + result.isL1TrendSwitchedToBullish = isL1TrendSwitchedToBullish; + result.isL1TrendSwitchedToBearish = isL1TrendSwitchedToBearish; + result.isL1TrendSwitchedToConsolidation = isL1TrendSwitchedToConsolidation; + + // + result.isL2TrendBullish = isL2TrendBullish; + result.isL2TrendBearish = isL2TrendBearish; + result.isL2TrendConsolidation = isL2TrendConsolidation; + + // + result.isL2TrendSwitchedToBullish = isL2TrendSwitchedToBullish; + result.isL2TrendSwitchedToBearish = isL2TrendSwitchedToBearish; + result.isL2TrendSwitchedToConsolidation = isL2TrendSwitchedToConsolidation; + + // + result.isL3TrendBullish = isL3TrendBullish; + result.isL3TrendBearish = isL3TrendBearish; + result.isL3TrendConsolidation = isL3TrendConsolidation; + + // + result.isL3TrendSwitchedToBullish = isL3TrendSwitchedToBullish; + result.isL3TrendSwitchedToBearish = isL3TrendSwitchedToBearish; + result.isL3TrendSwitchedToConsolidation = isL3TrendSwitchedToConsolidation; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Indicator Properties ... + // + // Market ... + // + // Cycle Length to Check ... + int mCycleLength; + // + // Number of Verifications ... + int mNumberOfVerifications; + // + // Calculations ... + // + // Detect Up ... + ENUM_SERIESMODE mHHMode; + // + // Detect Low ... + ENUM_SERIESMODE mLLMode; + // + // Cycles ... + // + // LEVEL 1 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mLLMethod; + // + // Time Period ... + ENUM_TIMEFRAMES mL1Period; + // + // LEVEL 2 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mL2Method; + // + // Time Period ... + ENUM_TIMEFRAMES mL2Period; + // + // LEVEL 3 ... + // + // How to Find Period ... + ENUM_X_PERIOD_METHOD mL3Method; + // + // Time Period ... + ENUM_TIMEFRAMES mL3Period; + // + // Presentation ... + // + // Show Consolidations ... + bool mShowConsolidations; + // + // Show Trend ... + bool mShowTrend; + // + // Show Cycle 1 Trend ... + bool mShowL1Trends; + // + // Show Cycle 2 Trend ... + bool mShowL2Trends; + // + // Show Cycle 3 Trend ... + bool mShowL3Trends; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xama.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xama.ex5 new file mode 100644 index 0000000..ba4ccbb Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xama.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xama.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xama.mq5 new file mode 100644 index 0000000..4856cbb --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xama.mq5 @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_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 X121_XAMA Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "X121_XAMA" + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 0, + X_XAMA_BEARISH = 2, + X_XAMA_NEUTURAL = 1, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int length = 52; // Length +input int fastEMA = 2; // Fast EMA Length +input int slowEMA = 30; // Slow EMA Length +input int maShift = 0; // Shift +input ENUM_APPLIED_PRICE appliedTo = PRICE_LOW; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// END Inputs ... +// + +// +// 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 + +double maBuffer[]; +double maColorBuffer[]; + +#property indicator_label1 "X121_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 maxLength; + +// +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; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing MA Handler ... + maHandler = iAMA( + _Symbol, + _Period, + length, + fastEMA, + slowEMA, + maShift, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + Print(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); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int 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; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ENUM_DRAW_TYPE drawType = showLine ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showLine); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// 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; + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xcc.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xcc.ex5 new file mode 100644 index 0000000..fb182bf Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xcc.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xcc.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xcc.mq5 new file mode 100644 index 0000000..7389725 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xcc.mq5 @@ -0,0 +1,454 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Styles +// --------------------------------------------------- +// Name: X121_CC +// Description: Candle Styles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_CC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_CC" + +// +// Holds an SnapShot of Charts Configuration ... +struct XChartStyle +{ + // + // chart's ID ... + long chartId; + // + // chart's mode ... + ENUM_CHART_MODE mode; + // + // show bid line ... + bool showBidLine; + // + // show ask line ... + bool showAskLine; + // + // show grids on chart ... + bool showGrid; + // + // show volumes ... + bool showVolumes; + // + // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ... + bool showTradeLevels; + // + // chart autoscroll ... + bool autoScroll; + // + // chart quick navigation state ... + bool quickNavigation; + // + // chart's foreground color ... + color foreGroundColor; + // + // chart's background color ... + color backGroundColor; + // + // Up Color ... + color upColor; + // + // Down Color ... + color downColor; + // + // Bullish color ... + color bullishColor; + // + // Bearish color ... + color bearishColor; + // + // grid color ... + color gridColor; + // + // bid line color ... + color bidLineColor; + // + // ask line color ... + color askLineColor; + // + // line mode and doji candlestick color ... + color lineColor; + // + // Color of stop order levels (Stop Loss and Take Profit) ... + color stopColor; + // + // volumes color ... + color volumesColor; +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Chart Style"; +input color upColor = clrLime; // Up Color +input color downColor = clrRed; // Down Color +input color lineColor = clrLime; // Line mode and Doji candlestick Color +input color bearishColor = clrRed; // Bullish Color +input color bullishColor = clrLime; // Bearish Color +input color volumesColor = clrGreen; // Volumes Color + +// +input group "Presentation"; +input bool showCandles = true; // Show Candles + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XChartStyle chartStyle; +XChartStyle clearStyle; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Apply Chart Style ... + ApplyCustomChartStyle(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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 = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ +} + +// +// Apply Custom Chart Style ... +void ApplyCustomChartStyle() +{ + // + // Read Current Chart Config and Store it ... + ReadChartStyle(); + + // + // After Reading Current Chart Style ... + // we have to Save Configs and Change Styles ... + clearStyle = chartStyle; + + // + clearStyle.upColor = CLR_NONE; + clearStyle.downColor = CLR_NONE; + clearStyle.lineColor = CLR_NONE; + clearStyle.bullishColor = CLR_NONE; + clearStyle.bearishColor = CLR_NONE; + + // + // Decide to Show or not Candles based on User Input ... + if (showCandles) + { + SetChartStyle(chartStyle); + } + else + { + SetChartStyle(clearStyle); + } +} + +// +// Read Previous Chart Style ... +void ReadChartStyle() +{ + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + chartStyle.chartId = chartId; + + // + // Retrieve Chart Mode ... + chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE); + + // + chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE); + chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE); + chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID); + chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES); + chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS); + chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL); + chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION); + + // + chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND); + chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND); + chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP); + chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN); + chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL); + chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR); + chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID); + chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID); + chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK); + chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL); + chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE); + chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME); + + // + chartStyle.upColor = upColor; + chartStyle.downColor = downColor; + chartStyle.lineColor = lineColor; + chartStyle.bearishColor = bearishColor; + chartStyle.bullishColor = bullishColor; + chartStyle.volumesColor = volumesColor; +} + +// +// Set Chart Style ... +void SetChartStyle( + XChartStyle &mChartStyle // Chart Style to Apply +) +{ + // + ApplyChartStyle( + mChartStyle.chartId, + mChartStyle.mode, + mChartStyle.showBidLine, + mChartStyle.showAskLine, + mChartStyle.showGrid, + mChartStyle.showVolumes, + mChartStyle.showTradeLevels, + mChartStyle.autoScroll, + mChartStyle.quickNavigation, + mChartStyle.foreGroundColor, + mChartStyle.backGroundColor, + mChartStyle.upColor, + mChartStyle.downColor, + mChartStyle.bullishColor, + mChartStyle.bearishColor, + mChartStyle.gridColor, + mChartStyle.bidLineColor, + mChartStyle.askLineColor, + mChartStyle.lineColor, + mChartStyle.stopColor, + mChartStyle.volumesColor); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xche.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xche.ex5 new file mode 100644 index 0000000..3960a6f Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xche.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xche.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xche.mq5 new file mode 100644 index 0000000..59e850f --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xche.mq5 @@ -0,0 +1,631 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XCHE +// Description: Chandelier Exit Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XCHE Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XCHE" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 35; // Length +input int loopback = 26; // Loopback +input double multiplier1 = 3.0; // 1st Multiplier +input double multiplier2 = 3.5; // 2nd Multiplier + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showLongExit1Line = true; // Show 1st Long Exit +input bool showShortExit1Line = true; // Show 1st Short Exit +input bool showLongExit2Line = true; // Show 2st Long Exit +input bool showShortExit2Line = true; // Show 2st Short Exit + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +// Long Exit 1 ... +#define longExit1BufferIndex 0 +double longExit1Buffer[]; + +// +#property indicator_label1 "X121_XCHE LE 1" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_DOT + +// +// Short Exit 1 ... +#define shortExit1BufferIndex 1 +double shortExit1Buffer[]; + +// +#property indicator_label2 "X121_XCHE SE 1" +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color2 clrRed + +// +// Long Exit 2 ... +#define longExit2BufferIndex 2 +double longExit2Buffer[]; + +// +#property indicator_label3 "X121_XCHE LE 2" +#property indicator_type3 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color3 clrAqua + +// +// Short Exit 2 ... +#define shortExit2BufferIndex 3 +double shortExit2Buffer[]; + +// +#property indicator_label4 "X121_XCHE SE 2" +#property indicator_type4 DRAW_LINE +#property indicator_style2 STYLE_DOT +#property indicator_color4 clrMagenta + +// +// START Arrows ... + +// +// Long Exit 1 Start ... +#define longExit1StartBufferIndex 4 +double longExit1StartBuffer[]; + +// +#property indicator_label5 "X121_XCHE LES 1" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrLime + +// +// Short Exit 1 Start ... +#define shortExit1StartBufferIndex 5 +double shortExit1StartBuffer[]; + +// +#property indicator_label6 "X121_XCHE SES 1" +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrRed + +// +// Long Exit 2 Start ... +#define longExit2StartBufferIndex 6 +double longExit2StartBuffer[]; + +// +#property indicator_label7 "X121_XCHE LES 2" +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrAqua + +// +// Short Exit 2 Start ... +#define shortExit2StartBufferIndex 7 +double shortExit2StartBuffer[]; + +// +#property indicator_label8 "X121_XCHE SES 2" +#property indicator_type8 DRAW_ARROW +#property indicator_color8 clrMagenta + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// Working Array ... +double work[][6]; +#define hi1Idx 0 +#define lo1Idx 1 +#define hi2Idx 2 +#define lo2Idx 3 +#define trend1Idx 4 +#define trend2Idx 5 + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart mPeriod is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + if (Bars(_Symbol, _Period) < rates_total) + { + return (prev_calculated); + } + + // + if (ArrayRange(work, 0) != rates_total) + { + ArrayResize(work, rates_total); + } + + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + low, + close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + loopback >= 0; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(length, loopback); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + uint arrowCode = 159; + + // + // LEVEL 1 ... + + // + // Long Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit1DrawType = showLongExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit1StartDrawType = showLongExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit1BufferIndex, longExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_SHOW_DATA, showLongExit1Line); + PlotIndexSetInteger(longExit1BufferIndex, PLOT_DRAW_TYPE, longExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit1StartBufferIndex, longExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_DRAW_TYPE, longExit1StartDrawType); + + // + // Short Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit1DrawType = showShortExit1Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit1StartDrawType = showShortExit1Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit1BufferIndex, shortExit1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_SHOW_DATA, showShortExit1Line); + PlotIndexSetInteger(shortExit1BufferIndex, PLOT_DRAW_TYPE, shortExit1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit1StartBufferIndex, shortExit1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_DRAW_TYPE, shortExit1StartDrawType); + + // + // LEVEL 2 ... + + // + // Long Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE longExit2DrawType = showLongExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE longExit2StartDrawType = showLongExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(longExit2BufferIndex, longExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_SHOW_DATA, showLongExit2Line); + PlotIndexSetInteger(longExit2BufferIndex, PLOT_DRAW_TYPE, longExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(longExit2StartBufferIndex, longExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_DRAW_TYPE, longExit2StartDrawType); + + // + // Short Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE shortExit2DrawType = showShortExit2Line ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE shortExit2StartDrawType = showShortExit2Line ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(shortExit2BufferIndex, shortExit2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_SHOW_DATA, showShortExit2Line); + PlotIndexSetInteger(shortExit2BufferIndex, PLOT_DRAW_TYPE, shortExit2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(shortExit2StartBufferIndex, shortExit2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_ARROW, arrowCode); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_DRAW_TYPE, shortExit2StartDrawType); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int prevCalculated, // Previous Calculated + int ratesTotal, // Total Rates + const double &open[], // Rates Open ... + const double &high[], // Rates High ... + const double &low[], // Rates Low ... + const double &close[] // Rates Close ... +) +{ + // + // Cleanup Buffers ... + longExit1Buffer[bar_index] = longExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index] = shortExit1StartBuffer[bar_index] = EMPTY_VALUE; + longExit2Buffer[bar_index] = longExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index] = shortExit2StartBuffer[bar_index] = EMPTY_VALUE; + + // + int start = MathMax(bar_index - loopback, 0); + + // + // Calculate ATR Value ... + double atrValue = 0; + for (int k = 1; k <= length && (bar_index - k - 1) >= 0; k++) + { + // + atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) - + MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]); + } + atrValue /= (double)length; + + // + // Retrieve Highest High and Lowest Lows ... + double loopbackMax = high[ArrayMaximum(high, start, loopback)]; + double loopbackMin = low[ArrayMinimum(low, start, loopback)]; + + // + // Fill Multi Dimesional Working Array ... + work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue; + work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue; + work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue; + work[bar_index][lo2Idx] = loopbackMin + multiplier2 * atrValue; + work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0; + work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0; + + // + if (bar_index > 0) + { + // + // Calculate Trends ... + if (close[bar_index] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][trend1Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][trend1Idx] = -1; + } + + // + if (close[bar_index] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][trend2Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][trend2Idx] = -1; + } + + // + // Calculate Exit Values ... + + // + // Exit 1 ... + + // + // Long ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == 1) + { + // + if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx]; + } + + // + longExit1Buffer[bar_index] = work[bar_index][hi1Idx]; + + // + if (longExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit1StartBuffer[bar_index] = longExit1Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier1 > 0 && work[bar_index][trend1Idx] == -1) + { + // + if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx]; + } + + // + shortExit1Buffer[bar_index] = work[bar_index][lo1Idx]; + + // + if (shortExit1Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index]; + } + } + + // + // Exit 2 ... + + // + // Long ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == 1) + { + if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx]; + } + + // + longExit2Buffer[bar_index] = work[bar_index][hi2Idx]; + + // + if (longExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + longExit2StartBuffer[bar_index] = longExit2Buffer[bar_index]; + } + } + + // + // Short ... + if (multiplier2 > 0 && work[bar_index][trend2Idx] == -1) + { + // + if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx]; + } + + // + shortExit2Buffer[bar_index] = work[bar_index][lo2Idx]; + + // + if (shortExit2Buffer[bar_index - 1] == EMPTY_VALUE) + { + shortExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index]; + } + } + } +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xct.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xct.ex5 new file mode 100644 index 0000000..8c752b5 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xct.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xct.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xct.mq5 new file mode 100644 index 0000000..72f2a26 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xct.mq5 @@ -0,0 +1,264 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XCT +// 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 X121_XCT Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XCT" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input color clr = clrYellow; // Text Color +input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; // Text Position + +// +input group "Presentation"; +input bool showCandleTime = true; // Show Candle Time + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 0 +#property indicator_plots 0 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (showCandleTime) + { + CreateIndicatorObject(); + } + else + { + ObjectDelete(0, ShortName); + } + + // + // 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 + + // + // Delete Object ... + ObjectDelete(0, ShortName); + + // + Comment(""); +} + +// +// 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[]) +{ + // + ArraySetAsSeries(time, true); + + // + if (!showCandleTime) + { + return rates_total; + } + + // + XCandleRemains remainTime; + GetCandleRemainsTime( + remainTime, + _Symbol, + _Period, + 0); + + // + string msg = ToString( + remainTime, + "", + "", + "", + "", + "", + ":", + true); + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + // + string _sp = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in: " + msg; + + // + ObjectSetInteger(0, ShortName, OBJPROP_COLOR, clr); + ObjectSetString(0, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(0, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(0, ShortName, OBJPROP_FONT, "Courier"); + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +void CreateIndicatorObject() +{ + // + if (!showCandleTime) + { + return; + } + + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, corner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + + // + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (corner) + { + case CORNER_LEFT_UPPER: + Anchor = ANCHOR_LEFT_UPPER; + break; + case CORNER_RIGHT_UPPER: + Anchor = ANCHOR_RIGHT_UPPER; + break; + case CORNER_LEFT_LOWER: + Anchor = ANCHOR_LEFT_LOWER; + break; + case CORNER_RIGHT_LOWER: + Anchor = ANCHOR_RIGHT_LOWER; + break; + } + + // + ObjectSetInteger(0, ShortName, OBJPROP_ANCHOR, Anchor); +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xhk.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhk.ex5 new file mode 100644 index 0000000..7b21716 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhk.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xhk.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhk.mq5 new file mode 100644 index 0000000..4d80fb3 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhk.mq5 @@ -0,0 +1,486 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------------- +// Name: X121_HK +// Description: Hiken Ashi ... +// 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 X121_XHK Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XHK" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Presentation"; +input bool drawCandles = true; // Draw Hiken Ashi Candle +input bool drawCandleLines = false; // Show HikenAshi Lines + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 13 +#property indicator_plots 5 + +// +// PLOTTED Buffers ... + +// +// Open ... +#define openBufferIndex 0 +double openBuffer[]; + +// +// High ... +#define highBufferIndex 1 +double highBuffer[]; + +// +// Low ... +#define lowBufferIndex 2 +double lowBuffer[]; + +// +// Close ... +#define closeBufferIndex 3 +double closeBuffer[]; + +// +// Candle Color ... +#define candleColorBufferIndex 4 +double candleColorBuffer[]; + +// +#define candlesBufferIndex 0 + +// +#property indicator_label1 "X121_XHK Open;X121_XHK High;X121_XHK Low;X121_XHK Close" +#property indicator_type1 DRAW_COLOR_CANDLES +#property indicator_color1 clrAqua, clrMagenta, CLR_NONE + +// +#define openHKBufferIndex 5 +#define openHKColorBufferIndex 6 +double openHKBuffer[]; +double openHKColorBuffer[]; + +// +#define openHKBufferPlotIndex 1 +#property indicator_label2 "X121_XHK O" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrAqua, clrMagenta, clrLightGray +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define highHKBufferIndex 7 +#define highHKColorBufferIndex 8 +double highHKBuffer[]; +double highHKColorBuffer[]; + +// +#define highHKBufferPlotIndex 2 +#property indicator_label3 "X121_XHK H" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, clrMagenta, clrLightGray +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define lowHKBufferIndex 9 +#define lowHKColorBufferIndex 10 +double lowHKBuffer[]; +double lowHKColorBuffer[]; + +// +#define lowHKBufferPlotIndex 3 +#property indicator_label4 "X121_XHK L" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrAqua, clrMagenta, clrLightGray +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define closeHKBufferIndex 11 +#define closeHKColorBufferIndex 12 +double closeHKBuffer[]; +double closeHKColorBuffer[]; + +// +#define closeHKBufferPlotIndex 4 +#property indicator_label5 "X121_XHK C" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 clrAqua, clrMagenta, clrLightGray +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, prev_calculated, rates_total, open, high, close, low); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Candles Color ... + ArraySetAsSeries(candleColorBuffer, true); + SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Candles Buffer ... + PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(candleColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(openBuffer, true); + PlotIndexSetInteger(openBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(highBuffer, true); + SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highBufferIndex, PLOT_SHOW_DATA, false); + + // + // Close ... + ArraySetAsSeries(closeBuffer, true); + SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeBufferIndex, PLOT_SHOW_DATA, false); + + // + // Low ... + ArraySetAsSeries(lowBuffer, true); + SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open HK ... + ENUM_DRAW_TYPE openDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(openHKBufferPlotIndex, PLOT_DRAW_TYPE, openDrawType); + + // + ArraySetAsSeries(openHKColorBuffer, true); + SetIndexBuffer(openHKColorBufferIndex, openHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // High HK ... + ENUM_DRAW_TYPE highDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(highHKBufferPlotIndex, PLOT_DRAW_TYPE, highDrawType); + + // + ArraySetAsSeries(highHKColorBuffer, true); + SetIndexBuffer(highHKColorBufferIndex, highHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Low HK ... + ENUM_DRAW_TYPE lowDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(lowHKBufferPlotIndex, PLOT_DRAW_TYPE, lowDrawType); + + // + ArraySetAsSeries(lowHKColorBuffer, true); + SetIndexBuffer(lowHKColorBufferIndex, lowHKColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Close HK ... + ENUM_DRAW_TYPE closeDrawType = drawCandleLines ? DRAW_COLOR_LINE : DRAW_NONE; + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_SHOW_DATA, drawCandleLines); + PlotIndexSetInteger(closeHKBufferPlotIndex, PLOT_DRAW_TYPE, closeDrawType); + + // + ArraySetAsSeries(closeHKColorBuffer, true); + SetIndexBuffer(closeHKColorBufferIndex, closeHKColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[]) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = openBuffer[bar_index + 1]; + mPrevHKCloseValue = closeBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + openBuffer[bar_index] = mHKOpenValue; + highBuffer[bar_index] = mHKHighValue; + lowBuffer[bar_index] = mHKLowValue; + closeBuffer[bar_index] = mHKCloseValue; + + // + double candleColorValue = + mHKOpenValue < mHKCloseValue ? 0 : 1; + + // + candleColorBuffer[bar_index] = drawCandles ? candleColorValue : 2; + + // + openHKBuffer[bar_index] = mHKOpenValue; + openHKColorBuffer[bar_index] = candleColorValue; + + // + highHKBuffer[bar_index] = mHKHighValue; + highHKColorBuffer[bar_index] = candleColorValue; + + // + lowHKBuffer[bar_index] = mHKLowValue; + lowHKColorBuffer[bar_index] = candleColorValue; + + // + closeHKBuffer[bar_index] = mHKCloseValue; + closeHKColorBuffer[bar_index] = candleColorValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xhull.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhull.ex5 new file mode 100644 index 0000000..b4cc743 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhull.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xhull.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhull.mq5 new file mode 100644 index 0000000..dbfc3e1 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xhull.mq5 @@ -0,0 +1,602 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XHULL +// Description: Hull Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XHULL Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XHULL" + +// +struct XHullData +{ + // + double value; + double value3; + + // + double wsum1; + double wsum2; + double wsum3; + + // + double lsum1; + double lsum2; + double lsum3; +}; + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// a Class For Hull Calculations ... +class XSCHull +{ + // +public: + // + // Constructor ... + XSCHull() : mFullPeriod(1), mHalfPeriod(1), mSqrtPeriod(1), mArraySize(-1) + { + // + // These are a way above to assign Private variables at Construct time ... + } + + // + // Deconstructor ... + ~XSCHull() + { + ArrayFree(mData); + } + + // + // Initial Hull ... + bool Init( + int mPeriod, + double mDivisor) + { + // + bool result = false; + + // + mFullPeriod = (int)(mPeriod > 1 ? mPeriod : 1); + mHalfPeriod = (int)(mFullPeriod > 1 ? mFullPeriod / (mDivisor > 1 ? mDivisor : 1) : 1); + mSqrtPeriod = (int)MathSqrt(mFullPeriod); + + // + mArraySize = -1; + mWeight1 = mWeight2 = mWeight3 = 1; + + // + result = true; + + // + return result; + } + + // + // CalCulate Specific Value ... + double Calculate( + double value, + int i, + int bars) + { + // + double result = 0; + + // + if (mArraySize < bars) + { + // + mArraySize = ArrayResize(mData, bars + 500); + if (mArraySize < bars) + return result; + } + + // + mData[i].value = value; + if (i > mFullPeriod) + { + // + mData[i].wsum1 = mData[i - 1].wsum1 + value * mHalfPeriod - mData[i - 1].lsum1; + mData[i].lsum1 = mData[i - 1].lsum1 + value - mData[i - mHalfPeriod].value; + mData[i].wsum2 = mData[i - 1].wsum2 + value * mFullPeriod - mData[i - 1].lsum2; + mData[i].lsum2 = mData[i - 1].lsum2 + value - mData[i - mFullPeriod].value; + } + else + { + // + mData[i].wsum1 = mData[i].wsum2 = + mData[i].lsum1 = mData[i].lsum2 = mWeight1 = mWeight2 = 0; + for (int k = 0, w1 = mHalfPeriod, w2 = mFullPeriod; w2 > 0 && i >= k; k++, w1--, w2--) + { + // + if (w1 > 0) + { + // + mData[i].wsum1 += mData[i - k].value * w1; + mData[i].lsum1 += mData[i - k].value; + mWeight1 += w1; + } + + // + mData[i].wsum2 += mData[i - k].value * w2; + mData[i].lsum2 += mData[i - k].value; + mWeight2 += w2; + } + } + + // + mData[i].value3 = 2.0 * mData[i].wsum1 / mWeight1 - mData[i].wsum2 / mWeight2; + + // + if (i > mSqrtPeriod) + { + // + mData[i].wsum3 = mData[i - 1].wsum3 + mData[i].value3 * mSqrtPeriod - mData[i - 1].lsum3; + mData[i].lsum3 = mData[i - 1].lsum3 + mData[i].value3 - mData[i - mSqrtPeriod].value3; + } + else + { + // + mData[i].wsum3 = + mData[i].lsum3 = mWeight3 = 0; + + // + for (int k = 0, w3 = mSqrtPeriod; w3 > 0 && i >= k; k++, w3--) + { + // + mData[i].wsum3 += mData[i - k].value3 * w3; + mData[i].lsum3 += mData[i - k].value3; + mWeight3 += w3; + } + } + + // + result = mData[i].wsum3 / mWeight3; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + int mFullPeriod; + int mHalfPeriod; + int mSqrtPeriod; + int mArraySize; + double mWeight1; + double mWeight2; + double mWeight3; + + // + XHullData mData[]; +}; + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 72; // Length +input double divisor = 2.0; // Divisor (Speed) + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Presentation"; +input bool showUpZone = true; // Show Up Zone +input bool showDownZone = true; // Show Down Zone + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// UP Zone ... + +// +#define upZoneBufferIndex 0 +#define upZoneColorBufferIndex 1 + +// +double upZoneBuffer[]; +double upZoneColorBuffer[]; + +// +#property indicator_label1 "X121_XHULL Up" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLightGray, clrAqua, clrMagenta +#property indicator_width1 1 + +// +// DOWN Zone ... + +// +#define downZoneBufferIndex 2 +#define downZoneColorBufferIndex 3 + +// +double downZoneBuffer[]; +double downZoneColorBuffer[]; + +// +#property indicator_label2 "X121_XHULL Down" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 clrLightGray, clrAqua, clrMagenta +#property indicator_width2 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +XSCHull *mUpZHull; +XSCHull *mDownZHull; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + mUpZHull = new XSCHull(); + mUpZHull.Init( + length, + divisor); + + // + mDownZHull = new XSCHull(); + mDownZHull.Init( + length, + divisor); + + // + // 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 mPeriod 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 + + // + delete mUpZHull; + delete mDownZHull; +} + +// +// 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[]) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + double upPrice = getPrice( + upAppliedTo, + open, high, low, close, i); + + // + double downPrice = getPrice( + downAppliedTo, + open, high, low, close, i); + + // + CalculateBuffers( + i, + rates_total, + upPrice, + downPrice); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + length >= 9 && + divisor >= 0.5; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE upZoneDrawType = showUpZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(upZoneBufferIndex, upZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_SHOW_DATA, showUpZone); + PlotIndexSetInteger(upZoneBufferIndex, PLOT_DRAW_TYPE, upZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(upZoneColorBufferIndex, upZoneColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DOWN Zone ... + + // + // Draw Type ... + ENUM_DRAW_TYPE downZoneDrawType = showDownZone ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(downZoneBufferIndex, downZoneBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_SHOW_DATA, showDownZone); + PlotIndexSetInteger(downZoneBufferIndex - 1, PLOT_DRAW_TYPE, downZoneDrawType); + + // + // Color Buffer ... + SetIndexBuffer(downZoneColorBufferIndex, downZoneColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int ratesTotal, // Total Rates + double upPrice, // Up Price ... + double downPrice // Down Price ... +) +{ + // + double upValue = mUpZHull.Calculate( + upPrice, + bar_index, + ratesTotal); + upZoneBuffer[bar_index] = upValue; + double upColorIDX = (bar_index > 0) + ? (upZoneBuffer[bar_index] > upZoneBuffer[bar_index - 1]) + ? 1 + : (upZoneBuffer[bar_index] < upZoneBuffer[bar_index - 1]) + ? 2 + : upZoneColorBuffer[bar_index - 1] + : 0; + upZoneColorBuffer[bar_index] = upColorIDX; + + // + double downValue = mDownZHull.Calculate( + downPrice, + bar_index, + ratesTotal); + downZoneBuffer[bar_index] = downValue; + double downColorIDX = (bar_index > 0) + ? (downZoneBuffer[bar_index] > downZoneBuffer[bar_index - 1]) + ? 1 + : (downZoneBuffer[bar_index] < downZoneBuffer[bar_index - 1]) + ? 2 + : downZoneColorBuffer[bar_index - 1] + : 0; + downZoneColorBuffer[bar_index] = downColorIDX; +} + +// +// END Functions ... +// + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xich.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xich.ex5 new file mode 100644 index 0000000..e0e91b2 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xich.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xich.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xich.mq5 new file mode 100644 index 0000000..5493ba2 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xich.mq5 @@ -0,0 +1,743 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121_XICH +// Description: Ichimoku Kinko Hyo ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XICH Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XICH" + +// +// Ichimoku Golden Numbers ... +enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS +{ + X_ICH_BASE = 9, + X_ICH_GOLDEN = 17, + X_ICH_CYCLE = 26, + X_ICH_PERIOD = 35, + X_ICH_STAR = 45, + X_ICH_MED = 52, + X_ICH_LONG = 63, + X_ICH_FULL = 72 +}; + +// +// Ichimoku Lines Calculator Mode ... +enum ENUM_X_ICHIMOKU_CALCULATION_MODE +{ + // + X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low + X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +// ICHIMOKU Kinko Hyo ... + +// +// TENKANSEN ... +input group "Tenkan Sen"; +input int tenkanSenLength = 9; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// KIJUNSEN ... +input group "Kijun Sen"; +input int kijunSenLength = 26; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// SENKOUSPANB ... +input group "Senkou Span B"; +input int senkouSpanBLength = 52; // Length +input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode + +// +// CHIKOUSPAN ... +input group "Chikou Span"; +input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type + +// +input group "Presentation"; +input bool showTenkanSen = true; // Show Tenkan Sen +input bool showKijunSen = true; // Show Kijun Sen +input bool showKijunSenPlus = false; // Show Kijun Sen + +input bool showKijunSenNegative = false; // Show Kijun Sen - +input bool showChikouSpan = true; // Show Chikou Span +input bool showSenkouSpanA = true; // Show Senkou Span A +input bool showSenkouSpanB = true; // Show Senkou Span B +input bool showKumo = true; // Show Kumo +input bool shiftKumo = true; // Shift Kumo to Future + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 8 + +// +// PLOTTED Buffers ... + +// +// ICHIMOKU ... + +// +// TENKANSEN ... + +// +#define tenkanSenBufferIndex 0 +double tenkanSenBuffer[]; + +// +#property indicator_label1 "X121_XICH TK" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// KIJUNSEN ... + +// +#define kijunSenBufferIndex 1 +double kijunSenBuffer[]; + +// +#property indicator_label2 "X121_XICH KJ" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrDodgerBlue +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#define kijunSenPlusBufferIndex 2 +double kijunSenPlusBuffer[]; + +// +#property indicator_label3 "X121_XICH KJ+" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrMediumTurquoise +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define kijunSenNegativeBufferIndex 3 +double kijunSenNegativeBuffer[]; + +// +#property indicator_label4 "X121_XICH KJ-" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrDarkSeaGreen +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CHIKOUSPAN ... + +// +#define chikouSpanBufferIndex 4 +double chikouSpanBuffer[]; + +// +#property indicator_label5 "X121_XICH CS" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrDarkGreen +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +#define senkouABufferIndex 5 +double senkouABuffer[]; + +// +#property indicator_label6 "X121_XICH SSA" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrLightGray +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +#define senkouBBufferIndex 6 +double senkouBBuffer[]; + +// +#property indicator_label7 "X121_XICH SSB" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLightGray +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// KUMO ... + +// +// SENKOUSPANA ... + +// +#define senkouSpanABufferIndex 7 +double senkouSpanABuffer[]; + +// +// SENKOUSPANB ... + +// +#define senkouSpanBBufferIndex 8 +double senkouSpanBBuffer[]; + +// +// KUMOCLOUD ... + +// +#define kumoBufferIndex 7 + +// +#property indicator_label8 "X121_XICH Kumo" +#property indicator_type8 DRAW_FILLING +#property indicator_color8 clrAqua, clrMagenta +#property indicator_style8 STYLE_SOLID +#property indicator_width8 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +ENUM_SERIESMODE mTenkanSenTopMode = NULL; +ENUM_SERIESMODE mTenkanSenBottomMode = NULL; + +// +ENUM_SERIESMODE mKijunSenTopMode = NULL; +ENUM_SERIESMODE mKijunSenBottomMode = NULL; + +// +ENUM_SERIESMODE mSenkouSpanBTopMode = NULL; +ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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 = + // + (tenkanSenLength > 2 && + kijunSenLength > tenkanSenLength && + senkouSpanBLength > kijunSenLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ichimoku ... + result = MathMax(result, tenkanSenLength); + result = MathMax(result, kijunSenLength); + result = MathMax(result, senkouSpanBLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // ICHIMOKU ... + + // + // TENKANSEN ... + + // + ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tenkanSenBuffer, true); + SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen); + PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType); + + // + // KIJUNSEN ... + + // + ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenBuffer, true); + SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen); + PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType); + + // + // KIJUNSEN Plus ... + + // + ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenPlusBuffer, true); + SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType); + + // + // KIJUNSEN Negative ... + + // + ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(kijunSenNegativeBuffer, true); + SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType); + + // + // CHIKOUSPAN ... + + // + ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(chikouSpanBuffer, true); + SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan); + PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType); + + // + // SENKOUSPAN A and B ... + int shiftSize = shiftKumo ? kijunSenLength : 0; + + // + // SENKOUSPANA ... + ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouABuffer, true); + SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA); + PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType); + + // + // SENKOUSPANB ... + ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(senkouBBuffer, true); + SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB); + PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType); + + // + // KUMO ... + + // + // SENKOUSPANA ... + ArraySetAsSeries(senkouSpanABuffer, true); + SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // SENKOUSPANB ... + ArraySetAsSeries(senkouSpanBBuffer, true); + SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA); + PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // KUMO ... + + // + ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE; + + // + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize); + PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // ICHIMOKU ... + + // + double topValue; + double bottomValue; + + // + // TENKANSEN ... + + // + // Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ... + if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL) + { + // + switch (tenkanSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mTenkanSenTopMode = MODE_HIGH; + mTenkanSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mTenkanSenTopMode = MODE_OPEN; + mTenkanSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mTenkanSenTopMode, + tenkanSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mTenkanSenBottomMode, + tenkanSenLength, + bar_index); + + // + double tenkanSenValue = (topValue + bottomValue) / 2; + tenkanSenBuffer[bar_index] = tenkanSenValue; + + // + // KIJUNSEN ... + + // + // Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ... + if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL) + { + // + switch (kijunSenMode) + { + // + case X_XICH_HH_LL_MODE: + // + mKijunSenTopMode = MODE_HIGH; + mKijunSenBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mKijunSenTopMode = MODE_OPEN; + mKijunSenBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mKijunSenTopMode, + kijunSenLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mKijunSenBottomMode, + kijunSenLength, + bar_index); + + // + double kijunSenValue = (topValue + bottomValue) / 2; + kijunSenBuffer[bar_index] = kijunSenValue; + + // + kijunSenPlusBuffer[bar_index] = kijunSenValue; + kijunSenNegativeBuffer[bar_index] = kijunSenValue; + + // + // CHIKOUSPAN ... + double chikouSpanValue = GetAppliedPrice( + bar_index, + chikuoSpanAppliedTo); + chikouSpanBuffer[bar_index] = chikouSpanValue; + + // + // KUMO ... + + // + // SENKOUSPANA ... + double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2; + senkouABuffer[bar_index] = senkouSpanAValue; + senkouSpanABuffer[bar_index] = senkouSpanAValue; + + // + // SENKOUSPANB ... + + // + // Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ... + if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL) + { + // + switch (senkouSpanBMode) + { + // + case X_XICH_HH_LL_MODE: + // + mSenkouSpanBTopMode = MODE_HIGH; + mSenkouSpanBBottomMode = MODE_LOW; + break; + + // + case X_XICH_HO_LC_MODE: + // + mSenkouSpanBTopMode = MODE_OPEN; + mSenkouSpanBBottomMode = MODE_CLOSE; + break; + } + } + + // + // Calculate Top ... + topValue = GetHighestHigh( + _Symbol, + _Period, + mSenkouSpanBTopMode, + senkouSpanBLength, + bar_index); + + // + // Calculate Bottom ... + bottomValue = GetLowestLow( + _Symbol, + _Period, + mSenkouSpanBBottomMode, + senkouSpanBLength, + bar_index); + + // + double senkouSpanBValue = (topValue + bottomValue) / 2; + senkouBBuffer[bar_index] = senkouSpanBValue; + senkouSpanBBuffer[bar_index] = senkouSpanBValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xmrb.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xmrb.ex5 new file mode 100644 index 0000000..c4bbb9b Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xmrb.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xmrb.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xmrb.mq5 new file mode 100644 index 0000000..ffe9e2e --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xmrb.mq5 @@ -0,0 +1,786 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------- +// Name: X121_XMRB +// Description: Moving Average Ribbon +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XMRB Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XMRB" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Ribbon 1"; +input int fast1Length = 3; // Fast +input int slow1Length = 5; // Slow + +// +input group "Ribbon 2"; +input int fast2Length = 8; // Fast +input int slow2Length = 13; // Slow + +// +input group "Ribbon 3"; +input int fast3Length = 21; // Fast +input int slow3Length = 34; // Slow + +// +input group "Ribbon 4"; +input int fast4Length = 55; // Fast +input int slow4Length = 89; // Slow + +// +input group "Ribbon 5"; +input int fast5Length = 144; // Fast +input int slow5Length = 233; // Slow + +// +input group "Calculation"; +input ENUM_MA_METHOD ribbonMode = MODE_EMA; // Mode +input ENUM_APPLIED_PRICE ribbonAppliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool showFastMa = true; // Show Fast +input bool showSlowMa = true; // Show Slow +input bool showRibbon = false; // Show Ribbon + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 12 +#property indicator_plots 12 + +// +// PLOTTED Buffers ... + +// +// MA ... + +// +// FAST ... +#define fastMaBufferIndex 0 +double fastMaBuffer[]; + +// +#property indicator_label1 "X121_XMRB F" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// SLOW ... +#define slowMaBufferIndex 1 +double slowMaBuffer[]; + +// +#property indicator_label2 "X121_XMRB S" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +// FAST ... + +// +#define fast1BufferIndex 2 +double fast1Buffer[]; + +// +#property indicator_label3 "X121_XMRB 1 F" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAquamarine +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define fast2BufferIndex 3 +double fast2Buffer[]; + +// +#property indicator_label4 "X121_XMRB 2 F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrAquamarine +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +#define fast3BufferIndex 4 +double fast3Buffer[]; + +// +#property indicator_label5 "X121_XMRB 3 F" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAquamarine +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +#define fast4BufferIndex 5 +double fast4Buffer[]; + +// +#property indicator_label6 "X121_XMRB 4 F" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrAquamarine +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +#define fast5BufferIndex 6 +double fast5Buffer[]; + +// +#property indicator_label7 "X121_XMRB 5 F" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrAquamarine +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// SLOW ... + +// +#define slow1BufferIndex 7 +double slow1Buffer[]; + +// +#property indicator_label8 "X121_XMRB 1 S" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrPlum +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +#define slow2BufferIndex 8 +double slow2Buffer[]; + +// +#property indicator_label9 "X121_XMRB 2 S" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrPlum +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define slow3BufferIndex 9 +double slow3Buffer[]; + +// +#property indicator_label10 "X121_XMRB 3 S" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrPlum +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define slow4BufferIndex 10 +double slow4Buffer[]; + +// +#property indicator_label11 "X121_XMRB 4 S" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrPlum +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define slow5BufferIndex 11 +double slow5Buffer[]; + +// +#property indicator_label12 "X121_XMRB 5 S" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrPlum +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int fast1MaHandler = INVALID_HANDLE; +int fast2MaHandler = INVALID_HANDLE; +int fast3MaHandler = INVALID_HANDLE; +int fast4MaHandler = INVALID_HANDLE; +int fast5MaHandler = INVALID_HANDLE; + +// +int slow1MaHandler = INVALID_HANDLE; +int slow2MaHandler = INVALID_HANDLE; +int slow3MaHandler = INVALID_HANDLE; +int slow4MaHandler = INVALID_HANDLE; +int slow5MaHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize MAs ... + if (!InitializeMas()) + { + 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 ... + + // + IndicatorRelease(fast1MaHandler); + IndicatorRelease(fast2MaHandler); + IndicatorRelease(fast3MaHandler); + IndicatorRelease(fast4MaHandler); + IndicatorRelease(fast5MaHandler); + + // + IndicatorRelease(slow1MaHandler); + IndicatorRelease(slow2MaHandler); + IndicatorRelease(slow3MaHandler); + IndicatorRelease(slow4MaHandler); + IndicatorRelease(slow5MaHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + // + int fast1MaCalculatedBars = BarsCalculated(fast1MaHandler); + int fast2MaCalculatedBars = BarsCalculated(fast2MaHandler); + int fast3MaCalculatedBars = BarsCalculated(fast3MaHandler); + int fast4MaCalculatedBars = BarsCalculated(fast4MaHandler); + int fast5MaCalculatedBars = BarsCalculated(fast5MaHandler); + // + int slow1MaCalculatedBars = BarsCalculated(slow1MaHandler); + int slow2MaCalculatedBars = BarsCalculated(slow2MaHandler); + int slow3MaCalculatedBars = BarsCalculated(slow3MaHandler); + int slow4MaCalculatedBars = BarsCalculated(slow4MaHandler); + int slow5MaCalculatedBars = BarsCalculated(slow5MaHandler); + if ( + fast1MaCalculatedBars < maxLength || + fast2MaCalculatedBars < maxLength || + fast3MaCalculatedBars < maxLength || + fast4MaCalculatedBars < maxLength || + fast5MaCalculatedBars < maxLength || + slow1MaCalculatedBars < maxLength || + slow2MaCalculatedBars < maxLength || + slow3MaCalculatedBars < maxLength || + slow4MaCalculatedBars < maxLength || + slow5MaCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + // + int copiedFast1Mas = CopyBuffer(fast1MaHandler, 0, 0, limit, fast1Buffer); + int copiedFast2Mas = CopyBuffer(fast2MaHandler, 0, 0, limit, fast2Buffer); + int copiedFast3Mas = CopyBuffer(fast3MaHandler, 0, 0, limit, fast3Buffer); + int copiedFast4Mas = CopyBuffer(fast4MaHandler, 0, 0, limit, fast4Buffer); + int copiedFast5Mas = CopyBuffer(fast5MaHandler, 0, 0, limit, fast5Buffer); + // + int copiedSlow1Mas = CopyBuffer(slow1MaHandler, 0, 0, limit, slow1Buffer); + int copiedSlow2Mas = CopyBuffer(slow2MaHandler, 0, 0, limit, slow2Buffer); + int copiedSlow3Mas = CopyBuffer(slow3MaHandler, 0, 0, limit, slow3Buffer); + int copiedSlow4Mas = CopyBuffer(slow4MaHandler, 0, 0, limit, slow4Buffer); + int copiedSlow5Mas = CopyBuffer(slow5MaHandler, 0, 0, limit, slow5Buffer); + if ( + copiedFast1Mas <= 0 || + copiedFast2Mas <= 0 || + copiedFast3Mas <= 0 || + copiedFast4Mas <= 0 || + copiedFast5Mas <= 0 || + copiedSlow1Mas <= 0 || + copiedSlow2Mas <= 0 || + copiedSlow3Mas <= 0 || + copiedSlow4Mas <= 0 || + copiedSlow5Mas <= 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 = + // + (fast1Length > 2 && + fast2Length > fast1Length && + fast3Length > fast2Length && + fast4Length > fast3Length && + fast5Length > fast4Length && + slow1Length > fast1Length && + slow2Length > fast2Length && + slow3Length > fast3Length && + slow4Length > fast4Length && + slow5Length > fast5Length && + slow2Length > slow1Length && + slow3Length > slow2Length && + slow4Length > slow3Length && + slow5Length > slow4Length + // + ) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Ma ... + + // + result = MathMax(fast1Length, fast2Length); + result = MathMax(result, fast3Length); + result = MathMax(result, fast4Length); + result = MathMax(result, fast5Length); + + // + result = MathMax(result, slow1Length); + result = MathMax(result, slow2Length); + result = MathMax(result, slow3Length); + result = MathMax(result, slow4Length); + result = MathMax(result, slow5Length); + + // + return result; +} + +// +// Initialize Ma Handlers ... +bool InitializeMas() +{ + // + bool result = false; + + // + fast1MaHandler = iMA( + _Symbol, + _Period, + fast1Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast2MaHandler = iMA( + _Symbol, + _Period, + fast2Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast3MaHandler = iMA( + _Symbol, + _Period, + fast3Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast4MaHandler = iMA( + _Symbol, + _Period, + fast4Length, + 0, + ribbonMode, + ribbonAppliedTo); + fast5MaHandler = iMA( + _Symbol, + _Period, + fast5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + slow1MaHandler = iMA( + _Symbol, + _Period, + slow1Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow2MaHandler = iMA( + _Symbol, + _Period, + slow2Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow3MaHandler = iMA( + _Symbol, + _Period, + slow3Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow4MaHandler = iMA( + _Symbol, + _Period, + slow4Length, + 0, + ribbonMode, + ribbonAppliedTo); + slow5MaHandler = iMA( + _Symbol, + _Period, + slow5Length, + 0, + ribbonMode, + ribbonAppliedTo); + + // + result = + fast1MaHandler != INVALID_HANDLE && + fast2MaHandler != INVALID_HANDLE && + fast3MaHandler != INVALID_HANDLE && + fast4MaHandler != INVALID_HANDLE && + fast5MaHandler != INVALID_HANDLE && + slow1MaHandler != INVALID_HANDLE && + slow2MaHandler != INVALID_HANDLE && + slow3MaHandler != INVALID_HANDLE && + slow4MaHandler != INVALID_HANDLE && + slow5MaHandler != INVALID_HANDLE; + + // + if (!result) + { + // + string message = "Error Initializing Handlers ..."; + Print(message); + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // FAST ... + ENUM_DRAW_TYPE fastDrawType = showFastMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(fastMaBuffer, true); + SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, showFastMa); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastDrawType); + + // + // SLOW ... + ENUM_DRAW_TYPE slowDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE; + + ArraySetAsSeries(slowMaBuffer, true); + SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, showSlowMa); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowDrawType); + + // + // DATA ... + ENUM_DRAW_TYPE ribbonDrawType = showRibbon ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(fast1Buffer, true); + SetIndexBuffer(fast1BufferIndex, fast1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast2Buffer, true); + SetIndexBuffer(fast2BufferIndex, fast2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast3Buffer, true); + SetIndexBuffer(fast3BufferIndex, fast3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast4Buffer, true); + SetIndexBuffer(fast4BufferIndex, fast4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(fast5Buffer, true); + SetIndexBuffer(fast5BufferIndex, fast5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fast5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fast5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow1Buffer, true); + SetIndexBuffer(slow1BufferIndex, slow1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow1BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow1BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow2Buffer, true); + SetIndexBuffer(slow2BufferIndex, slow2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow2BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow2BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow3Buffer, true); + SetIndexBuffer(slow3BufferIndex, slow3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow3BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow3BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow4Buffer, true); + SetIndexBuffer(slow4BufferIndex, slow4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow4BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow4BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); + + // + ArraySetAsSeries(slow5Buffer, true); + SetIndexBuffer(slow5BufferIndex, slow5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(slow5BufferIndex, PLOT_SHOW_DATA, showRibbon); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(slow5BufferIndex, PLOT_DRAW_TYPE, ribbonDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Retireve Values ... + + // + double fast1Value = fast1Buffer[bar_index]; + double fast2Value = fast2Buffer[bar_index]; + double fast3Value = fast3Buffer[bar_index]; + double fast4Value = fast4Buffer[bar_index]; + double fast5Value = fast5Buffer[bar_index]; + + // + double slow1Value = slow1Buffer[bar_index]; + double slow2Value = slow2Buffer[bar_index]; + double slow3Value = slow3Buffer[bar_index]; + double slow4Value = slow4Buffer[bar_index]; + double slow5Value = slow5Buffer[bar_index]; + + // + double fastValue = (fast1Value + fast2Value + fast3Value + fast4Value + fast5Value) / 5; + fastMaBuffer[bar_index] = fastValue; + + // + double slowValue = (slow1Value + slow2Value + slow3Value + slow4Value + slow5Value) / 5; + slowMaBuffer[bar_index] = slowValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xpv.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xpv.ex5 new file mode 100644 index 0000000..878e0fe Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xpv.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xpv.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xpv.mq5 new file mode 100644 index 0000000..6110e12 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xpv.mq5 @@ -0,0 +1,992 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: X121_XPV +// Description: Market Peaks and Vales +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XPV Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XPV" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length +input int hindLength = 35; // Hind Length +input double fiboLevel1 = 0.382; // Fibio 1st Level +input double fiboLevel2 = 0.5; // Fibio 2st Level +input double fiboLevel3 = 0.618; // Fibio 3rd Level + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showLevels = false; // Show Levels +input bool showFibo1Levels = true; // Show Fibo 1st Level +input bool showFibo2Levels = true; // Show Fibo 2nd Level +input bool showFibo3Levels = true; // Show Fibo 3rd Level + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 26 +#property indicator_plots 18 + +// +// PEKSANDVALES ... + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "X121_XPV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "X121_XPV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "X121_XPV R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 clrAqua, CLR_NONE +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "X121_XPV S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 clrMagenta, CLR_NONE +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "X121_XPV FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "X121_XPV FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "X121_XPV FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// LEVELS ... + +// +#define sHHBufferIndex 12 +#define sHHBufferPlotIndex 7 +double sHHBuffer[]; + +// +#property indicator_label8 "X121_XPV SHH" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrLightGray +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +#define sLLBufferIndex 13 +#define sLLBufferPlotIndex 8 +double sLLBuffer[]; + +// +#property indicator_label9 "X121_XPV SLL" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrLightGray +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +#define mHHBufferIndex 14 +#define mHHBufferPlotIndex 9 +double mHHBuffer[]; + +// +#property indicator_label10 "X121_XPV MHH" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrLightGray +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +#define mLLBufferIndex 15 +#define mLLBufferPlotIndex 10 +double mLLBuffer[]; + +// +#property indicator_label11 "X121_XPV MLL" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrLightGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define lHHBufferIndex 16 +#define lHHBufferPlotIndex 11 +double lHHBuffer[]; + +// +#property indicator_label12 "X121_XPV LHH" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrLightGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define lLLBufferIndex 17 +#define lLLBufferPlotIndex 12 +double lLLBuffer[]; + +// +#property indicator_label13 "X121_XPV LLL" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrLightGray +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define hHHBufferIndex 18 +#define hHHBufferPlotIndex 13 +double hHHBuffer[]; + +// +#property indicator_label14 "X121_XPV HHH" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrLightGray +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define hLLBufferIndex 19 +#define hLLBufferPlotIndex 14 +double hLLBuffer[]; + +// +#property indicator_label15 "X121_XPV HLL" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrLightGray +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +double lastPeak; +double lastVale; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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 = + // + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength && + hindLength > longLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + result = MathMax(result, hindLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RANGE ... + + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + // PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW_SHIFT, -20); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + // PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW_SHIFT, 20); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // BULLISH ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // BULLISH ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // BULLISH ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // BULLISH Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + ENUM_DRAW_TYPE zoneDrawType = showLevels ? DRAW_LINE : DRAW_NONE; + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hHHBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); + + // + // LOW ... + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hLLBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_TYPE, zoneDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + double rColorIDX = 1; + double sColorIDX = 1; + + // + // SHORT ... + + // + // HIGH ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LOW ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HIGH ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LOW ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HIGH ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LOW ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // HIND ... + + // + // HIGH ... + int hHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + hindLength, + bar_index); + double hHHValue = GetAppliedPrice( + hHHIndex, + hhMode); + + // + hHHBuffer[bar_index] = hHHValue; + + // + // LOW ... + int hLLIndex = iLowest( + _Symbol, + _Period, + llMode, + hindLength, + bar_index); + double hLLValue = GetAppliedPrice( + hLLIndex, + llMode); + + // + hLLBuffer[bar_index] = hLLValue; + + // + // RESISTANCE SUPPORT ... + + // + // RESISTANCE ... + double rValue = (sHHValue + mHHValue + lHHValue + hHHValue) / 4; + rBuffer[bar_index] = rValue; + + // + // SUPPORT ... + double sValue = (sLLValue + mLLValue + lLLValue + hLLValue) / 4; + sBuffer[bar_index] = sValue; + + // + // PEAKS and VALES ... + + // + // PEAKS ... + bool isPeak = rValue == hHHValue && + hHHValue == lHHValue && + lHHValue == mHHValue && + mHHValue == sHHValue; + // + if (isPeak && lastPeak != rValue) + { + // + if (showPeaksAndVales) + { + rColorIDX = 0; + } + + // + lastPeak = rValue; + peaksBuffer[bar_index] = lastPeak; + } + else + { + peaksBuffer[bar_index] = lastPeak; + } + + // + // VALES ... + bool isVale = sValue == hLLValue && + hLLValue == lLLValue && + lLLValue == mLLValue && + mLLValue == sLLValue; + + // + if (isVale && lastVale != sValue) + { + // + if (showPeaksAndVales) + { + sColorIDX = 0; + } + + // + lastVale = sValue; + valesBuffer[bar_index] = lastVale; + } + else + { + valesBuffer[bar_index] = lastVale; + } + + // + // Set Default Colors ... + + // + rColorBuffer[bar_index] = rColorIDX; + sColorBuffer[bar_index] = sColorIDX; + + // + // Calculate Fibonacci ... + double upPrice = peaksBuffer[bar_index]; + double downPrice = valesBuffer[bar_index]; + + // + // Level 1 ... + + // + // Bullish ... + double fibLevel1BullishValue = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + fl1Buffer[bar_index] = fibLevel1BullishValue; + double fl1BullColorIdx = showFibo1Levels ? 1 : 0; + fl1ColorBuffer[bar_index] = fl1BullColorIdx; + + // // + // // Bearish ... + // double fibLevel1BearishValue = GetFibonacciLevel( + // upPrice, + // downPrice, + // fiboLevel1, + // 0); + // fl1BearBuffer[bar_index] = fibLevel1BearishValue; + // double fl1BearColorIdx = showFibo1Levels ? 1 : 0; + // fl1BearColorBuffer[bar_index] = fl1BearColorIdx; + + // + // Level 2 ... + + // + // Bullish ... + double fibLevel2BullishValue = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + fl2Buffer[bar_index] = fibLevel2BullishValue; + double fl2BullColorIdx = showFibo2Levels ? 1 : 0; + fl2ColorBuffer[bar_index] = fl2BullColorIdx; + + // // + // // Bearish ... + // double fibLevel2BearishValue = GetFibonacciLevel( + // upPrice, + // downPrice, + // fiboLevel2, + // 0); + // fl2BearBuffer[bar_index] = fibLevel2BearishValue; + // double fl2BearColorIdx = showFibo2Levels ? 1 : 0; + // fl2BearColorBuffer[bar_index] = fl2BearColorIdx; + + // + // Level 3 ... + + // + // Bullish ... + double fibLevel3BullishValue = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + fl3Buffer[bar_index] = fibLevel3BullishValue; + double fl3BullColorIdx = showFibo3Levels ? 1 : 0; + fl3ColorBuffer[bar_index] = fl3BullColorIdx; + + // // + // // Bearish ... + // double fibLevel3BearishValue = GetFibonacciLevel( + // upPrice, + // downPrice, + // fiboLevel3, + // 0); + // fl3BearBuffer[bar_index] = fibLevel3BearishValue; + // double fl3BearColorIdx = showFibo3Levels ? 1 : 0; + // fl3BearColorBuffer[bar_index] = fl3BearColorIdx; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xsslc.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xsslc.ex5 new file mode 100644 index 0000000..0a292c2 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xsslc.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xsslc.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xsslc.mq5 new file mode 100644 index 0000000..e682067 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xsslc.mq5 @@ -0,0 +1,437 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ---------------------------------------------------- +// Name: X121_XSSLC +// Description: SSL Channel Indicator +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XSSLC Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XSSLC" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 36; // Length + +// +input group "Calculation"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Applied To +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Applied To + +// +input group "Presentation"; +input bool showUp = true; // Show Up +input bool showDown = true; // Show Down + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 2 + +// +// PLOTTED Buffers ... + +// +#define upBufferIndex 0 +double upBuffer[]; + +// +#property indicator_label1 "X121_XSSLC Up" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#define downBufferIndex 1 +double downBuffer[]; + +// +#property indicator_label2 "X121_XSSLC Down" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// DATA Buffers ... + +// +#define upMaBufferIndex 2 +double upMaBuffer[]; + +// +#define downMaBufferIndex 3 +double downMaBuffer[]; + +// +#define kpiBufferIndex 4 +double kpiBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int upHandler = INVALID_HANDLE; +int downHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initialize Requierd Handlers ... + upHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + upAppliedTo); + downHandler = iMA( + _Symbol, + _Period, + length, + 0, + method, + downAppliedTo); + if (upHandler == INVALID_HANDLE || downHandler == INVALID_HANDLE) + { + // + string msg = "Error in Initilizing Indicator ..."; + Print(msg); + + // + 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 + + // + // Release Indicators ... + IndicatorRelease(upHandler); + IndicatorRelease(downHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int upCalculatedBars = BarsCalculated(upHandler); + int downCalculatedBars = BarsCalculated(downHandler); + if (upCalculatedBars < maxLength || + downCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedUps = CopyBuffer(upHandler, 0, 0, limit, upMaBuffer); + int copiedDowns = CopyBuffer(downHandler, 0, 0, limit, downMaBuffer); + if (copiedUps <= 0 || + copiedDowns <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i, limit, rates_total, prev_calculated, close); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (length > 2) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(result, length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // UP ... + + // + ENUM_DRAW_TYPE upDrawType = showUp ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(upBuffer, true); + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_DATA); + PlotIndexSetInteger(upBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(upBufferIndex, PLOT_DRAW_TYPE, upDrawType); + + // + // DOWN ... + + // + ENUM_DRAW_TYPE downDrawType = showDown ? DRAW_LINE : DRAW_NONE; + + + ArraySetAsSeries(downBuffer, true); + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_DATA); + PlotIndexSetInteger(downBufferIndex, PLOT_SHOW_DATA, showDown); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(downBufferIndex, PLOT_DRAW_TYPE, downDrawType); + + // + // DATA Buffers ... + + // + // UP MA ... + ArraySetAsSeries(upMaBuffer, true); + SetIndexBuffer(upMaBufferIndex, upMaBuffer, INDICATOR_CALCULATIONS); + + // + // DOWN MA ... + ArraySetAsSeries(downMaBuffer, true); + SetIndexBuffer(downMaBufferIndex, downMaBuffer, INDICATOR_CALCULATIONS); + + // + // KPI ... + ArraySetAsSeries(kpiBuffer, true); + SetIndexBuffer(kpiBufferIndex, kpiBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + int limit, + int ratesTotal, + int prevCalculated, + const double &close[]) +{ + // + double upMaValue = upMaBuffer[bar_index]; + double downMaValue = downMaBuffer[bar_index]; + + // + double closeValue = close[bar_index]; + + // + double kpiValue; + if (closeValue > upMaValue) { + kpiValue = 1; + } else if (closeValue < downMaValue) { + kpiValue = -1; + } else { + kpiValue = kpiBuffer[bar_index + 1]; + } + + // + kpiBuffer[bar_index] = kpiValue; + + // + double upValue = kpiValue < 0 ? downMaValue : upMaValue; + upBuffer[bar_index] = upValue; + + // + double downValue = kpiValue < 0 ? upMaValue : downMaValue; + downBuffer[bar_index] = downValue; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xtm.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtm.ex5 new file mode 100644 index 0000000..f8abd49 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtm.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xtm.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtm.mq5 new file mode 100644 index 0000000..c483d3b --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtm.mq5 @@ -0,0 +1,354 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_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 X121_XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "X121_XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 0, + X_XTM_BEARISH = 2, + X_XTM_NEUTURAL = 1, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int length = 35; // Length +input int shift = 0; // Shift + +// +input group "Calculations"; +input ENUM_MA_METHOD method = MODE_SMA; // Method +input ENUM_APPLIED_PRICE appliedTo = PRICE_LOW; // Applied To + +// +input group "Presentation"; +input bool showLine = true; // Show Line + +// +// END Inputs ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 2 +#property indicator_plots 2 + +// +// maBuffer ... +#define maBufferIndex 0 +double maBuffer[]; + +#define maColorBufferIndex 1 +double maColorBuffer[]; + +// +#property indicator_label1 "X121_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 maxLength; + +// +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; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + length, + shift, + method, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + Print(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); +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // Check Calculated Bars ... + int 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; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ENUM_DRAW_TYPE drawType = showLine ? DRAW_COLOR_LINE : DRAW_NONE; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, drawType); + PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showLine); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// 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; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xtrnd.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtrnd.ex5 new file mode 100644 index 0000000..9004830 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtrnd.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.x121.xtrnd.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtrnd.mq5 new file mode 100644 index 0000000..a5d92fc --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.x121.xtrnd.mq5 @@ -0,0 +1,1253 @@ +///////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// -------------------------------------------------- +// Name: X121_XTRND +// Description: Market Trend Detector ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XTRND Indicator" +#property strict + +// +// START Constants ... +// + +// +// Indicator Short Name ... +#define ShortName "X121_XTRND" + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Makret"; +input int cycleLength = 2; // Cycle Length to Check +input int numberOfVerifications = 2; // Number of Verifications + +// +input group "Calculation"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Detect Up +input ENUM_SERIESMODE llMode = MODE_LOW; // Detect Low + +// +input group "Cycles"; + +// +input group "Level 1"; +input ENUM_X_PERIOD_METHOD l1Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l1Period = NULL; // Time Period + +// +input group "Level 2"; +input ENUM_X_PERIOD_METHOD l2Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l2Period = NULL; // Time Period + +// +input group "Level 3"; +input ENUM_X_PERIOD_METHOD l3Method = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES l3Period = NULL; // Time Period + +// +input group "Presentation"; +input bool showConsolidations = false; // Show Consolidations +input bool showTrend = true; // Show Trend +input bool showL1Trend = false; // Show Cycle 1 Trend +input bool showL2Trend = false; // Show Cycle 2 Trend +input bool showL3Trend = false; // Show Cycle 3 Trend + +// +// END Inputs ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START Buffers ... +// + +// +#property indicator_chart_window + +// +#property indicator_buffers 24 +#property indicator_plots 16 + +// +// Higher High ... +#define hhBufferIndex 0 +#define hhPlotBufferIndex 0 +double hhBuffer[]; + +#define hhColorBufferIndex 1 +double hhColorBuffer[]; + +// +#property indicator_label1 "X121_XTRND U" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// Lower Low ... +#define llBufferIndex 2 +#define llPlotBufferIndex 1 +double llBuffer[]; + +#define llColorBufferIndex 3 +double llColorBuffer[]; + +// +#property indicator_label2 "X121_XTRND D" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// CYCLE 1 ... + +// +// Higher High ... +#define l1hhBufferIndex 4 +#define l1hhPlotBufferIndex 2 +double l1hhBuffer[]; + +#define l1hhColorBufferIndex 5 +double l1hhColorBuffer[]; + +// +#property indicator_label3 "X121_XTRND C1 U" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Lower Low ... +#define l1llBufferIndex 6 +#define l1llPlotBufferIndex 3 +double l1llBuffer[]; + +#define l1llColorBufferIndex 7 +double l1llColorBuffer[]; + +// +#property indicator_label4 "X121_XTRND C1 D" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// CYCLE 2 ... + +// +// Higher High ... +#define l2hhBufferIndex 8 +#define l2hhPlotBufferIndex 4 +double l2hhBuffer[]; + +#define l2hhColorBufferIndex 9 +double l2hhColorBuffer[]; + +// +#property indicator_label5 "X121_XTRND C2 U" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// Lower Low ... +#define l2llBufferIndex 10 +#define l2llPlotBufferIndex 5 +double l2llBuffer[]; + +#define l2llColorBufferIndex 11 +double l2llColorBuffer[]; + +// +#property indicator_label6 "X121_XTRND C2 D" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +// CYCLE 3 ... + +// +// Higher High... +#define l3hhBufferIndex 12 +#define l3hhPlotBufferIndex 6 +double l3hhBuffer[]; + +#define l3hhColorBufferIndex 13 +double l3hhColorBuffer[]; + +// +#property indicator_label7 "X121_XTRND C3 U" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// Lower Low ... +#define l3llBufferIndex 14 +#define l3llPlotBufferIndex 7 +double l3llBuffer[]; + +#define l3llColorBufferIndex 15 +double l3llColorBuffer[]; + +// +#property indicator_label8 "X121_XTRND C3 D" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +// DATA Buffers ... + +#define hhStateBufferIndex 16 +#define llStateBufferIndex 17 +double hhStateBuffer[]; +double llStateBuffer[]; + +#define l1HHStateBufferIndex 18 +#define l1LLStateBufferIndex 19 +double l1HHStateBuffer[]; +double l1LLStateBuffer[]; + +#define l2HHStateBufferIndex 20 +#define l2LLStateBufferIndex 21 +double l2HHStateBuffer[]; +double l2LLStateBuffer[]; + +#define l3HHStateBufferIndex 22 +#define l3LLStateBufferIndex 23 +double l3HHStateBuffer[]; +double l3LLStateBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +int currentPeriodSecconds = 0; + +// +// CYCLE 1 ... +int mL1Candles; +int mL1PeriodSecconds = 0; +int mLastL1StartBarIndex = 0; +datetime mLastL1StartTime = NULL; +ENUM_TIMEFRAMES mL1Period = NULL; + +// +// CYCLE 2 ... +int mL2Candles; +int mL2PeriodSecconds = 0; +int mLastL2StartBarIndex = 0; +datetime mLastL2StartTime = NULL; +ENUM_TIMEFRAMES mL2Period = NULL; + +// +// CYCLE 3 ... +int mL3Candles; +int mL3PeriodSecconds = 0; +int mLastL3StartBarIndex = 0; +datetime mLastL3StartTime = NULL; +ENUM_TIMEFRAMES mL3Period = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Initial Periods ... + InitialCycles(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (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 = + // + (cycleLength > 0 && + numberOfVerifications > 0) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax( + cycleLength, + numberOfVerifications); + + // + return result; +} + +// +// Initial Multi Time Frame Cycles Periods ... +void InitialCycles() +{ + // + // Calculate Current Period Secconds ... + currentPeriodSecconds = PeriodSeconds(_Period); + + // + // Nearest ... + // Calculate Cycle 1 Requirements ... + if (mL1Period == NULL) + { + // + if (l1Method == X_PERIOD_AUTO) + { + mL1Period = GetNearestTimeFrame(_Period); + } + else + { + mL1Period = l1Period; + } + + // + mL1PeriodSecconds = PeriodSeconds(mL1Period); + + // + mL1Candles = mL1PeriodSecconds / currentPeriodSecconds; + } + + // + // Mediest ... + // Calculate Cycle 2 Requirements ... + if (mL2Period == NULL) + { + // + if (l2Method == X_PERIOD_AUTO) + { + mL2Period = GetMediestTimeFrame(_Period); + } + else + { + mL2Period = l2Period; + } + + // + mL2PeriodSecconds = PeriodSeconds(mL2Period); + + // + mL2Candles = mL2PeriodSecconds / currentPeriodSecconds; + } + + // + // Farest ... + // Calculate Cycle 3 Requirements ... + if (mL3Period == NULL) + { + // + if (l3Method == X_PERIOD_AUTO) + { + mL3Period = GetFarestTimeFrame(_Period); + } + else + { + mL3Period = l3Period; + } + + // + mL3PeriodSecconds = PeriodSeconds(mL3Period); + + // + mL3Candles = mL3PeriodSecconds / currentPeriodSecconds; + } +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(hhColorBuffer, true); + SetIndexBuffer(hhColorBufferIndex, hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(llPlotBufferIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetInteger(llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(llColorBuffer, true); + SetIndexBuffer(llColorBufferIndex, llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // CYCLES ... + + // + // NEAREST ... + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l1hhBuffer, true); + SetIndexBuffer(l1hhBufferIndex, l1hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l1hhPlotBufferIndex, PLOT_SHOW_DATA, showL1Trend); + PlotIndexSetInteger(l1hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l1hhColorBuffer, true); + SetIndexBuffer(l1hhColorBufferIndex, l1hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l1llBuffer, true); + SetIndexBuffer(l1llBufferIndex, l1llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l1llPlotBufferIndex, PLOT_SHOW_DATA, showL1Trend); + PlotIndexSetInteger(l1llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l1llColorBuffer, true); + SetIndexBuffer(l1llColorBufferIndex, l1llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIEST ... + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l2hhBuffer, true); + SetIndexBuffer(l2hhBufferIndex, l2hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l2hhPlotBufferIndex, PLOT_SHOW_DATA, showL2Trend); + PlotIndexSetInteger(l2hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l2hhColorBuffer, true); + SetIndexBuffer(l2hhColorBufferIndex, l2hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l2llBuffer, true); + SetIndexBuffer(l2llBufferIndex, l2llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l2llPlotBufferIndex, PLOT_SHOW_DATA, showL2Trend); + PlotIndexSetInteger(l2llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l2llColorBuffer, true); + SetIndexBuffer(l2llColorBufferIndex, l2llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FAREST ... + + // + // HH Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l3hhBuffer, true); + SetIndexBuffer(l3hhBufferIndex, l3hhBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l3hhPlotBufferIndex, PLOT_SHOW_DATA, showL3Trend); + PlotIndexSetInteger(l3hhPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l3hhColorBuffer, true); + SetIndexBuffer(l3hhColorBufferIndex, l3hhColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LL Buffer ... + + // + // SERIES ... + ArraySetAsSeries(l3llBuffer, true); + SetIndexBuffer(l3llBufferIndex, l3llBuffer, INDICATOR_DATA); + + // + // PLOT Config ... + PlotIndexSetInteger(l3llPlotBufferIndex, PLOT_SHOW_DATA, showL3Trend); + PlotIndexSetInteger(l3llPlotBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // COLOR Buffer ... + ArraySetAsSeries(l3llColorBuffer, true); + SetIndexBuffer(l3llColorBufferIndex, l3llColorBuffer, INDICATOR_COLOR_INDEX); + + // + // DATA Buffers ... + ArraySetAsSeries(hhStateBuffer, true); + SetIndexBuffer(hhStateBufferIndex, hhStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(llStateBuffer, true); + SetIndexBuffer(llStateBufferIndex, llStateBuffer, INDICATOR_CALCULATIONS); + + // + // LEVEL 1 ... + ArraySetAsSeries(l1HHStateBuffer, true); + SetIndexBuffer(l1HHStateBufferIndex, l1HHStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(l1LLStateBuffer, true); + SetIndexBuffer(l1LLStateBufferIndex, l1LLStateBuffer, INDICATOR_CALCULATIONS); + + // + // LEVEL 2 ... + ArraySetAsSeries(l2HHStateBuffer, true); + SetIndexBuffer(l2HHStateBufferIndex, l2HHStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(l2LLStateBuffer, true); + SetIndexBuffer(l2LLStateBufferIndex, l2LLStateBuffer, INDICATOR_CALCULATIONS); + + // + // LEVEL 3 ... + ArraySetAsSeries(l3HHStateBuffer, true); + SetIndexBuffer(l3HHStateBufferIndex, l3HHStateBuffer, INDICATOR_CALCULATIONS); + + ArraySetAsSeries(l3LLStateBuffer, true); + SetIndexBuffer(l3LLStateBufferIndex, l3LLStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // HIGHER Highs ... + double hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + cycleLength, + bar_index); + + // + hhBuffer[bar_index] = hh; + + // + // LOWER Lows ... + double ll = GetLowestLow( + _Symbol, + _Period, + llMode, + cycleLength, + bar_index); + + // + llBuffer[bar_index] = ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double hhColorIDX = showConsolidations && showTrend ? 1 : 0; + double llColorIDX = showConsolidations && showTrend ? 1 : 0; + hhColorBuffer[bar_index] = hhColorIDX; + llColorBuffer[bar_index] = llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int cycleCLength = cycleLength * numberOfVerifications; + bool isCycleCLengthPassed = MathAbs(ArraySize(hhBuffer) - bar_index) > cycleCLength + 1; + + // + if (isCycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + cycleCLength; i++) + { + // + double iHH = hhBuffer[i]; + double iLL = llBuffer[i]; + + // + if (hh < iHH) + { + isHighsestHighUp = false; + } + else if (hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (ll < iLL) + { + isLowestLowUp = false; + } + else if (ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + hhColorIDX = 2; + llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + hhColorIDX = 3; + llColorIDX = 3; + } + } + + // + if (showTrend) + { + // + hhColorBuffer[bar_index] = hhColorIDX; + llColorBuffer[bar_index] = llColorIDX; + } + + // + hhColorIDX = + hhColorIDX == 0 || hhColorIDX == 1 + ? 0 + : hhColorIDX - 1; + llColorIDX = + llColorIDX == 0 || llColorIDX == 1 + ? 0 + : llColorIDX - 1; + + // + hhStateBuffer[bar_index] = hhColorIDX; + llStateBuffer[bar_index] = llColorIDX; + + // + // CYCLE 1 ... + + // + int l1cycleLength = cycleLength * mL1Candles; + + // + // HIGHER Highs ... + double l1hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l1cycleLength, + bar_index); + + // + l1hhBuffer[bar_index] = l1hh; + + // + // LOWER Lows ... + double l1ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l1cycleLength, + bar_index); + + // + l1llBuffer[bar_index] = l1ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l1hhColorIDX = showConsolidations && showL1Trend ? 1 : 0; + double l1llColorIDX = showConsolidations && showL1Trend ? 1 : 0; + l1hhColorBuffer[bar_index] = l1hhColorIDX; + l1llColorBuffer[bar_index] = l1llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int l1cycleCLength = l1cycleLength * numberOfVerifications; + bool isl1CycleCLengthPassed = MathAbs(ArraySize(l1hhBuffer) - bar_index) > l1cycleCLength + 1; + + // + if (isl1CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l1cycleCLength; i++) + { + // + double iHH = l1hhBuffer[i]; + double iLL = l1llBuffer[i]; + + // + if (l1hh < iHH) + { + isHighsestHighUp = false; + } + else if (l1hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l1ll < iLL) + { + isLowestLowUp = false; + } + else if (l1ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l1hhColorIDX = 2; + l1llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l1hhColorIDX = 3; + l1llColorIDX = 3; + } + } + + // + if (showL1Trend) + { + // + l1hhColorBuffer[bar_index] = l1hhColorIDX; + l1llColorBuffer[bar_index] = l1llColorIDX; + } + + // + l1hhColorIDX = + l1hhColorIDX == 0 || l1hhColorIDX == 1 + ? 0 + : l1hhColorIDX - 1; + l1llColorIDX = + l1llColorIDX == 0 || l1llColorIDX == 1 + ? 0 + : l1llColorIDX - 1; + + // + l1HHStateBuffer[bar_index] = l1hhColorIDX; + l1LLStateBuffer[bar_index] = l1llColorIDX; + + + // + // CYCLE 2 ... + + // + int l2cycleLength = cycleLength * mL2Candles; + + // + // HIGHER Highs ... + double l2hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l2cycleLength, + bar_index); + + // + l2hhBuffer[bar_index] = l2hh; + + // + // LOWER Lows ... + double l2ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l2cycleLength, + bar_index); + + // + l2llBuffer[bar_index] = l2ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l2hhColorIDX = showConsolidations && showL2Trend ? 1 : 0; + double l2llColorIDX = showConsolidations && showL2Trend ? 1 : 0; + l2hhColorBuffer[bar_index] = l2hhColorIDX; + l2llColorBuffer[bar_index] = l2llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int l2cycleCLength = l2cycleLength * numberOfVerifications; + bool isl2CycleCLengthPassed = MathAbs(ArraySize(l2hhBuffer) - bar_index) > l2cycleCLength + 1; + + // + if (isl2CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l2cycleCLength; i++) + { + // + double iHH = l2hhBuffer[i]; + double iLL = l2llBuffer[i]; + + // + if (l2hh < iHH) + { + isHighsestHighUp = false; + } + else if (l2hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l2ll < iLL) + { + isLowestLowUp = false; + } + else if (l2ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l2hhColorIDX = 2; + l2llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l2hhColorIDX = 3; + l2llColorIDX = 3; + } + } + + // + if (showL2Trend) + { + // + l2hhColorBuffer[bar_index] = l2hhColorIDX; + l2llColorBuffer[bar_index] = l2llColorIDX; + } + + // + l2hhColorIDX = + l2hhColorIDX == 0 || l2hhColorIDX == 1 + ? 0 + : l2hhColorIDX - 1; + l2llColorIDX = + l2llColorIDX == 0 || l2llColorIDX == 1 + ? 0 + : l2llColorIDX - 1; + + // + l2HHStateBuffer[bar_index] = l2hhColorIDX; + l2LLStateBuffer[bar_index] = l2llColorIDX; + + // + // CYCLE 3 ... + + // + int l3cycleLength = cycleLength * mL3Candles; + + // + // HIGHER Highs ... + double l3hh = GetHighestHigh( + _Symbol, + _Period, + hhMode, + l3cycleLength, + bar_index); + + // + l3hhBuffer[bar_index] = l3hh; + + // + // LOWER Lows ... + double l3ll = GetLowestLow( + _Symbol, + _Period, + llMode, + l3cycleLength, + bar_index); + + // + l3llBuffer[bar_index] = l3ll; + + // + // Set Default Color ... + // in Consolidations use index 0 for CLR_NONE ... + double l3hhColorIDX = showConsolidations && showL3Trend ? 1 : 0; + double l3llColorIDX = showConsolidations && showL3Trend ? 1 : 0; + l3hhColorBuffer[bar_index] = l3hhColorIDX; + l3llColorBuffer[bar_index] = l3llColorIDX; + + // + // Calculate Cycle Changes ... + + // + int l3cycleCLength = l3cycleLength * numberOfVerifications; + bool isl3CycleCLengthPassed = MathAbs(ArraySize(l3hhBuffer) - bar_index) > l3cycleCLength + 1; + + // + if (isl3CycleCLengthPassed) + { + // + bool isLowestLowUp = true; + bool isLowestLowDown = true; + bool isHighsestHighUp = true; + bool isHighsestHighDown = true; + for (int i = bar_index; i < bar_index + l3cycleCLength; i++) + { + // + double iHH = l3hhBuffer[i]; + double iLL = l3llBuffer[i]; + + // + if (l3hh < iHH) + { + isHighsestHighUp = false; + } + else if (l3hh > iHH) + { + isHighsestHighDown = false; + } + + // + if (l3ll < iLL) + { + isLowestLowUp = false; + } + else if (l3ll > iLL) + { + isLowestLowDown = false; + } + } + + // + // Detect Trends and Change Colors ... + + // + if (isLowestLowUp && + isHighsestHighUp) + { + // + l3hhColorIDX = 2; + l3llColorIDX = 2; + } + + // + if (isLowestLowDown && + isHighsestHighDown) + { + // + l3hhColorIDX = 3; + l3llColorIDX = 3; + } + } + + // + if (showL3Trend) + { + // + l3hhColorBuffer[bar_index] = l3hhColorIDX; + l3llColorBuffer[bar_index] = l3llColorIDX; + } + + // + l3hhColorIDX = + l3hhColorIDX == 0 || l3hhColorIDX == 1 + ? 0 + : l3hhColorIDX - 1; + l3llColorIDX = + l3llColorIDX == 0 || l3llColorIDX == 1 + ? 0 + : l3llColorIDX - 1; + + // + l3HHStateBuffer[bar_index] = l3hhColorIDX; + l3LLStateBuffer[bar_index] = l3llColorIDX; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/Indicators/x-saherelm.xchnl.ex5 b/MQLTestWorkspace/Indicators/x-saherelm.xchnl.ex5 new file mode 100644 index 0000000..0ed2147 Binary files /dev/null and b/MQLTestWorkspace/Indicators/x-saherelm.xchnl.ex5 differ diff --git a/MQLTestWorkspace/Indicators/x-saherelm.xchnl.mq5 b/MQLTestWorkspace/Indicators/x-saherelm.xchnl.mq5 new file mode 100644 index 0000000..c850540 --- /dev/null +++ b/MQLTestWorkspace/Indicators/x-saherelm.xchnl.mq5 @@ -0,0 +1,775 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: X121_XCHNL +// Description: XCHL Channel Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121_XCHNL Indicator" +#property strict + +// +// START Constants ... +// + +// +#define ShortName "X121_XCHNL" + +// +// END Constants ... +// + +// +// START Includes and Imports ... +// + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// END Includes and Imports ... +// + +// +// START XSCHULL Class Definition ... +// + +// +// END XSCHULL Class Definition ... +// + +// +// START Inputs ... +// + +// +input group "Makret Cycles"; +input int shortLength = 9; // Short Length +input int mediumLength = 17; // Medium Length +input int longLength = 26; // Long Length +input int hindLength = 35; // Hind Length + +// +input group "Trend"; +input int numOfShoulder = 10; // Number of Shoulders for Swings + +// +input group "Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showTrend = false; // Show Trend +input bool showSRs = false; // Show Support and Resistance + +// +// END Inputs ... +// + +// +// START Buffers ... +// + +// +// PEKSANDVALES ... + +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 0 + +#define sHHBufferIndex 0 +#define sLLBufferIndex 1 +#define mHHBufferIndex 2 +#define mLLBufferIndex 3 +#define lHHBufferIndex 4 +#define lLLBufferIndex 5 +#define hHHBufferIndex 6 +#define hLLBufferIndex 7 + +double sHHBuffer[]; +double sLLBuffer[]; +double mHHBuffer[]; +double mLLBuffer[]; +double lHHBuffer[]; +double lLLBuffer[]; +double hHHBuffer[]; +double hLLBuffer[]; + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int maxLength; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Make an Instance of Hull Class ... + + // + // 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 mPeriod 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 + + // + RemoveDraws(drawPrefix); +} + +// +// 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[]) +{ + // + // this counts Available Bars ... + int limit; + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + // + // Validate Peaks and Vales ... + (shortLength > 2 && + mediumLength > shortLength && + longLength > mediumLength && + hindLength > longLength) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Peaks and Vales ... + result = MathMax(shortLength, mediumLength); + result = MathMax(result, longLength); + result = MathMax(result, hindLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_CALCULATIONS); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate ... + + // + // SHORT ... + + // + // HIGH ... + int sHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + shortLength, + bar_index); + double sHHValue = GetAppliedPrice( + sHHIndex, + hhMode); + + // + sHHBuffer[bar_index] = sHHValue; + + // + // LOW ... + int sLLIndex = iLowest( + _Symbol, + _Period, + llMode, + shortLength, + bar_index); + double sLLValue = GetAppliedPrice( + sLLIndex, + llMode); + + // + sLLBuffer[bar_index] = sLLValue; + + // + // MEDIUM ... + + // + // HIGH ... + int mHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + mediumLength, + bar_index); + double mHHValue = GetAppliedPrice( + mHHIndex, + hhMode); + + // + mHHBuffer[bar_index] = mHHValue; + + // + // LOW ... + int mLLIndex = iLowest( + _Symbol, + _Period, + llMode, + mediumLength, + bar_index); + double mLLValue = GetAppliedPrice( + mLLIndex, + llMode); + + // + mLLBuffer[bar_index] = mLLValue; + + // + // LONG ... + + // + // HIGH ... + int lHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + longLength, + bar_index); + double lHHValue = GetAppliedPrice( + lHHIndex, + hhMode); + + // + lHHBuffer[bar_index] = lHHValue; + + // + // LOW ... + int lLLIndex = iLowest( + _Symbol, + _Period, + llMode, + longLength, + bar_index); + double lLLValue = GetAppliedPrice( + lLLIndex, + llMode); + + // + lLLBuffer[bar_index] = lLLValue; + + // + // HIND ... + + // + // HIGH ... + int hHHIndex = iHighest( + _Symbol, + _Period, + hhMode, + hindLength, + bar_index); + double hHHValue = GetAppliedPrice( + hHHIndex, + hhMode); + + // + hHHBuffer[bar_index] = hHHValue; + + // + // LOW ... + int hLLIndex = iLowest( + _Symbol, + _Period, + llMode, + hindLength, + bar_index); + double hLLValue = GetAppliedPrice( + hLLIndex, + llMode); + + // + hLLBuffer[bar_index] = hLLValue; + + // + // Find Swings ... + + // + // High ... + int hSwing1 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + bar_index + 1); + + int hSwing2 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing1 + 1); + + // + // High ... + int hSwing3 = FindSwing( + _Symbol, + _Period, + MODE_HIGH, + numOfShoulder, + hSwing2 + 1); + + // int hSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_HIGH, + // numOfShoulder, + // hSwing3 + 1); + + // + // Low ... + int lSwing1 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + bar_index + 1); + + int lSwing2 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing1 + 1); + + int lSwing3 = FindSwing( + _Symbol, + _Period, + MODE_LOW, + numOfShoulder, + lSwing2 + 1); + + // int lSwing4 = FindSwing( + // _Symbol, + // _Period, + // MODE_LOW, + // numOfShoulder, + // lSwing3 + 1); + + // + if (bar_index < 50) + { + + // + bool isStrongResistance = + // + hHHBuffer[bar_index + 1] == hHHBuffer[bar_index + 2] && + hHHBuffer[bar_index + 2] == hHHBuffer[bar_index + 3] && + // + lHHBuffer[bar_index + 1] == lHHBuffer[bar_index + 2] && + lHHBuffer[bar_index + 2] == lHHBuffer[bar_index + 3] && + // + mHHBuffer[bar_index + 1] == mHHBuffer[bar_index + 2] && + mHHBuffer[bar_index + 2] == mHHBuffer[bar_index + 3] && + // + sHHBuffer[bar_index + 1] == sHHBuffer[bar_index + 2] && + sHHBuffer[bar_index + 2] == sHHBuffer[bar_index + 3] + // + ; + + // + bool isStrongSupport = + // + hLLBuffer[bar_index + 1] == hLLBuffer[bar_index + 2] && + hLLBuffer[bar_index + 2] == hLLBuffer[bar_index + 3] && + // + lLLBuffer[bar_index + 1] == lLLBuffer[bar_index + 2] && + lLLBuffer[bar_index + 2] == lLLBuffer[bar_index + 3] && + // + mLLBuffer[bar_index + 1] == mLLBuffer[bar_index + 2] && + mLLBuffer[bar_index + 2] == mLLBuffer[bar_index + 3] && + // + sLLBuffer[bar_index + 1] == sLLBuffer[bar_index + 2] && + sLLBuffer[bar_index + 2] == sLLBuffer[bar_index + 3] + // + ; + + // + if (isStrongResistance && showSRs) + { + // + DrawSupportResistance( + "R", + clrRed, + sHHBuffer[bar_index + 3], + bar_index + 3); + } + + // + if (isStrongSupport && showSRs) + { + // + DrawSupportResistance( + "S", + clrGreen, + sLLBuffer[bar_index + 3], + bar_index + 3); + } + } + + // + if (showTrend && bar_index < 20) + { + // + DrawSwing( + "High1", + MODE_HIGH, + clrAqua, + hSwing1, + hSwing2); + + // + DrawSwing( + "Low1", + MODE_LOW, + clrAqua, + lSwing1, + lSwing2); + + // + DrawSwing( + "High2", + MODE_HIGH, + clrMagenta, + hSwing2, + hSwing3); + + // + DrawSwing( + "Low2", + MODE_LOW, + clrMagenta, + lSwing2, + lSwing3); + } +} + +// +void DrawSwing( + string prefix, // Prefix ... + ENUM_SERIESMODE mode, // Swing Mode ... + color swingColor, // Color ... + int index1, // Index 1 ... + int index2 // Index 2 ... +) +{ + // + if (mode != MODE_HIGH && mode != MODE_LOW) + { + return; + } + + // + XOHCL c1 = GetCandle( + _Symbol, + _Period, + index1); + + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + index1); + + // + XOHCL c2 = GetCandle( + _Symbol, + _Period, + index2); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + index2); + + // + double value1 = -1; + double value2 = -1; + + // + switch (mode) + { + // + case MODE_HIGH: + value1 = c1.high; + value2 = c2.high; + break; + + // + case MODE_LOW: + value1 = c1.low; + value2 = c2.low; + break; + } + + // + if (value1 == -1 || value2 == -1) + { + return; + } + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TrendLine"; + + // // + // if (IsDrawExists(tlName)) { + // RemoveDraw(tlName); + // } + + // + DrawTrendLine( + chartId, + tlName, + 0, + time2, + value2, + time1, + value1, + swingColor, + STYLE_DOT, + 3, + false, + false, + true); +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + string prefix, // Prefix ... + color lColor, // Color ... + double price, // Support or Resistance price ... + int bar_index // Start Bar Index ... +) +{ + // + datetime time1 = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime time2 = GetCandleTime( + _Symbol, + _Period, + bar_index - 1); + + // + long chartId = ChartID(); + string tlName = prefix + "_" + "TL" + "_" + (string)(NormalizePrice(price, _Symbol)); + + // + DrawTrendLine( + chartId, + tlName, + 0, + time1, + price, + time2, + price, + lColor, + STYLE_DOT, + 3, + false, + false, + true); +} diff --git a/MQLTestWorkspace/Libraries/x-saherelm.alert.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.alert.lib.ex5 new file mode 100644 index 0000000..0c761ae Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.alert.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.alert.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.alert.lib.mq5 new file mode 100644 index 0000000..429d830 --- /dev/null +++ b/MQLTestWorkspace/Libraries/x-saherelm.alert.lib.mq5 @@ -0,0 +1,187 @@ +/////////////////////////////////////////////////////// +// +// 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); + } +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/Libraries/x-saherelm.common.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.common.lib.ex5 new file mode 100644 index 0000000..b41cad3 Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.common.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.common.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..f9b09b3 --- /dev/null +++ b/MQLTestWorkspace/Libraries/x-saherelm.common.lib.mq5 @@ -0,0 +1,5193 @@ +/////////////////////////////////////////////////////// +// +// 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; +} +bool IsNewCandle( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod // Trading Time Frame ... +) +{ + // + bool result = false; + + // + static string mChartTags[]; + static int mChartBars[]; + + // + string chTag = mSymbol + "," + ToString(mPeriod); + + // + int currChTagIdx = -1; + int chCountedBars = 0; + int currentBars = Bars(mSymbol, mPeriod); + + // + if (ArraySize(mChartTags) > 0) + { + // + for (int i = 0; i < ArraySize(mChartTags); i++) + { + // + string iTag = mChartTags[i]; + if (iTag != chTag) + { + continue; + } + + // + currChTagIdx = i; + break; + } + + // + if (currChTagIdx > -1) + { + chCountedBars = mChartBars[currChTagIdx]; + } + } + + // + result = currentBars > chCountedBars; + if (result) + { + // + if (currChTagIdx > -1) + { + // + mChartTags[currChTagIdx] = chTag; + mChartBars[currChTagIdx] = currentBars; + } + else + { + // + Add(chTag, mChartTags); + Add(currentBars, mChartBars); + } + } + + // + return result; +} + +// +double XNZ(double check, double val = 0) +{ + if (check == EMPTY_VALUE || check == 0) + { + return val; + } + else + { + return check; + } +} + +// +// 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_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == NULL) + { + return result; + } + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == NULL) + { + return result; + } + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + // Validate Arg ... + if (type == NULL) + { + return result; + } + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Determine a Position type is Long or not ... +bool IsLong(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_BUY; + + // + return result; +} +bool IsLong(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_BUY; + + // + return result; +} + +// +// Determine a Position type is Short or not ... +bool IsShort(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_SELL; + + // + return result; +} +bool IsShort(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_SELL; + + // + 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; +} + +// +// Convert Price to Point ... +double PriceToPoint( + double price // the price amount which required to calculate +) +{ + return PriceToPoint(_Symbol, price); +} +double PriceToPoint( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = price / point; + + // + return result; +} + +// +// Converts Point to Price ... +double PointToPrice( + double points // Points Size +) +{ + return PointToPrice(_Symbol, points); +} +double PointToPrice( + string symbol, // Selected Symbol + double points // Points Size +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = points * point; + + // + 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; +} + +// +// Check a Candle is Base Candle for RTM or not ... +bool IsBaseCandle( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + bool result = body > range; + + // + 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 CandleHasStrongBody(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 = CandleHasStrongBody(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 = CandleHasStrongBody(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 = CandleHasStrongBody(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; +} + +// +// Find Swing Points ... +int FindSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (StringLen(mSymbol) == 0 || (mode != MODE_HIGH && mode != MODE_LOW)) + { + return result; + } + + // + int current = bar_index; + int founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + + // + while (founded != current) + { + // + current = FindNextSwing( + mSymbol, + mPeriod, + mode, + mLength, + current + 1); + + // + founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + } + + // + result = current; + + // + return result; +} + +// +// Find Next Swing ... +int FindNextSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (bar_index < 0) + { + mLength += bar_index; + bar_index = 0; + } + + // + result = mode == MODE_HIGH + ? iHighest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index) + : iLowest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index); + + // + 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; +} + +// +// Find Support and Resistance for Specific Bar based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + int barIndex, // Bar Index ... + const double &pivots[], // Provided Pivot Points ... + int count = 3, // Number of Requireds ... + string mSymbol = NULL, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ... +) +{ + // + if (StringLen(mSymbol) == 0 || mSymbol == NULL) + { + mSymbol = _Symbol; + } + + // + if (mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + XOHCL cBar = GetCandle( + mSymbol, + mPeriod, + barIndex); + + // + double tmpR[]; + + // + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > cBar.high) + { + Add( + iFlat, + tmpR); + } + else if (iFlat < cBar.low) + { + Add( + iFlat, + tmpS); + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindLesserThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Biggest Lesser Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue < value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindBiggerThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Smallest Bigger Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (!isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue > value) + { + // + result = iValue; + break; + } + } + + // + 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; +} + +// +// Find Same Values in Array ... +void FindSameValueInBuffer( + double &result[], // Holds Result ... + double &source[], // Source ... + int verifications = 3 // Number of Consequence Repeat ... +) +{ + // + Clean(result); + + // + // TenkanSen Flats ... + int sourceCount = ArraySize(source); + if (sourceCount > verifications) + { + // + double mLast = 0; + int mVerified = 0; + for (int i = 0; i < sourceCount; i++) + { + // + double iVal = source[i]; + if (mLast == 0) + { + mLast = iVal; + } + else if (mLast == iVal) + { + mVerified++; + } + else + { + mLast = iVal; + mVerified = 0; + } + + // + if (iVal == mLast && mVerified >= verifications) + { + // + Add( + iVal, + result); + + // + mLast = 0; + mVerified = 0; + } + } + } +} + +// +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; +} + +// +void Clean(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(ulong &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(string &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(double &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; +} + +// +// Add an Item to a Buffer if not Exists ... +void AddIfNotExists( + double value, + double &values[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int valuesCount = ArraySize(values); + if (valuesCount <= 0) + { + // + Add(value, + values); + } + else + { + // + bool isExists = false; + for (int i = 0; i < valuesCount; i++) + { + // + double iVal = values[i]; + + // + double diff = MathAbs(iVal - value); + + // + if (iVal == value || diff < smoothingValue) + { + // + isExists = true; + break; + } + } + + // + if (!isExists) + { + // + Add(value, + values); + } + } +} + +// +// Add a Buffers Child to another Buffer +// if it's not Contains them ... +void AddsIfNotExists( + double &source[], + double &dest[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + double iSource = source[i]; + + // + AddIfNotExists( + iSource, + dest, + smoothingPoint); + } +} + +// +// 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; +} +template +string ToString(T value) +{ + return (string)value; +} + +// +// 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; +} + +// +// Retrieve Number of Candles in a Day ... +int GetDailyCandleCount(ENUM_TIMEFRAMES mPeriod) +{ + // + int seconds = PeriodSeconds(mPeriod); + + // + int daySeconds = 24 * 60 * 60; + + // + int result = daySeconds / seconds; + + // + return result; +} + +int GetDailyCandleCount() +{ + // + int result = GetDailyCandleCount(_Period); + + // + 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 Hindmost Time Frame ... +ENUM_TIMEFRAMES GetHindmostTimeFrame( + 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: + result = PERIOD_H12; + break; + + // + case PERIOD_M20: + case PERIOD_M30: + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + result = PERIOD_D1; + 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 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; +} + +// +struct XCandleRemains +{ + // + int days; + int hours; + int minutes; + int seconds; +}; + +// +string ToString( + XCandleRemains &item, + string dayId = "d", + string hourId = "h", + string minuteId = "m", + string secondId = "s", + string idSeparator = ": ", + string separator = ", ", + bool ignoreZeroValues = true) +{ + // + string result = ""; + + // + // Days ... + if (!ignoreZeroValues || item.days > 0) + { + result += dayId + idSeparator + (string)item.days + separator; + } + + // + // Hours ... + if (!ignoreZeroValues || item.hours > 0) + { + result += hourId + idSeparator + (string)item.hours + separator; + } + + // + // Minutes ... + if (!ignoreZeroValues || item.minutes > 0) + { + result += minuteId + idSeparator + (string)item.minutes + separator; + } + + // + // Seconds ... + if (!ignoreZeroValues || item.seconds > 0) + { + result += secondId + idSeparator + (string)item.seconds; + } + + // + return result; +} + +// +// Retrieve Specific Candles Ramained Time ... +void GetCandleRemainsTime( + XCandleRemains &result, // Holds Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mBarIndex = 0 // Specified Bar Index ... +) +{ + // + int minuteSecoonds = 60; + int hourSeconds = minuteSecoonds * 60; + int daySeconds = 24 * hourSeconds; + + // + int periodSeconds = PeriodSeconds( + mPeriod); + datetime startTime = GetCandleTime( + mSymbol, + mPeriod, + mBarIndex); + + // + int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); + + // + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + // + int mWorkingSecondsDiff = secondsDiff; + if (mWorkingSecondsDiff > daySeconds) + { + // + days = mWorkingSecondsDiff / daySeconds; + mWorkingSecondsDiff -= days * daySeconds; + } + if (mWorkingSecondsDiff > hourSeconds) + { + // + hours = mWorkingSecondsDiff / hourSeconds; + mWorkingSecondsDiff -= hours * hourSeconds; + } + if (mWorkingSecondsDiff > minuteSecoonds) + { + // + minutes = mWorkingSecondsDiff / minuteSecoonds; + mWorkingSecondsDiff -= minutes * minuteSecoonds; + } + seconds = mWorkingSecondsDiff; + + // + result.days = days; + result.hours = hours; + result.minutes = minutes; + result.seconds = seconds; +} + +// +// Converts an String to TimeFrame ... +ENUM_TIMEFRAMES ToPeriod(string value) +{ + // + if (StringLen(value) == 0) + { + return _Period; + } + + // + StringTrimLeft(value); + StringTrimRight(value); + + // + ENUM_TIMEFRAMES result = _Period; + + // + if (value == "M1") + { + result = PERIOD_M1; + } + else if (value == "M2") + { + result = PERIOD_M2; + } + else if (value == "M3") + { + result = PERIOD_M3; + } + else if (value == "M4") + { + result = PERIOD_M4; + } + else if (value == "M5") + { + result = PERIOD_M5; + } + else if (value == "M6") + { + result = PERIOD_M6; + } + else if (value == "M10") + { + result = PERIOD_M10; + } + else if (value == "M12") + { + result = PERIOD_M12; + } + else if (value == "M15") + { + result = PERIOD_M15; + } + else if (value == "M20") + { + result = PERIOD_M20; + } + else if (value == "M30") + { + result = PERIOD_M30; + } + else if (value == "H1") + { + result = PERIOD_H1; + } + else if (value == "H2") + { + result = PERIOD_H2; + } + else if (value == "H3") + { + result = PERIOD_H3; + } + else if (value == "H4") + { + result = PERIOD_H4; + } + else if (value == "H6") + { + result = PERIOD_H6; + } + else if (value == "H8") + { + result = PERIOD_H8; + } + else if (value == "H12") + { + result = PERIOD_H12; + } + else if (value == "D1") + { + result = PERIOD_D1; + } + else if (value == "W1") + { + result = PERIOD_W1; + } + else if (value == "MN1") + { + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Converts Period to String ... +string ToString(ENUM_TIMEFRAMES period) +{ + // + string result = ""; + + // + string mPStr = EnumToString(period); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[1]; + + // + return result; +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/Libraries/x-saherelm.draw.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.draw.lib.ex5 new file mode 100644 index 0000000..4f61b18 Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.draw.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.draw.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.draw.lib.mq5 new file mode 100644 index 0000000..7771f54 --- /dev/null +++ b/MQLTestWorkspace/Libraries/x-saherelm.draw.lib.mq5 @@ -0,0 +1,2462 @@ +/////////////////////////////////////////////////////// +// +// 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(); +} + +// +// 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; +} + +// +// Deselect All Draws ... +void DeselectAllDraws() +{ + // + int objs = ObjectsTotal(ChartID(), 0); + for (int o = 0; o < objs; o++) + { + ObjectSetInteger(ChartID(), ObjectName(ChartID(), o, 0), OBJPROP_SELECTED, false); + } + + // + ChartRedraw(); +} + +// +// 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 subWindow = 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, subWindow, 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 bgColor = 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, bgColor); + + // + // 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 ... +// + +// +// START Button Functions ... +// + +// +// Create the button ... +bool ButtonCreate( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int subWindow = 0, // subwindow index + const int x = 0, // X coordinate + const int y = 0, // Y coordinate + const int width = 50, // button width + const int height = 15, // button height + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring + const string text = "Button", // text + const string font = "Arial", // font + const int fontSize = 8, // font size + const color clr = clrBlack, // text color + const color bgColor = clrLightGray, // background color + const color borderColor = clrNONE, // border color + const bool state = false, // pressed/released + 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 +) +{ + // + bool result = false; + + // + // create the button + result = ObjectCreate(chartID, name, OBJ_BUTTON, subWindow, 0, 0); + if (!result) + { + return result; + } + + // + // set button coordinates + ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + // set button size + ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + // set the chart's corner, relative to which point coordinates are defined + ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + // 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 text color + ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); + + // + // set background color + ObjectSetInteger(chartID, name, OBJPROP_BGCOLOR, bgColor); + + // + // set border color + ObjectSetInteger(chartID, name, OBJPROP_BORDER_COLOR, borderColor); + + // + // display in the foreground false or background true + ObjectSetInteger(chartID, name, OBJPROP_BACK, back); + + // + // set button state + ObjectSetInteger(chartID, name, OBJPROP_STATE, state); + + // + // enable true or disable false the mode of moving the button 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); + + // + return result; +} + +// +// Move the button ... +bool ButtonMove( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int x = 0, // X coordinate + const int y = 0 // Y coordinate +) +{ + // + bool result = false; + + // + // move the button + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y); + + // + return result; +} + +// +// Change button size ... +bool ButtonChangeSize( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const int width = 50, // button width + const int height = 18 // button height +) +{ + // + bool result = false; + + // + // change the button size + + // + result = ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width); + if (!result) + { + return result; + } + + // + result = ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height); + + // + return result; +} + +// +// Change corner of the chart for binding the button ... +bool ButtonChangeCorner( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER // chart corner for anchoring +) +{ + // + bool result = false; + + // + // change anchor corner + + // + result = ObjectSetInteger(chartID, name, OBJPROP_CORNER, corner); + + // + return result; +} + +// +// Change button text ... +bool ButtonTextChange( + const long chartID = 0, // chart's ID + const string name = "Button", // button name + const string text = "Text" // text +) +{ + // + bool result = false; + + // + // change object text + result = ObjectSetString(chartID, name, OBJPROP_TEXT, text); + + // + return result; +} + +// +// Delete the button ... +bool ButtonDelete( + const long chartID = 0, // chart's ID + const string name = "Button" // button name +) +{ + // + bool result = false; + + // + // delete the button + result = ObjectDelete(chartID, name); + + // + return result; +} +// +// END Button Functions ... +// + +// +// END Regular Draws ... +// + +// +// START Chart Style Drawers ... +// +// +// Apply Styles On Chart ... +void ApplyChartStyle( + long mChartId = -1, // chart's ID + ENUM_CHART_MODE mMode = CHART_CANDLES, // chart's mMode + bool mShowBidLine = true, // show bid line + bool mShowAskLine = true, // show ask line + bool mShowGrid = false, // show grids on chart + bool mShowVolumes = false, // show volumes + bool mShowTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true, // chart autoscroll + bool mQuickNavigation = true, // chart quick navigation state + color mForeGroundColor = clrWhite, // chart's foreground color + color mBackGroundColor = clrBlack, // chart's background color + color mUpColor = clrGreen, // Up Color + color mDownColor = clrRed, // Down Color + color mBullishColor = clrGreen, // Bullish color + color mBearishColor = clrRed, // Bearish color + color mGridColor = clrGray, // grid color + color mBidLineColor = clrGray, // bid line color + color mAskLineColor = clrRed, // ask line color + color mLineColor = clrLime, // line mMode and doji candlestick color + color mStopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen // volumes color +) +{ + // + // Validate Args ... + if (mChartId == -1) + { + mChartId = 0; + } + + // + ChartSetInteger(mChartId, CHART_MODE, mMode); + ChartSetInteger(mChartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(mChartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(mChartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(mChartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(mChartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(mChartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(mChartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(mChartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(mChartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(mChartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(mChartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(mChartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(mChartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(mChartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(mChartId, CHART_COLOR_VOLUME, mVolumesColor); +} + +// +// Retrieve Chart Size in Pixel ... +struct XSize +{ + long width; + long height; + + // + int x; + int y; + int w; + int h; + + // + int wStep; + int hStep; +}; + +// +// Retrieve Chart Size ... +bool GetChartSize( + XSize &result, // Holds Result ... + long chartID = 0 // Specified Chart ID ... +) +{ + // + bool mResult = false; + + // + mResult = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0, result.width); + if (!mResult) + { + return mResult; + } + + // + mResult = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0, result.height); + + // + return mResult; +} + +// +// END Chart Style Drawers ... +// \ No newline at end of file diff --git a/MQLTestWorkspace/Libraries/x-saherelm.http.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.http.lib.ex5 new file mode 100644 index 0000000..134ec79 Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.http.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.http.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.http.lib.mq5 new file mode 100644 index 0000000..97f7ac0 --- /dev/null +++ b/MQLTestWorkspace/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/MQLTestWorkspace/Libraries/x-saherelm.log.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.log.lib.ex5 new file mode 100644 index 0000000..ef1ae04 Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.log.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.log.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.log.lib.mq5 new file mode 100644 index 0000000..3235c63 --- /dev/null +++ b/MQLTestWorkspace/Libraries/x-saherelm.log.lib.mq5 @@ -0,0 +1,117 @@ +/////////////////////////////////////////////////////// +// +// 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); +} + +// +void LogEmptyLine() +{ + LogMessage(" "); +} + +// +// 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); +} +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/Libraries/x-saherelm.models.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.models.lib.ex5 new file mode 100644 index 0000000..6fce75c Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.models.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.models.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.models.lib.mq5 new file mode 100644 index 0000000..d2552c1 --- /dev/null +++ b/MQLTestWorkspace/Libraries/x-saherelm.models.lib.mq5 @@ -0,0 +1,238 @@ +/////////////////////////////////////////////////////// +// +// 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 +}; + +// +// Swing Types Enum ... +enum ENUM_X_SWING_TYPE +{ + X_NO_SWING = 0, + X_SWING_HIGH = 1, + X_SWING_LOW = -1, +}; + +// +// Available Guard Action ... +enum ENUM_X_GUARD_ACTIONS +{ + X_GUARD_ACTION_HEDGE, + X_GUARD_PARTIAL_CLOSE, + X_GUARD_ACTION_TRAIL_STOP, + X_GUARD_ACTION_FORCE_CLOSE, + X_GUARD_ACTION_ADD_SUPPORT_SIGNAL, + X_GUARD_ACTION_CANCEL_PENDING_ORDERS, +}; + +// +// Model Guard Info ... +struct XGuard +{ + string symbol; + string provider; + ENUM_TIMEFRAMES period; + ENUM_POSITION_TYPE type; + ENUM_X_GUARD_ACTIONS action; + + // + double dblPayLoad; + string strPayload; +}; + +// +// Describe an Specific Candle ... +struct XOHCL +{ + double high; + double open; + double close; + double low; +}; + +// +// Model Support and Resistance +// for Specific Bar ... +struct XOHCLSupRes +{ + // + double res[]; + + // + double sup[]; +}; + +// +// Available Order Modes ... +enum ENUM_X_ORDER_MODES +{ + X_ORDER_MODE_MARKET = 0, // Market Order + X_ORDER_MODE_STOP = 1, // Pending Stop Order + X_ORDER_MODE_LIMIT = 2, // Pending Limit Order + X_ORDER_MODE_STOP_LIMIT = 3, // Pending Stop Limit Order +}; + +// +// Model a Signal ... +struct XSignal +{ + // + string providers[]; + + // + string symbol; + + // + ENUM_TIMEFRAMES period; + + // + ENUM_POSITION_TYPE type; + + // + ENUM_X_ORDER_MODES mode; + + // + double entry; + + // + double riskAmount; + + // + double tp; + + // + double sl; + + // + double r2r; + + // + double volume; + + // + bool calculateTP; + + // + bool useSupportAndResistance; + + // + bool useRiskAmountAsVolume; +}; +// +// EXTENSION Methods ... + +// +void Add( + XSignal &item, + XSignal &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Clear an Specific Signal Item ... +void Clean(XSignal &item) +{ + // + ArrayFree(item.providers); + ArrayResize(item.providers, 0); + + // + item.symbol = ""; + item.type = NULL; + item.mode = NULL; + item.period = NULL; + + // + item.tp = 0; + item.sl = 0; + item.r2r = 0; + item.entry = 0; + item.volume = 0; + item.riskAmount = 0; +} + +// +void Clean(XSignal &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +void Clean(XGuard &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/Libraries/x-saherelm.seriallizer.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.seriallizer.lib.ex5 new file mode 100644 index 0000000..71e9aa6 Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.seriallizer.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.seriallizer.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.seriallizer.lib.mq5 new file mode 100644 index 0000000..c843458 --- /dev/null +++ b/MQLTestWorkspace/Libraries/x-saherelm.seriallizer.lib.mq5 @@ -0,0 +1,85 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Seriallize Library +// --------------------------------------- +// Name: XSeriallizer +// Description: provides Seriallizing EA abilities ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +string XProviderToken = "PRV"; +string XSupportToken = "SP"; + +// +string GenerateSupportSignalComment( + ulong ticket // Position/Order Ticket +) +{ + // + string result = ""; + + // + result = XSupportToken + "(" + (string)ticket + ")"; + + // + return result; +} + +// +string ExtractParentTicketOfSupport(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XSupportToken + "(", + ")"); + + // + return result; +} + +// +// Extract a Provider name if exists from a Comment ... +string ExtractProvider(string comment) +{ + // + string result = ""; + if (StringLen(comment) <= 0) + { + return result; + } + + // + result = ExtractString( + comment, + XProviderToken + "(", + ")"); + + // + return result; +} \ No newline at end of file diff --git a/MQLTestWorkspace/Libraries/x-saherelm.x121.draw.lib.ex5 b/MQLTestWorkspace/Libraries/x-saherelm.x121.draw.lib.ex5 new file mode 100644 index 0000000..e0fe4a7 Binary files /dev/null and b/MQLTestWorkspace/Libraries/x-saherelm.x121.draw.lib.ex5 differ diff --git a/MQLTestWorkspace/Libraries/x-saherelm.x121.draw.lib.mq5 b/MQLTestWorkspace/Libraries/x-saherelm.x121.draw.lib.mq5 new file mode 100644 index 0000000..941d61b --- /dev/null +++ b/MQLTestWorkspace/Libraries/x-saherelm.x121.draw.lib.mq5 @@ -0,0 +1,241 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X12 Draw Library +// ------------------------------------------ +// Name: X121Draw +// Description: provides Draw Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// START Draw Functions ... +// + +// +// Draw Signal ... +void DrawSignal(const ulong ticket, XSignal &signal) +{ + // + bool isLong = IsLong(signal.type); + + // + string prefix = (string)ticket + "_" + ToString(signal.period); + + // + // Retrieve Time ... + datetime time = iTime( + signal.symbol, + signal.period, + 0); + + // + // Retrieve 3 Time ... + datetime time3 = iTime( + signal.symbol, + signal.period, + 3); + + // + color posColor = isLong + ? clrSpringGreen + : clrTomato; + color tpColor = clrSpringGreen; + color slColor = clrTomato; + color entryColor = clrGold; + + // + ENUM_LINE_STYLE vLineStyle = STYLE_DOT; + ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE slLineStyle = STYLE_SOLID; + ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID; + + // + int lineWidth = 2; + + // + long chartID = ChartID(); + + // + // Vertical Line ... + string vlName = prefix + "_" + (string)time; + + // + DrawVerticalLine( + chartID, + vlName, + 0, + time, + posColor, + vLineStyle, + lineWidth); + + // + // TP ... + double profit = (MathAbs(signal.tp - signal.entry)) * signal.volume; + string tpName = prefix + "_TP_" + (string)profit; + + // + DrawTrendLine( + chartID, + tpName, + 0, + time3, + signal.tp, + time, + signal.tp, + tpColor, + tpLineStyle, + lineWidth); + + // + // SL ... + double lost = (MathAbs(signal.sl - signal.entry)) * signal.volume; + string slName = prefix + "_SL_" + (string)lost; + + // + DrawTrendLine( + chartID, + slName, + 0, + time3, + signal.sl, + time, + signal.sl, + slColor, + slLineStyle, + lineWidth); + + // + // ENTRY ... + string entryName = prefix + "_ENTRY_" + (string)lost; + + // + DrawTrendLine( + chartID, + entryName, + 0, + time3, + signal.entry, + time, + signal.entry, + entryColor, + entryLineStyle, + lineWidth); +} + +// +// Draw Support and Resistance ... +void DrawSupportResistance( + int bar_index, + XOHCLSupRes &data, + string prefix = "", + color supportColor = clrOrange, + color resistanceColor = clrOrange) +{ + // + datetime barTime = GetCandleTime( + _Symbol, + _Period, + bar_index); + + // + datetime prevBarTime = GetCandleTime( + _Symbol, + _Period, + bar_index + 5); + + // + long chID = ChartID(); + int subWindiw = 0; + int lineWidth = 1; + + // + string mPrefix = prefix + "_" + (string)barTime + "_"; + + // + // SUPPORTS ... + + // + int supCount = ArraySize(data.sup); + if (supCount > 0) + { + // + for (int i = 0; i < supCount; i++) + { + // + double iSup = data.sup[i]; + + // + string supTlName = mPrefix + "SUP[" + (string)(i + 1) + "]_(" + (string)iSup + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + supTlName, + subWindiw, + prevBarTime, + iSup, + barTime, + iSup, + supportColor, + STYLE_DOT, + lineWidth, + true); + } + } + + // + // RESISTANCES ... + + // + int resCount = ArraySize(data.res); + if (resCount > 0) + { + // + for (int i = 0; i < resCount; i++) + { + // + double iRes = data.res[i]; + + // + string resTlName = mPrefix + "RES[" + (string)(i + 1) + "]_(" + (string)iRes + ")"; + + // + // Draw Support ... + DrawTrendLine( + chID, + resTlName, + subWindiw, + prevBarTime, + iRes, + barTime, + iRes, + resistanceColor, + STYLE_DOT, + lineWidth, + true); + } + } +} + +// +// END Draw Functions ... +//