From 868eecc9161763a8c6754e71cc50262fa8db5032 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 20 Nov 2024 01:50:13 +0330 Subject: [PATCH] add XCHSAR Indicator, Complete it's Helper and Implement usage of this in EA ... --- Helpers/x-saherelm.xchsar.helper.mq5 | 1267 +++++++++++++++++ Indicators/x-saherelm.xchsar.mq5 | 691 +++++++++ X121SMCEA/Libraries/x-121.smc.lib.mq5 | 2 + .../x-121.smc.test.strategy.class.mq5 | 56 +- 4 files changed, 1996 insertions(+), 20 deletions(-) create mode 100644 Helpers/x-saherelm.xchsar.helper.mq5 create mode 100644 Indicators/x-saherelm.xchsar.mq5 diff --git a/Helpers/x-saherelm.xchsar.helper.mq5 b/Helpers/x-saherelm.xchsar.helper.mq5 new file mode 100644 index 00000000..de0a620b --- /dev/null +++ b/Helpers/x-saherelm.xchsar.helper.mq5 @@ -0,0 +1,1267 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCXCHSARHelper +// 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.x-helper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XCHSAR_BUFFERS +{ + // + // Current ... + XCHSAR_C_LINE = 0, + // + // Short ... + XCHSAR_S_LINE = 1, + // + // Medium ... + XCHSAR_M_LINE = 2, + // + // Long ... + XCHSAR_L_LINE = 3, + // + // Hind ... + XCHSAR_H_LINE = 4, +}; + +// +// Input Models ... +struct XCHSARInputs +{ + // + // Props ... + + // + // Market ... + double sarStep; // Step + double sarMax; // Maximum + + // + // 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 ... + + // + int cArrowCode; // Current Cycle Arrow Code + int sArrowCode; // Short Cycle Arrow Code + int mArrowCode; // Medium Cycle Arrow Code + int lArrowCode; // Long Cycle Arrow Code + int hArrowCode; // Hind Cycle Arrow Code + + // + 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) ... + XCHSARInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + sarStep = 0.02; + sarMax = 0.2; + + // + scMethod = X_PERIOD_AUTO; + scPeriod = NULL; + mcMethod = X_PERIOD_AUTO; + mcPeriod = NULL; + lcMethod = X_PERIOD_AUTO; + lcPeriod = NULL; + hcMethod = X_PERIOD_AUTO; + hcPeriod = NULL; + + // + cArrowCode = 255; + sArrowCode = 255; + mArrowCode = 255; + lArrowCode = 255; + hArrowCode = 255; + + // + showCurrent = true; + showShort = true; + showMedium = true; + showLong = true; + showHind = true; + } + + // + // Default ... + void Default() + { + // + sarStep = 0.02; + sarMax = 0.2; + + // + scMethod = X_PERIOD_AUTO; + scPeriod = NULL; + mcMethod = X_PERIOD_AUTO; + mcPeriod = NULL; + lcMethod = X_PERIOD_AUTO; + lcPeriod = NULL; + hcMethod = X_PERIOD_AUTO; + hcPeriod = NULL; + + // + cArrowCode = 255; + sArrowCode = 255; + mArrowCode = 255; + lArrowCode = 255; + hArrowCode = 255; + + // + showCurrent = true; + showShort = true; + showMedium = true; + showLong = true; + showHind = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + sarStep > 0 && + sarMax > sarStep && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + return result; + } +}; + +// +// Define Conditions ... +struct XCHSARConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + double cSars[]; + double sSars[]; + double mSars[]; + double lSars[]; + double hSars[]; + + // + // Conditions ... + + // + // Current ... + + // + bool isCBullish; + bool isCBearish; + + // + bool isCSwitchedBullish; + bool isCSwitchedBearish; + + // + // Short ... + + // + bool isSBullish; + bool isSBearish; + + // + bool isSSwitchedBullish; + bool isSSwitchedBearish; + + // + // Medium ... + + // + bool isMBullish; + bool isMBearish; + + // + bool isMSwitchedBullish; + bool isMSwitchedBearish; + + // + // Long ... + + // + bool isLBullish; + bool isLBearish; + + // + bool isLSwitchedBullish; + bool isLSwitchedBearish; + + // + // Hind ... + + // + bool isHBullish; + bool isHBearish; + + // + bool isHSwitchedBullish; + bool isHSwitchedBearish; + + // + void Clean() + { + // + Clean(cSars); + Clean(sSars); + Clean(mSars); + Clean(lSars); + Clean(hSars); + + // + ArraySetAsSeries(cSars, true); + ArraySetAsSeries(sSars, true); + ArraySetAsSeries(mSars, true); + ArraySetAsSeries(lSars, true); + ArraySetAsSeries(hSars, true); + + // + isCBullish = false; + isCBearish = false; + isCSwitchedBullish = false; + isCSwitchedBearish = false; + isSBullish = false; + isSBearish = false; + isSSwitchedBullish = false; + isSSwitchedBearish = false; + isMBullish = false; + isMBearish = false; + isMSwitchedBullish = false; + isMSwitchedBearish = false; + isLBullish = false; + isLBearish = false; + isLSwitchedBullish = false; + isLSwitchedBearish = false; + isHBullish = false; + isHBearish = false; + isHSwitchedBullish = false; + isHSwitchedBearish = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Current ... + if (isCBullish) + { + bullishScore++; + } + if (isCSwitchedBullish) + { + bullishScore++; + } + if (isCBearish) + { + bearishScore++; + } + if (isCSwitchedBearish) + { + bearishScore++; + } + + // + // Short ... + if (isSBullish) + { + bullishScore++; + } + if (isSSwitchedBullish) + { + bullishScore++; + } + if (isSBearish) + { + bearishScore++; + } + if (isSSwitchedBearish) + { + bearishScore++; + } + + // + // Medium ... + if (isMBullish) + { + bullishScore++; + } + if (isMSwitchedBullish) + { + bullishScore++; + } + if (isMBearish) + { + bearishScore++; + } + if (isMSwitchedBearish) + { + bearishScore++; + } + + // + // Long ... + if (isLBullish) + { + bullishScore++; + } + if (isLSwitchedBullish) + { + bullishScore++; + } + if (isLBearish) + { + bearishScore++; + } + if (isLSwitchedBearish) + { + bearishScore++; + } + + // + // Hind ... + if (isHBullish) + { + bullishScore++; + } + if (isHSwitchedBullish) + { + bullishScore++; + } + if (isHBearish) + { + bearishScore++; + } + if (isHSwitchedBearish) + { + 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("isCBearish", isCBearish, ignoreFalseConditions, separator) + + ToString("isCSwitchedBullish", isCSwitchedBullish, ignoreFalseConditions, separator) + + ToString("isCSwitchedBearish", isCSwitchedBearish, ignoreFalseConditions, separator) + + // + // Short ... + ToString("isSBullish", isSBullish, ignoreFalseConditions, separator) + + ToString("isSBearish", isSBearish, ignoreFalseConditions, separator) + + ToString("isSSwitchedBullish", isSSwitchedBullish, ignoreFalseConditions, separator) + + ToString("isSSwitchedBearish", isSSwitchedBearish, ignoreFalseConditions, separator) + + // + // Medium ... + ToString("isMBullish", isMBullish, ignoreFalseConditions, separator) + + ToString("isMBearish", isMBearish, ignoreFalseConditions, separator) + + ToString("isMSwitchedBullish", isMSwitchedBullish, ignoreFalseConditions, separator) + + ToString("isMSwitchedBearish", isMSwitchedBearish, ignoreFalseConditions, separator) + + // + // Long ... + ToString("isLBullish", isLBullish, ignoreFalseConditions, separator) + + ToString("isLBearish", isLBearish, ignoreFalseConditions, separator) + + ToString("isLSwitchedBullish", isLSwitchedBullish, ignoreFalseConditions, separator) + + ToString("isLSwitchedBearish", isLSwitchedBearish, ignoreFalseConditions, separator) + + // + // Hind ... + ToString("isHBullish", isHBullish, ignoreFalseConditions, separator) + + ToString("isHBearish", isHBearish, ignoreFalseConditions, separator) + + ToString("isHSwitchedBullish", isHSwitchedBullish, ignoreFalseConditions, separator) + + ToString("isHSwitchedBearish", isHSwitchedBearish, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "XCHSAR"; + } +}; + +// +// Class ... +class XCXCHSARHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCXCHSARHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCXCHSARHelper() + { + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XCHSARInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(cBuffer, true); + ArraySetAsSeries(sBuffer, true); + ArraySetAsSeries(mBuffer, true); + ArraySetAsSeries(lBuffer, true); + ArraySetAsSeries(hBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xchsar", + // + // Inputs ... + // + // Market ... + "", + mInputs.sarStep, + mInputs.sarMax, + // + // Cycles ... + "", + // + // Short ... + "", + mInputs.scMethod, + mInputs.scPeriod, + // + // Medium ... + "", + mInputs.mcMethod, + mInputs.mcPeriod, + // + // Long ... + "", + mInputs.lcMethod, + mInputs.lcPeriod, + // + // Hind ... + "", + mInputs.hcMethod, + mInputs.hcPeriod, + // + // Presentation ... + "", + mInputs.cArrowCode, + mInputs.sArrowCode, + mInputs.mArrowCode, + mInputs.lArrowCode, + mInputs.hArrowCode, + mInputs.showCurrent, + mInputs.showShort, + mInputs.showMedium, + mInputs.showLong, + mInputs.showHind + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XCHSARInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XCHSARInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Buffers ... + + // + // Current ... + + // + double GetC( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(cBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return cBuffer[barIndex]; + } + + // + // Copy Required Items ... + 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, + cBuffer, + buffer, + forceClean + // + ); + } + + // + // Short ... + + // + double GetS( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(sBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sBuffer[barIndex]; + } + + // + // Copy Required Items ... + 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, + sBuffer, + buffer, + forceClean + // + ); + } + + // + // Medium ... + + // + double GetM( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(mBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mBuffer[barIndex]; + } + + // + // Copy Required Items ... + 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, + mBuffer, + buffer, + forceClean + // + ); + } + + // + // Long ... + + // + double GetL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(lBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lBuffer[barIndex]; + } + + // + // Copy Required Items ... + 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, + lBuffer, + buffer, + forceClean + // + ); + } + + // + // Hind ... + + // + double GetH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(hBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hBuffer[barIndex]; + } + + // + // Copy Required Items ... + 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, + hBuffer, + buffer, + forceClean + // + ); + } + + // + bool GetConditions( + XCHSARConditions &conditions, // + int barIndex = 0, // + int loopback = 3 // + ) + { + // + bool result = true; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + 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.cSars // + ); + + // + // Short ... + CopyS( + zIndex, + loopback, + conditions.sSars // + ); + + // + // Medium ... + CopyM( + zIndex, + loopback, + conditions.mSars // + ); + + // + // Long ... + CopyL( + zIndex, + loopback, + conditions.lSars // + ); + + // + // Hind ... + CopyH( + zIndex, + loopback, + conditions.hSars // + ); + + // + // 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; + } + double hhValue = pBar.FindHighest( + loopback, + MODE_HIGH // + ); + double llValue = pBar.FindLowest( + loopback, + MODE_LOW // + ); + + // + // Current ... + + // + bool isCBullish = conditions.cSars[cIndex] < cBar.low; + bool isCBullishPrev = conditions.cSars[pIndex] < pBar.low; + + // + bool isCBearish = conditions.cSars[cIndex] > cBar.high; + bool isCBearishPrev = conditions.cSars[pIndex] > pBar.high; + + // + bool isCSwitchedBullish = isCBullish && + !isCBullishPrev; + bool isCSwitchedBearish = isCBearish && + !isCBearishPrev; + + // + conditions.isCBullish = isCBullish; + conditions.isCBearish = isCBearish; + conditions.isCSwitchedBullish = isCSwitchedBullish; + conditions.isCSwitchedBearish = isCSwitchedBearish; + + // + // Short ... + + // + bool isSBullish = conditions.sSars[cIndex] < cBar.low; + bool isSBullishPrev = conditions.sSars[pIndex] < pBar.low; + + // + bool isSBearish = conditions.sSars[cIndex] > cBar.high; + bool isSBearishPrev = conditions.sSars[pIndex] > pBar.high; + + // + bool isSSwitchedBullish = isSBullish && + !isSBullishPrev; + bool isSSwitchedBearish = isSBearish && + !isSBearishPrev; + + // + conditions.isSBullish = isSBullish; + conditions.isSBearish = isSBearish; + conditions.isSSwitchedBullish = isSSwitchedBullish; + conditions.isSSwitchedBearish = isSSwitchedBearish; + + // + // Medium ... + + // + bool isMBullish = conditions.mSars[cIndex] < cBar.low; + bool isMBullishPrev = conditions.mSars[pIndex] < pBar.low; + + // + bool isMBearish = conditions.mSars[cIndex] > cBar.high; + bool isMBearishPrev = conditions.mSars[pIndex] > pBar.high; + + // + bool isMSwitchedBullish = isMBullish && + !isMBullishPrev; + bool isMSwitchedBearish = isMBearish && + !isMBearishPrev; + + // + conditions.isMBullish = isMBullish; + conditions.isMBearish = isMBearish; + conditions.isMSwitchedBullish = isMSwitchedBullish; + conditions.isMSwitchedBearish = isMSwitchedBearish; + + // + // Long ... + + // + bool isLBullish = conditions.lSars[cIndex] < cBar.low; + bool isLBullishPrev = conditions.lSars[pIndex] < pBar.low; + + // + bool isLBearish = conditions.lSars[cIndex] > cBar.high; + bool isLBearishPrev = conditions.lSars[pIndex] > pBar.high; + + // + bool isLSwitchedBullish = isLBullish && + !isLBullishPrev; + bool isLSwitchedBearish = isLBearish && + !isLBearishPrev; + + // + conditions.isLBullish = isLBullish; + conditions.isLBearish = isLBearish; + conditions.isLSwitchedBullish = isLSwitchedBullish; + conditions.isLSwitchedBearish = isLSwitchedBearish; + + // + // Hind ... + + // + bool isHBullish = conditions.hSars[cIndex] < cBar.low; + bool isHBullishPrev = conditions.hSars[pIndex] < pBar.low; + + // + bool isHBearish = conditions.hSars[cIndex] > cBar.high; + bool isHBearishPrev = conditions.hSars[pIndex] > pBar.high; + + // + bool isHSwitchedBullish = isHBullish && + !isHBullishPrev; + bool isHSwitchedBearish = isHBearish && + !isHBearishPrev; + + // + conditions.isHBullish = isHBullish; + conditions.isHBearish = isHBearish; + conditions.isHSwitchedBullish = isHSwitchedBullish; + conditions.isHSwitchedBearish = isHSwitchedBearish; + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + XCHSARInputs mInputs; // Inputs ... + + // + // Buffers ... + + // + double cBuffer[]; + double sBuffer[]; + double mBuffer[]; + double lBuffer[]; + double hBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Current ... + CopyBuffer( + mHandler, + XCHSAR_C_LINE, + 0, + totalBars, + cBuffer + // + ); + + // + // Short ... + CopyBuffer( + mHandler, + XCHSAR_S_LINE, + 0, + totalBars, + sBuffer + // + ); + + // + // Medium ... + CopyBuffer( + mHandler, + XCHSAR_S_LINE, + 0, + totalBars, + mBuffer + // + ); + + // + // Long ... + CopyBuffer( + mHandler, + XCHSAR_S_LINE, + 0, + totalBars, + lBuffer + // + ); + + // + // Hind ... + CopyBuffer( + mHandler, + XCHSAR_S_LINE, + 0, + totalBars, + hBuffer + // + ); + } +}; + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.xchsar.mq5 b/Indicators/x-saherelm.xchsar.mq5 new file mode 100644 index 00000000..05023873 --- /dev/null +++ b/Indicators/x-saherelm.xchsar.mq5 @@ -0,0 +1,691 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHM +// Description: XCHMrend Detector ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHM Indicator" +#property strict + +// +#define ShortName "XCHSAR" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input double sarStep = 0.02; // Step +input double sarMax = 0.2; // Maximum + +// +input group "Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +// Presentation ... +input group "Presentation"; + +// +input int cArrowCode = 225; // Current Cycle Arrow Code +input int sArrowCode = 225; // Short Cycle Arrow Code +input int mArrowCode = 225; // Medium Cycle Arrow Code +input int lArrowCode = 225; // Long Cycle Arrow Code +input int hArrowCode = 225; // Hind Cycle Arrow Code + +// +input bool showCurrent = true; // Show Current Cycle +input bool showShort = 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_chart_window + +// +#property indicator_buffers 5 +#property indicator_plots 5 + +// +// Current ... +#define cBufferIndex 0 +double cBuffer[]; + +// +#property indicator_label1 "XCHSAR C" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrRed +#property indicator_width1 1 + +// +// Short ... +#define sBufferIndex 1 +double sBuffer[]; + +// +#property indicator_label2 "XCHSAR S" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +// Medium ... +#define mBufferIndex 2 +double mBuffer[]; + +// +#property indicator_label3 "XCHSAR M" +#property indicator_type3 DRAW_ARROW +#property indicator_color3 clrDodgerBlue +#property indicator_width3 1 + +// +// Long ... +#define lBufferIndex 3 +double lBuffer[]; + +// +#property indicator_label4 "XCHSAR L" +#property indicator_type4 DRAW_ARROW +#property indicator_color4 clrLime +#property indicator_width4 1 + +// +// Hind ... +#define hBufferIndex 4 +double hBuffer[]; + +// +#property indicator_label5 "XCHSAR H" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrYellow +#property indicator_width5 1 + +// +// Variables ... + +// +int maxLength; + +// +// Current ... +int cHandler = INVALID_HANDLE; + +// +// Short ... +ENUM_TIMEFRAMES mSCPeriod = NULL; +int sHandler = INVALID_HANDLE; + +// +// Medium ... +ENUM_TIMEFRAMES mMCPeriod = NULL; +int mHandler = INVALID_HANDLE; + +// +// Long ... +ENUM_TIMEFRAMES mLCPeriod = NULL; +int lHandler = INVALID_HANDLE; + +// +// Hind ... +ENUM_TIMEFRAMES mHCPeriod = NULL; +int hHandler = INVALID_HANDLE; + +// +// EVENT Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Current ... + IndicatorRelease(cHandler); + + // + // Short ... + IndicatorRelease(sHandler); + + // + // Medium ... + IndicatorRelease(mHandler); + + // + // Long ... + IndicatorRelease(lHandler); + + // + // Hind ... + IndicatorRelease(hHandler); +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + + // + // this counts Available Bars ... + int limit; + + // + // Validate Calculated Bars ... + bool isPassedRequiredCalculatedBars = + // + // Current ... + BarsCalculated(cHandler) >= maxLength && + // + // Short ... + BarsCalculated(sHandler) >= maxLength && + // + // Medium ... + BarsCalculated(mHandler) >= maxLength && + // + // Long ... + BarsCalculated(lHandler) >= maxLength && + // + // Hind ... + BarsCalculated(hHandler) >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // Current ... + int copiedCs = CopyBuffer(cHandler, 0, 0, limit, cBuffer); + + // + // Short ... + int copiedSs = CopyBuffer(sHandler, 0, 0, limit, sBuffer); + + // + // Medium ... + int copiedMs = CopyBuffer(mHandler, 0, 0, limit, mBuffer); + + // + // Long ... + int copiedLs = CopyBuffer(lHandler, 0, 0, limit, lBuffer); + + // + // Hind ... + int copiedHs = CopyBuffer(hHandler, 0, 0, limit, hBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // + // Current ... + copiedCs > 0 && + // + // Short ... + copiedSs > 0 && + // + // Medium ... + copiedMs > 0 && + // + // Long ... + copiedLs > 0 && + // + // Hind ... + copiedHs > 0 + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + // for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + // { + // CalculateBuffers(i); + // } + + // + return rates_total; +} + +// +// CUSTOM Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + sarStep > 0 && + sarMax > sarStep && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // CURRENT ... + + // + ENUM_DRAW_TYPE cDrawType = showCurrent ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(cBuffer, true); + SetIndexBuffer(cBufferIndex, cBuffer, INDICATOR_DATA); + PlotIndexSetInteger(cBufferIndex, PLOT_ARROW, cArrowCode); + PlotIndexSetDouble(cBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(cBufferIndex, PLOT_SHOW_DATA, showCurrent); + PlotIndexSetInteger(cBufferIndex, PLOT_DRAW_TYPE, cDrawType); + + // + // SHORT ... + + // + ENUM_DRAW_TYPE sDrawType = showShort ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mBufferIndex, PLOT_ARROW, sArrowCode); + PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(sBufferIndex, PLOT_SHOW_DATA, showShort); + PlotIndexSetInteger(sBufferIndex, PLOT_DRAW_TYPE, sDrawType); + + // + // MEDIUM ... + + // + ENUM_DRAW_TYPE mDrawType = showMedium ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(mBuffer, true); + SetIndexBuffer(mBufferIndex, mBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mBufferIndex, PLOT_ARROW, mArrowCode); + PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(mBufferIndex, PLOT_SHOW_DATA, showMedium); + PlotIndexSetInteger(mBufferIndex, PLOT_DRAW_TYPE, mDrawType); + + // + // LONG ... + + // + ENUM_DRAW_TYPE lDrawType = showLong ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(lBuffer, true); + SetIndexBuffer(lBufferIndex, lBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lBufferIndex, PLOT_ARROW, lArrowCode); + PlotIndexSetDouble(lBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(lBufferIndex, PLOT_SHOW_DATA, showLong); + PlotIndexSetInteger(lBufferIndex, PLOT_DRAW_TYPE, lDrawType); + + // + // HIND ... + + // + ENUM_DRAW_TYPE hDrawType = showHind ? DRAW_ARROW : DRAW_NONE; + + // + ArraySetAsSeries(hBuffer, true); + SetIndexBuffer(hBufferIndex, hBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hBufferIndex, PLOT_ARROW, hArrowCode); + PlotIndexSetDouble(hBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(hBufferIndex, PLOT_SHOW_DATA, showHind); + PlotIndexSetInteger(hBufferIndex, PLOT_DRAW_TYPE, hDrawType); +} + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Current Cycle Initialization ... + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Initialize Handlers ... + + // + // Current ... + cHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMax // + ); + result = cHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + sHandler = iSAR( + _Symbol, + mSCPeriod, + sarStep, + sarMax // + ); + result = sHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mHandler = iSAR( + _Symbol, + mMCPeriod, + sarStep, + sarMax // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + lHandler = iSAR( + _Symbol, + mLCPeriod, + sarStep, + sarMax // + ); + result = lHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + hHandler = iSAR( + _Symbol, + mHCPeriod, + sarStep, + sarMax // + ); + result = hHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Do all Custom Calculations ... +void CalculateBuffers(int barIndex) +{ +} + +// \ No newline at end of file diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index e61f7a36..a0a46180 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -24,6 +24,7 @@ #include "../../Classes/x-saherelm.base.class.mq5" #include "../../Helpers/x-saherelm.x3ma.helper.mq5" #include "../../Helpers/x-saherelm.x3vwap.helper.mq5" +#include "../../Helpers/x-saherelm.xchsar.helper.mq5" #include "../../Helpers/x-saherelm.xpv.helper.mq5" #include "../../Libraries/x-saherelm.common.lib.mq5" #include "../../Libraries/x-saherelm.x-poi.lib.mq5" @@ -387,6 +388,7 @@ struct X121SMCStrategyConditions XPVConditions xpvConditions; X3MAConditions x3maConditions; X3VWAPConditions x3vwapConditions; + XCHSARConditions xchsarConditions; // void X121SMCStrategyConditions() diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index ed3c653b..d539b754 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -25,6 +25,7 @@ // #include "../../Helpers/x-saherelm.x3ma.helper.mq5" #include "../../Helpers/x-saherelm.x3vwap.helper.mq5" +#include "../../Helpers/x-saherelm.xchsar.helper.mq5" #include "../../Helpers/x-saherelm.xpv.helper.mq5" #include "../Classes/x-121.smc.base.strategy.class.mq5" @@ -70,10 +71,8 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // delete xpvHelper; delete x3maHelper; + delete xchsarHelper; delete x3vwapHelper; - - // - IndicatorRelease(mPSarHandler); } /** @@ -412,9 +411,9 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy XCX3VWAPHelper *x3vwapHelper; // - // Parabolic Sar ... - int mPSarHandler; - double mPSars[]; + // XCHSAR ... + XCHSARInputs xchsarInputs; + XCXCHSARHelper *xchsarHelper; // XPVPivot mOrderFlow[]; @@ -490,15 +489,12 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy } // - // Retrieve Parabolic Sars ... - int sarsCopied = CopyBuffer( - mPSarHandler, - 0, - 0, - conditionsLoopback, - mPSars // + // XCHSAR ... + result = xchsarHelper.GetConditions( + conditions.xchsarConditions, + cIndex, + conditionsLoopback // ); - result = sarsCopied >= conditionsLoopback; if (!result) { return result; @@ -1829,14 +1825,34 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy ); // - // Initialize PSar ... - double sarStep = 0.02; - double sarMax = 0.2; - mPSarHandler = iSAR( + // XCHCHSAR ... + + // + xchsarInputs.Default(); + + // + xchsarInputs.scMethod = scMethod; + xchsarInputs.scPeriod = scPeriod; + xchsarInputs.mcMethod = mcMethod; + xchsarInputs.mcPeriod = mcPeriod; + xchsarInputs.lcMethod = lcMethod; + xchsarInputs.lcPeriod = lcPeriod; + xchsarInputs.hcMethod = hcMethod; + xchsarInputs.hcPeriod = hcPeriod; + + // + xchsarInputs.showCurrent = true; + xchsarInputs.showShort = true; + xchsarInputs.showMedium = false; + xchsarInputs.showLong = false; + xchsarInputs.showHind = false; + + // + xchsarHelper = new XCXCHSARHelper(); + xchsarHelper.Init( symbol, period, - sarStep, - sarMax // + xchsarInputs // ); }