diff --git a/.vscode/vscode-kanban.json b/.vscode/vscode-kanban.json index 19cdef7d..0080b68e 100644 --- a/.vscode/vscode-kanban.json +++ b/.vscode/vscode-kanban.json @@ -7,7 +7,7 @@ }, "creation_time": "2024-07-28T22:48:10.644Z", "details": { - "content": "[] Add Recovery Options when try to Synchronize Positions Using Trade Handler ...\n[] Add Do not Trail Support or Recovery Positions in Trade Handler ...\n[] Add a TP and SL to Recovery Position ...\n[] Made Multi Asset ...\n[] Add Pressure Based Trailling ...\n[] Add Support for Pressures in Recovery ...\n[] Add OB / FVG and Other things Like XPV Signalling ...\n[] Create XCHCHE Insicator and it's Helper class ...\n", + "content": "[] Add Recovery Options when try to Synchronize Positions Using Trade Handler ...\n[x] Add Do not Trail Support or Recovery Positions in Trade Handler ...\n[x] Add a TP and SL to Recovery Position ...\n[x] Made Multi Asset ...\n[] Add Pressure Based Trailling ...\n[x] Add Support for Pressures in Recovery ...\n[] Add OB / FVG and Other things Like XPV Signalling ...\n[x] Create XCHCHE Insicator and it's Helper class ...\n[] Create XCHVLM. XCHTD ...\n", "mime": "text/markdown" }, "id": "86", diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index 5feb6696..06c690b7 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -5640,21 +5640,60 @@ private: } // - bool FixRecoveredPositionTPSL(XPosition &osition) + bool FixRecoveredPositionTPSL(XPosition &position) { // bool result = false; // - // Try to Remove SL of Recovery Signals ... - if (osition.sl > 0 || osition.tp > 0) + result = position.IsValid(); + if (!result) + { + return result; + } + + // + double points = GetPoints(position.symbol); + + // // + // // Try to Remove SL and TP of Recovery Signals ... + // if (position.sl > 0 || position.tp > 0) + // { + // // + // string comment = "EQM Recover Remove TP/SL"; + // result = mTrader.Modify( + // position.ticket, + // 0, + // 0, + // comment // + // ); + // } + + // + // Try to Remove TP of Recovery Signals ... + if (position.tp > 0) { // - string comment = "EQM Recover Remove TP/SL"; + double tp = 0; + bool isLong = IsLong(position.type); + double reward = MathAbs(position.tp - position.entry) / points; + if (reward <= mRecoveryTPPoint) + { + // + reward = (mRecoveryTPPoint * 2 * points); + tp = + isLong + ? position.entry + reward + : position.entry - reward; + tp = NormalizePrice(tp, position.symbol); + } + + // + string comment = "EQM Recover Fix TP/SL"; result = mTrader.Modify( - osition.ticket, - 0, - 0, + position.ticket, + position.sl, + tp, comment // ); } diff --git a/Experts/x-test-strategies.ea.mq5 b/Experts/x-test-strategies.ea.mq5 index e19f0382..ef12683f 100644 --- a/Experts/x-test-strategies.ea.mq5 +++ b/Experts/x-test-strategies.ea.mq5 @@ -59,9 +59,10 @@ bool eaIgnoreSL = false; // Ignore SL double eaR2R = 1.5; // Risk to Reward Ratio // -bool eaMultiSymbol = false; // Use Multi Symbol +bool eaMultiSymbol = true; // Use Multi Symbol bool eaUseMaxAllowedTradesPerSymbol = true; // Use Max Allowed Trades Per Symbol -string eaSymbols = "EURUSDb,USDJPYb,USDCHFb,GBPUSDb,XAUUSDb,XAGUSDb"; // Trading Symbols +string eaSymbols = "EURUSDb,USDJPYb"; // Trading Symbols +// string eaSymbols = "EURUSDb,USDJPYb,USDCHFb,GBPUSDb,XAUUSDb,XAGUSDb"; // Trading Symbols // // Variables ... @@ -82,13 +83,14 @@ XSCBaseStrategy *strategies[]; // Trader Instance Class ... XSCTrade *eaTrader; -// -// XTimeTracker eaTimeTracker; - // // Alert Class ... XSCAlert *eaAlert; +// +// Time Tracker ... +XTimeTracker eaTimeTracker; + // // Trade Handler Instance Class ... XSCXTradeHandler *eaTradeHandler; @@ -167,6 +169,7 @@ void OnTick() { // HandleTradeState(); + HandleTimeReport(); HandleStrategiesOnTick(); } @@ -183,6 +186,8 @@ void OnTimer() { // // HandleTradeState(); + // HandleTimeReport(); + // HandleStrategiesOnTick(); // // // if (eaTimeTracker.IsNewDay()) @@ -269,7 +274,7 @@ bool InitialEA() // // Configure Hedging ... - eaTradeHandler.AllowHedging(false); + eaTradeHandler.AllowHedging(true); eaTradeHandler.HedgeVolumeFactor(eaVolume); eaTradeHandler.OnlyHedgeSupportedPositions(false); eaTradeHandler.HedgeMinProfitPerVolumeFactor(0.3); @@ -307,7 +312,7 @@ bool InitialEA() eaSlippage, eaMagicNumber, true, // Ignore Signal Execution - true, // Use TP SL Point + true, // Use TP SL Point false, // Use Max eaTPPoint, // TP eaSLPoint, // SL @@ -444,6 +449,21 @@ void HandleTradeState() eaTradeHandler.HandleProtection(); } +// +// Time Reporting ... +void HandleTimeReport() +{ + // + if (eaTimeTracker.IsNewDay()) + { + // + string msg = "New Day ..."; + + // + eaAlert.Alert(msg); + } +} + // // All Signals from Strategies Comming Here for Execution or // Analyzing ... diff --git a/Helpers/x-saherelm.xchtd.helper.mq5 b/Helpers/x-saherelm.xchtd.helper.mq5 new file mode 100644 index 00000000..ba4312f8 --- /dev/null +++ b/Helpers/x-saherelm.xchtd.helper.mq5 @@ -0,0 +1,2955 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHTDHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XCHTD_MODE +{ + XCHTD_POWER_MODE = 0, // Using Power + XCHTD_PRESSURE_MODE = 1, // Using Pressure + XCHTD_TYPE_MODE = 2, // Using Type + XCHTD_STRONG_MODE = 3, // Using Power and Pressures +}; + +// +enum ENUM_XCHTD_BUFFERS +{ + // + XCHTD_C_BULL_LINE = 0, + XCHTD_C_BEAR_LINE = 1, + // + XCHTD_S_BULL_LINE = 2, + XCHTD_S_BEAR_LINE = 3, + // + XCHTD_M_BULL_LINE = 4, + XCHTD_M_BEAR_LINE = 5, + // + XCHTD_L_BULL_LINE = 6, + XCHTD_L_BEAR_LINE = 7, + // + XCHTD_H_BULL_LINE = 8, + XCHTD_H_BEAR_LINE = 9, +}; + +// +// Input Models ... +struct XCHTDInputs +{ + // + // Props ... + + // + // Market ... + int length; // Length + ENUM_XCHTD_MODE mode; // Mode + + // + // Cycles ... + + // + // Short ... + ENUM_X_PERIOD_METHOD scMethod; // How to Find Period + ENUM_TIMEFRAMES scPeriod; // Time Period + + // + // Medium ... + ENUM_X_PERIOD_METHOD mcMethod; // How to Find Period + ENUM_TIMEFRAMES mcPeriod; // Time Period + + // + // Long ... + ENUM_X_PERIOD_METHOD lcMethod; // How to Find Period + ENUM_TIMEFRAMES lcPeriod; // Time Period + + // + // Hind ... + ENUM_X_PERIOD_METHOD hcMethod; // How to Find Period + ENUM_TIMEFRAMES hcPeriod; // Time Period + + // + // Presentation ... + bool showCurrent; // Show Current Cycle + bool showShort; // Show Short Cycle + bool showMedium; // Show Medium Cycle + bool showLong; // Show Long Cycle + bool showHind; // Show Hind Cycle + + // + // Constructor(s) ... + XCHTDInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + mode = XCHTD_POWER_MODE; + + // + scMethod = X_PERIOD_AUTO; + scPeriod = NULL; + mcMethod = X_PERIOD_AUTO; + mcPeriod = NULL; + lcMethod = X_PERIOD_AUTO; + lcPeriod = NULL; + hcMethod = X_PERIOD_AUTO; + hcPeriod = NULL; + + // + showCurrent = false; + showShort = false; + showMedium = false; + showLong = false; + showHind = false; + } + + // + // Default ... + void Default() + { + // + length = 14; + mode = XCHTD_POWER_MODE; + + // + scMethod = X_PERIOD_AUTO; + scPeriod = NULL; + mcMethod = X_PERIOD_AUTO; + mcPeriod = NULL; + lcMethod = X_PERIOD_AUTO; + lcPeriod = NULL; + hcMethod = X_PERIOD_AUTO; + hcPeriod = NULL; + + // + showCurrent = true; + showShort = true; + showMedium = true; + showLong = true; + showHind = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length > 0 && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = + // + MathMax(0, length) + // + ; + + // + return result; + } +}; + +// +// Define Conditions ... +struct XCHTDConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + // Current ... + double cBull[]; + double cBear[]; + + // + // Short ... + double sBull[]; + double sBear[]; + + // + // Medium ... + double mBull[]; + double mBear[]; + + // + // Long ... + double lBull[]; + double lBear[]; + + // + // Hind ... + double hBull[]; + double hBear[]; + + // + // Conditions ... + // + // Power ... + bool hasBullishPower; + bool hasBearishPower; + bool isBullishPowerUp; + bool isBearishPowerUp; + bool isBullishPowerIncreasing; + bool isBullishPowerDecreasing; + bool isBearishPowerIncreasing; + bool isBearishPowerDecreasing; + + // + // Current ... + bool isCBullish; + bool isCBearish; + bool isCSwitchedToBullish; + bool isCSwitchedToBearish; + + // + // Short ... + bool isSBullish; + bool isSBearish; + bool isSSwitchedToBullish; + bool isSSwitchedToBearish; + + // + // Medium ... + bool isMBullish; + bool isMBearish; + bool isMSwitchedToBullish; + bool isMSwitchedToBearish; + + // + // Long ... + bool isLBullish; + bool isLBearish; + bool isLSwitchedToBullish; + bool isLSwitchedToBearish; + + // + // Hind ... + bool isHBullish; + bool isHBearish; + bool isHSwitchedToBullish; + bool isHSwitchedToBearish; + + // + void Clean() + { + // + Clean(cBull); + Clean(cBear); + Clean(sBull); + Clean(sBear); + Clean(mBull); + Clean(mBear); + Clean(lBull); + Clean(lBear); + Clean(hBull); + Clean(hBear); + + // + ArraySetAsSeries(cBull, true); + ArraySetAsSeries(cBear, true); + ArraySetAsSeries(sBull, true); + ArraySetAsSeries(sBear, true); + ArraySetAsSeries(mBull, true); + ArraySetAsSeries(mBear, true); + ArraySetAsSeries(lBull, true); + ArraySetAsSeries(lBear, true); + ArraySetAsSeries(hBull, true); + ArraySetAsSeries(hBear, true); + + // + // Conditions ... + + // + // Power ... + hasBullishPower = false; + hasBearishPower = false; + isBullishPowerUp = false; + isBearishPowerUp = false; + isBullishPowerIncreasing = false; + isBullishPowerDecreasing = false; + isBearishPowerIncreasing = false; + isBearishPowerDecreasing = false; + + // + // Current ... + isCBullish = false; + isCBearish = false; + isCSwitchedToBullish = false; + isCSwitchedToBearish = false; + + // + // Short ... + isSBullish = false; + isSBearish = false; + isSSwitchedToBullish = false; + isSSwitchedToBearish = false; + + // + // Medium ... + isMBullish = false; + isMBearish = false; + isMSwitchedToBullish = false; + isMSwitchedToBearish = false; + + // + // Long ... + isLBullish = false; + isLBearish = false; + isLSwitchedToBullish = false; + isLSwitchedToBearish = false; + + // + // Hind ... + isHBullish = false; + isHBearish = false; + isHSwitchedToBullish = false; + isHSwitchedToBearish = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Since We have to Use this + // Only for Filtering Signals ... + // We Can Ignore Scoring ... + // or Complete this later ... + + // + // Conditions ... + + // + // Power ... + if (hasBullishPower) + { + bullishScore++; + } + if (hasBearishPower) + { + bearishScore++; + } + if (isBullishPowerUp) + { + bullishScore++; + } + if (isBearishPowerUp) + { + bearishScore++; + } + if (isBullishPowerIncreasing) + { + bullishScore++; + } + if (isBullishPowerDecreasing) + { + bearishScore++; + } + if (isBearishPowerIncreasing) + { + bearishScore++; + } + if (isBearishPowerDecreasing) + { + bullishScore++; + } + + // + // Current ... + if (isCBullish) + { + bullishScore++; + } + if (isCBearish) + { + bearishScore++; + } + if (isCSwitchedToBullish) + { + bullishScore++; + } + if (isCSwitchedToBearish) + { + bearishScore++; + } + + // + // Short ... + if (isSBullish) + { + bullishScore++; + } + if (isSBearish) + { + bearishScore++; + } + if (isSSwitchedToBullish) + { + bullishScore++; + } + if (isSSwitchedToBearish) + { + bearishScore++; + } + + // + // Medium ... + if (isMBullish) + { + bullishScore++; + } + if (isMBearish) + { + bearishScore++; + } + if (isMSwitchedToBullish) + { + bullishScore++; + } + if (isMSwitchedToBearish) + { + bearishScore++; + } + + // + // Long ... + if (isLBullish) + { + bullishScore++; + } + if (isLBearish) + { + bearishScore++; + } + if (isLSwitchedToBullish) + { + bullishScore++; + } + if (isLSwitchedToBearish) + { + bearishScore++; + } + + // + // Hind ... + if (isHBullish) + { + bullishScore++; + } + if (isHBearish) + { + bearishScore++; + } + if (isHSwitchedToBullish) + { + bullishScore++; + } + if (isHSwitchedToBearish) + { + bearishScore++; + } + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + // Power ... + ToString("hasBullishPower", hasBullishPower, ignoreFalseConditions, separator) + + ToString("hasBearishPower", hasBearishPower, ignoreFalseConditions, separator) + + ToString("isBullishPowerUp", isBullishPowerUp, ignoreFalseConditions, separator) + + ToString("isBearishPowerUp", isBearishPowerUp, ignoreFalseConditions, separator) + + ToString("isBullishPowerIncreasing", isBullishPowerIncreasing, ignoreFalseConditions, separator) + + ToString("isBullishPowerDecreasing", isBullishPowerDecreasing, ignoreFalseConditions, separator) + + ToString("isBearishPowerIncreasing", isBearishPowerIncreasing, ignoreFalseConditions, separator) + + ToString("isBearishPowerDecreasing", isBearishPowerDecreasing, ignoreFalseConditions, separator) + + // + // Current ... + ToString("isCBullish", isCBullish, ignoreFalseConditions, separator) + + ToString("isCBearish", isCBearish, ignoreFalseConditions, separator) + + ToString("isCSwitchedToBullish", isCSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCSwitchedToBearish", isCSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Short ... + ToString("isSBullish", isSBullish, ignoreFalseConditions, separator) + + ToString("isSBearish", isSBearish, ignoreFalseConditions, separator) + + ToString("isSSwitchedToBullish", isSSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSSwitchedToBearish", isSSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Medium ... + ToString("isMBullish", isMBullish, ignoreFalseConditions, separator) + + ToString("isMBearish", isMBearish, ignoreFalseConditions, separator) + + ToString("isMSwitchedToBullish", isMSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isMSwitchedToBearish", isMSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Long ... + ToString("isLBullish", isLBullish, ignoreFalseConditions, separator) + + ToString("isLBearish", isLBearish, ignoreFalseConditions, separator) + + ToString("isLSwitchedToBullish", isLSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isLSwitchedToBearish", isLSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Hind ... + ToString("isHBullish", isHBullish, ignoreFalseConditions, separator) + + ToString("isHBearish", isHBearish, ignoreFalseConditions, separator) + + ToString("isHSwitchedToBullish", isHSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isHSwitchedToBearish", isHSwitchedToBearish, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "XCHTD"; + } +}; + +// +// Class ... +class XSCXCHTDHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCHTDHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCHTDHelper() + { + // + Clean(cBullBuffer); + Clean(cBearBuffer); + Clean(sBullBuffer); + Clean(sBearBuffer); + Clean(mBullBuffer); + Clean(mBearBuffer); + Clean(lBullBuffer); + Clean(lBearBuffer); + Clean(hBullBuffer); + Clean(hBearBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCHTDInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(cBullBuffer, true); + ArraySetAsSeries(cBearBuffer, true); + ArraySetAsSeries(sBullBuffer, true); + ArraySetAsSeries(sBearBuffer, true); + ArraySetAsSeries(mBullBuffer, true); + ArraySetAsSeries(mBearBuffer, true); + ArraySetAsSeries(lBullBuffer, true); + ArraySetAsSeries(lBearBuffer, true); + ArraySetAsSeries(hBullBuffer, true); + ArraySetAsSeries(hBearBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xchtd", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, // Length + mInputs.mode, // Mode + // + // Cycles ... + "", + // + // Short ... + "", + mInputs.scMethod, + mInputs.scPeriod, + // + // Medium ... + "", + mInputs.mcMethod, + mInputs.mcPeriod, + // + // Long ... + "", + mInputs.lcMethod, + mInputs.lcPeriod, + // + // Hind ... + "", + mInputs.hcMethod, + mInputs.hcPeriod, + // + // Presentation ... + "", + mInputs.showCurrent, + mInputs.showShort, + mInputs.showMedium, + mInputs.showLong, + mInputs.showHind + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCHTDInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCHTDInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Current ... + + // + double GetCBull( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return cBullBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyCBull( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + cBullBuffer, + buffer, + forceClean + // + ); + } + + // + double GetCBear( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return cBearBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyCBear( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + cBearBuffer, + buffer, + forceClean + // + ); + } + + // + // Short ... + + // + double GetSBull( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return sBullBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopySBull( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + sBullBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSBear( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return sBearBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopySBear( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + sBearBuffer, + buffer, + forceClean + // + ); + } + + // + // Medium ... + + // + double GetMBull( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return mBullBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyMBull( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mBullBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMBear( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return mBearBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyMBear( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mBearBuffer, + buffer, + forceClean + // + ); + } + + // + // Long ... + + // + double GetLBull( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return lBullBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyLBull( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lBullBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLBear( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return lBearBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyLBear( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lBearBuffer, + buffer, + forceClean + // + ); + } + + // + // Hind ... + + // + double GetHBull( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return hBullBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyHBull( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hBullBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHBear( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return hBearBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyHBear( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hBearBuffer, + buffer, + forceClean + // + ); + } + + // + // Tools ... + + // + void GetCycle( + int barIndex, // Bar Index + double &bull, + double &bear, + ENUM_X_MARKET_CYCLES cycle // + ) + { + // + bull = 0; + bear = 0; + + // + switch (cycle) + { + // + // CURRENT ... + case X_MARKET_CYCLE_UNKNOWN: + // + bull = GetCBull(barIndex); + bear = GetCBear(barIndex); + break; + // + // SHORT ... + case X_MARKET_CYCLE_SHORT: + // + bull = GetSBull(barIndex); + bear = GetSBear(barIndex); + break; + // + // MEDIUM ... + case X_MARKET_CYCLE_MEDIUM: + // + bull = GetMBull(barIndex); + bear = GetMBear(barIndex); + break; + // + // LONG ... + case X_MARKET_CYCLE_LONG: + // + bull = GetLBull(barIndex); + bear = GetLBear(barIndex); + break; + // + // HIND ... + case X_MARKET_CYCLE_HIND: + // + bull = GetHBull(barIndex); + bear = GetHBear(barIndex); + break; + } + } + + // + bool IsCycleBullish( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // + ) + { + // + bool result = false; + + // + double bull = 0; + double bear = 0; + GetCycle( + barIndex, + bull, + bear, + cycle // + ); + + // + result = bull > bear; + + // + return result; + } + + // + bool IsCycleBearish( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // + ) + { + // + bool result = false; + + // + double bull = 0; + double bear = 0; + GetCycle( + barIndex, + bull, + bear, + cycle // + ); + + // + result = bull < bear; + + // + return result; + } + + // + double GetCyclePower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // + ) + { + // + double result = 0; + + // + double bull = 0; + double bear = 0; + GetCycle( + barIndex, + bull, + bear, + cycle // + ); + + // + result = MathAbs(bull - bear); + + // + return result; + } + + // + int GetPowers( + int barIndex, // Bar Index + double &values[] // + ) + { + // + int result = 0; + + // + Clean(values); + + // + ENUM_X_MARKET_CYCLES allCycles[]; + int count = GetAllMarketCycles(allCycles); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetCyclesPowers( + barIndex, + values, + allCycles // + ); + + // + return result; + } + + // + int GetCyclesPowers( + int barIndex, // Bar Index + double &values[], + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + int result = 0; + + // + Clean(values); + + // + int count = ArraySize(cycles); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + double iValue = GetCyclePower( + barIndex, + cycles[i] // + ); + + // + Add( + iValue, + values // + ); + } + + // + result = ArraySize(values); + + // + return result; + } + + // + int GetBullishCycles( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + int result = 0; + + // + Clean(cycles); + + // + ENUM_X_MARKET_CYCLES allCycles[]; + int count = GetAllMarketCycles(allCycles); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isBullish = IsCycleBullish( + barIndex, + allCycles[i] // + ); + + // + if (isBullish) + { + // + Add( + allCycles[i], + cycles // + ); + } + } + + // + result = ArraySize(cycles); + + // + return result; + } + + // + int GetBearishCycles( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + int result = 0; + + // + Clean(cycles); + + // + ENUM_X_MARKET_CYCLES allCycles[]; + int count = GetAllMarketCycles(allCycles); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isBearish = IsCycleBearish( + barIndex, + allCycles[i] // + ); + + // + if (isBearish) + { + // + Add( + allCycles[i], + cycles // + ); + } + } + + // + result = ArraySize(cycles); + + // + return result; + } + + // + int GetBullishCyclesPowers( + int barIndex, // Bar Index + double &values[] // + ) + { + // + int result = 0; + + // + Clean(values); + + // + ENUM_X_MARKET_CYCLES cycles[]; + int count = GetBullishCycles( + barIndex, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetCyclesPowers( + barIndex, + values, + cycles // + ); + + // + return result; + } + + // + int GetBearishCyclesPowers( + int barIndex, // Bar Index + double &values[] // + ) + { + // + int result = 0; + + // + Clean(values); + + // + ENUM_X_MARKET_CYCLES cycles[]; + int count = GetBearishCycles( + barIndex, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetCyclesPowers( + barIndex, + values, + cycles // + ); + + // + return result; + } + + // + double GetMaxPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetMinPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMin(values); + + // + return result; + } + + // + double GetCyclesMaxPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + double result = 0; + + // + double values[]; + int count = GetCyclesPowers( + barIndex, + values, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetCyclesMinPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + double result = 0; + + // + double values[]; + int count = GetCyclesPowers( + barIndex, + values, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMin(values); + + // + return result; + } + + // + double GetMaxBullishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBullishCyclesPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetMinBullishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBullishCyclesPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMin(values); + + // + return result; + } + + // + double GetMaxBearishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBearishCyclesPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetMinBearishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBearishCyclesPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMin(values); + + // + return result; + } + + // + double GetBullishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBullishCyclesPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSum(values); + + // + return result; + } + + // + double GetBearishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBearishCyclesPowers( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSum(values); + + // + return result; + } + + // + double GetCyclesBullishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + double result = 0; + + // + int cyclesCount = ArraySize(cycles); + if (!IsValidSize(cyclesCount)) + { + return result; + } + + // + for (int i = 0; i < cyclesCount; i++) + { + // + bool isBullish = IsCycleBullish( + barIndex, + cycles[i] // + ); + if (isBullish) + { + // + double power = GetCyclePower( + barIndex, + cycles[i] // + ); + + // + result += MathAbs(power); + } + } + + // + return result; + } + + // + double GetCyclesBearishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + double result = 0; + + // + int cyclesCount = ArraySize(cycles); + if (!IsValidSize(cyclesCount)) + { + return result; + } + + // + for (int i = 0; i < cyclesCount; i++) + { + // + bool isBearish = IsCycleBearish( + barIndex, + cycles[i] // + ); + if (isBearish) + { + // + double power = GetCyclePower( + barIndex, + cycles[i] // + ); + + // + result += MathAbs(power); + } + } + + // + return result; + } + + // + bool HasBullishPower( + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + double bullishPower = GetBullishPower(barIndex); + double bearishPower = GetBearishPower(barIndex); + + // + result = + // + bearishPower >= 0 && + bullishPower > bearishPower + // + ; + + // + return result; + } + + // + bool HasBearishPower( + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + double bullishPower = GetBullishPower(barIndex); + double bearishPower = GetBearishPower(barIndex); + + // + result = + // + bullishPower >= 0 && + bearishPower > bullishPower + // + ; + + // + return result; + } + + // + bool HasCyclesBullishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + bool result = false; + + // + double bullishPower = GetCyclesBullishPower(barIndex, cycles); + double bearishPower = GetCyclesBearishPower(barIndex, cycles); + + // + result = + // + bearishPower >= 0 && + bullishPower > bearishPower + // + ; + + // + return result; + } + + // + bool HasCyclesBearishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + bool result = false; + + // + double bullishPower = GetCyclesBullishPower(barIndex, cycles); + double bearishPower = GetCyclesBearishPower(barIndex, cycles); + + // + result = + // + bullishPower >= 0 && + bearishPower > bullishPower + // + ; + + // + return result; + } + + // + // Check Bullish Power Increasing ... + bool IsBullishPowerIncreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBullishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBullishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bullish Power Decreasing ... + bool IsBullishPowerDecreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBullishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBullishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Increasing ... + bool IsBearishPowerIncreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBearishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBearishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Decreasing ... + bool IsBearishPowerDecreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBearishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBearishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Check Bullish Power Increasing ... + bool IsCyclesBullishPowerIncreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBullishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBullishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bullish Power Decreasing ... + bool IsCyclesBullishPowerDecreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBullishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBullishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Increasing ... + bool IsCyclesBearishPowerIncreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBearishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBearishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Decreasing ... + bool IsCyclesBearishPowerDecreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBearishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBearishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Conditions ... + + // + bool GetConditions( + XCHTDConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Buffers ... + + // + // Current ... + CopyCBull( + zIndex, + loopback, + conditions.cBull // + ); + CopyCBear( + zIndex, + loopback, + conditions.cBear // + ); + + // + // Short ... + CopySBull( + zIndex, + loopback, + conditions.sBull // + ); + CopySBear( + zIndex, + loopback, + conditions.sBear // + ); + + // + // Medium ... + CopyMBull( + zIndex, + loopback, + conditions.mBull // + ); + CopyMBear( + zIndex, + loopback, + conditions.mBear // + ); + + // + // Long ... + CopyLBull( + zIndex, + loopback, + conditions.lBull // + ); + CopyLBear( + zIndex, + loopback, + conditions.lBear // + ); + + // + // Hind ... + CopyHBull( + zIndex, + loopback, + conditions.hBull // + ); + CopyHBear( + zIndex, + loopback, + conditions.hBear // + ); + + // + // Conditions ... + + // + XOHCL cBar; + result = cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + mSymbol, + mPeriod, + pIndex // + ); + if (!result) + { + return result; + } + + // + // Power ... + + // + bool hasBullishPower = HasBullishPower(cIndex); + bool hasBullishPowerPrev = HasBullishPower(pIndex); + + // + bool hasBearishPower = HasBearishPower(cIndex); + bool hasBearishPowerPrev = HasBearishPower(pIndex); + + // + bool isBullishPowerUp = hasBullishPower && + !hasBullishPowerPrev; + bool isBearishPowerUp = hasBearishPower && + !hasBearishPowerPrev; + + // + bool isBullishPowerIncreasing = IsBullishPowerIncreasing(cIndex); + bool isBullishPowerDecreasing = IsBullishPowerDecreasing(cIndex); + bool isBearishPowerIncreasing = IsBearishPowerIncreasing(cIndex); + bool isBearishPowerDecreasing = IsBearishPowerDecreasing(cIndex); + + // + conditions.hasBullishPower = hasBullishPower; + conditions.hasBearishPower = hasBearishPower; + conditions.isBullishPowerUp = isBullishPowerUp; + conditions.isBearishPowerUp = isBearishPowerUp; + conditions.isBullishPowerIncreasing = isBullishPowerIncreasing; + conditions.isBullishPowerDecreasing = isBullishPowerDecreasing; + conditions.isBearishPowerIncreasing = isBearishPowerIncreasing; + conditions.isBearishPowerDecreasing = isBearishPowerDecreasing; + + // + // Current ... + + // + bool isCBullish = conditions.cBull[cIndex] > conditions.cBear[cIndex]; + bool isCBullishPrev = conditions.cBull[pIndex] > conditions.cBear[pIndex]; + + // + bool isCBearish = conditions.cBull[cIndex] < conditions.cBear[cIndex]; + bool isCBearishPrev = conditions.cBull[pIndex] < conditions.cBear[pIndex]; + + // + bool isCSwitchedToBullish = isCBullish && + !isCBullishPrev; + bool isCSwitchedToBearish = isCBearish && + !isCBearishPrev; + + // + conditions.isCBullish = isCBullish; + conditions.isCBearish = isCBearish; + conditions.isCSwitchedToBullish = isCSwitchedToBullish; + conditions.isCSwitchedToBearish = isCSwitchedToBearish; + + // + // Short ... + + // + bool isSBullish = conditions.sBull[cIndex] > conditions.sBear[cIndex]; + bool isSBullishPrev = conditions.sBull[pIndex] > conditions.sBear[pIndex]; + + // + bool isSBearish = conditions.sBull[cIndex] < conditions.sBear[cIndex]; + bool isSBearishPrev = conditions.sBull[pIndex] < conditions.sBear[pIndex]; + + // + bool isSSwitchedToBullish = isSBullish && + !isSBullishPrev; + bool isSSwitchedToBearish = isSBearish && + !isSBearishPrev; + + // + conditions.isSBullish = isSBullish; + conditions.isSBearish = isSBearish; + conditions.isSSwitchedToBullish = isSSwitchedToBullish; + conditions.isSSwitchedToBearish = isSSwitchedToBearish; + + // + // Medium ... + + // + bool isMBullish = conditions.mBull[cIndex] > conditions.mBear[cIndex]; + bool isMBullishPrev = conditions.mBull[pIndex] > conditions.mBear[pIndex]; + + // + bool isMBearish = conditions.mBull[cIndex] < conditions.mBear[cIndex]; + bool isMBearishPrev = conditions.mBull[pIndex] < conditions.mBear[pIndex]; + + // + bool isMSwitchedToBullish = isMBullish && + !isMBullishPrev; + bool isMSwitchedToBearish = isMBearish && + !isMBearishPrev; + + // + conditions.isMBullish = isMBullish; + conditions.isMBearish = isMBearish; + conditions.isMSwitchedToBullish = isMSwitchedToBullish; + conditions.isMSwitchedToBearish = isMSwitchedToBearish; + + // + // Long ... + + // + bool isLBullish = conditions.lBull[cIndex] > conditions.lBear[cIndex]; + bool isLBullishPrev = conditions.lBull[pIndex] > conditions.lBear[pIndex]; + + // + bool isLBearish = conditions.lBull[cIndex] < conditions.lBear[cIndex]; + bool isLBearishPrev = conditions.lBull[pIndex] < conditions.lBear[pIndex]; + + // + bool isLSwitchedToBullish = isLBullish && + !isLBullishPrev; + bool isLSwitchedToBearish = isLBearish && + !isLBearishPrev; + + // + conditions.isLBullish = isLBullish; + conditions.isLBearish = isLBearish; + conditions.isLSwitchedToBullish = isLSwitchedToBullish; + conditions.isLSwitchedToBearish = isLSwitchedToBearish; + + // + // Hind ... + + // + bool isHBullish = conditions.hBull[cIndex] > conditions.hBear[cIndex]; + bool isHBullishPrev = conditions.hBull[pIndex] > conditions.hBear[pIndex]; + + // + bool isHBearish = conditions.hBull[cIndex] < conditions.hBear[cIndex]; + bool isHBearishPrev = conditions.hBull[pIndex] < conditions.hBear[pIndex]; + + // + bool isHSwitchedToBullish = isHBullish && + !isHBullishPrev; + bool isHSwitchedToBearish = isHBearish && + !isHBearishPrev; + + // + conditions.isHBullish = isHBullish; + conditions.isHBearish = isHBearish; + conditions.isHSwitchedToBullish = isHSwitchedToBullish; + conditions.isHSwitchedToBearish = isHSwitchedToBearish; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCHTDInputs mInputs; // Inputs ... + + // + // Buffers ... + + // + // Current ... + double cBullBuffer[]; + double cBearBuffer[]; + + // + // Short ... + double sBullBuffer[]; + double sBearBuffer[]; + + // + // Medium ... + double mBullBuffer[]; + double mBearBuffer[]; + + // + // Long ... + double lBullBuffer[]; + double lBearBuffer[]; + + // + // Hind ... + double hBullBuffer[]; + double hBearBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Current ... + + // + // Bull ... + CopyBuffer( + mHandler, + XCHTD_C_BULL_LINE, + 0, + totalBars, + cBullBuffer + // + ); + + // + // Bear ... + CopyBuffer( + mHandler, + XCHTD_C_BEAR_LINE, + 0, + totalBars, + cBearBuffer + // + ); + + // + // Short ... + + // + // Bull ... + CopyBuffer( + mHandler, + XCHTD_S_BULL_LINE, + 0, + totalBars, + sBullBuffer + // + ); + + // + // Bear ... + CopyBuffer( + mHandler, + XCHTD_S_BEAR_LINE, + 0, + totalBars, + sBearBuffer + // + ); + + // + // Medium ... + + // + // Bull ... + CopyBuffer( + mHandler, + XCHTD_M_BULL_LINE, + 0, + totalBars, + mBullBuffer + // + ); + + // + // Bear ... + CopyBuffer( + mHandler, + XCHTD_M_BEAR_LINE, + 0, + totalBars, + mBearBuffer + // + ); + + // + // Long ... + + // + // Bull ... + CopyBuffer( + mHandler, + XCHTD_L_BULL_LINE, + 0, + totalBars, + lBullBuffer + // + ); + + // + // Bear ... + CopyBuffer( + mHandler, + XCHTD_L_BEAR_LINE, + 0, + totalBars, + lBearBuffer + // + ); + + // + // Hind ... + + // + // Bull ... + CopyBuffer( + mHandler, + XCHTD_H_BULL_LINE, + 0, + totalBars, + hBullBuffer + // + ); + + // + // Bear ... + CopyBuffer( + mHandler, + XCHTD_H_BEAR_LINE, + 0, + totalBars, + hBearBuffer + // + ); + }; +}; + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.xchvlm.helper.mq5 b/Helpers/x-saherelm.xchvlm.helper.mq5 new file mode 100644 index 00000000..4d062c89 --- /dev/null +++ b/Helpers/x-saherelm.xchvlm.helper.mq5 @@ -0,0 +1,2465 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHVLMHelper +// 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 + +// +// Imports ... +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XCHVLM_BUFFERS +{ + // + XCHVLM_C_LINE = 0, + // + XCHVLM_S_LINE = 2, + // + XCHVLM_M_LINE = 4, + // + XCHVLM_L_LINE = 6, + // + XCHVLM_H_LINE = 8, +}; + +// +enum ENUM_XCHVLM_STATES +{ + // + XCHVLM_BULLISH_STATE = 0, + XCHVLM_BEARISH_STATE = 1, +}; + +// +// Input Models ... +struct XCHVLMInputs +{ + // + // Props ... + + // + // Market ... + int length; // Length + + // + // Cycles ... + + // + // Short ... + ENUM_X_PERIOD_METHOD scMethod; // How to Find Period + ENUM_TIMEFRAMES scPeriod; // Time Period + + // + // Medium ... + ENUM_X_PERIOD_METHOD mcMethod; // How to Find Period + ENUM_TIMEFRAMES mcPeriod; // Time Period + + // + // Long ... + ENUM_X_PERIOD_METHOD lcMethod; // How to Find Period + ENUM_TIMEFRAMES lcPeriod; // Time Period + + // + // Hind ... + ENUM_X_PERIOD_METHOD hcMethod; // How to Find Period + ENUM_TIMEFRAMES hcPeriod; // Time Period + + // + // Presentation ... + bool showCurrent; // Show Current Cycle + bool showShort; // Show Short Cycle + bool showMedium; // Show Medium Cycle + bool showLong; // Show Long Cycle + bool showHind; // Show Hind Cycle + + // + // Constructor(s) ... + XCHVLMInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + length = 0; + + // + scMethod = X_PERIOD_AUTO; + scPeriod = NULL; + mcMethod = X_PERIOD_AUTO; + mcPeriod = NULL; + lcMethod = X_PERIOD_AUTO; + lcPeriod = NULL; + hcMethod = X_PERIOD_AUTO; + hcPeriod = NULL; + + // + showCurrent = false; + showShort = false; + showMedium = false; + showLong = false; + showHind = false; + } + + // + // Default ... + void Default() + { + // + length = 14; + + // + scMethod = X_PERIOD_AUTO; + scPeriod = NULL; + mcMethod = X_PERIOD_AUTO; + mcPeriod = NULL; + lcMethod = X_PERIOD_AUTO; + lcPeriod = NULL; + hcMethod = X_PERIOD_AUTO; + hcPeriod = NULL; + + // + showCurrent = true; + showShort = true; + showMedium = true; + showLong = true; + showHind = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length > 0 && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = + // + MathMax(0, length) + // + ; + + // + return result; + } +}; + +// +// Define Conditions ... +struct XCHVLMConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + // Current ... + double cVolume[]; + + // + // Short ... + double sVolume[]; + + // + // Medium ... + double mVolume[]; + + // + // Long ... + double lVolume[]; + + // + // Hind ... + double hVolume[]; + + // + // Conditions ... + // + // Power ... + bool hasBullishPower; + bool hasBearishPower; + bool isBullishPowerUp; + bool isBearishPowerUp; + bool isBullishPowerIncreasing; + bool isBullishPowerDecreasing; + bool isBearishPowerIncreasing; + bool isBearishPowerDecreasing; + + // + // Current ... + bool isCBullish; + bool isCBearish; + bool isCSwitchedToBullish; + bool isCSwitchedToBearish; + + // + // Short ... + bool isSBullish; + bool isSBearish; + bool isSSwitchedToBullish; + bool isSSwitchedToBearish; + + // + // Medium ... + bool isMBullish; + bool isMBearish; + bool isMSwitchedToBullish; + bool isMSwitchedToBearish; + + // + // Long ... + bool isLBullish; + bool isLBearish; + bool isLSwitchedToBullish; + bool isLSwitchedToBearish; + + // + // Hind ... + bool isHBullish; + bool isHBearish; + bool isHSwitchedToBullish; + bool isHSwitchedToBearish; + + // + void Clean() + { + // + Clean(cVolume); + Clean(sVolume); + Clean(mVolume); + Clean(lVolume); + Clean(hVolume); + + // + ArraySetAsSeries(cVolume, true); + ArraySetAsSeries(sVolume, true); + ArraySetAsSeries(mVolume, true); + ArraySetAsSeries(lVolume, true); + ArraySetAsSeries(hVolume, true); + + // + // Conditions ... + + // + // Power ... + hasBullishPower = false; + hasBearishPower = false; + isBullishPowerUp = false; + isBearishPowerUp = false; + isBullishPowerIncreasing = false; + isBullishPowerDecreasing = false; + isBearishPowerIncreasing = false; + isBearishPowerDecreasing = false; + + // + // Current ... + isCBullish = false; + isCBearish = false; + isCSwitchedToBullish = false; + isCSwitchedToBearish = false; + + // + // Short ... + isSBullish = false; + isSBearish = false; + isSSwitchedToBullish = false; + isSSwitchedToBearish = false; + + // + // Medium ... + isMBullish = false; + isMBearish = false; + isMSwitchedToBullish = false; + isMSwitchedToBearish = false; + + // + // Long ... + isLBullish = false; + isLBearish = false; + isLSwitchedToBullish = false; + isLSwitchedToBearish = false; + + // + // Hind ... + isHBullish = false; + isHBearish = false; + isHSwitchedToBullish = false; + isHSwitchedToBearish = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Since We have to Use this + // Only for Filtering Signals ... + // We Can Ignore Scoring ... + // or Complete this later ... + + // + // Conditions ... + + // + // Power ... + if (hasBullishPower) + { + bullishScore++; + } + if (hasBearishPower) + { + bearishScore++; + } + if (isBullishPowerUp) + { + bullishScore++; + } + if (isBearishPowerUp) + { + bearishScore++; + } + if (isBullishPowerIncreasing) + { + bullishScore++; + } + if (isBullishPowerDecreasing) + { + bearishScore++; + } + if (isBearishPowerIncreasing) + { + bearishScore++; + } + if (isBearishPowerDecreasing) + { + bullishScore++; + } + + // + // Current ... + if (isCBullish) + { + bullishScore++; + } + if (isCBearish) + { + bearishScore++; + } + if (isCSwitchedToBullish) + { + bullishScore++; + } + if (isCSwitchedToBearish) + { + bearishScore++; + } + + // + // Short ... + if (isSBullish) + { + bullishScore++; + } + if (isSBearish) + { + bearishScore++; + } + if (isSSwitchedToBullish) + { + bullishScore++; + } + if (isSSwitchedToBearish) + { + bearishScore++; + } + + // + // Medium ... + if (isMBullish) + { + bullishScore++; + } + if (isMBearish) + { + bearishScore++; + } + if (isMSwitchedToBullish) + { + bullishScore++; + } + if (isMSwitchedToBearish) + { + bearishScore++; + } + + // + // Long ... + if (isLBullish) + { + bullishScore++; + } + if (isLBearish) + { + bearishScore++; + } + if (isLSwitchedToBullish) + { + bullishScore++; + } + if (isLSwitchedToBearish) + { + bearishScore++; + } + + // + // Hind ... + if (isHBullish) + { + bullishScore++; + } + if (isHBearish) + { + bearishScore++; + } + if (isHSwitchedToBullish) + { + bullishScore++; + } + if (isHSwitchedToBearish) + { + bearishScore++; + } + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + // Power ... + ToString("hasBullishPower", hasBullishPower, ignoreFalseConditions, separator) + + ToString("hasBearishPower", hasBearishPower, ignoreFalseConditions, separator) + + ToString("isBullishPowerUp", isBullishPowerUp, ignoreFalseConditions, separator) + + ToString("isBearishPowerUp", isBearishPowerUp, ignoreFalseConditions, separator) + + ToString("isBullishPowerIncreasing", isBullishPowerIncreasing, ignoreFalseConditions, separator) + + ToString("isBullishPowerDecreasing", isBullishPowerDecreasing, ignoreFalseConditions, separator) + + ToString("isBearishPowerIncreasing", isBearishPowerIncreasing, ignoreFalseConditions, separator) + + ToString("isBearishPowerDecreasing", isBearishPowerDecreasing, ignoreFalseConditions, separator) + + // + // Current ... + ToString("isCBullish", isCBullish, ignoreFalseConditions, separator) + + ToString("isCBearish", isCBearish, ignoreFalseConditions, separator) + + ToString("isCSwitchedToBullish", isCSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCSwitchedToBearish", isCSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Short ... + ToString("isSBullish", isSBullish, ignoreFalseConditions, separator) + + ToString("isSBearish", isSBearish, ignoreFalseConditions, separator) + + ToString("isSSwitchedToBullish", isSSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSSwitchedToBearish", isSSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Medium ... + ToString("isMBullish", isMBullish, ignoreFalseConditions, separator) + + ToString("isMBearish", isMBearish, ignoreFalseConditions, separator) + + ToString("isMSwitchedToBullish", isMSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isMSwitchedToBearish", isMSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Long ... + ToString("isLBullish", isLBullish, ignoreFalseConditions, separator) + + ToString("isLBearish", isLBearish, ignoreFalseConditions, separator) + + ToString("isLSwitchedToBullish", isLSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isLSwitchedToBearish", isLSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Hind ... + ToString("isHBullish", isHBullish, ignoreFalseConditions, separator) + + ToString("isHBearish", isHBearish, ignoreFalseConditions, separator) + + ToString("isHSwitchedToBullish", isHSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isHSwitchedToBearish", isHSwitchedToBearish, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "XCHVLM"; + } +}; + +// +// Class ... +class XSCXCHVLMHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCHVLMHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCHVLMHelper() + { + // + Clean(cVolumeBuffer); + Clean(sVolumeBuffer); + Clean(mVolumeBuffer); + Clean(lVolumeBuffer); + Clean(hVolumeBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCHVLMInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(cVolumeBuffer, true); + ArraySetAsSeries(sVolumeBuffer, true); + ArraySetAsSeries(mVolumeBuffer, true); + ArraySetAsSeries(lVolumeBuffer, true); + ArraySetAsSeries(hVolumeBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xchvlm", + // + // Inputs ... + // + // Market ... + "", + mInputs.length, // Length + // + // Cycles ... + "", + // + // Short ... + "", + mInputs.scMethod, + mInputs.scPeriod, + // + // Medium ... + "", + mInputs.mcMethod, + mInputs.mcPeriod, + // + // Long ... + "", + mInputs.lcMethod, + mInputs.lcPeriod, + // + // Hind ... + "", + mInputs.hcMethod, + mInputs.hcPeriod, + // + // Presentation ... + "", + mInputs.showCurrent, + mInputs.showShort, + mInputs.showMedium, + mInputs.showLong, + mInputs.showHind + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCHVLMInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCHVLMInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Current ... + + // + double GetC( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return cVolumeBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyC( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + cVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Short ... + + // + double GetS( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return sVolumeBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyS( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + sVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Medium ... + + // + double GetM( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return mVolumeBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyM( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + mVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Long ... + + // + double GetL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return lVolumeBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + lVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Hind ... + + // + double GetH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return hVolumeBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + hVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Tools ... + + // + ENUM_XCHVLM_STATES ToState(double value) + { + // + ENUM_XCHVLM_STATES result = value >= 0 + ? XCHVLM_BULLISH_STATE + : XCHVLM_BEARISH_STATE; + + // + return result; + } + + // + bool IsBullish(double value) + { + // + bool result = false; + + // + result = + // + ToState(value) == XCHVLM_BEARISH_STATE; + // + ; + + // + return result; + } + + // + bool IsBearish(double value) + { + // + bool result = false; + + // + result = + // + ToState(value) == XCHVLM_BEARISH_STATE; + // + ; + + // + return result; + } + + // + int GetValues( + int barIndex, // Bar Index + double &values[] // Result + ) + { + // + int result = 0; + + // + Clean(values); + + // + ENUM_X_MARKET_CYCLES cycles[]; + int cyclesCount = GetAllMarketCycles(cycles); + if (!IsValidSize(cyclesCount)) + { + return result; + } + + // + for (int i = 0; i < cyclesCount; i++) + { + // + double iValue = GetCycleValue( + barIndex, + cycles[i] // + ); + + // + Add( + iValue, + values // + ); + } + + // + result = ArraySize(values); + + // + return result; + } + + // + double GetCycleValue( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // Cycle + ) + { + // + double result = 0; + + // + switch (cycle) + { + // + // CURRENT ... + case X_MARKET_CYCLE_UNKNOWN: + result = GetC(barIndex); + break; + + // + // SHORT ... + case X_MARKET_CYCLE_SHORT: + result = GetS(barIndex); + break; + + // + // MEDIUM ... + case X_MARKET_CYCLE_MEDIUM: + result = GetM(barIndex); + break; + + // + // LONG ... + case X_MARKET_CYCLE_LONG: + result = GetL(barIndex); + break; + + // + // HIND ... + case X_MARKET_CYCLE_HIND: + result = GetH(barIndex); + break; + } + + // + return result; + } + + // + int GetBullishCycles( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // Result + ) + { + // + int result = 0; + + // + Clean(cycles); + + // + ENUM_X_MARKET_CYCLES allCycles[]; + int allCyclesCount = GetAllMarketCycles(allCycles); + if (!IsValidSize(allCyclesCount)) + { + return result; + } + + // + for (int i = 0; i < allCyclesCount; i++) + { + // + double cValue = GetCycleValue( + barIndex, + allCycles[i] // + ); + + // + if (IsBullish(cValue)) + { + // + Add( + allCycles[i], + cycles // + ); + } + } + + // + result = ArraySize(cycles); + + // + return result; + } + + // + int GetBearishCycles( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // Result + ) + { + // + int result = 0; + + // + Clean(cycles); + + // + ENUM_X_MARKET_CYCLES allCycles[]; + int allCyclesCount = GetAllMarketCycles(allCycles); + if (!IsValidSize(allCyclesCount)) + { + return result; + } + + // + for (int i = 0; i < allCyclesCount; i++) + { + // + double cValue = GetCycleValue( + barIndex, + allCycles[i] // + ); + + // + if (IsBearish(cValue)) + { + // + Add( + allCycles[i], + cycles // + ); + } + } + + // + result = ArraySize(cycles); + + // + return result; + } + + // + int GetCyclesValues( + int barIndex, // Bar Index + double &values[], // Values + ENUM_X_MARKET_CYCLES &cycles[] // Cycles + ) + { + // + int result = 0; + + // + Clean(values); + + // + int count = ArraySize(cycles); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + double iValue = GetCycleValue( + barIndex, + cycles[i] // + ); + + // + Add( + iValue, + values // + ); + } + + // + result = ArraySize(values); + + // + return result; + } + + // + int GetBullishCyclesValues( + int barIndex, // Bar Index + double &values[] // Values + ) + { + // + int result = 0; + + // + Clean(values); + + // + ENUM_X_MARKET_CYCLES cycles[]; + int count = GetBullishCycles( + barIndex, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetCyclesValues( + barIndex, + values, + cycles // + ); + + // + return result; + } + + // + int GetBearishCyclesValues( + int barIndex, // Bar Index + double &values[] // Values + ) + { + // + int result = 0; + + // + Clean(values); + + // + ENUM_X_MARKET_CYCLES cycles[]; + int count = GetBearishCycles( + barIndex, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetCyclesValues( + barIndex, + values, + cycles // + ); + + // + return result; + } + + // + double GetCyclesMax( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // Cycles + ) + { + // + double result = 0; + + // + double values[]; + int count = GetCyclesValues( + barIndex, + values, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetCyclesMin( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // Cycles + ) + { + // + double result = 0; + + // + double values[]; + int count = GetCyclesValues( + barIndex, + values, + cycles // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSpecifiedMin(values); + + // + return result; + } + + // + double GetMax( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int valuesCount = GetValues( + barIndex, + values // + ); + if (!IsValidSize(valuesCount)) + { + return result; + } + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetMin( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int valuesCount = GetValues( + barIndex, + values // + ); + if (!IsValidSize(valuesCount)) + { + return result; + } + + // + result = GetSpecifiedMin(values); + + // + return result; + } + + // + double GetBullishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBullishCyclesValues( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSum(values); + + // + return result; + } + + // + double GetBearishPower( + int barIndex // Bar Index + ) + { + // + double result = 0; + + // + double values[]; + int count = GetBearishCyclesValues( + barIndex, + values // + ); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetSum(values); + + // + return result; + } + + // + double GetCyclesBullishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + double result = 0; + + // + int cyclesCount = ArraySize(cycles); + if (!IsValidSize(cyclesCount)) + { + return result; + } + + // + for (int i = 0; i < cyclesCount; i++) + { + // + double power = GetCycleValue( + barIndex, + cycles[i] // + ); + + // + if (IsBullish(power)) + { + result += MathAbs(power); + } + } + + // + return result; + } + + // + double GetCyclesBearishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + double result = 0; + + // + int cyclesCount = ArraySize(cycles); + if (!IsValidSize(cyclesCount)) + { + return result; + } + + // + for (int i = 0; i < cyclesCount; i++) + { + // + double power = GetCycleValue( + barIndex, + cycles[i] // + ); + + // + if (IsBearish(power)) + { + result += MathAbs(power); + } + } + + // + return result; + } + + // + bool HasBullishPower( + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + double bullishPower = GetBullishPower(barIndex); + double bearishPower = GetBearishPower(barIndex); + + // + result = + // + bearishPower >= 0 && + bullishPower > bearishPower + // + ; + + // + return result; + } + + // + bool HasBearishPower( + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + double bullishPower = GetBullishPower(barIndex); + double bearishPower = GetBearishPower(barIndex); + + // + result = + // + bullishPower >= 0 && + bearishPower > bullishPower + // + ; + + // + return result; + } + + // + bool HasCyclesBullishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + bool result = false; + + // + double bullishPower = GetCyclesBullishPower(barIndex, cycles); + double bearishPower = GetCyclesBearishPower(barIndex, cycles); + + // + result = + // + bearishPower >= 0 && + bullishPower > bearishPower + // + ; + + // + return result; + } + + // + bool HasCyclesBearishPower( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[] // + ) + { + // + bool result = false; + + // + double bullishPower = GetCyclesBullishPower(barIndex, cycles); + double bearishPower = GetCyclesBearishPower(barIndex, cycles); + + // + result = + // + bullishPower >= 0 && + bearishPower > bullishPower + // + ; + + // + return result; + } + + // + // Check Bullish Power Increasing ... + bool IsBullishPowerIncreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBullishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBullishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bullish Power Decreasing ... + bool IsBullishPowerDecreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBullishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBullishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Increasing ... + bool IsBearishPowerIncreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBearishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBearishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Decreasing ... + bool IsBearishPowerDecreasing( + int barIndex, // Bar Index + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetBearishPower(barIndex); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetBearishPower(i); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Check Bullish Power Increasing ... + bool IsCyclesBullishPowerIncreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBullishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBullishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bullish Power Decreasing ... + bool IsCyclesBullishPowerDecreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBullishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBullishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Increasing ... + bool IsCyclesBearishPowerIncreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBearishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBearishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower > iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower > lastPower + // + ; + } + + // + return result; + } + + // + // Check Bearish Power Decreasing ... + bool IsCyclesBearishPowerDecreasing( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES &cycles[], // + int loopback = 5 // Loopback + ) + { + // + bool result = false; + + // + if (loopback <= 0) + { + loopback = 5; + } + + // + double firstPower = GetCyclesBearishPower(barIndex, cycles); + double lastPower = firstPower; + for (int i = barIndex + 1; i < barIndex + loopback; i++) + { + // + double iPower = GetCyclesBearishPower(i, cycles); + + // + result = + // + iPower > 0 && + firstPower > 0 && + lastPower < iPower + // + ; + if (!result) + { + break; + } + + // + lastPower = iPower; + } + + // + if (result) + { + // + result = + // + firstPower < lastPower + // + ; + } + + // + return result; + } + + // + // Conditions ... + + // + bool GetConditions( + XCHVLMConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Buffers ... + + // + // Current ... + CopyC( + zIndex, + loopback, + conditions.cVolume // + ); + + // + // Short ... + CopyS( + zIndex, + loopback, + conditions.sVolume // + ); + + // + // Medium ... + CopyM( + zIndex, + loopback, + conditions.mVolume // + ); + + // + // Long ... + CopyL( + zIndex, + loopback, + conditions.lVolume // + ); + + // + // Hind ... + CopyH( + zIndex, + loopback, + conditions.hVolume // + ); + + // + // Conditions ... + + // + XOHCL cBar; + result = cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + mSymbol, + mPeriod, + pIndex // + ); + if (!result) + { + return result; + } + + // + // Power ... + + // + bool hasBullishPower = HasBullishPower(cIndex); + bool hasBullishPowerPrev = HasBullishPower(pIndex); + + // + bool hasBearishPower = HasBearishPower(cIndex); + bool hasBearishPowerPrev = HasBearishPower(pIndex); + + // + bool isBullishPowerUp = hasBullishPower && + !hasBullishPowerPrev; + bool isBearishPowerUp = hasBearishPower && + !hasBearishPowerPrev; + + // + bool isBullishPowerIncreasing = IsBullishPowerIncreasing(cIndex); + bool isBullishPowerDecreasing = IsBullishPowerDecreasing(cIndex); + bool isBearishPowerIncreasing = IsBearishPowerIncreasing(cIndex); + bool isBearishPowerDecreasing = IsBearishPowerDecreasing(cIndex); + + // + conditions.hasBullishPower = hasBullishPower; + conditions.hasBearishPower = hasBearishPower; + conditions.isBullishPowerUp = isBullishPowerUp; + conditions.isBearishPowerUp = isBearishPowerUp; + conditions.isBullishPowerIncreasing = isBullishPowerIncreasing; + conditions.isBullishPowerDecreasing = isBullishPowerDecreasing; + conditions.isBearishPowerIncreasing = isBearishPowerIncreasing; + conditions.isBearishPowerDecreasing = isBearishPowerDecreasing; + + // + // Current ... + + // + bool isCBullish = IsBullish(conditions.cVolume[cIndex]); + bool isCBullishPrev = IsBullish(conditions.cVolume[pIndex]); + + // + bool isCBearish = IsBearish(conditions.cVolume[cIndex]); + bool isCBearishPrev = IsBearish(conditions.cVolume[pIndex]); + + // + bool isCSwitchedToBullish = isCBullish && + !isCBullishPrev; + bool isCSwitchedToBearish = isCBearish && + !isCBearishPrev; + + // + conditions.isCBullish = isCBullish; + conditions.isCBearish = isCBearish; + conditions.isCSwitchedToBullish = isCSwitchedToBullish; + conditions.isCSwitchedToBearish = isCSwitchedToBearish; + + // + // Short ... + + // + bool isSBullish = IsBullish(conditions.sVolume[cIndex]); + bool isSBullishPrev = IsBullish(conditions.sVolume[pIndex]); + + // + bool isSBearish = IsBearish(conditions.sVolume[cIndex]); + bool isSBearishPrev = IsBearish(conditions.sVolume[pIndex]); + + // + bool isSSwitchedToBullish = isSBullish && + !isSBullishPrev; + bool isSSwitchedToBearish = isSBearish && + !isSBearishPrev; + + // + conditions.isSBullish = isSBullish; + conditions.isSBearish = isSBearish; + conditions.isSSwitchedToBullish = isSSwitchedToBullish; + conditions.isSSwitchedToBearish = isSSwitchedToBearish; + + // + // Medium ... + + // + bool isMBullish = IsBullish(conditions.mVolume[cIndex]); + bool isMBullishPrev = IsBullish(conditions.mVolume[pIndex]); + + // + bool isMBearish = IsBearish(conditions.mVolume[cIndex]); + bool isMBearishPrev = IsBearish(conditions.mVolume[pIndex]); + + // + bool isMSwitchedToBullish = isMBullish && + !isMBullishPrev; + bool isMSwitchedToBearish = isMBearish && + !isMBearishPrev; + + // + conditions.isMBullish = isMBullish; + conditions.isMBearish = isMBearish; + conditions.isMSwitchedToBullish = isMSwitchedToBullish; + conditions.isMSwitchedToBearish = isMSwitchedToBearish; + + // + // Long ... + + // + bool isLBullish = IsBullish(conditions.lVolume[cIndex]); + bool isLBullishPrev = IsBullish(conditions.lVolume[pIndex]); + + // + bool isLBearish = IsBearish(conditions.lVolume[cIndex]); + bool isLBearishPrev = IsBearish(conditions.lVolume[pIndex]); + + // + bool isLSwitchedToBullish = isLBullish && + !isLBullishPrev; + bool isLSwitchedToBearish = isLBearish && + !isLBearishPrev; + + // + conditions.isLBullish = isLBullish; + conditions.isLBearish = isLBearish; + conditions.isLSwitchedToBullish = isLSwitchedToBullish; + conditions.isLSwitchedToBearish = isLSwitchedToBearish; + + // + // Hind ... + + // + bool isHBullish = IsBullish(conditions.hVolume[cIndex]); + bool isHBullishPrev = IsBullish(conditions.hVolume[pIndex]); + + // + bool isHBearish = IsBearish(conditions.hVolume[cIndex]); + bool isHBearishPrev = IsBearish(conditions.hVolume[pIndex]); + + // + bool isHSwitchedToBullish = isHBullish && + !isHBullishPrev; + bool isHSwitchedToBearish = isHBearish && + !isHBearishPrev; + + // + conditions.isHBullish = isHBullish; + conditions.isHBearish = isHBearish; + conditions.isHSwitchedToBullish = isHSwitchedToBullish; + conditions.isHSwitchedToBearish = isHSwitchedToBearish; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCHVLMInputs mInputs; // Inputs ... + + // + // Buffers ... + + // + // Current ... + double cVolumeBuffer[]; + + // + // Short ... + double sVolumeBuffer[]; + + // + // Medium ... + double mVolumeBuffer[]; + + // + // Long ... + double lVolumeBuffer[]; + + // + // Hind ... + double hVolumeBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Current ... + CopyBuffer( + mHandler, + XCHVLM_C_LINE, + 0, + totalBars, + cVolumeBuffer + // + ); + + // + // Short ... + CopyBuffer( + mHandler, + XCHVLM_S_LINE, + 0, + totalBars, + sVolumeBuffer + // + ); + + // + // Medium ... + CopyBuffer( + mHandler, + XCHVLM_M_LINE, + 0, + totalBars, + mVolumeBuffer + // + ); + + // + // Long ... + CopyBuffer( + mHandler, + XCHVLM_L_LINE, + 0, + totalBars, + lVolumeBuffer + // + ); + + // + // Hind ... + CopyBuffer( + mHandler, + XCHVLM_H_LINE, + 0, + totalBars, + hVolumeBuffer + // + ); + }; +}; + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xchtd.mq5 b/Indicators/x-saherelm.xchtd.mq5 new file mode 100644 index 00000000..8b30a6ef --- /dev/null +++ b/Indicators/x-saherelm.xchtd.mq5 @@ -0,0 +1,898 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHTD +// Description: XCHTD Cycles ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHTD Indicator" +#property strict + +// +#define ShortName "XCHTD" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +enum ENUM_XCHTD_MODE +{ + XCHTD_POWER_MODE = 0, // Using Power + XCHTD_PRESSURE_MODE = 1, // Using Pressure + XCHTD_TYPE_MODE = 2, // Using Type + XCHTD_STRONG_MODE = 3, // Using Power and Pressures +}; + +// +// Inputs ... + +// +input group "Market"; +input int length = 14; // Length +input ENUM_XCHTD_MODE mode = XCHTD_POWER_MODE; // Mode + +// +input group "Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +// Presentation ... +input group "Presentation"; + +// +// Current ... +input bool showCurrent = true; // Show Current Cycle +input bool showShort = true; // Show Short Cycle +input bool showMedium = true; // Show Medium Cycle +input bool showLong = true; // Show Long Cycle +input bool showHind = true; // Show Hind Cycle + +// +// Buffers ... + +// +#property indicator_separate_window + +// +#property indicator_buffers 10 +#property indicator_plots 10 + +// +// Current ... + +// +#define cBullBufferIndex 0 +double cBullBuffer[]; + +// +#property indicator_label1 "XCHTD C Bull" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID + +// +#define cBearBufferIndex 1 +double cBearBuffer[]; + +// +#property indicator_label2 "XCHTD C Bear" +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_SOLID +#property indicator_color2 clrRed + +// +// Short ... + +// +#define sBullBufferIndex 2 +double sBullBuffer[]; + +// +#property indicator_label3 "XCHTD S Bull" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrLime +#property indicator_style3 STYLE_SOLID + +// +#define sBearBufferIndex 3 +double sBearBuffer[]; + +// +#property indicator_label4 "XCHTD S Bear" +#property indicator_type4 DRAW_LINE +#property indicator_style4 STYLE_SOLID +#property indicator_color4 clrRed + +// +// Medium ... + +// +#define mBullBufferIndex 4 +double mBullBuffer[]; + +// +#property indicator_label5 "XCHTD M Bull" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrLime +#property indicator_style5 STYLE_SOLID + +// +#define mBearBufferIndex 5 +double mBearBuffer[]; + +// +#property indicator_label6 "XCHTD M Bear" +#property indicator_type6 DRAW_LINE +#property indicator_style6 STYLE_SOLID +#property indicator_color6 clrRed + +// +// Long ... + +// +#define lBullBufferIndex 6 +double lBullBuffer[]; + +// +#property indicator_label7 "XCHTD L Bull" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLime +#property indicator_style7 STYLE_SOLID + +// +#define lBearBufferIndex 7 +double lBearBuffer[]; + +// +#property indicator_label8 "XCHTD L Bear" +#property indicator_type8 DRAW_LINE +#property indicator_style8 STYLE_SOLID +#property indicator_color8 clrRed + +// +// Hind ... + +// +#define hBullBufferIndex 8 +double hBullBuffer[]; + +// +#property indicator_label9 "XCHTD H Bull" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrLime +#property indicator_style9 STYLE_SOLID + +// +#define hBearBufferIndex 9 +double hBearBuffer[]; + +// +#property indicator_label10 "XCHTD H Bear" +#property indicator_type10 DRAW_LINE +#property indicator_style10 STYLE_SOLID +#property indicator_color10 clrRed + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +// Current ... +int mCMarketLength = length; + +// +// Short ... +int mSCycleLength = 0; +int mSMarketLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// Medium ... +int mMCycleLength = 0; +int mMMarketLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// Long ... +int mLCycleLength = 0; +int mLMarketLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// Hind ... +int mHCycleLength = 0; +int mHMarketLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // 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 ... + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + length >= 2 && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Initialize Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Current Cycle Initialization ... + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + mSCycleLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + mSMarketLength = mSCycleLength * mCMarketLength; + result = mSCycleLength > 0; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mMCycleLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + mMMarketLength = mMCycleLength * mCMarketLength; + result = mMCycleLength > 0; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + mLCycleLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + mLMarketLength = mLCycleLength * mCMarketLength; + result = mLCycleLength > 0; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + mHCycleLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + mHMarketLength = mHCycleLength * mCMarketLength; + result = mHCycleLength > 0; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mCMarketLength, mSMarketLength); + result = MathMax(result, mMMarketLength); + result = MathMax(result, mLMarketLength); + result = MathMax(result, mHMarketLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Current ... + + // + ENUM_DRAW_TYPE cDrawType = showCurrent ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(cBullBuffer, true); + SetIndexBuffer(cBullBufferIndex, cBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(cBullBufferIndex, PLOT_DRAW_TYPE, cDrawType); + PlotIndexSetInteger(cBullBufferIndex, PLOT_SHOW_DATA, showCurrent); + + // + ArraySetAsSeries(cBearBuffer, true); + SetIndexBuffer(cBearBufferIndex, cBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(cBearBufferIndex, PLOT_DRAW_TYPE, cDrawType); + PlotIndexSetInteger(cBearBufferIndex, PLOT_SHOW_DATA, showCurrent); + + // + // Short ... + + // + ENUM_DRAW_TYPE sDrawType = showShort ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(sBullBuffer, true); + SetIndexBuffer(sBullBufferIndex, sBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBullBufferIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetInteger(sBullBufferIndex, PLOT_SHOW_DATA, showShort); + + // + ArraySetAsSeries(sBearBuffer, true); + SetIndexBuffer(sBearBufferIndex, sBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBearBufferIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetInteger(sBearBufferIndex, PLOT_SHOW_DATA, showShort); + + // + // Medium ... + + // + ENUM_DRAW_TYPE mDrawType = showMedium ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(mBullBuffer, true); + SetIndexBuffer(mBullBufferIndex, mBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mBullBufferIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetInteger(mBullBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + ArraySetAsSeries(mBearBuffer, true); + SetIndexBuffer(mBearBufferIndex, mBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mBearBufferIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetInteger(mBearBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + // Long ... + + // + ENUM_DRAW_TYPE lDrawType = showLong ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(lBullBuffer, true); + SetIndexBuffer(lBullBufferIndex, lBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lBullBufferIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetInteger(lBullBufferIndex, PLOT_SHOW_DATA, showLong); + + // + ArraySetAsSeries(lBearBuffer, true); + SetIndexBuffer(lBearBufferIndex, lBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lBearBufferIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetInteger(lBearBufferIndex, PLOT_SHOW_DATA, showLong); + + // + // Hind ... + + // + ENUM_DRAW_TYPE hDrawType = showHind ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(hBullBuffer, true); + SetIndexBuffer(hBullBufferIndex, hBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hBullBufferIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetInteger(hBullBufferIndex, PLOT_SHOW_DATA, showHind); + + // + ArraySetAsSeries(hBearBuffer, true); + SetIndexBuffer(hBearBufferIndex, hBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hBearBufferIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetInteger(hBearBufferIndex, PLOT_SHOW_DATA, showHind); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculations ... + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + CalculateCycles( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); +} + +// +void CalculateCycles( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // CURRENT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mCMarketLength, + showCurrent, + cBullBuffer, + cBearBuffer // + ); + + // + // SHORT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mSMarketLength, + showShort, + sBullBuffer, + sBearBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mMMarketLength, + showMedium, + mBullBuffer, + mBearBuffer // + ); + + // + // LONG ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mLMarketLength, + showLong, + lBullBuffer, + lBearBuffer // + ); + + // + // HIND ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mHMarketLength, + showHind, + hBullBuffer, + hBearBuffer // + ); +} + +// +void CalculateCycle( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[], + // + int _length, // Calculation Length + bool _show, + double &_bull[], + double &_bear[] // +) +{ + // + double bullPower = 0; + double bearPower = 0; + + // + double lowShadow = 0; + double highShadow = 0; + + // + double bullPressure = 0; + double bearPressure = 0; + + // + double bullRange = 0; + double bearRange = 0; + + // + for (int i = bar_index; i < bar_index + _length; i++) + { + // + bool isBullish = + // + close[i] > open[i] + // + ; + + // + bool isBearish = + // + close[i] < open[i] + // + ; + + // + double iUpper = MathMax(open[i], close[i]); + double iLower = MathMin(open[i], close[i]); + + // + double iBody = iUpper - iLower; + double iRange = high[i] - low[i]; + + // + double iHighShadow = high[i] - iUpper; + double iLowShadow = iLower - low[i]; + + // + if (isBullish) + { + // + bullPower += iBody; + bullRange += iRange; + bearPressure += iHighShadow; + } + else if (isBearish) + { + // + bearPower += iBody; + bearRange += iRange; + bullPressure += iLowShadow; + } + + // + lowShadow += iLowShadow; + highShadow += iHighShadow; + } + + // + if (mode == XCHTD_POWER_MODE) + { + // + _bull[bar_index] = bullPower; + _bear[bar_index] = bearPower; + } + else if (mode == XCHTD_PRESSURE_MODE) + { + // + _bull[bar_index] = bullPressure; + _bear[bar_index] = bearPressure; + } + else if (mode == XCHTD_TYPE_MODE) + { + // + _bull[bar_index] = bullRange; + _bear[bar_index] = bearRange; + } else if (mode == XCHTD_STRONG_MODE) { + // + _bull[bar_index] = bullPower + bullPressure; + _bear[bar_index] = bearPower + bearPressure; + } +} + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xchtd.osc.mq5 b/Indicators/x-saherelm.xchtd.osc.mq5 new file mode 100644 index 00000000..8b30a6ef --- /dev/null +++ b/Indicators/x-saherelm.xchtd.osc.mq5 @@ -0,0 +1,898 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHTD +// Description: XCHTD Cycles ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHTD Indicator" +#property strict + +// +#define ShortName "XCHTD" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +enum ENUM_XCHTD_MODE +{ + XCHTD_POWER_MODE = 0, // Using Power + XCHTD_PRESSURE_MODE = 1, // Using Pressure + XCHTD_TYPE_MODE = 2, // Using Type + XCHTD_STRONG_MODE = 3, // Using Power and Pressures +}; + +// +// Inputs ... + +// +input group "Market"; +input int length = 14; // Length +input ENUM_XCHTD_MODE mode = XCHTD_POWER_MODE; // Mode + +// +input group "Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +// Presentation ... +input group "Presentation"; + +// +// Current ... +input bool showCurrent = true; // Show Current Cycle +input bool showShort = true; // Show Short Cycle +input bool showMedium = true; // Show Medium Cycle +input bool showLong = true; // Show Long Cycle +input bool showHind = true; // Show Hind Cycle + +// +// Buffers ... + +// +#property indicator_separate_window + +// +#property indicator_buffers 10 +#property indicator_plots 10 + +// +// Current ... + +// +#define cBullBufferIndex 0 +double cBullBuffer[]; + +// +#property indicator_label1 "XCHTD C Bull" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID + +// +#define cBearBufferIndex 1 +double cBearBuffer[]; + +// +#property indicator_label2 "XCHTD C Bear" +#property indicator_type2 DRAW_LINE +#property indicator_style2 STYLE_SOLID +#property indicator_color2 clrRed + +// +// Short ... + +// +#define sBullBufferIndex 2 +double sBullBuffer[]; + +// +#property indicator_label3 "XCHTD S Bull" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrLime +#property indicator_style3 STYLE_SOLID + +// +#define sBearBufferIndex 3 +double sBearBuffer[]; + +// +#property indicator_label4 "XCHTD S Bear" +#property indicator_type4 DRAW_LINE +#property indicator_style4 STYLE_SOLID +#property indicator_color4 clrRed + +// +// Medium ... + +// +#define mBullBufferIndex 4 +double mBullBuffer[]; + +// +#property indicator_label5 "XCHTD M Bull" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrLime +#property indicator_style5 STYLE_SOLID + +// +#define mBearBufferIndex 5 +double mBearBuffer[]; + +// +#property indicator_label6 "XCHTD M Bear" +#property indicator_type6 DRAW_LINE +#property indicator_style6 STYLE_SOLID +#property indicator_color6 clrRed + +// +// Long ... + +// +#define lBullBufferIndex 6 +double lBullBuffer[]; + +// +#property indicator_label7 "XCHTD L Bull" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrLime +#property indicator_style7 STYLE_SOLID + +// +#define lBearBufferIndex 7 +double lBearBuffer[]; + +// +#property indicator_label8 "XCHTD L Bear" +#property indicator_type8 DRAW_LINE +#property indicator_style8 STYLE_SOLID +#property indicator_color8 clrRed + +// +// Hind ... + +// +#define hBullBufferIndex 8 +double hBullBuffer[]; + +// +#property indicator_label9 "XCHTD H Bull" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrLime +#property indicator_style9 STYLE_SOLID + +// +#define hBearBufferIndex 9 +double hBearBuffer[]; + +// +#property indicator_label10 "XCHTD H Bear" +#property indicator_type10 DRAW_LINE +#property indicator_style10 STYLE_SOLID +#property indicator_color10 clrRed + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +// Current ... +int mCMarketLength = length; + +// +// Short ... +int mSCycleLength = 0; +int mSMarketLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// Medium ... +int mMCycleLength = 0; +int mMMarketLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// Long ... +int mLCycleLength = 0; +int mLMarketLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// Hind ... +int mHCycleLength = 0; +int mHMarketLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // 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 ... + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + length >= 2 && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Initialize Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Current Cycle Initialization ... + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + mSCycleLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + mSMarketLength = mSCycleLength * mCMarketLength; + result = mSCycleLength > 0; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mMCycleLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + mMMarketLength = mMCycleLength * mCMarketLength; + result = mMCycleLength > 0; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + mLCycleLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + mLMarketLength = mLCycleLength * mCMarketLength; + result = mLCycleLength > 0; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + mHCycleLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + mHMarketLength = mHCycleLength * mCMarketLength; + result = mHCycleLength > 0; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mCMarketLength, mSMarketLength); + result = MathMax(result, mMMarketLength); + result = MathMax(result, mLMarketLength); + result = MathMax(result, mHMarketLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Current ... + + // + ENUM_DRAW_TYPE cDrawType = showCurrent ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(cBullBuffer, true); + SetIndexBuffer(cBullBufferIndex, cBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(cBullBufferIndex, PLOT_DRAW_TYPE, cDrawType); + PlotIndexSetInteger(cBullBufferIndex, PLOT_SHOW_DATA, showCurrent); + + // + ArraySetAsSeries(cBearBuffer, true); + SetIndexBuffer(cBearBufferIndex, cBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(cBearBufferIndex, PLOT_DRAW_TYPE, cDrawType); + PlotIndexSetInteger(cBearBufferIndex, PLOT_SHOW_DATA, showCurrent); + + // + // Short ... + + // + ENUM_DRAW_TYPE sDrawType = showShort ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(sBullBuffer, true); + SetIndexBuffer(sBullBufferIndex, sBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBullBufferIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetInteger(sBullBufferIndex, PLOT_SHOW_DATA, showShort); + + // + ArraySetAsSeries(sBearBuffer, true); + SetIndexBuffer(sBearBufferIndex, sBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBearBufferIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetInteger(sBearBufferIndex, PLOT_SHOW_DATA, showShort); + + // + // Medium ... + + // + ENUM_DRAW_TYPE mDrawType = showMedium ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(mBullBuffer, true); + SetIndexBuffer(mBullBufferIndex, mBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mBullBufferIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetInteger(mBullBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + ArraySetAsSeries(mBearBuffer, true); + SetIndexBuffer(mBearBufferIndex, mBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mBearBufferIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetInteger(mBearBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + // Long ... + + // + ENUM_DRAW_TYPE lDrawType = showLong ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(lBullBuffer, true); + SetIndexBuffer(lBullBufferIndex, lBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lBullBufferIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetInteger(lBullBufferIndex, PLOT_SHOW_DATA, showLong); + + // + ArraySetAsSeries(lBearBuffer, true); + SetIndexBuffer(lBearBufferIndex, lBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lBearBufferIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetInteger(lBearBufferIndex, PLOT_SHOW_DATA, showLong); + + // + // Hind ... + + // + ENUM_DRAW_TYPE hDrawType = showHind ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(hBullBuffer, true); + SetIndexBuffer(hBullBufferIndex, hBullBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hBullBufferIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetInteger(hBullBufferIndex, PLOT_SHOW_DATA, showHind); + + // + ArraySetAsSeries(hBearBuffer, true); + SetIndexBuffer(hBearBufferIndex, hBearBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hBearBufferIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetInteger(hBearBufferIndex, PLOT_SHOW_DATA, showHind); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculations ... + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + CalculateCycles( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); +} + +// +void CalculateCycles( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // CURRENT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mCMarketLength, + showCurrent, + cBullBuffer, + cBearBuffer // + ); + + // + // SHORT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mSMarketLength, + showShort, + sBullBuffer, + sBearBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mMMarketLength, + showMedium, + mBullBuffer, + mBearBuffer // + ); + + // + // LONG ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mLMarketLength, + showLong, + lBullBuffer, + lBearBuffer // + ); + + // + // HIND ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mHMarketLength, + showHind, + hBullBuffer, + hBearBuffer // + ); +} + +// +void CalculateCycle( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[], + // + int _length, // Calculation Length + bool _show, + double &_bull[], + double &_bear[] // +) +{ + // + double bullPower = 0; + double bearPower = 0; + + // + double lowShadow = 0; + double highShadow = 0; + + // + double bullPressure = 0; + double bearPressure = 0; + + // + double bullRange = 0; + double bearRange = 0; + + // + for (int i = bar_index; i < bar_index + _length; i++) + { + // + bool isBullish = + // + close[i] > open[i] + // + ; + + // + bool isBearish = + // + close[i] < open[i] + // + ; + + // + double iUpper = MathMax(open[i], close[i]); + double iLower = MathMin(open[i], close[i]); + + // + double iBody = iUpper - iLower; + double iRange = high[i] - low[i]; + + // + double iHighShadow = high[i] - iUpper; + double iLowShadow = iLower - low[i]; + + // + if (isBullish) + { + // + bullPower += iBody; + bullRange += iRange; + bearPressure += iHighShadow; + } + else if (isBearish) + { + // + bearPower += iBody; + bearRange += iRange; + bullPressure += iLowShadow; + } + + // + lowShadow += iLowShadow; + highShadow += iHighShadow; + } + + // + if (mode == XCHTD_POWER_MODE) + { + // + _bull[bar_index] = bullPower; + _bear[bar_index] = bearPower; + } + else if (mode == XCHTD_PRESSURE_MODE) + { + // + _bull[bar_index] = bullPressure; + _bear[bar_index] = bearPressure; + } + else if (mode == XCHTD_TYPE_MODE) + { + // + _bull[bar_index] = bullRange; + _bear[bar_index] = bearRange; + } else if (mode == XCHTD_STRONG_MODE) { + // + _bull[bar_index] = bullPower + bullPressure; + _bear[bar_index] = bearPower + bearPressure; + } +} + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xchvlm.mq5 b/Indicators/x-saherelm.xchvlm.mq5 new file mode 100644 index 00000000..6916c09d --- /dev/null +++ b/Indicators/x-saherelm.xchvlm.mq5 @@ -0,0 +1,810 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHVLM +// Description: XCHVLM Cycles ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHVLM Indicator" +#property strict + +// +#define ShortName "XCHVLM" + +// +// Includes Common Library ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; +input int length = 14; // Length + +// +input group "Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +// Presentation ... +input group "Presentation"; + +// +// Current ... +input bool showCurrent = true; // Show Current Cycle +input bool showShort = true; // Show Short Cycle +input bool showMedium = true; // Show Medium Cycle +input bool showLong = true; // Show Long Cycle +input bool showHind = true; // Show Hind Cycle + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 + +// +#property indicator_separate_window + +// +#property indicator_buffers 10 +#property indicator_plots 10 + +// +// Current ... + +// +#define cBufferIndex 0 +double cBuffer[]; + +// +#define cColorBufferIndex 1 +double cColorBuffer[]; + +// +#define cPlotBufferIndex 0 +#property indicator_label1 "XCHVLM C" +#property indicator_style1 STYLE_SOLID +#property indicator_type1 DRAW_COLOR_HISTOGRAM +#property indicator_color1 CLR_NONE, clrLime, clrRed + +// +// Short ... + +// +#define sBufferIndex 2 +double sBuffer[]; + +// +#define sColorBufferIndex 3 +double sColorBuffer[]; + +// +#define sPlotBufferIndex 1 +#property indicator_label2 "XCHVLM S" +#property indicator_style2 STYLE_SOLID +#property indicator_type2 DRAW_COLOR_HISTOGRAM +#property indicator_color2 CLR_NONE, clrLime, clrRed + +// +// Medium ... + +// +#define mBufferIndex 4 +double mBuffer[]; + +// +#define mColorBufferIndex 5 +double mColorBuffer[]; + +// +#define mPlotBufferIndex 2 +#property indicator_label3 "XCHVLM M" +#property indicator_style3 STYLE_SOLID +#property indicator_type3 DRAW_COLOR_HISTOGRAM +#property indicator_color3 CLR_NONE, clrLime, clrRed + +// +// Long ... + +// +#define lBufferIndex 6 +double lBuffer[]; + +// +#define lColorBufferIndex 7 +double lColorBuffer[]; + +// +#define lPlotBufferIndex 3 +#property indicator_label4 "XCHVLM L" +#property indicator_style4 STYLE_SOLID +#property indicator_type4 DRAW_COLOR_HISTOGRAM +#property indicator_color4 CLR_NONE, clrLime, clrRed + +// +// Hind ... + +// +#define hBufferIndex 8 +double hBuffer[]; + +// +#define hColorBufferIndex 9 +double hColorBuffer[]; + +// +#define hPlotBufferIndex 4 +#property indicator_label5 "XCHVLM H" +#property indicator_style5 STYLE_SOLID +#property indicator_type5 DRAW_COLOR_HISTOGRAM +#property indicator_color5 CLR_NONE, clrLime, clrRed + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +// Current ... +int mCMarketLength = length; +double cVolumes[]; +double cDistances[]; + +// +// Short ... +int mSCycleLength = 0; +int mSMarketLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; +double sVolumes[]; +double sDistances[]; + +// +// Medium ... +int mMCycleLength = 0; +int mMMarketLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; +double mVolumes[]; +double mDistances[]; + +// +// Long ... +int mLCycleLength = 0; +int mLMarketLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; +double lVolumes[]; +double lDistances[]; + +// +// Hind ... +int mHCycleLength = 0; +int mHMarketLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; +double hVolumes[]; +double hDistances[]; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Current ... + ArrayResize(cVolumes, maxLength, 0); + ArrayResize(cDistances, maxLength, 0); + + // + // Short ... + ArrayResize(sVolumes, maxLength, 0); + ArrayResize(sDistances, maxLength, 0); + + // + // Medium ... + ArrayResize(mVolumes, maxLength, 0); + ArrayResize(mDistances, maxLength, 0); + + // + // Long ... + ArrayResize(lVolumes, maxLength, 0); + ArrayResize(lDistances, maxLength, 0); + + // + // Hind ... + ArrayResize(hVolumes, maxLength, 0); + ArrayResize(hDistances, maxLength, 0); + + // + // 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 + + // + Clean(cVolumes); + Clean(cDistances); + + // + Clean(sVolumes); + Clean(sDistances); + + // + Clean(mVolumes); + Clean(mDistances); + + // + Clean(lVolumes); + Clean(lDistances); + + // + Clean(hVolumes); + Clean(hDistances); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + static int i = maxLength * 2; + for (i; i < rates_total; i++) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + i = rates_total - 1; + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + length >= 2 && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Initialize Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Current Cycle Initialization ... + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + mSCycleLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + mSMarketLength = mSCycleLength * mCMarketLength; + result = mSCycleLength > 0; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mMCycleLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + mMMarketLength = mMCycleLength * mCMarketLength; + result = mMCycleLength > 0; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + mLCycleLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + mLMarketLength = mLCycleLength * mCMarketLength; + result = mLCycleLength > 0; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + mHCycleLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + mHMarketLength = mHCycleLength * mCMarketLength; + result = mHCycleLength > 0; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mCMarketLength, mSMarketLength); + result = MathMax(result, mMMarketLength); + result = MathMax(result, mLMarketLength); + result = MathMax(result, mHMarketLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Current ... + + // + // ENUM_DRAW_TYPE cDrawType = showCurrent ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(cPlotBufferIndex, PLOT_DRAW_TYPE, cDrawType); + SetIndexBuffer(cBufferIndex, cBuffer, INDICATOR_DATA); + SetIndexBuffer(cColorBufferIndex, cColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(cPlotBufferIndex, PLOT_SHOW_DATA, showCurrent); + + // + // Short ... + + // + // ENUM_DRAW_TYPE sDrawType = showShort ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(sPlotBufferIndex, PLOT_DRAW_TYPE, sDrawType); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(sPlotBufferIndex, PLOT_SHOW_DATA, showShort); + + // + // Medium ... + + // + // ENUM_DRAW_TYPE mDrawType = showMedium ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(mPlotBufferIndex, PLOT_DRAW_TYPE, mDrawType); + SetIndexBuffer(mBufferIndex, mBuffer, INDICATOR_DATA); + SetIndexBuffer(mColorBufferIndex, mColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(mPlotBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + // Long ... + + // + // ENUM_DRAW_TYPE lDrawType = showLong ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(lPlotBufferIndex, PLOT_DRAW_TYPE, lDrawType); + SetIndexBuffer(lBufferIndex, lBuffer, INDICATOR_DATA); + SetIndexBuffer(lColorBufferIndex, lColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(lPlotBufferIndex, PLOT_SHOW_DATA, showLong); + + // + // Hind ... + + // + ENUM_DRAW_TYPE hDrawType = showHind ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + SetIndexBuffer(hBufferIndex, hBuffer, INDICATOR_DATA); + SetIndexBuffer(hColorBufferIndex, hColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(hPlotBufferIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetInteger(hPlotBufferIndex, PLOT_SHOW_DATA, showHind); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculations ... + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + CalculateCycles( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); +} + +// +void CalculateCycles( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // CURRENT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mCMarketLength, + showCurrent, + cVolumes, + cDistances, + cBuffer, + cColorBuffer // + ); + + // + // SHORT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mSMarketLength, + showShort, + sVolumes, + sDistances, + sBuffer, + sColorBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mMMarketLength, + showMedium, + mVolumes, + mDistances, + mBuffer, + mColorBuffer // + ); + + // + // LONG ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mLMarketLength, + showLong, + lVolumes, + lDistances, + lBuffer, + lColorBuffer // + ); + + // + // HIND ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mHMarketLength, + showHind, + hVolumes, + hDistances, + hBuffer, + hColorBuffer // + ); +} + +// +void CalculateCycle( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[], + // + int _length, // Calculation Length + bool _show, + double &_volumes[], + double &_distances[], + double &_buffer[], + double &_colorBuffer[] // +) +{ + // + for (int x = 0; x < _length; x++) + { + // + _volumes[x] = (double)tickVolume[bar_index - x]; + _distances[x] = + (close[bar_index - x] > open[bar_index - x]) + ? high[bar_index - x] - low[bar_index - x] + : low[bar_index - x] - high[bar_index - x]; + } + + // + double iValue = MathMean(_volumes) * MathMean(_distances); + + // + _buffer[bar_index] = iValue; + _colorBuffer[bar_index] = iValue > 0 + ? _show + ? bullishColorIDX + : hideColorIDX + : _show + ? bearishColorIDX + : hideColorIDX; +} + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xchvlm.osc.mq5 b/Indicators/x-saherelm.xchvlm.osc.mq5 new file mode 100644 index 00000000..6916c09d --- /dev/null +++ b/Indicators/x-saherelm.xchvlm.osc.mq5 @@ -0,0 +1,810 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHVLM +// Description: XCHVLM Cycles ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHVLM Indicator" +#property strict + +// +#define ShortName "XCHVLM" + +// +// Includes Common Library ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; +input int length = 14; // Length + +// +input group "Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +// Presentation ... +input group "Presentation"; + +// +// Current ... +input bool showCurrent = true; // Show Current Cycle +input bool showShort = true; // Show Short Cycle +input bool showMedium = true; // Show Medium Cycle +input bool showLong = true; // Show Long Cycle +input bool showHind = true; // Show Hind Cycle + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 + +// +#property indicator_separate_window + +// +#property indicator_buffers 10 +#property indicator_plots 10 + +// +// Current ... + +// +#define cBufferIndex 0 +double cBuffer[]; + +// +#define cColorBufferIndex 1 +double cColorBuffer[]; + +// +#define cPlotBufferIndex 0 +#property indicator_label1 "XCHVLM C" +#property indicator_style1 STYLE_SOLID +#property indicator_type1 DRAW_COLOR_HISTOGRAM +#property indicator_color1 CLR_NONE, clrLime, clrRed + +// +// Short ... + +// +#define sBufferIndex 2 +double sBuffer[]; + +// +#define sColorBufferIndex 3 +double sColorBuffer[]; + +// +#define sPlotBufferIndex 1 +#property indicator_label2 "XCHVLM S" +#property indicator_style2 STYLE_SOLID +#property indicator_type2 DRAW_COLOR_HISTOGRAM +#property indicator_color2 CLR_NONE, clrLime, clrRed + +// +// Medium ... + +// +#define mBufferIndex 4 +double mBuffer[]; + +// +#define mColorBufferIndex 5 +double mColorBuffer[]; + +// +#define mPlotBufferIndex 2 +#property indicator_label3 "XCHVLM M" +#property indicator_style3 STYLE_SOLID +#property indicator_type3 DRAW_COLOR_HISTOGRAM +#property indicator_color3 CLR_NONE, clrLime, clrRed + +// +// Long ... + +// +#define lBufferIndex 6 +double lBuffer[]; + +// +#define lColorBufferIndex 7 +double lColorBuffer[]; + +// +#define lPlotBufferIndex 3 +#property indicator_label4 "XCHVLM L" +#property indicator_style4 STYLE_SOLID +#property indicator_type4 DRAW_COLOR_HISTOGRAM +#property indicator_color4 CLR_NONE, clrLime, clrRed + +// +// Hind ... + +// +#define hBufferIndex 8 +double hBuffer[]; + +// +#define hColorBufferIndex 9 +double hColorBuffer[]; + +// +#define hPlotBufferIndex 4 +#property indicator_label5 "XCHVLM H" +#property indicator_style5 STYLE_SOLID +#property indicator_type5 DRAW_COLOR_HISTOGRAM +#property indicator_color5 CLR_NONE, clrLime, clrRed + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +// Current ... +int mCMarketLength = length; +double cVolumes[]; +double cDistances[]; + +// +// Short ... +int mSCycleLength = 0; +int mSMarketLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; +double sVolumes[]; +double sDistances[]; + +// +// Medium ... +int mMCycleLength = 0; +int mMMarketLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; +double mVolumes[]; +double mDistances[]; + +// +// Long ... +int mLCycleLength = 0; +int mLMarketLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; +double lVolumes[]; +double lDistances[]; + +// +// Hind ... +int mHCycleLength = 0; +int mHMarketLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; +double hVolumes[]; +double hDistances[]; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Current ... + ArrayResize(cVolumes, maxLength, 0); + ArrayResize(cDistances, maxLength, 0); + + // + // Short ... + ArrayResize(sVolumes, maxLength, 0); + ArrayResize(sDistances, maxLength, 0); + + // + // Medium ... + ArrayResize(mVolumes, maxLength, 0); + ArrayResize(mDistances, maxLength, 0); + + // + // Long ... + ArrayResize(lVolumes, maxLength, 0); + ArrayResize(lDistances, maxLength, 0); + + // + // Hind ... + ArrayResize(hVolumes, maxLength, 0); + ArrayResize(hDistances, maxLength, 0); + + // + // 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 + + // + Clean(cVolumes); + Clean(cDistances); + + // + Clean(sVolumes); + Clean(sDistances); + + // + Clean(mVolumes); + Clean(mDistances); + + // + Clean(lVolumes); + Clean(lDistances); + + // + Clean(hVolumes); + Clean(hDistances); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + static int i = maxLength * 2; + for (i; i < rates_total; i++) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + i = rates_total - 1; + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + length >= 2 && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Initialize Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Current Cycle Initialization ... + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + mSCycleLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + mSMarketLength = mSCycleLength * mCMarketLength; + result = mSCycleLength > 0; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mMCycleLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + mMMarketLength = mMCycleLength * mCMarketLength; + result = mMCycleLength > 0; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + mLCycleLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + mLMarketLength = mLCycleLength * mCMarketLength; + result = mLCycleLength > 0; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + mHCycleLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + mHMarketLength = mHCycleLength * mCMarketLength; + result = mHCycleLength > 0; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mCMarketLength, mSMarketLength); + result = MathMax(result, mMMarketLength); + result = MathMax(result, mLMarketLength); + result = MathMax(result, mHMarketLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Current ... + + // + // ENUM_DRAW_TYPE cDrawType = showCurrent ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(cPlotBufferIndex, PLOT_DRAW_TYPE, cDrawType); + SetIndexBuffer(cBufferIndex, cBuffer, INDICATOR_DATA); + SetIndexBuffer(cColorBufferIndex, cColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(cPlotBufferIndex, PLOT_SHOW_DATA, showCurrent); + + // + // Short ... + + // + // ENUM_DRAW_TYPE sDrawType = showShort ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(sPlotBufferIndex, PLOT_DRAW_TYPE, sDrawType); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(sPlotBufferIndex, PLOT_SHOW_DATA, showShort); + + // + // Medium ... + + // + // ENUM_DRAW_TYPE mDrawType = showMedium ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(mPlotBufferIndex, PLOT_DRAW_TYPE, mDrawType); + SetIndexBuffer(mBufferIndex, mBuffer, INDICATOR_DATA); + SetIndexBuffer(mColorBufferIndex, mColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(mPlotBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + // Long ... + + // + // ENUM_DRAW_TYPE lDrawType = showLong ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + // PlotIndexSetInteger(lPlotBufferIndex, PLOT_DRAW_TYPE, lDrawType); + SetIndexBuffer(lBufferIndex, lBuffer, INDICATOR_DATA); + SetIndexBuffer(lColorBufferIndex, lColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(lPlotBufferIndex, PLOT_SHOW_DATA, showLong); + + // + // Hind ... + + // + ENUM_DRAW_TYPE hDrawType = showHind ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; + SetIndexBuffer(hBufferIndex, hBuffer, INDICATOR_DATA); + SetIndexBuffer(hColorBufferIndex, hColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(hPlotBufferIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetInteger(hPlotBufferIndex, PLOT_SHOW_DATA, showHind); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculations ... + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + CalculateCycles( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); +} + +// +void CalculateCycles( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // CURRENT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mCMarketLength, + showCurrent, + cVolumes, + cDistances, + cBuffer, + cColorBuffer // + ); + + // + // SHORT ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mSMarketLength, + showShort, + sVolumes, + sDistances, + sBuffer, + sColorBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mMMarketLength, + showMedium, + mVolumes, + mDistances, + mBuffer, + mColorBuffer // + ); + + // + // LONG ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mLMarketLength, + showLong, + lVolumes, + lDistances, + lBuffer, + lColorBuffer // + ); + + // + // HIND ... + CalculateCycle( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume, + // + mHMarketLength, + showHind, + hVolumes, + hDistances, + hBuffer, + hColorBuffer // + ); +} + +// +void CalculateCycle( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[], + // + int _length, // Calculation Length + bool _show, + double &_volumes[], + double &_distances[], + double &_buffer[], + double &_colorBuffer[] // +) +{ + // + for (int x = 0; x < _length; x++) + { + // + _volumes[x] = (double)tickVolume[bar_index - x]; + _distances[x] = + (close[bar_index - x] > open[bar_index - x]) + ? high[bar_index - x] - low[bar_index - x] + : low[bar_index - x] - high[bar_index - x]; + } + + // + double iValue = MathMean(_volumes) * MathMean(_distances); + + // + _buffer[bar_index] = iValue; + _colorBuffer[bar_index] = iValue > 0 + ? _show + ? bullishColorIDX + : hideColorIDX + : _show + ? bearishColorIDX + : hideColorIDX; +} + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 9a2e1f36..98f5ac99 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -8909,6 +8909,43 @@ bool Contains( return result; } +// +// Calculate a Buffer's Sum ... +template +double GetSum( + T &buffer[], // the Buffer which required to search + int start = 0, // Start Index + int count = 0 // Count for Search +) +{ + // + double result = 0; + + // + T tmp[]; + int tmpCount = Copy( + start, + count, + buffer, + tmp + // + ); + if (tmpCount <= 0) + { + return result; + } + + // + // Calculate Summary ... + for (int i = 0; i < tmpCount; i++) + { + result += buffer[i]; + } + + // + return result; +} + // // Calculate a Buffer's Average ... template