From 47afcb1917324de8417dab79a892103dd63feec5 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 25 Jul 2024 02:02:32 +0330 Subject: [PATCH] last ... --- Experts/x-test-strategies.ea.mq5 | 2 +- Helpers/x-saherelm.xchstr.helper.mq5 | 3017 ++++++++++++++++++++++ Indicators/x-saherelm.xchm.mq5 | 1086 ++++++++ Indicators/x-saherelm.xchstr.mq5 | 1246 +++++++++ Strategies/x-saherelm.xchkm.strategy.mq5 | 4 +- 5 files changed, 5352 insertions(+), 3 deletions(-) create mode 100644 Helpers/x-saherelm.xchstr.helper.mq5 create mode 100644 Indicators/x-saherelm.xchm.mq5 create mode 100644 Indicators/x-saherelm.xchstr.mq5 diff --git a/Experts/x-test-strategies.ea.mq5 b/Experts/x-test-strategies.ea.mq5 index 15af63b3..1e5b2daa 100644 --- a/Experts/x-test-strategies.ea.mq5 +++ b/Experts/x-test-strategies.ea.mq5 @@ -328,7 +328,7 @@ bool InitialEA() eurusdSymbol, PERIOD_M5, eaVolume, - 1, // eaR2R, // R2R ... + 0.75, // eaR2R, // R2R ... eaSlippage, magicNumber, true, // Ignore Signal Execution diff --git a/Helpers/x-saherelm.xchstr.helper.mq5 b/Helpers/x-saherelm.xchstr.helper.mq5 new file mode 100644 index 00000000..1a384ab8 --- /dev/null +++ b/Helpers/x-saherelm.xchstr.helper.mq5 @@ -0,0 +1,3017 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXCHHKHelper +// 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_XCHHK_BUFFERS +{ + // + // Current ... + XCHHK_CO_LINE = 0, + XCHHK_CH_LINE = 1, + XCHHK_CL_LINE = 2, + XCHHK_CC_LINE = 3, + // + // Short ... + XCHHK_SO_LINE = 5, + XCHHK_SH_LINE = 6, + XCHHK_SL_LINE = 7, + XCHHK_SC_LINE = 8, + // + // Medium ... + XCHHK_MO_LINE = 10, + XCHHK_MH_LINE = 11, + XCHHK_ML_LINE = 12, + XCHHK_MC_LINE = 13, + // + // Long ... + XCHHK_LO_LINE = 15, + XCHHK_LH_LINE = 16, + XCHHK_LL_LINE = 17, + XCHHK_LC_LINE = 18, + // + // Hind ... + XCHHK_HO_LINE = 20, + XCHHK_HH_LINE = 21, + XCHHK_HL_LINE = 22, + XCHHK_HC_LINE = 23, +}; + +// +// Input Models ... +struct XCHHKInputs +{ + // + // Props ... + + // + // Market ... + int cSmoothingLength; // Smoothing 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) ... + XCHHKInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + cSmoothingLength = 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() + { + // + cSmoothingLength = 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 = + // + cSmoothingLength > 2 && + // + (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, cSmoothingLength) + // + ; + + // + return result; + } +}; + +// +// Define Conditions ... +struct XCHHKConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + // Current ... + XOHCL cBars[]; + + // + // Short ... + XOHCL sBars[]; + + // + // Medium ... + XOHCL mBars[]; + + // + // Long ... + XOHCL lBars[]; + + // + // Hind ... + XOHCL hBars[]; + + // + // Conditions ... + + // + // Current ... + + // + bool isCBullish; + bool isCSwitchedToBullish; + bool isCBearish; + bool isCSwitchedToBearish; + + // + bool isCloseOverCHigh; + bool isCloseUnderCLow; + + // + // Short ... + + // + bool isSBullish; + bool isSSwitchedToBullish; + bool isSBearish; + bool isSSwitchedToBearish; + + // + bool isCloseOverSHigh; + bool isCloseUnderSLow; + + // + // Medium ... + + // + bool isMBullish; + bool isMSwitchedToBullish; + bool isMBearish; + bool isMSwitchedToBearish; + + // + bool isCloseOverMHigh; + bool isCloseUnderMLow; + + // + // Long ... + + // + bool isLBullish; + bool isLSwitchedToBullish; + bool isLBearish; + bool isLSwitchedToBearish; + + // + bool isCloseOverLHigh; + bool isCloseUnderLLow; + + // + // Hind ... + + // + bool isHBullish; + bool isHSwitchedToBullish; + bool isHBearish; + bool isHSwitchedToBearish; + + // + bool isCloseOverHHigh; + bool isCloseUnderHLow; + + // + void Clean() + { + // + Clean(cBars); + Clean(sBars); + Clean(mBars); + Clean(lBars); + Clean(hBars); + + // + ArraySetAsSeries(cBars, true); + ArraySetAsSeries(sBars, true); + ArraySetAsSeries(mBars, true); + ArraySetAsSeries(lBars, true); + ArraySetAsSeries(hBars, true); + + // + // Conditions ... + + // + // Current ... + + // + isCBullish = false; + isCSwitchedToBullish = false; + isCBearish = false; + isCSwitchedToBearish = false; + + // + isCloseOverCHigh = false; + isCloseUnderCLow = false; + + // + // Short ... + + // + isSBullish = false; + isSSwitchedToBullish = false; + isSBearish = false; + isSSwitchedToBearish = false; + + // + isCloseOverSHigh = false; + isCloseUnderSLow = false; + + // + // Medium ... + + // + isMBullish = false; + isMSwitchedToBullish = false; + isMBearish = false; + isMSwitchedToBearish = false; + + // + isCloseOverMHigh = false; + isCloseUnderMLow = false; + + // + // Long ... + + // + isLBullish = false; + isLSwitchedToBullish = false; + isLBearish = false; + isLSwitchedToBearish = false; + + // + isCloseOverLHigh = false; + isCloseUnderLLow = false; + + // + // Hind ... + + // + isHBullish = false; + isHSwitchedToBullish = false; + isHBearish = false; + isHSwitchedToBearish = false; + + // + isCloseOverHHigh = false; + isCloseUnderHLow = 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 ... + + // + // Current ... + if (isCBullish) + { + bullishScore++; + } + if (isCSwitchedToBullish) + { + bullishScore++; + } + if (isCBearish) + { + bearishScore++; + } + if (isCSwitchedToBearish) + { + bearishScore++; + } + if (isCloseOverCHigh) + { + bullishScore++; + } + if (isCloseUnderCLow) + { + bearishScore++; + } + + // + // Short ... + if (isSBullish) + { + bullishScore++; + } + if (isSSwitchedToBullish) + { + bullishScore++; + } + if (isSBearish) + { + bearishScore++; + } + if (isSSwitchedToBearish) + { + bearishScore++; + } + if (isCloseOverSHigh) + { + bullishScore++; + } + if (isCloseUnderSLow) + { + bearishScore++; + } + + // + // Medium ... + if (isMBullish) + { + bullishScore++; + } + if (isMSwitchedToBullish) + { + bullishScore++; + } + if (isMBearish) + { + bearishScore++; + } + if (isMSwitchedToBearish) + { + bearishScore++; + } + if (isCloseOverMHigh) + { + bullishScore++; + } + if (isCloseUnderMLow) + { + bearishScore++; + } + + // + // Long ... + if (isLBullish) + { + bullishScore++; + } + if (isLSwitchedToBullish) + { + bullishScore++; + } + if (isLBearish) + { + bearishScore++; + } + if (isLSwitchedToBearish) + { + bearishScore++; + } + if (isCloseOverLHigh) + { + bullishScore++; + } + if (isCloseUnderLLow) + { + bearishScore++; + } + + // + // Hind ... + if (isHBullish) + { + bullishScore++; + } + if (isHSwitchedToBullish) + { + bullishScore++; + } + if (isHBearish) + { + bearishScore++; + } + if (isHSwitchedToBearish) + { + bearishScore++; + } + if (isCloseOverHHigh) + { + bullishScore++; + } + if (isCloseUnderHLow) + { + 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 = + // + // Current ... + ToString("isCBullish", isCBullish, ignoreFalseConditions, separator) + + ToString("isCSwitchedToBullish", isCSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCBearish", isCBearish, ignoreFalseConditions, separator) + + ToString("isCSwitchedToBearish", isCSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCloseOverCHigh", isCloseOverCHigh, ignoreFalseConditions, separator) + + ToString("isCloseUnderCLow", isCloseUnderCLow, ignoreFalseConditions, separator) + + // + // Short ... + ToString("isSBullish", isSBullish, ignoreFalseConditions, separator) + + ToString("isSSwitchedToBullish", isSSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSBearish", isSBearish, ignoreFalseConditions, separator) + + ToString("isSSwitchedToBearish", isSSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCloseOverSHigh", isCloseOverSHigh, ignoreFalseConditions, separator) + + ToString("isCloseUnderSLow", isCloseUnderSLow, ignoreFalseConditions, separator) + + // + // Medium ... + ToString("isMBullish", isMBullish, ignoreFalseConditions, separator) + + ToString("isMSwitchedToBullish", isMSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isMBearish", isMBearish, ignoreFalseConditions, separator) + + ToString("isMSwitchedToBearish", isMSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCloseOverMHigh", isCloseOverMHigh, ignoreFalseConditions, separator) + + ToString("isCloseUnderMLow", isCloseUnderMLow, ignoreFalseConditions, separator) + + // + // Long ... + ToString("isLBullish", isLBullish, ignoreFalseConditions, separator) + + ToString("isLSwitchedToBullish", isLSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isLBearish", isLBearish, ignoreFalseConditions, separator) + + ToString("isLSwitchedToBearish", isLSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCloseOverLHigh", isCloseOverLHigh, ignoreFalseConditions, separator) + + ToString("isCloseUnderLLow", isCloseUnderLLow, ignoreFalseConditions, separator) + + // + // Hind ... + ToString("isHBullish", isHBullish, ignoreFalseConditions, separator) + + ToString("isHSwitchedToBullish", isHSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isHBearish", isHBearish, ignoreFalseConditions, separator) + + ToString("isHSwitchedToBearish", isHSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCloseOverHHigh", isCloseOverHHigh, ignoreFalseConditions, separator) + + ToString("isCloseUnderHLow", isCloseUnderHLow, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "XCHHK"; + } +}; + +// +// Class ... +class XSCXCHHKHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXCHHKHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXCHHKHelper() + { + // + Clean(cOpenBuffer); + Clean(cHighBuffer); + Clean(cLowBuffer); + Clean(cCloseBuffer); + Clean(sOpenBuffer); + Clean(sHighBuffer); + Clean(sLowBuffer); + Clean(sCloseBuffer); + Clean(mOpenBuffer); + Clean(mHighBuffer); + Clean(mLowBuffer); + Clean(mCloseBuffer); + Clean(lOpenBuffer); + Clean(lHighBuffer); + Clean(lLowBuffer); + Clean(lCloseBuffer); + Clean(hOpenBuffer); + Clean(hHighBuffer); + Clean(hLowBuffer); + Clean(hCloseBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCHHKInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(cOpenBuffer, true); + ArraySetAsSeries(cHighBuffer, true); + ArraySetAsSeries(cLowBuffer, true); + ArraySetAsSeries(cCloseBuffer, true); + ArraySetAsSeries(sOpenBuffer, true); + ArraySetAsSeries(sHighBuffer, true); + ArraySetAsSeries(sLowBuffer, true); + ArraySetAsSeries(sCloseBuffer, true); + ArraySetAsSeries(mOpenBuffer, true); + ArraySetAsSeries(mHighBuffer, true); + ArraySetAsSeries(mLowBuffer, true); + ArraySetAsSeries(mCloseBuffer, true); + ArraySetAsSeries(lOpenBuffer, true); + ArraySetAsSeries(lHighBuffer, true); + ArraySetAsSeries(lLowBuffer, true); + ArraySetAsSeries(lCloseBuffer, true); + ArraySetAsSeries(hOpenBuffer, true); + ArraySetAsSeries(hHighBuffer, true); + ArraySetAsSeries(hLowBuffer, true); + ArraySetAsSeries(hCloseBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xchhk", + // + // Inputs ... + // + // Market ... + "", + mInputs.cSmoothingLength, + // + // 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 ... + + // + XCHHKInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCHHKInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Current ... + + // + double GetCOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(cOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return cOpenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyCOpen( + 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, + cOpenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetCHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(cHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return cHighBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyCHigh( + 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, + cHighBuffer, + buffer, + forceClean + // + ); + } + + // + double GetCLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(cLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return cLowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyCLow( + 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, + cLowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetCClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(cCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return cCloseBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyCClose( + 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, + cCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // Get XOHCL ... + bool CAsOHCL( + XOHCL &bar, // Holds Result + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(cOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + double open = GetCOpen(barIndex); + double high = GetCHigh(barIndex); + double close = GetCClose(barIndex); + double low = GetCLow(barIndex); + + // + result = bar.Init( + mSymbol, + mPeriod, + open, + high, + close, + low, + barIndex + // + ); + + // + return result; + } + + // + // Copy Required Items ... + int CopyCAsOHCL( + int start, // Start + int count, // Number of Items for read + XOHCL &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + int result = 0; + + // + // Update Calculations ... + Calculate(); + + // + if (forceClean) + { + Clean(buffer); + } + + // + int before = ArraySize(buffer); + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(cOpenBuffer)) + { + start = ArraySize(cOpenBuffer) - 1; + } + + // + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); + + // + for (int i = start; i < start + count; i++) + { + // + XOHCL iBar; + bool isInit = CAsOHCL(iBar, i); + + // + if (isInit) + { + // + AddRef( + iBar, + buffer + // + ); + } + } + + // + ArraySetAsSeries(buffer, asSeriesBuffer); + + // + int after = ArraySize(buffer); + + // + result = after - before; + + // + return result; + } + + // + // Short ... + + // + double GetSOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(sOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sOpenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySOpen( + 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, + sOpenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(sHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sHighBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySHigh( + 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, + sHighBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(sLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sLowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySLow( + 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, + sLowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(sCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sCloseBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopySClose( + 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, + sCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // Get XOHCL ... + bool SAsOHCL( + XOHCL &bar, // Holds Result + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(sOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + double open = GetSOpen(barIndex); + double high = GetSHigh(barIndex); + double close = GetSClose(barIndex); + double low = GetSLow(barIndex); + + // + result = bar.Init( + mSymbol, + mPeriod, + open, + high, + close, + low, + barIndex + // + ); + + // + return result; + } + + // + // Copy Required Items ... + int CopySAsOHCL( + int start, // Start + int count, // Number of Items for read + XOHCL &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + int result = 0; + + // + // Update Calculations ... + Calculate(); + + // + if (forceClean) + { + Clean(buffer); + } + + // + int before = ArraySize(buffer); + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(sOpenBuffer)) + { + start = ArraySize(sOpenBuffer) - 1; + } + + // + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); + + // + for (int i = start; i < start + count; i++) + { + // + XOHCL iBar; + bool isInit = SAsOHCL(iBar, i); + + // + if (isInit) + { + // + AddRef( + iBar, + buffer + // + ); + } + } + + // + ArraySetAsSeries(buffer, asSeriesBuffer); + + // + int after = ArraySize(buffer); + + // + result = after - before; + + // + return result; + } + + // + // Medium ... + + // + double GetMOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mOpenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMOpen( + 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, + mOpenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mHighBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMHigh( + 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, + mHighBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mLowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMLow( + 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, + mLowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetMClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mCloseBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyMClose( + 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, + mCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // Get XOHCL ... + bool MAsOHCL( + XOHCL &bar, // Holds Result + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + double open = GetMOpen(barIndex); + double high = GetMHigh(barIndex); + double close = GetMClose(barIndex); + double low = GetMLow(barIndex); + + // + result = bar.Init( + mSymbol, + mPeriod, + open, + high, + close, + low, + barIndex + // + ); + + // + return result; + } + + // + // Copy Required Items ... + int CopyMAsOHCL( + int start, // Start + int count, // Number of Items for read + XOHCL &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + int result = 0; + + // + // Update Calculations ... + Calculate(); + + // + if (forceClean) + { + Clean(buffer); + } + + // + int before = ArraySize(buffer); + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(mOpenBuffer)) + { + start = ArraySize(mOpenBuffer) - 1; + } + + // + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); + + // + for (int i = start; i < start + count; i++) + { + // + XOHCL iBar; + bool isInit = MAsOHCL(iBar, i); + + // + if (isInit) + { + // + AddRef( + iBar, + buffer + // + ); + } + } + + // + ArraySetAsSeries(buffer, asSeriesBuffer); + + // + int after = ArraySize(buffer); + + // + result = after - before; + + // + return result; + } + + // + // Long ... + + // + double GetLOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lOpenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLOpen( + 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, + lOpenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lHighBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLHigh( + 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, + lHighBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lLowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLLow( + 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, + lLowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lCloseBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyLClose( + 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, + lCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // Get XOHCL ... + bool LAsOHCL( + XOHCL &bar, // Holds Result + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + double open = GetLOpen(barIndex); + double high = GetLHigh(barIndex); + double close = GetLClose(barIndex); + double low = GetLLow(barIndex); + + // + result = bar.Init( + mSymbol, + mPeriod, + open, + high, + close, + low, + barIndex + // + ); + + // + return result; + } + + // + // Copy Required Items ... + int CopyLAsOHCL( + int start, // Start + int count, // Number of Items for read + XOHCL &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + int result = 0; + + // + // Update Calculations ... + Calculate(); + + // + if (forceClean) + { + Clean(buffer); + } + + // + int before = ArraySize(buffer); + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(lOpenBuffer)) + { + start = ArraySize(lOpenBuffer) - 1; + } + + // + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); + + // + for (int i = start; i < start + count; i++) + { + // + XOHCL iBar; + bool isInit = LAsOHCL(iBar, i); + + // + if (isInit) + { + // + AddRef( + iBar, + buffer + // + ); + } + } + + // + ArraySetAsSeries(buffer, asSeriesBuffer); + + // + int after = ArraySize(buffer); + + // + result = after - before; + + // + return result; + } + + // + // Hind ... + + // + double GetHOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hOpenBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHOpen( + 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, + hOpenBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hHighBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHHigh( + 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, + hHighBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hLowBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHLow( + 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, + hLowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetHClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hCloseBuffer[barIndex]; + } + + // + // Copy Required Items ... + int CopyHClose( + 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, + hCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // Get XOHCL ... + bool HAsOHCL( + XOHCL &bar, // Holds Result + int barIndex // Bar Index + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + double open = GetHOpen(barIndex); + double high = GetHHigh(barIndex); + double close = GetHClose(barIndex); + double low = GetHLow(barIndex); + + // + result = bar.Init( + mSymbol, + mPeriod, + open, + high, + close, + low, + barIndex + // + ); + + // + return result; + } + + // + // Copy Required Items ... + int CopyHAsOHCL( + int start, // Start + int count, // Number of Items for read + XOHCL &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + int result = 0; + + // + // Update Calculations ... + Calculate(); + + // + if (forceClean) + { + Clean(buffer); + } + + // + int before = ArraySize(buffer); + + // + if (start < 0) + { + start = 0; + } + + // + if (start >= ArraySize(hOpenBuffer)) + { + start = ArraySize(hOpenBuffer) - 1; + } + + // + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); + + // + for (int i = start; i < start + count; i++) + { + // + XOHCL iBar; + bool isInit = HAsOHCL(iBar, i); + + // + if (isInit) + { + // + AddRef( + iBar, + buffer + // + ); + } + } + + // + ArraySetAsSeries(buffer, asSeriesBuffer); + + // + int after = ArraySize(buffer); + + // + result = after - before; + + // + return result; + } + + // + // Conditions ... + + // + bool GetConditions( + XCHHKConditions &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 ... + CopyCAsOHCL( + zIndex, + loopback, + conditions.cBars // + ); + + // + // Short ... + CopySAsOHCL( + zIndex, + loopback, + conditions.sBars // + ); + + // + // Medium ... + CopyMAsOHCL( + zIndex, + loopback, + conditions.mBars // + ); + + // + // Long ... + CopyLAsOHCL( + zIndex, + loopback, + conditions.lBars // + ); + + // + // Hind ... + CopyHAsOHCL( + zIndex, + loopback, + conditions.hBars // + ); + + // + // 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; + } + + // + // Current ... + + // + bool isCBullish = conditions.cBars[cIndex].IsBullish(); + bool isCBullishPrev = conditions.cBars[pIndex].IsBullish(); + + // + bool isCBearish = conditions.cBars[cIndex].IsBearish(); + bool isCBearishPrev = conditions.cBars[pIndex].IsBearish(); + + // + bool isCSwitchedToBullish = isCBullish && + !isCBullishPrev; + bool isCSwitchedToBearish = isCBearish && + !isCBearishPrev; + + // + bool isCloseOverCHigh = cBar.close > conditions.cBars[cIndex].high; + bool isCloseUnderCLow = cBar.close < conditions.cBars[cIndex].low; + + // + conditions.isCBullish = isCBullish; + conditions.isCSwitchedToBullish = isCSwitchedToBullish; + conditions.isCBearish = isCBearish; + conditions.isCSwitchedToBearish = isCSwitchedToBearish; + + // + conditions.isCloseOverCHigh = isCloseOverCHigh; + conditions.isCloseUnderCLow = isCloseUnderCLow; + + // + // Short ... + + // + bool isSBullish = conditions.sBars[cIndex].IsBullish(); + bool isSBullishPrev = conditions.sBars[pIndex].IsBullish(); + + // + bool isSBearish = conditions.sBars[cIndex].IsBearish(); + bool isSBearishPrev = conditions.sBars[pIndex].IsBearish(); + + // + bool isSSwitchedToBullish = isSBullish && + !isSBullishPrev; + bool isSSwitchedToBearish = isSBearish && + !isSBearishPrev; + + // + bool isCloseOverSHigh = cBar.close > conditions.sBars[cIndex].high; + bool isCloseUnderSLow = cBar.close < conditions.sBars[cIndex].low; + + // + conditions.isSBullish = isSBullish; + conditions.isSSwitchedToBullish = isSSwitchedToBullish; + conditions.isSBearish = isSBearish; + conditions.isSSwitchedToBearish = isSSwitchedToBearish; + + // + conditions.isCloseOverSHigh = isCloseOverSHigh; + conditions.isCloseUnderSLow = isCloseUnderSLow; + + // + // Medium ... + + // + bool isMBullish = conditions.mBars[cIndex].IsBullish(); + bool isMBullishPrev = conditions.mBars[pIndex].IsBullish(); + + // + bool isMBearish = conditions.mBars[cIndex].IsBearish(); + bool isMBearishPrev = conditions.mBars[pIndex].IsBearish(); + + // + bool isMSwitchedToBullish = isMBullish && + !isMBullishPrev; + bool isMSwitchedToBearish = isMBearish && + !isMBearishPrev; + + // + bool isCloseOverMHigh = cBar.close > conditions.mBars[cIndex].high; + bool isCloseUnderMLow = cBar.close < conditions.mBars[cIndex].low; + + // + conditions.isMBullish = isMBullish; + conditions.isMSwitchedToBullish = isMSwitchedToBullish; + conditions.isMBearish = isMBearish; + conditions.isMSwitchedToBearish = isMSwitchedToBearish; + + // + conditions.isCloseOverMHigh = isCloseOverMHigh; + conditions.isCloseUnderMLow = isCloseUnderMLow; + + // + // Long ... + + // + bool isLBullish = conditions.lBars[cIndex].IsBullish(); + bool isLBullishPrev = conditions.lBars[pIndex].IsBullish(); + + // + bool isLBearish = conditions.lBars[cIndex].IsBearish(); + bool isLBearishPrev = conditions.lBars[pIndex].IsBearish(); + + // + bool isLSwitchedToBullish = isLBullish && + !isLBullishPrev; + bool isLSwitchedToBearish = isLBearish && + !isLBearishPrev; + + // + bool isCloseOverLHigh = cBar.close > conditions.lBars[cIndex].high; + bool isCloseUnderLLow = cBar.close < conditions.lBars[cIndex].low; + + // + conditions.isLBullish = isLBullish; + conditions.isLSwitchedToBullish = isLSwitchedToBullish; + conditions.isLBearish = isLBearish; + conditions.isLSwitchedToBearish = isLSwitchedToBearish; + + // + conditions.isCloseOverLHigh = isCloseOverLHigh; + conditions.isCloseUnderLLow = isCloseUnderLLow; + + // + // Hind ... + + // + bool isHBullish = conditions.hBars[cIndex].IsBullish(); + bool isHBullishPrev = conditions.hBars[pIndex].IsBullish(); + + // + bool isHBearish = conditions.hBars[cIndex].IsBearish(); + bool isHBearishPrev = conditions.hBars[pIndex].IsBearish(); + + // + bool isHSwitchedToBullish = isHBullish && + !isHBullishPrev; + bool isHSwitchedToBearish = isHBearish && + !isHBearishPrev; + + // + bool isCloseOverHHigh = cBar.close > conditions.hBars[cIndex].high; + bool isCloseUnderHLow = cBar.close < conditions.hBars[cIndex].low; + + // + conditions.isHBullish = isHBullish; + conditions.isHSwitchedToBullish = isHSwitchedToBullish; + conditions.isHBearish = isHBearish; + conditions.isHSwitchedToBearish = isHSwitchedToBearish; + + // + conditions.isCloseOverHHigh = isCloseOverHHigh; + conditions.isCloseUnderHLow = isCloseUnderHLow; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XCHHKInputs mInputs; // Inputs ... + + // + // Buffers ... + + // + // Current ... + double cOpenBuffer[]; + double cHighBuffer[]; + double cLowBuffer[]; + double cCloseBuffer[]; + + // + // Short ... + double sOpenBuffer[]; + double sHighBuffer[]; + double sLowBuffer[]; + double sCloseBuffer[]; + + // + // Medium ... + double mOpenBuffer[]; + double mHighBuffer[]; + double mLowBuffer[]; + double mCloseBuffer[]; + + // + // Long ... + double lOpenBuffer[]; + double lHighBuffer[]; + double lLowBuffer[]; + double lCloseBuffer[]; + + // + // Hind ... + double hOpenBuffer[]; + double hHighBuffer[]; + double hLowBuffer[]; + double hCloseBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Current ... + + // + // Open ... + CopyBuffer( + mHandler, + XCHHK_CO_LINE, + 0, + totalBars, + cOpenBuffer + // + ); + + // + // High ... + CopyBuffer( + mHandler, + XCHHK_CH_LINE, + 0, + totalBars, + cHighBuffer + // + ); + + // + // Low ... + CopyBuffer( + mHandler, + XCHHK_CL_LINE, + 0, + totalBars, + cLowBuffer + // + ); + + // + // Close ... + CopyBuffer( + mHandler, + XCHHK_CC_LINE, + 0, + totalBars, + cCloseBuffer + // + ); + + // + // Short ... + + // + // Open ... + CopyBuffer( + mHandler, + XCHHK_SO_LINE, + 0, + totalBars, + sOpenBuffer + // + ); + + // + // High ... + CopyBuffer( + mHandler, + XCHHK_SH_LINE, + 0, + totalBars, + sHighBuffer + // + ); + + // + // Low ... + CopyBuffer( + mHandler, + XCHHK_SL_LINE, + 0, + totalBars, + sLowBuffer + // + ); + + // + // Close ... + CopyBuffer( + mHandler, + XCHHK_SC_LINE, + 0, + totalBars, + sCloseBuffer + // + ); + + // + // Medium ... + + // + // Open ... + CopyBuffer( + mHandler, + XCHHK_MO_LINE, + 0, + totalBars, + mOpenBuffer + // + ); + + // + // High ... + CopyBuffer( + mHandler, + XCHHK_MH_LINE, + 0, + totalBars, + mHighBuffer + // + ); + + // + // Low ... + CopyBuffer( + mHandler, + XCHHK_ML_LINE, + 0, + totalBars, + mLowBuffer + // + ); + + // + // Close ... + CopyBuffer( + mHandler, + XCHHK_MC_LINE, + 0, + totalBars, + mCloseBuffer + // + ); + + // + // Long ... + + // + // Open ... + CopyBuffer( + mHandler, + XCHHK_LO_LINE, + 0, + totalBars, + lOpenBuffer + // + ); + + // + // High ... + CopyBuffer( + mHandler, + XCHHK_LH_LINE, + 0, + totalBars, + lHighBuffer + // + ); + + // + // Low ... + CopyBuffer( + mHandler, + XCHHK_LL_LINE, + 0, + totalBars, + lLowBuffer + // + ); + + // + // Close ... + CopyBuffer( + mHandler, + XCHHK_LC_LINE, + 0, + totalBars, + lCloseBuffer + // + ); + + // + // Hind ... + + // + // Open ... + CopyBuffer( + mHandler, + XCHHK_HO_LINE, + 0, + totalBars, + hOpenBuffer + // + ); + + // + // High ... + CopyBuffer( + mHandler, + XCHHK_HH_LINE, + 0, + totalBars, + hHighBuffer + // + ); + + // + // Low ... + CopyBuffer( + mHandler, + XCHHK_HL_LINE, + 0, + totalBars, + hLowBuffer + // + ); + + // + // Close ... + CopyBuffer( + mHandler, + XCHHK_HC_LINE, + 0, + totalBars, + hCloseBuffer + // + ); + }; +}; + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xchm.mq5 b/Indicators/x-saherelm.xchm.mq5 new file mode 100644 index 00000000..5ca10784 --- /dev/null +++ b/Indicators/x-saherelm.xchm.mq5 @@ -0,0 +1,1086 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHM +// Description: XCHMrend Detector ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHM Indicator" +#property strict + +// +#define ShortName "XCHM" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int fastLength = 9; // Fast Length +input int slowLength = 18; // Slow Length +input ENUM_MA_METHOD method = MODE_SMA; // Mode +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +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"; + +// +// AVG ... +input bool showFast = true; // Show Fast +input bool showSlow = true; // Show Slow + +// +// Current ... +input bool showCCFast = true; // Show Current Cycle Fast +input bool showCCSlow = true; // Show Current Cycle Slow +// +// Short ... +input bool showSCFast = true; // Show Short Cycle Fast +input bool showSCSlow = true; // Show Short Cycle Slow +// +// Medium ... +input bool showMCFast = true; // Show Medium Cycle Fast +input bool showMCSlow = true; // Show Medium Cycle Slow +// +// Long ... +input bool showLCFast = true; // Show Long Cycle Fast +input bool showLCSlow = true; // Show Long Cycle Slow +// +// Hind ... +input bool showHCFast = true; // Show Hind Cycle Fast +input bool showHCSlow = true; // Show Hind Cycle Slow + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 12 +#property indicator_plots 12 + +// +// AVG ... + +// +// Fast ... +#define avgFastBufferIndex 0 +double avgFastBuffer[]; + +// +#property indicator_label1 "XCHM AF" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrGreen +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// Slow ... +#define avgSlowBufferIndex 1 +double avgSlowBuffer[]; + +// +#property indicator_label2 "XCHM AS" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// Current ... + +// +// Fast ... +#define cFastBufferIndex 2 +double cFastBuffer[]; + +// +#property indicator_label3 "XCHM CF" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +// Slow ... +#define cSlowBufferIndex 3 +double cSlowBuffer[]; + +// +#property indicator_label4 "XCHM CS" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// Short ... + +// +// Fast ... +#define sFastBufferIndex 4 +double sFastBuffer[]; + +// +#property indicator_label5 "XCHM SF" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAqua +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// Slow ... +#define sSlowBufferIndex 5 +double sSlowBuffer[]; + +// +#property indicator_label6 "XCHM SS" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrMagenta +#property indicator_style6 STYLE_DOT +#property indicator_width6 1 + +// +// Medium ... + +// +// Fast ... +#define mFastBufferIndex 6 +double mFastBuffer[]; + +// +#property indicator_label7 "XCHM MF" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrAqua +#property indicator_style7 STYLE_DOT +#property indicator_width7 1 + +// +// Slow ... +#define mSlowBufferIndex 7 +double mSlowBuffer[]; + +// +#property indicator_label8 "XCHM MS" +#property indicator_type8 DRAW_LINE +#property indicator_color8 clrMagenta +#property indicator_style8 STYLE_DOT +#property indicator_width8 1 + +// +// Long ... + +// +// Fast ... +#define lFastBufferIndex 8 +double lFastBuffer[]; + +// +#property indicator_label9 "XCHM LF" +#property indicator_type9 DRAW_LINE +#property indicator_color9 clrAqua +#property indicator_style9 STYLE_DOT +#property indicator_width9 1 + +// +// Slow ... +#define lSlowBufferIndex 9 +double lSlowBuffer[]; + +// +#property indicator_label10 "XCHM LS" +#property indicator_type10 DRAW_LINE +#property indicator_color10 clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +// +// Hind ... + +// +// Fast ... +#define hFastBufferIndex 10 +double hFastBuffer[]; + +// +#property indicator_label11 "XCHM HF" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrAqua +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +// Slow ... +#define hSlowBufferIndex 11 +double hSlowBuffer[]; + +// +#property indicator_label12 "XCHM HS" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// Variables ... + +// +int maxLength; + +// +// Current ... +int cFastHandler = INVALID_HANDLE; +int cSlowHandler = INVALID_HANDLE; + +// +// Short ... +int mSCLength = 0; +int mSCFastLength = 0; +int mSCSlowLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; +int sFastHandler = INVALID_HANDLE; +int sSlowHandler = INVALID_HANDLE; + +// +// Medium ... +int mMCLength = 0; +int mMCFastLength = 0; +int mMCSlowLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; +int mFastHandler = INVALID_HANDLE; +int mSlowHandler = INVALID_HANDLE; + +// +// Long ... +int mLCLength = 0; +int mLCFastLength = 0; +int mLCSlowLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; +int lFastHandler = INVALID_HANDLE; +int lSlowHandler = INVALID_HANDLE; + +// +// Hind ... +int mHCLength = 0; +int mHCFastLength = 0; +int mHCSlowLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; +int hFastHandler = INVALID_HANDLE; +int hSlowHandler = INVALID_HANDLE; + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Current ... + IndicatorRelease(cFastHandler); + IndicatorRelease(cSlowHandler); + + // + // Short ... + IndicatorRelease(sFastHandler); + IndicatorRelease(sSlowHandler); + + // + // Medium ... + IndicatorRelease(mFastHandler); + IndicatorRelease(mSlowHandler); + + // + // Long ... + IndicatorRelease(lFastHandler); + IndicatorRelease(lSlowHandler); + + // + // Hind ... + IndicatorRelease(hFastHandler); + IndicatorRelease(hSlowHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + + // + // this counts Available Bars ... + int limit; + + // + // Validate Calculated Bars ... + bool isPassedRequiredCalculatedBars = + // + // Current ... + BarsCalculated(cFastHandler) >= maxLength && + BarsCalculated(cSlowHandler) >= maxLength && + // + // Short ... + BarsCalculated(sFastHandler) >= maxLength && + BarsCalculated(sSlowHandler) >= maxLength && + // + // Medium ... + BarsCalculated(mFastHandler) >= maxLength && + BarsCalculated(mSlowHandler) >= maxLength && + // + // Long ... + BarsCalculated(lFastHandler) >= maxLength && + BarsCalculated(lSlowHandler) >= maxLength && + // + // Hind ... + BarsCalculated(hFastHandler) >= maxLength && + BarsCalculated(hSlowHandler) >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // Current ... + int copiedCFasts = CopyBuffer(cFastHandler, 0, 0, limit, cFastBuffer); + int copiedCSlows = CopyBuffer(cSlowHandler, 0, 0, limit, cSlowBuffer); + + // + // Short ... + int copiedSFasts = CopyBuffer(sFastHandler, 0, 0, limit, sFastBuffer); + int copiedSSlows = CopyBuffer(sSlowHandler, 0, 0, limit, sSlowBuffer); + + // + // Medium ... + int copiedMFasts = CopyBuffer(mFastHandler, 0, 0, limit, mFastBuffer); + int copiedMSlows = CopyBuffer(mSlowHandler, 0, 0, limit, mSlowBuffer); + + // + // Long ... + int copiedLFasts = CopyBuffer(lFastHandler, 0, 0, limit, lFastBuffer); + int copiedLSlows = CopyBuffer(lSlowHandler, 0, 0, limit, lSlowBuffer); + + // + // Hind ... + int copiedHFasts = CopyBuffer(hFastHandler, 0, 0, limit, hFastBuffer); + int copiedHSlows = CopyBuffer(hSlowHandler, 0, 0, limit, hSlowBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // + // Current ... + copiedCFasts > 0 && + copiedCSlows > 0 && + // + // Short ... + copiedSFasts > 0 && + copiedSSlows > 0 && + // + // Medium ... + copiedMFasts > 0 && + copiedMSlows > 0 && + // + // Long ... + copiedLFasts > 0 && + copiedLSlows > 0 && + // + // Hind ... + copiedHFasts > 0 && + copiedHSlows > 0 + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + fastLength > 2 && + slowLength > fastLength && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + // Current ... + result = MathMax(fastLength, slowLength); + + // + // Short ... + result = MathMax(result, mSCFastLength); + result = MathMax(result, mSCSlowLength); + + // + // Medium ... + result = MathMax(result, mMCFastLength); + result = MathMax(result, mMCSlowLength); + + // + // Long ... + result = MathMax(result, mLCFastLength); + result = MathMax(result, mLCSlowLength); + + // + // Hind ... + result = MathMax(result, mHCFastLength); + result = MathMax(result, mHCSlowLength); + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // AVG ... + + // + // Fast ... + ENUM_DRAW_TYPE avgFastDrawType = showFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(avgFastBuffer, true); + SetIndexBuffer(avgFastBufferIndex, avgFastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(avgFastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(avgFastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(avgFastBufferIndex, PLOT_SHOW_DATA, showFast); + PlotIndexSetInteger(avgFastBufferIndex, PLOT_DRAW_TYPE, avgFastDrawType); + + // + // Slow ... + ENUM_DRAW_TYPE avgSlowDrawType = showSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(avgSlowBuffer, true); + SetIndexBuffer(avgSlowBufferIndex, avgSlowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(avgSlowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(avgSlowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(avgSlowBufferIndex, PLOT_SHOW_DATA, showSlow); + PlotIndexSetInteger(avgSlowBufferIndex, PLOT_DRAW_TYPE, avgSlowDrawType); + + // + // Current ... + + // + // Fast ... + ENUM_DRAW_TYPE cFastDrawType = showCCFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(cFastBuffer, true); + SetIndexBuffer(cFastBufferIndex, cFastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(cFastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(cFastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(cFastBufferIndex, PLOT_SHOW_DATA, showCCFast); + PlotIndexSetInteger(cFastBufferIndex, PLOT_DRAW_TYPE, cFastDrawType); + + // + // Slow ... + ENUM_DRAW_TYPE cSlowDrawType = showCCSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(cSlowBuffer, true); + SetIndexBuffer(cSlowBufferIndex, cSlowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(cSlowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(cSlowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(cSlowBufferIndex, PLOT_SHOW_DATA, showCCSlow); + PlotIndexSetInteger(cSlowBufferIndex, PLOT_DRAW_TYPE, cSlowDrawType); + + // + // Short ... + + // + // Fast ... + ENUM_DRAW_TYPE sFastDrawType = showSCFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(sFastBuffer, true); + SetIndexBuffer(sFastBufferIndex, sFastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(sFastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(sFastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sFastBufferIndex, PLOT_SHOW_DATA, showSCFast); + PlotIndexSetInteger(sFastBufferIndex, PLOT_DRAW_TYPE, sFastDrawType); + + // + // Slow ... + ENUM_DRAW_TYPE sSlowDrawType = showSCSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(sSlowBuffer, true); + SetIndexBuffer(sSlowBufferIndex, sSlowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(sSlowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(sSlowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sSlowBufferIndex, PLOT_SHOW_DATA, showSCSlow); + PlotIndexSetInteger(sSlowBufferIndex, PLOT_DRAW_TYPE, sSlowDrawType); + + // + // Medium ... + + // + // Fast ... + ENUM_DRAW_TYPE mFastDrawType = showMCFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(mFastBuffer, true); + SetIndexBuffer(mFastBufferIndex, mFastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(mFastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(mFastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mFastBufferIndex, PLOT_SHOW_DATA, showMCFast); + PlotIndexSetInteger(mFastBufferIndex, PLOT_DRAW_TYPE, mFastDrawType); + + // + // Slow ... + ENUM_DRAW_TYPE mSlowDrawType = showMCSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(mSlowBuffer, true); + SetIndexBuffer(mSlowBufferIndex, mSlowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(mSlowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(mSlowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mSlowBufferIndex, PLOT_SHOW_DATA, showMCSlow); + PlotIndexSetInteger(mSlowBufferIndex, PLOT_DRAW_TYPE, mSlowDrawType); + + // + // Long ... + + // + // Fast ... + ENUM_DRAW_TYPE lFastDrawType = showLCFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(lFastBuffer, true); + SetIndexBuffer(lFastBufferIndex, lFastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(lFastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(lFastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lFastBufferIndex, PLOT_SHOW_DATA, showLCFast); + PlotIndexSetInteger(lFastBufferIndex, PLOT_DRAW_TYPE, lFastDrawType); + + // + // Slow ... + ENUM_DRAW_TYPE lSlowDrawType = showLCSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(lSlowBuffer, true); + SetIndexBuffer(lSlowBufferIndex, lSlowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(lSlowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(lSlowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lSlowBufferIndex, PLOT_SHOW_DATA, showLCSlow); + PlotIndexSetInteger(lSlowBufferIndex, PLOT_DRAW_TYPE, lSlowDrawType); + + // + // Hind ... + + // + // Fast ... + ENUM_DRAW_TYPE hFastDrawType = showHCFast ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(hFastBuffer, true); + SetIndexBuffer(hFastBufferIndex, hFastBuffer, INDICATOR_DATA); + PlotIndexSetDouble(hFastBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(hFastBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hFastBufferIndex, PLOT_SHOW_DATA, showHCFast); + PlotIndexSetInteger(hFastBufferIndex, PLOT_DRAW_TYPE, hFastDrawType); + + // + // Slow ... + ENUM_DRAW_TYPE hSlowDrawType = showHCSlow ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(hSlowBuffer, true); + SetIndexBuffer(hSlowBufferIndex, hSlowBuffer, INDICATOR_DATA); + PlotIndexSetDouble(hSlowBufferIndex, PLOT_EMPTY_VALUE, 0); + PlotIndexSetInteger(hSlowBufferIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hSlowBufferIndex, PLOT_SHOW_DATA, showHCSlow); + PlotIndexSetInteger(hSlowBufferIndex, PLOT_DRAW_TYPE, hSlowDrawType); +} + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Current Cycle Initialization ... + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Initialize Handlers ... + cFastHandler = iMA( + _Symbol, + _Period, + fastLength, + 0, + method, + appliedTo // + ); + cSlowHandler = iMA( + _Symbol, + _Period, + slowLength, + 0, + method, + appliedTo // + ); + result = + // + cFastHandler != INVALID_HANDLE && + cSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + mSCFastLength = fastLength * mSCLength; + mSCSlowLength = slowLength * mSCLength; + + // + result = mSCLength > 0; + if (!result) + { + return result; + } + + // + // Initialize Handlers ... + sFastHandler = iMA( + _Symbol, + _Period, + mSCFastLength, + 0, + method, + appliedTo // + ); + sSlowHandler = iMA( + _Symbol, + _Period, + mSCSlowLength, + 0, + method, + appliedTo // + ); + result = + // + sFastHandler != INVALID_HANDLE && + sSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + mMCFastLength = fastLength * mMCLength; + mMCSlowLength = slowLength * mMCLength; + + // + result = mMCLength > 0; + if (!result) + { + return result; + } + + // + // Initialize Handlers ... + mFastHandler = iMA( + _Symbol, + _Period, + mMCFastLength, + 0, + method, + appliedTo // + ); + mSlowHandler = iMA( + _Symbol, + _Period, + mMCSlowLength, + 0, + method, + appliedTo // + ); + result = + // + mFastHandler != INVALID_HANDLE && + mSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + mLCFastLength = fastLength * mLCLength; + mLCSlowLength = slowLength * mLCLength; + + // + result = mLCLength > 0; + if (!result) + { + return result; + } + + // + // Initialize Handlers ... + lFastHandler = iMA( + _Symbol, + _Period, + mLCFastLength, + 0, + method, + appliedTo // + ); + lSlowHandler = iMA( + _Symbol, + _Period, + mLCSlowLength, + 0, + method, + appliedTo // + ); + result = + // + lFastHandler != INVALID_HANDLE && + lSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + mHCFastLength = fastLength * mHCLength; + mHCSlowLength = slowLength * mHCLength; + + // + result = mHCLength > 0; + if (!result) + { + return result; + } + + // + // Initialize Handlers ... + hFastHandler = iMA( + _Symbol, + _Period, + mHCFastLength, + 0, + method, + appliedTo // + ); + hSlowHandler = iMA( + _Symbol, + _Period, + mHCSlowLength, + 0, + method, + appliedTo // + ); + result = + // + hFastHandler != INVALID_HANDLE && + hSlowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Do all Custom Calculations ... +void CalculateBuffers(int barIndex) +{ + // + double cFast = cFastBuffer[barIndex]; + double sFast = sFastBuffer[barIndex]; + double mFast = mFastBuffer[barIndex]; + double lFast = lFastBuffer[barIndex]; + double hFast = hFastBuffer[barIndex]; + + // + double fast = + cFast + + sFast + + mFast + + lFast + + hFast; + avgFastBuffer[barIndex] = fast / 5; + + // + double cSlow = cSlowBuffer[barIndex]; + double sSlow = sSlowBuffer[barIndex]; + double mSlow = mSlowBuffer[barIndex]; + double lSlow = lSlowBuffer[barIndex]; + double hSlow = hSlowBuffer[barIndex]; + + // + double slow = + cSlow + + sSlow + + mSlow + + lSlow + + hSlow; + avgSlowBuffer[barIndex] = slow / 5; +} + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xchstr.mq5 b/Indicators/x-saherelm.xchstr.mq5 new file mode 100644 index 00000000..b67b000c --- /dev/null +++ b/Indicators/x-saherelm.xchstr.mq5 @@ -0,0 +1,1246 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHSTR +// Description: Smoothed HikenAshi 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 XCHSTR Indicator" +#property strict + +// +#define ShortName "XCHSTR" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; + +// +input int atrLength = 14; // Length +input double atrMultiplier = 3.0; // Multiplier +input ENUM_APPLIED_PRICE atrAppliedTo = PRICE_MEDIAN; // Applied To + +// +input group "Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +// Presentation ... +input group "Presentation"; + +// +input 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_chart_window + +// +#property indicator_buffers 35 +#property indicator_plots 10 + +// +// Current ... + +// +#define cBufferIndex 0 +#define cPlotBufferIndex 0 +double cBuffer[]; + +// +#define cColorBufferIndex 1 +double cColorBuffer[]; + +// +#property indicator_label1 "C XSTR" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style1 STYLE_DOT + +// +// Short ... + +// +#define sBufferIndex 2 +#define sPlotBufferIndex 1 +double sBuffer[]; + +// +#define sColorBufferIndex 3 +double sColorBuffer[]; + +// +#property indicator_label2 "S XSTR" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style2 STYLE_DOT + +// +// Medium ... + +// +#define mBufferIndex 4 +#define mPlotBufferIndex 2 +double mBuffer[]; + +// +#define mColorBufferIndex 5 +double mColorBuffer[]; + +// +#property indicator_label3 "M XSTR" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style3 STYLE_DOT + +// +// Long ... + +// +#define lBufferIndex 6 +#define lPlotBufferIndex 3 +double lBuffer[]; + +// +#define lColorBufferIndex 7 +double lColorBuffer[]; + +// +#property indicator_label4 "L XSTR" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style4 STYLE_DOT + +// +// Hind ... + +// +#define hBufferIndex 8 +#define hPlotBufferIndex 4 +double hBuffer[]; + +// +#define hColorBufferIndex 9 +double hColorBuffer[]; + +// +#property indicator_label5 "H XSTR" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style5 STYLE_DOT + +// +// Data Buffers ... + +// +// Current ... + +// +#define cAtrBufferIndex 10 +double cAtrBuffer[]; + +// +#define cTrendBufferIndex 11 +double cTrendBuffer[]; + +// +#define cUpBufferIndex 12 +double cUpBuffer[]; + +// +#define cDownBufferIndex 13 +double cDownBuffer[]; + +// +#define cPriceBufferIndex 14 +double cPriceBuffer[]; + +// +// Short ... + +// +#define sAtrBufferIndex 15 +double sAtrBuffer[]; + +// +#define sTrendBufferIndex 16 +double sTrendBuffer[]; + +// +#define sUpBufferIndex 17 +double sUpBuffer[]; + +// +#define sDownBufferIndex 18 +double sDownBuffer[]; + +// +#define sPriceBufferIndex 19 +double sPriceBuffer[]; + +// +// Medium ... + +// +#define mAtrBufferIndex 20 +double mAtrBuffer[]; + +// +#define mTrendBufferIndex 21 +double mTrendBuffer[]; + +// +#define mUpBufferIndex 22 +double mUpBuffer[]; + +// +#define mDownBufferIndex 23 +double mDownBuffer[]; + +// +#define mPriceBufferIndex 24 +double mPriceBuffer[]; + +// +// Long ... + +// +#define lAtrBufferIndex 25 +double lAtrBuffer[]; + +// +#define lTrendBufferIndex 26 +double lTrendBuffer[]; + +// +#define lUpBufferIndex 27 +double lUpBuffer[]; + +// +#define lDownBufferIndex 28 +double lDownBuffer[]; + +// +#define lPriceBufferIndex 29 +double lPriceBuffer[]; + +// +// Hind ... + +// +#define hAtrBufferIndex 30 +double hAtrBuffer[]; + +// +#define hTrendBufferIndex 31 +double hTrendBuffer[]; + +// +#define hUpBufferIndex 32 +double hUpBuffer[]; + +// +#define hDownBufferIndex 33 +double hDownBuffer[]; + +// +#define hPriceBufferIndex 34 +double hPriceBuffer[]; + +// +// Variables, Properties and etc ... + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +int maxLength; + +// +// Current ... +int mCSMLength = atrLength; +int mCAtrHandler = INVALID_HANDLE; + +// +// Short ... +int mSCLength = 0; +int mSSMLength = 0; +int mSAtrHandler = INVALID_HANDLE; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// Medium ... +int mMCLength = 0; +int mMSMLength = 0; +int mMAtrHandler = INVALID_HANDLE; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// Long ... +int mLCLength = 0; +int mLSMLength = 0; +int mLAtrHandler = INVALID_HANDLE; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// Hind ... +int mHCLength = 0; +int mHSMLength = 0; +int mHAtrHandler = INVALID_HANDLE; +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 ... +) +{ + // + int numOfRequiredAtrs; + if (prev_calculated > rates_total || prev_calculated < 0) + { + numOfRequiredAtrs = rates_total; + } + else + { + // + numOfRequiredAtrs = rates_total - prev_calculated; + if (prev_calculated > 0) + { + numOfRequiredAtrs++; + } + } + + // + // Checking for stop ... + if (IsStopped()) + { + return 0; + } + + // + // Check Number of items Copy or not ... + int copiedCATRs = CopyBuffer(mCAtrHandler, 0, 0, numOfRequiredAtrs, cAtrBuffer); + int copiedSATRs = CopyBuffer(mSAtrHandler, 0, 0, numOfRequiredAtrs, sAtrBuffer); + int copiedMATRs = CopyBuffer(mMAtrHandler, 0, 0, numOfRequiredAtrs, mAtrBuffer); + int copiedLATRs = CopyBuffer(mLAtrHandler, 0, 0, numOfRequiredAtrs, lAtrBuffer); + int copiedHATRs = CopyBuffer(mHAtrHandler, 0, 0, numOfRequiredAtrs, hAtrBuffer); + if (copiedCATRs <= 0 || + copiedSATRs <= 0 || + copiedMATRs <= 0 || + copiedLATRs <= 0 || + copiedHATRs <= 0) + { + return 0; + } + + // + int limit; + + // + // checking for the limit start of calculation of an indicator ... + if (prev_calculated > rates_total || prev_calculated <= 0) + { + // + // starting index for calculation of all bars ... + limit = maxLength; + } + else + { + // + // starting number for calculation of new bars + limit = prev_calculated - 1; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + CalculateBuffers( + open, + high, + low, + close, + i // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + atrLength >= 2 && + atrMultiplier > 0 && + // + (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); + + // + mCAtrHandler = iATR( + _Symbol, + _Period, + mCSMLength // + ); + result = mCAtrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + mSSMLength = mSCLength * mCSMLength; + result = mSCLength > 0; + if (!result) + { + return result; + } + + // + mSAtrHandler = iATR( + _Symbol, + _Period, + mSSMLength // + ); + result = mSAtrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + mMSMLength = mMCLength * mCSMLength; + result = mMCLength > 0; + if (!result) + { + return result; + } + + // + mMAtrHandler = iATR( + _Symbol, + _Period, + mMSMLength // + ); + result = mMAtrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + mLSMLength = mLCLength * mCSMLength; + result = mLCLength > 0; + if (!result) + { + return result; + } + + // + mLAtrHandler = iATR( + _Symbol, + _Period, + mLSMLength // + ); + result = mLAtrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + mHSMLength = mHCLength * mCSMLength; + result = mHCLength > 0; + if (!result) + { + return result; + } + + // + mHAtrHandler = iATR( + _Symbol, + _Period, + mHSMLength // + ); + result = mHAtrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mCSMLength, mSSMLength); + result = MathMax(result, mMSMLength); + result = MathMax(result, mLSMLength); + result = MathMax(result, mHSMLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // CURRENT Cycle ... + + // + // STR ... + SetIndexBuffer(cBufferIndex, cBuffer, INDICATOR_DATA); + + // + // Color ... + SetIndexBuffer(cColorBufferIndex, cColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(cPlotBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(cPlotBufferIndex, PLOT_SHOW_DATA, showCurrent); + + // + // Data Buffers ... + + // + // ATR ... + SetIndexBuffer(cAtrBufferIndex, cAtrBuffer, INDICATOR_CALCULATIONS); + + // + // Price ... + SetIndexBuffer(cPriceBufferIndex, cPriceBuffer, INDICATOR_CALCULATIONS); + + // + // Trend ... + SetIndexBuffer(cTrendBufferIndex, cTrendBuffer, INDICATOR_CALCULATIONS); + + // + // Up ... + SetIndexBuffer(cUpBufferIndex, cUpBuffer, INDICATOR_CALCULATIONS); + + // + // Down ... + SetIndexBuffer(cDownBufferIndex, cDownBuffer, INDICATOR_CALCULATIONS); + + // + // SHORT Cycle ... + + // + // STR ... + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + + // + // Color ... + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(sPlotBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(sPlotBufferIndex, PLOT_SHOW_DATA, showShort); + + // + // Data Buffers ... + + // + // ATR ... + SetIndexBuffer(sAtrBufferIndex, sAtrBuffer, INDICATOR_CALCULATIONS); + + // + // Price ... + SetIndexBuffer(sPriceBufferIndex, sPriceBuffer, INDICATOR_CALCULATIONS); + + // + // Trend ... + SetIndexBuffer(sTrendBufferIndex, sTrendBuffer, INDICATOR_CALCULATIONS); + + // + // Up ... + SetIndexBuffer(sUpBufferIndex, sUpBuffer, INDICATOR_CALCULATIONS); + + // + // Down ... + SetIndexBuffer(sDownBufferIndex, sDownBuffer, INDICATOR_CALCULATIONS); + + // + // MEDIUM Cycle ... + + // + // STR ... + SetIndexBuffer(mBufferIndex, mBuffer, INDICATOR_DATA); + + // + // Color ... + SetIndexBuffer(mColorBufferIndex, mColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(mPlotBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(mPlotBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + // Data Buffers ... + + // + // ATR ... + SetIndexBuffer(mAtrBufferIndex, mAtrBuffer, INDICATOR_CALCULATIONS); + + // + // Price ... + SetIndexBuffer(mPriceBufferIndex, mPriceBuffer, INDICATOR_CALCULATIONS); + + // + // Trend ... + SetIndexBuffer(mTrendBufferIndex, mTrendBuffer, INDICATOR_CALCULATIONS); + + // + // Up ... + SetIndexBuffer(mUpBufferIndex, mUpBuffer, INDICATOR_CALCULATIONS); + + // + // Down ... + SetIndexBuffer(mDownBufferIndex, mDownBuffer, INDICATOR_CALCULATIONS); + + // + // LONG Cycle ... + + // + // STR ... + SetIndexBuffer(lBufferIndex, lBuffer, INDICATOR_DATA); + + // + // Color ... + SetIndexBuffer(lColorBufferIndex, lColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(lPlotBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(lPlotBufferIndex, PLOT_SHOW_DATA, showLong); + + // + // Data Buffers ... + + // + // ATR ... + SetIndexBuffer(lAtrBufferIndex, lAtrBuffer, INDICATOR_CALCULATIONS); + + // + // Price ... + SetIndexBuffer(lPriceBufferIndex, lPriceBuffer, INDICATOR_CALCULATIONS); + + // + // Trend ... + SetIndexBuffer(lTrendBufferIndex, lTrendBuffer, INDICATOR_CALCULATIONS); + + // + // Up ... + SetIndexBuffer(lUpBufferIndex, lUpBuffer, INDICATOR_CALCULATIONS); + + // + // Down ... + SetIndexBuffer(lDownBufferIndex, lDownBuffer, INDICATOR_CALCULATIONS); + + // + // HIND Cycle ... + + // + // STR ... + SetIndexBuffer(hBufferIndex, hBuffer, INDICATOR_DATA); + + // + // Color ... + SetIndexBuffer(hColorBufferIndex, hColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(hPlotBufferIndex, PLOT_EMPTY_VALUE, 0.0); + PlotIndexSetInteger(hPlotBufferIndex, PLOT_SHOW_DATA, showHind); + + // + // Data Buffers ... + + // + // ATR ... + SetIndexBuffer(hAtrBufferIndex, hAtrBuffer, INDICATOR_CALCULATIONS); + + // + // Price ... + SetIndexBuffer(hPriceBufferIndex, hPriceBuffer, INDICATOR_CALCULATIONS); + + // + // Trend ... + SetIndexBuffer(hTrendBufferIndex, hTrendBuffer, INDICATOR_CALCULATIONS); + + // + // Up ... + SetIndexBuffer(hUpBufferIndex, hUpBuffer, INDICATOR_CALCULATIONS); + + // + // Down ... + SetIndexBuffer(hDownBufferIndex, hDownBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculations ... + +// +// Calculate Hiken Ashi ... +void CalculateBuffers( + const double &open[], + const double &high[], + const double &low[], + const double &close[], + int barIndex // +) +{ + // + // Current ... + CalculateCycle( + open, + high, + low, + close, + barIndex, + cAtrBuffer, + cPriceBuffer, + cUpBuffer, + cDownBuffer, + cTrendBuffer, + cBuffer, + cColorBuffer, + showCurrent // + ); + + // + // Short ... + CalculateCycle( + open, + high, + low, + close, + barIndex, + sAtrBuffer, + sPriceBuffer, + sUpBuffer, + sDownBuffer, + sTrendBuffer, + sBuffer, + sColorBuffer, + showShort // + ); + + // + // Short ... + CalculateCycle( + open, + high, + low, + close, + barIndex, + mAtrBuffer, + mPriceBuffer, + mUpBuffer, + mDownBuffer, + mTrendBuffer, + mBuffer, + mColorBuffer, + showMedium // + ); + + // + // Short ... + CalculateCycle( + open, + high, + low, + close, + barIndex, + lAtrBuffer, + lPriceBuffer, + lUpBuffer, + lDownBuffer, + lTrendBuffer, + lBuffer, + lColorBuffer, + showLong // + ); + + // + // Hind ... + CalculateCycle( + open, + high, + low, + close, + barIndex, + hAtrBuffer, + hPriceBuffer, + hUpBuffer, + hDownBuffer, + hTrendBuffer, + hBuffer, + hColorBuffer, + showHind // + ); +} + +// +void CalculateCycle( + const double &open[], + const double &high[], + const double &low[], + const double &close[], + int barIndex, + double &atr[], + double &price[], + double &up[], + double &down[], + double &trend[], + double &main[], + double &clr[], // Color Index Buffer + bool show // +) +{ + // + // Calculated Price ... + double _price = getPrice( + atrAppliedTo, + open, + high, + low, + close, + barIndex // + ); + price[barIndex] = _price; + + // + double _atr = atr[barIndex]; + + // + // Up ... + up[barIndex] = _price + (atrMultiplier * _atr); + + // + // Down ... + down[barIndex] = _price - (atrMultiplier * _atr); + + // + if (close[barIndex] > up[barIndex - 1]) + { + // + trend[barIndex] = 1; + if (trend[barIndex - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[barIndex] < down[barIndex - 1]) + { + // + trend[barIndex] = -1; + if (trend[barIndex - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (trend[barIndex - 1] == 1) + { + // + trend[barIndex] = 1; + changeOfTrend = 0; + } + else if (trend[barIndex - 1] == -1) + { + // + trend[barIndex] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (trend[barIndex] < 0 && trend[barIndex - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (trend[barIndex] > 0 && trend[barIndex - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (trend[barIndex] > 0 && down[barIndex] < down[barIndex - 1]) + { + down[barIndex] = down[barIndex - 1]; + } + + // + if (trend[barIndex] < 0 && up[barIndex] > up[barIndex - 1]) + { + up[barIndex] = up[barIndex - 1]; + } + + // + if (startBearishTrend == 1) + { + up[barIndex] = price[barIndex] + (atrMultiplier * _atr); + } + + // + if (startBullishTrend == 1) + { + down[barIndex] = price[barIndex] - (atrMultiplier * _atr); + } + + // + double colorIDX = hideColorIDX; + clr[barIndex] = colorIDX; + + // + if (trend[barIndex] == 1) + { + // + main[barIndex] = down[barIndex]; + if (changeOfTrend == 1) + { + // + main[barIndex - 1] = main[barIndex - 2]; + changeOfTrend = 0; + } + + // + colorIDX = bullishColorIDX; + } + else if (trend[barIndex] == -1) + { + // + main[barIndex] = up[barIndex]; + if (changeOfTrend == 1) + { + // + main[barIndex - 1] = main[barIndex - 2]; + changeOfTrend = 0; + } + + // + colorIDX = bearishColorIDX; + } + + // + if (show) + { + clr[barIndex] = colorIDX; + } + + // +} + +// +// TEMPLATE Function ... + +template +double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} + +// \ No newline at end of file diff --git a/Strategies/x-saherelm.xchkm.strategy.mq5 b/Strategies/x-saherelm.xchkm.strategy.mq5 index 5a877e3b..838c88d4 100644 --- a/Strategies/x-saherelm.xchkm.strategy.mq5 +++ b/Strategies/x-saherelm.xchkm.strategy.mq5 @@ -1395,7 +1395,7 @@ private: strInputs.fillTrends = false; // - strHelper = new XSCXPVHelper(); + strHelper = new XSCXSTRHelper(); strHelper.Init( mSymbol, mPeriod, @@ -1415,7 +1415,7 @@ private: cheInputs.showShortExit2Line = true; // - cheHelper = new XSCXPVHelper(); + cheHelper = new XSCXCHEHelper(); cheHelper.Init( mSymbol, mPeriod,