diff --git a/Experts/x-test-strategies.ea.mq5 b/Experts/x-test-strategies.ea.mq5 index c291ec8a..6bfb3e5d 100644 --- a/Experts/x-test-strategies.ea.mq5 +++ b/Experts/x-test-strategies.ea.mq5 @@ -29,6 +29,7 @@ // #include "../Strategies/x-saherelm.xdtd.strategy.mq5" +#include "../Strategies/x-saherelm.xchkm.strategy.mq5" #include "../Strategies/x-saherelm.xtest.strategy.mq5" // @@ -254,8 +255,8 @@ bool InitialEA() // // Configure Trailing ... eaTradeHandler.AllowTrailStops(false); - eaTradeHandler.TrailStepInPoint(15); - eaTradeHandler.TrailStartInPoint(60); + eaTradeHandler.TrailStepInPoint(25); + eaTradeHandler.TrailStartInPoint(50); eaTradeHandler.IgnoreTPOnTrail(true); eaTradeHandler.TrailBasedOnProfit(true); @@ -274,7 +275,8 @@ bool InitialEA() // bool useXTest = false; - bool useXDTD = true; + bool useXDTD = false; + bool useXCHKM = true; // // EURUSD ... @@ -316,6 +318,37 @@ bool InitialEA() RegisterStrategy(eurusdXTDTStrategy); } + // + // XCHKM ... + if (useXCHKM) + { + // + XSCXCHKMStrategy *eurusdXCHKMStrategy; + eurusdXCHKMStrategy = new XSCXCHKMStrategy( + eurusdSymbol, + PERIOD_M5, + eaVolume, + eaR2R, // R2R ... + eaSlippage, + magicNumber, + true, // Ignore Signal Execution + false, // Use TP SL Point + false, // Use Max + eaTPPoint, // TP + eaSLPoint, // SL + eaIgnoreTP, + eaIgnoreSL, + eaAllowLong, + eaAllowShort, + eaMaxAllowedLongs, // Max Longs + eaMaxAllowedShorts // Max Shorts + ); + eurusdXCHKMStrategy.SetAlertLogAlerts(true); + eurusdXCHKMStrategy.SetAlertEnableAlerts(true); + eurusdXCHKMStrategy.AddSignalEventHandler(OnSignalRecieved); + RegisterStrategy(eurusdXCHKMStrategy); + } + // // XTest ... if (useXTest) diff --git a/Helpers/x-saherelm.xchhk.helper.mq5 b/Helpers/x-saherelm.xchhk.helper.mq5 new file mode 100644 index 00000000..1a384ab8 --- /dev/null +++ b/Helpers/x-saherelm.xchhk.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.chhk.mq5 b/Indicators/x-saherelm.xchhk.mq5 similarity index 99% rename from Indicators/x-saherelm.chhk.mq5 rename to Indicators/x-saherelm.xchhk.mq5 index b3b694f1..c2193e98 100644 --- a/Indicators/x-saherelm.chhk.mq5 +++ b/Indicators/x-saherelm.xchhk.mq5 @@ -56,24 +56,16 @@ input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period input group "Hind"; input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + // // Presentation ... input group "Presentation"; // -// Current ... input bool showCurrent = true; // Show Current Cycle -// -// Short ... input bool showShort = true; // Show Short Cycle -// -// Medium ... input bool showMedium = true; // Show Medium Cycle -// -// Long ... input bool showLong = true; // Show Long Cycle -// -// Hind ... input bool showHind = true; // Show Hind Cycle // diff --git a/Strategies/x-saherelm.xchkm.strategy.mq5 b/Strategies/x-saherelm.xchkm.strategy.mq5 new file mode 100644 index 00000000..61b42b73 --- /dev/null +++ b/Strategies/x-saherelm.xchkm.strategy.mq5 @@ -0,0 +1,1400 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XSCXCHKMStrategy +// Description: provides all based classes for use ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... + +// +// Import(s) Helper(s) ... +#include "../Helpers/x-saherelm.xchma.helper.mq5" +#include "../Helpers/x-saherelm.xchhk.helper.mq5" + +// +// Base Classes ... +#include "../Classes/x-saherelm.xstrategy.class.mq5" + +// +// Specific Identifier(s) of XStrategy ... +string XCHKMStartegyToken = "XCHKM"; + +// +// XStrategy Class Implementation(s) ... +class XSCXCHKMStrategy : public XSCBaseStrategy +{ + // + // Public ... +public: + // + // Constructor(s) ... + void XSCXCHKMStrategy( + // + // Base ... + string _symbol, // Trading Symbol + ENUM_TIMEFRAMES _period, // Trading TimeFrame + double _volume, // Voluem + double _r2r, // Risk/Reward Ratio + int _slippage, // Trader Slippage + long _magicNumber, // Trader Magic Number + bool _ignoreSignalExecution = false, // Ignore Signal Execution + bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points + bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points + double _tpPoint = 0, // TP As Point + double _slPoint = 0, // SL As Point + bool _ignoreTP = false, // TP set to 0 + bool _ignoreSL = false, // SL set to 0 + bool _allowLong = true, + bool _allowShort = true, + int _maxAllowedLongs = 0, + int _maxAllowedShorts = 0 // + ) : XSCBaseStrategy(_symbol, + _period, + _volume, + _r2r, + _slippage, + _magicNumber, + _ignoreSignalExecution, + _useTPSLAsPoint, + _forceMaxTPSLAsPoint, + _tpPoint, + _slPoint, + _ignoreTP, + _ignoreSL, + _allowLong, + _allowShort, + _maxAllowedLongs, + _maxAllowedShorts // + ) + { + // + SetAlertPrefix(GetTag()); + + // + PrepareRequirements(); + } + + // + // Deconstructor ... + void ~XSCXCHKMStrategy() + { + // + delete chhkHelper; + delete chmaHelper; + } + + // + // Getter / Setter (s) ... + + // + // Overrides ... + + // + // Customize Strategy Identifier ... + string GetTag() override + { + return XCHKMStartegyToken; + } + + // + // Check Conditions For Signal ... + bool HasSignal( + XSignal &signal // + ) override + { + // + bool result = false; + + // + signal.Clean(); + + // + double sl = 0; + double tp = 0; + double risk = 0; + double entry = 0; + double reward = 0; + double r2r = R2R(); + ENUM_POSITION_TYPE type = POSITION_TYPE_BUY; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + + // + bool hasLong = false; + bool hasShort = false; + + // + bool forceCloseLongs = false; + bool forceCloseShorts = false; + + // + // Retrieve Conditions ... + + // + // XCHMA ... + XCHMAConditions chmaConditions; + result = chmaHelper.GetConditions(chmaConditions); + if (!result) + { + return result; + } + + // + // XCHE ... + XCHHKConditions chhkConditions; + result = chhkHelper.GetConditions(chhkConditions); + if (!result) + { + return result; + } + + // + // Start Calculations ... + + // + double points = GetPoints(mSymbol); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + // Retrieve Bars ... + + // + // Last Bar ... + XOHCL cBar; + result = cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + if (!result) + { + return result; + } + + // + // Previous Bar of Last Bar ... + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Last Swing Low Bar ... + XOHCL lastSwingLow; + result = cBar.FindLastSwingLow(lastSwingLow); + if (!result) + { + return result; + } + + // + // Last Swing High Bar ... + XOHCL lastSwingHigh; + result = cBar.FindLastSwingHigh(lastSwingHigh); + if (!result) + { + return result; + } + + // + // Retrieve Highest High(s) and Lowest Low(s) ... + + // + // Highest High ... + double hh5 = cBar.FindHighest( + 5, + MODE_HIGH // + ); + + // + // Lowest Low ... + double ll5 = cBar.FindLowest( + 5, + MODE_LOW // + ); + + // + // Check Support Exists or Find ... + bool hasSupport = support.IsValid(); + if (!hasSupport) + { + // + hasSupport = + // + cBar.HasSupport(support) + // + ; + + // + if (hasSupport) + { + // + DrawSupport( + support, + ChartID() // + ); + + // + supportTime = cBar.time; + } + } + + // + // Check Resistance Exists or Find ... + bool hasResistance = resistance.IsValid(); + if (!hasResistance) + { + // + hasResistance = + // + cBar.HasResistance(resistance) + // + ; + + // + if (hasResistance) + { + // + DrawResistance( + resistance, + ChartID() // + ); + + // + resistanceTime = cBar.time; + } + } + + // + // For Trend ... + XOHCL tmpHSW[]; + XOHCL tmpLSW[]; + + // + // Detect Bullish/Bearish Patterns and Trends ... + + // + // Bullish ... + bool hasBullishPattern = HasBullishPattern(cBar); + bool isBullishTrend = cBar.HasBullishTrend( + tmpHSW, + tmpLSW, + true // + ); + + // + // Bearish ... + bool hasBearishPattern = HasBearishPattern(cBar); + bool isBearishTrend = cBar.HasBearishTrend( + tmpHSW, + tmpLSW, + false // + ); + + // + // Detect XCHMA based Conditions ... + + // + // Bullish ... + + // + bool isCHMAHCrossedOver = + // + ( + // + chmaConditions.isHFastCrossedOverSlow && + chmaConditions.isLFastOverSlow && + chmaConditions.isMFastOverSlow && + chmaConditions.isSFastOverSlow + // + ) + // + ; + + // + bool isCHMALCrossedOver = + // + ( + // + chmaConditions.isLFastCrossedOverSlow && + chmaConditions.isHFastOverSlow && + chmaConditions.isMFastOverSlow && + chmaConditions.isSFastOverSlow + // + ) + // + ; + + // + bool isCHMAMCrossedOver = + // + ( + // + chmaConditions.isMFastCrossedOverSlow && + chmaConditions.isHFastOverSlow && + chmaConditions.isLFastOverSlow && + chmaConditions.isSFastOverSlow + // + ) + // + ; + + // + bool isCHMASCrossedOver = + // + ( + // + chmaConditions.isSFastCrossedOverSlow && + chmaConditions.isHFastOverSlow && + chmaConditions.isLFastOverSlow && + chmaConditions.isMFastOverSlow + // + ) + // + ; + + // + // Bullish XCHMA Conditions ... + bool isCHMACrossedOver = + // + isCHMAHCrossedOver + // + || + // + isCHMALCrossedOver + // + || + // + isCHMAMCrossedOver + // + || + // + isCHMASCrossedOver + // + ; + + // + // Bearish ... + + // + bool isCHMAHCrossedUnder = + // + ( + // + chmaConditions.isHFastCrossedUnderSlow && + chmaConditions.isLFastUnderSlow && + chmaConditions.isMFastUnderSlow && + chmaConditions.isSFastUnderSlow + // + ) + // + ; + + // + bool isCHMALCrossedUnder = + // + ( + // + chmaConditions.isLFastCrossedUnderSlow && + chmaConditions.isHFastUnderSlow && + chmaConditions.isMFastUnderSlow && + chmaConditions.isSFastUnderSlow + // + ) + // + ; + + // + bool isCHMAMCrossedUnder = + // + ( + // + chmaConditions.isMFastCrossedUnderSlow && + chmaConditions.isHFastUnderSlow && + chmaConditions.isLFastUnderSlow && + chmaConditions.isSFastUnderSlow + // + ) + // + ; + + // + bool isCHMASCrossedUnder = + // + ( + // + chmaConditions.isSFastCrossedUnderSlow && + chmaConditions.isHFastUnderSlow && + chmaConditions.isLFastUnderSlow && + chmaConditions.isMFastUnderSlow + // + ) + // + ; + + // + // Bullish XCHMA Conditions ... + bool isCHMACrossedUnder = + // + isCHMAHCrossedUnder + // + || + // + isCHMALCrossedUnder + // + || + // + isCHMAMCrossedUnder + // + || + // + isCHMASCrossedUnder + // + ; + + // + // XCHHM Conditions ... + + // + // Bullish ... + + // + bool isCHHKCSwitchedToBullish = + // + ( + // + chhkConditions.isCSwitchedToBullish && + chhkConditions.isSBullish && + chhkConditions.isMBullish && + chhkConditions.isLBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKSSwitchedToBullish = + // + ( + // + chhkConditions.isSSwitchedToBullish && + chhkConditions.isCBullish && + chhkConditions.isMBullish && + chhkConditions.isLBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKMSwitchedToBullish = + // + ( + // + chhkConditions.isMSwitchedToBullish && + chhkConditions.isCBullish && + chhkConditions.isSBullish && + chhkConditions.isLBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKLSwitchedToBullish = + // + ( + // + chhkConditions.isLSwitchedToBullish && + chhkConditions.isCBullish && + chhkConditions.isSBullish && + chhkConditions.isMBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKHSwitchedToBullish = + // + ( + // + chhkConditions.isHSwitchedToBullish && + chhkConditions.isCBullish && + chhkConditions.isSBullish && + chhkConditions.isMBullish && + chhkConditions.isLBullish + // + ) + // + ; + + // + bool isCHHKCBullishBreaked = + // + ( + // + chhkConditions.isCBearish && + chhkConditions.isSBullish && + chhkConditions.isMBullish && + chhkConditions.isLBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKSBullishBreaked = + // + ( + // + chhkConditions.isSBearish && + chhkConditions.isCBullish && + chhkConditions.isMBullish && + chhkConditions.isLBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKMBullishBreaked = + // + ( + // + chhkConditions.isMBearish && + chhkConditions.isCBullish && + chhkConditions.isSBullish && + chhkConditions.isLBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKLBullishBreaked = + // + ( + // + chhkConditions.isLBearish && + chhkConditions.isCBullish && + chhkConditions.isSBullish && + chhkConditions.isMBullish && + chhkConditions.isHBullish + // + ) + // + ; + + // + bool isCHHKHBullishBreaked = + // + ( + // + chhkConditions.isHBearish && + chhkConditions.isCBullish && + chhkConditions.isSBullish && + chhkConditions.isMBullish && + chhkConditions.isLBullish + // + ) + // + ; + + // + bool isCHHKBullish = + // + isCHHKCSwitchedToBullish + // + || + // + isCHHKSSwitchedToBullish + // + || + // + isCHHKMSwitchedToBullish + // + || + // + isCHHKLSwitchedToBullish + // + || + // + isCHHKHSwitchedToBullish + // + ; + + // + bool isCHHKBullishBreaked = + // + isCHHKCBullishBreaked + // + || + // + isCHHKSBullishBreaked + // + || + // + isCHHKMBullishBreaked + // + || + // + isCHHKLBullishBreaked + // + || + // + isCHHKHBullishBreaked + // + ; + + // + // Max ... + double maxCHMA = MathMax( + chmaConditions.cFast[cIndex], + chmaConditions.cSlow[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.sFast[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.sSlow[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.mFast[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.mSlow[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.lFast[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.lSlow[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.hFast[cIndex] // + ); + maxCHMA = MathMax( + maxCHMA, + chmaConditions.hSlow[cIndex] // + ); + + // + // Min + double minCHMA = MathMin( + chmaConditions.cFast[cIndex], + chmaConditions.cSlow[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.sFast[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.sSlow[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.mFast[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.mSlow[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.lFast[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.lSlow[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.hFast[cIndex] // + ); + minCHMA = MathMin( + minCHMA, + chmaConditions.hSlow[cIndex] // + ); + + // + double chmaDistanceDiffInPoint = + // + (maxCHMA - minCHMA) / points + // + ; + + // + // Bearish ... + + // + bool isCHHKCSwitchedToBearish = + // + ( + // + chhkConditions.isCSwitchedToBearish && + chhkConditions.isSBearish && + chhkConditions.isMBearish && + chhkConditions.isLBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKSSwitchedToBearish = + // + ( + // + chhkConditions.isSSwitchedToBearish && + chhkConditions.isCBearish && + chhkConditions.isMBearish && + chhkConditions.isLBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKMSwitchedToBearish = + // + ( + // + chhkConditions.isMSwitchedToBearish && + chhkConditions.isCBearish && + chhkConditions.isSBearish && + chhkConditions.isLBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKLSwitchedToBearish = + // + ( + // + chhkConditions.isLSwitchedToBearish && + chhkConditions.isCBearish && + chhkConditions.isSBearish && + chhkConditions.isMBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKHSwitchedToBearish = + // + ( + // + chhkConditions.isHSwitchedToBearish && + chhkConditions.isCBearish && + chhkConditions.isSBearish && + chhkConditions.isMBearish && + chhkConditions.isLBearish + // + ) + // + ; + + // + bool isCHHKCBearishBreaked = + // + ( + // + chhkConditions.isCBullish && + chhkConditions.isSBearish && + chhkConditions.isMBearish && + chhkConditions.isLBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKSBearishBreaked = + // + ( + // + chhkConditions.isSBullish && + chhkConditions.isCBearish && + chhkConditions.isMBearish && + chhkConditions.isLBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKMBearishBreaked = + // + ( + // + chhkConditions.isMBullish && + chhkConditions.isCBearish && + chhkConditions.isSBearish && + chhkConditions.isLBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKLBearishBreaked = + // + ( + // + chhkConditions.isLBullish && + chhkConditions.isCBearish && + chhkConditions.isSBearish && + chhkConditions.isMBearish && + chhkConditions.isHBearish + // + ) + // + ; + + // + bool isCHHKHBearishBreaked = + // + ( + // + chhkConditions.isHBullish && + chhkConditions.isCBearish && + chhkConditions.isSBearish && + chhkConditions.isMBearish && + chhkConditions.isLBearish + // + ) + // + ; + + // + bool isCHHKBearish = + // + isCHHKCSwitchedToBearish + // + || + // + isCHHKSSwitchedToBearish + // + || + // + isCHHKMSwitchedToBearish + // + || + // + isCHHKLSwitchedToBearish + // + || + // + isCHHKHSwitchedToBearish + // + ; + + // + bool isCHHKBearishBreaked = + // + isCHHKCBearishBreaked + // + || + // + isCHHKSBearishBreaked + // + || + // + isCHHKMBearishBreaked + // + || + // + isCHHKLBearishBreaked + // + || + // + isCHHKHBearishBreaked + // + ; + + // + // Max High ... + double maxCHHKHigh = MathMax( + chhkConditions.cBars[cIndex].high, + chhkConditions.sBars[cIndex].high // + ); + maxCHHKHigh = MathMax( + maxCHHKHigh, + chhkConditions.mBars[cIndex].high // + ); + maxCHHKHigh = MathMax( + maxCHHKHigh, + chhkConditions.lBars[cIndex].high // + ); + maxCHHKHigh = MathMax( + maxCHHKHigh, + chhkConditions.hBars[cIndex].high // + ); + + // + // Min High ... + double minCHHKHigh = MathMin( + chhkConditions.cBars[cIndex].high, + chhkConditions.sBars[cIndex].high // + ); + minCHHKHigh = MathMin( + minCHHKHigh, + chhkConditions.mBars[cIndex].high // + ); + minCHHKHigh = MathMin( + minCHHKHigh, + chhkConditions.lBars[cIndex].high // + ); + minCHHKHigh = MathMin( + minCHHKHigh, + chhkConditions.hBars[cIndex].high // + ); + + // + // Max Low ... + double maxCHHKLow = MathMax( + chhkConditions.cBars[cIndex].low, + chhkConditions.sBars[cIndex].low // + ); + maxCHHKLow = MathMax( + maxCHHKLow, + chhkConditions.mBars[cIndex].low // + ); + maxCHHKLow = MathMax( + maxCHHKLow, + chhkConditions.lBars[cIndex].low // + ); + maxCHHKLow = MathMax( + maxCHHKLow, + chhkConditions.hBars[cIndex].low // + ); + + // + // Min Low ... + double minCHHKLow = MathMin( + chhkConditions.cBars[cIndex].low, + chhkConditions.sBars[cIndex].low // + ); + minCHHKLow = MathMin( + minCHHKLow, + chhkConditions.mBars[cIndex].low // + ); + minCHHKLow = MathMin( + minCHHKLow, + chhkConditions.lBars[cIndex].low // + ); + minCHHKLow = MathMin( + minCHHKLow, + chhkConditions.hBars[cIndex].low // + ); + + // + double chhkDistanceDiffInPoint = + // + (maxCHHKHigh - minCHHKLow) / points + // + ; + + // + // Signalling ... + // Looking for Signals Based on Conditions ... + + // + // Preparing Signals for Execution ... + + // + if (isCHHKBullish) + { + // + hasLong = + // + isCHHKBullish && + hasBullishPattern && + chhkDistanceDiffInPoint <= 250 + // + ; + + // + if (hasLong) + { + // + type = POSITION_TYPE_BUY; + sl = maxCHHKLow; + } + } + + // + if (isCHHKBearish) + { + // + hasShort = + // + isCHHKBearish && + hasBearishPattern && + chhkDistanceDiffInPoint <= 250 + // + ; + + // + if (hasShort) + { + // + type = POSITION_TYPE_SELL; + sl = minCHHKHigh; + } + } + + // + // forceCloseLongs = isCHHKBullishBreaked; + // forceCloseShorts = isCHHKBearishBreaked; + + // + // Check Exist Conditions ... + if (forceCloseLongs || forceCloseShorts) + { + // + string comment = "Exit Condition ..."; + + // + ENUM_X_POSITION_TYPES mType = + forceCloseLongs + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + int count = trader.Close( + comment, + mSymbol, + GetTag(), + mPeriod, + mType, + false // Filter By Magic ... + ); + if (IsValidSize(count)) + { + // + string msg = "Close (" + ToString(count) + ") " + (forceCloseLongs ? "Long" : "Short") + " Positions due Exit Conditions ..."; + Alert(msg); + } + } + + // + result = hasLong || hasShort; + if (!result) + { + // + CheckSupportValidation(); + CheckResistanceValidation(); + return result; + } + + // + if (hasSupport) + { + // + supportTime = NULL; + isSupportTested = false; + RemoveSupport(support); + support.Clean(); + } + + // + if (hasResistance) + { + // + resistanceTime = NULL; + isResistanceTested = false; + RemoveResistance(resistance); + resistance.Clean(); + } + + // + // Retrieve Entry Price based on Position Type ... + entry = GetEntry(mSymbol, type); + + // + // Calculate TP and SL ... + // based on Strategy ... + CalculateTPSLByPrice( + sl, + tp, + type, + entry, + r2r // + ); + + // + // Preparing Signal ... + result = signal.Prepare( + mSymbol, + GetTag(), + mPeriod, + type, + mode, + entry, + mVolume, + sl, + tp // + ); + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + + // + XOHCL support; + XOHCL resistance; + + // + // XHK ... + XCHHKInputs chhkInputs; + XSCXCHHKHelper *chhkHelper; + + // + // XCHMA ... + XCHMAInputs chmaInputs; + XSCXCHMAHelper *chmaHelper; + + // + // Private ... +private: + // + // Props ... + + // + void PrepareRequirements() + { + // + support.Clean(); + supportTime = NULL; + isSupportTested = false; + + // + resistance.Clean(); + resistanceTime = NULL; + isResistanceTested = false; + + // + // XCHMA ... + + // + chmaInputs.Default(); + + // + chmaInputs.showFast = true; + chmaInputs.showSlow = true; + chmaInputs.showCCFast = false; + chmaInputs.showCCSlow = false; + chmaInputs.showSCFast = false; + chmaInputs.showSCSlow = false; + chmaInputs.showMCFast = false; + chmaInputs.showMCSlow = false; + chmaInputs.showLCFast = false; + chmaInputs.showLCSlow = false; + chmaInputs.showHCFast = false; + chmaInputs.showHCSlow = false; + + // + chmaHelper = new XSCXCHMAHelper(); + chmaHelper.Init( + mSymbol, + mPeriod, + chmaInputs // + ); + + // + // XCHHK ... + + // + chhkInputs.Default(); + + // + chhkInputs.showCurrent = true; + chhkInputs.showShort = true; + chhkInputs.showMedium = true; + chhkInputs.showLong = true; + chhkInputs.showHind = true; + + // + chhkHelper = new XSCXCHHKHelper(); + chhkHelper.Init( + mSymbol, + mPeriod, + chhkInputs // + ); + } + + // + bool isSupportTested; + datetime supportTime; + void CheckSupportValidation() + { + // + if (!isSupportTested) + { + // + if (support.IsValid() && IsValid(supportTime)) + { + // + int age = (int)(((int)(TimeToSeconds(TimeCurrent()) - TimeToSeconds(supportTime))) / PeriodSeconds(mPeriod)); + if (age >= 50) + { + // + isSupportTested = false; + supportTime = NULL; + RemoveSupport(support); + support.Clean(); + } + } + return; + } + + // + XOHCL cBar; + bool isInited = cBar.Init( + mSymbol, + mPeriod, + 1 // + ); + if (!isInited) + { + return; + } + + // + double points = GetPoints(mSymbol); + + // + // Find Price Distance ... + double highDiff = MathAbs(cBar.high - support.high); + double lowDiff = MathAbs(cBar.low - support.high); + + // + bool isBreaked = MathMax(highDiff, lowDiff) >= 100 * points; + if (!isBreaked) + { + return; + } + + // + isSupportTested = false; + RemoveSupport(support); + supportTime = NULL; + support.Clean(); + } + + // + bool isResistanceTested; + datetime resistanceTime; + void CheckResistanceValidation() + { + // + if (!isResistanceTested) + { + // + if (resistance.IsValid() && IsValid(resistanceTime)) + { + // + int age = (int)(((int)(TimeToSeconds(TimeCurrent()) - TimeToSeconds(resistanceTime))) / PeriodSeconds(mPeriod)); + if (age >= 50) + { + // + isResistanceTested = false; + resistanceTime = NULL; + RemoveResistance(resistance); + resistance.Clean(); + } + } + return; + } + + // + XOHCL cBar; + bool isInited = cBar.Init( + mSymbol, + mPeriod, + 1 // + ); + if (!isInited) + { + return; + } + + // + double points = GetPoints(mSymbol); + + // + // Find Price Distance ... + double highDiff = MathAbs(cBar.high - resistance.low); + double lowDiff = MathAbs(cBar.low - resistance.low); + + // + bool isBreaked = MathMax(highDiff, lowDiff) >= 100 * points; + if (!isBreaked) + { + return; + } + + // + isResistanceTested = false; + RemoveResistance(resistance); + resistanceTime = NULL; + resistance.Clean(); + } +}; + +// \ No newline at end of file