diff --git a/Documents/BKP/1/signals/2.mq5 b/Documents/BKP/1/signals/2.mq5 index e1ece64f..d69c8d28 100644 --- a/Documents/BKP/1/signals/2.mq5 +++ b/Documents/BKP/1/signals/2.mq5 @@ -931,6 +931,883 @@ if (has) ///////////////////////////////////////////////////////// +// +bool GeneratePVBox( + XBoxZone &box, + int barIndex = 0 // +) +{ + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + box.Clean(); + box.symbol = GetSymbol(); + box.period = GetPeriod(); + + // + int index = barIndex; + + // + // Peak ... + datetime peaksSameFrom = NULL; + double peak = mX121Helper.xpvHelper.GetPeak(index); + double prevPeak = mX121Helper.xpvHelper.GetPeak(index + 1); + bool startsByPeak = peak == prevPeak; + + // + // Vale ... + datetime valesSameFrom = NULL; + double vale = mX121Helper.xpvHelper.GetVale(index); + double prevVale = mX121Helper.xpvHelper.GetVale(index + 1); + bool startsByVale = + !startsByPeak && + vale == prevVale; + + // + bool canBreak = false; + while (!canBreak) + { + // + index++; + + // + datetime cTime = iTime( + box.symbol, + box.period, + index // + ); + + // + // Peak ... + double iPeak = mX121Helper.xpvHelper.GetPeak(index); + + // + // Vale ... + double iVale = mX121Helper.xpvHelper.GetVale(index); + + // + // Start By Peak or Value ... + bool isSame = false; + if (startsByPeak) + { + // + isSame = iPeak == peak; + bool canSetVale = vale == 0 + ? true + : iVale > vale; + if (canSetVale) + { + vale = iVale; + } + } + else if (startsByVale) + { + // + isSame = iVale == vale; + bool canSetPeak = peak == 0 + ? true + : iPeak < peak; + if (canSetPeak) + { + peak = iPeak; + } + } + + // + if (isSame) + { + // + box.from = cTime; + box.upper = peak; + box.lower = vale; + } + else if (IsValid(box.from)) + { + // + // Complete Box ... + box.to = iTime( + box.symbol, + box.period, + barIndex // + ); + + // + box.type = "XPVBox"; + box.dir = startsByPeak + ? X_DIRECTION_BEARISH + : startsByVale + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + } + + // + canBreak = !isSame; + } + + // + result = box.IsValid(); + if (!result) + { + box.Clean(); + } + + // + return result; +} + +// +void DetectPVPivots( + int barIndex = 0, + int validation = 50, + int loopback = 100 // +) +{ + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + loopback = NormalizeInt(loopback, 10); + validation = NormalizeInt(validation, 5); + + // + int iPeakVerified = 0; + int iValeVerified = 0; + datetime iPeakTo = GetBarTime( + GetSymbol(), + GetPeriod(), + barIndex // + ); + datetime iValeTo = GetBarTime( + GetSymbol(), + GetPeriod(), + barIndex // + ); + double iPeak = mX121Helper.xpvHelper.GetPeak(barIndex); + double iVale = mX121Helper.xpvHelper.GetVale(barIndex); + double iPeakGolden = mX121Helper.xpvHelper.GetPeakGoldenZone(barIndex); + double iValeGolden = mX121Helper.xpvHelper.GetValeGoldenZone(barIndex); + for (int i = barIndex + 1; i < barIndex + 1 + loopback; i++) + { + // + double iiPeak = mX121Helper.xpvHelper.GetPeak(i); + double iiVale = mX121Helper.xpvHelper.GetVale(i); + double iiPeakGolden = mX121Helper.xpvHelper.GetPeakGoldenZone(i); + double iiValeGolden = mX121Helper.xpvHelper.GetValeGoldenZone(i); + + // + if (iiPeak == iPeak) + { + // + iPeakVerified++; + iPeakGolden = iPeakGolden < iiPeakGolden + ? iiPeakGolden + : iPeakGolden; + } + else + { + // + if (iPeakVerified > 0 && + iPeakVerified < validation) + { + // + // Reset ... + iPeak = iiPeak; + iPeakVerified = 0; + iPeakGolden = iiPeakGolden; + iPeakTo = GetBarTime( + GetSymbol(), + GetPeriod(), + i // + ); + } + } + + // + if (iiVale == iVale) + { + // + iValeVerified++; + iValeGolden = iValeGolden > iiValeGolden + ? iiValeGolden + : iValeGolden; + } + else + { + // + if (iValeVerified > 0 && + iValeVerified < validation) + { + // + // Reset ... + iVale = iiVale; + iValeVerified = 0; + iValeGolden = iiValeGolden; + iValeTo = GetBarTime( + GetSymbol(), + GetPeriod(), + i // + ); + } + } + + // + if (iPeakVerified >= validation && + iValeVerified >= validation) + { + break; + } + } + + // + // Checking PV Pivots ... + + // + if (iPeakVerified >= validation) + { + // + XPVPivot iPivot; + + // + iPivot.to = iPeakTo; + iPivot.value = iPeak; + iPivot.type = X_PV_PEAK; + iPivot.golden = iPeakGolden; + iPivot.symbol = GetSymbol(); + iPivot.period = GetPeriod(); + iPivot.from = ((datetime)iPeakTo - (PeriodSeconds(GetPeriod()) * iPeakVerified)); + + // + if (iPivot.IsValid()) + { + // + AddRef( + iPivot, + mPVPivots // + ); + + // + XBoxZone iBox; + XCBoxObject *iObj; + bool iHas = iPivot.AsBox(iBox); + if (iHas) + { + // + iHas = mPOIDrawer.DrawBox( + iBox, + iObj // + ); + if (iHas) + { + Print("Peak Pivot ..."); + } + } + } + + // + iPivot.Clean(); + } + + // + if (iValeVerified >= validation) + { + // + XPVPivot iPivot; + + // + iPivot.to = iValeTo; + iPivot.value = iVale; + iPivot.type = X_PV_VALE; + iPivot.symbol = GetSymbol(); + iPivot.period = GetPeriod(); + iPivot.golden = iValeGolden; + iPivot.from = ((datetime)iValeTo - (PeriodSeconds(GetPeriod()) * iValeVerified)); + + // + if (iPivot.IsValid()) + { + // + AddRef( + iPivot, + mPVPivots // + ); + + // + XBoxZone iBox; + XCBoxObject *iObj; + bool iHas = iPivot.AsBox(iBox); + if (iHas) + { + // + iHas = mPOIDrawer.DrawBox( + iBox, + iObj // + ); + if (iHas) + { + Print("Vale Pivot ..."); + } + } + } + + // + iPivot.Clean(); + } + + // +} + +// +DetectPVPivots(barIndex); + +///////////////////////////////////////////////////////// +// +// Detect Support and Resistances ... +XBoxZone tmpBoxes[]; +XBoxZone selectedSupRes[]; +count = provider.triggerState.SupportResistancesAsBox(tmpBoxes); +has = IsValidSize(count); +if (has) +{ + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + // Validate Box ... + bool isDirPassed = iBox.dir == selectedBox.dir; + bool isPlacePassed = IsBoxInsideOr(iBox, selectedBox, true); + has = isDirPassed && + isPlacePassed; + if (has) + { + // + AddRef( + iBox, + selectedSupRes // + ); + } + + // + iBox.Clean(); + } + + // + Clean(tmpBoxes); +} +has = HasChild(selectedSupRes); +if (has) +{ + // + count = ArraySize(selectedSupRes); + for (int i = 0; i < count; i++) + { + // + selectedSupRes[i].to = TimeCurrent(); + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + selectedSupRes[i], + iObj // + ); + } +} + +///////////////////////////////////////////////////////// + // + // double strSupport = 0; + // datetime strIn = NULL; + // datetime strOut = NULL; + // bool isStrInBox = false; + // double strResistance = 0; + // bool isStrOutBox = false; + // Checking STR Variables ... + // CheckBoxStr( + // cHelper, + // selectedBox, + // isStrInBox, + // strIn, + // isStrOutBox, + // strOut, + // strSupport, + // strResistance // + // ); + + +///////////////////////////////////////////////////////// + +// +bool IsFVGBoxValid( + XBoxZone &box, + ENUM_X_CYCLES cycle, + X121SMCStrategySignalProviderData &provider // +) +{ + // + bool result = false; + + // + result = box.IsValid(); + if (!result) + { + return result; + } + + // + // Fil Selected Data ... + XPOIState cState; + X121Conditions cXConditions; + XPOIStateEvents cStateEvents; + XC121SMCCycleHelper *cHelper; + X121SMCCycleConditions cConditions; + result = provider.SelectCycle( + cycle, + cState, + cStateEvents, + cXConditions, + cHelper, + cConditions // + ); + if (!result) + { + // + cState.Clean(); + ZeroMemory(cHelper); + cConditions.Clean(); + cXConditions.Clean(); + cStateEvents.Clean(); + + // + return result; + } + + // + bool isBoxBullish = box.IsBullish(); + + // + int count = 0; + bool has = false; + + // + XBoxZone tmpBoxes[]; + count = cState.FairValueGapsAsBox(tmpBoxes); + has = IsValidSize(count); + + // + // Check Must Contains Inner Cycle FVG ... + XBoxZone selectedBox; + bool hasSelectedBox = false; + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tmpBoxes[i]; + + // + // Regular Validation of Boxes ... + bool isValid = IsBoxValid( + iBox, + 0, + iBox.period // + ); + bool isTypePassed = iBox.dir == box.dir; + bool isFromPssed = iBox.from >= box.from; + bool isPlacePassed = + IsBoxInsideOr( + iBox, + box // + ) && + (isBoxBullish + ? iBox.lower >= box.lower + : iBox.upper <= box.upper); + has = + isValid && + isFromPssed && + isTypePassed && + isPlacePassed; + if (!has) + { + // + iBox.Clean(); + continue; + } + + // + has = + !hasSelectedBox + ? true + : isBoxBullish + ? selectedBox.upper > iBox.upper + : selectedBox.lower < iBox.lower; + if (has) + { + // + selectedBox = iBox; + hasSelectedBox = selectedBox.IsValid(); + } + + // + iBox.Clean(); + } + } + + // + result = hasSelectedBox; + + // + // IGNORE Box Validations ... + // if (result) + // { + // // // + // // // From Index ... + // // int fromIndex = GetBarIndex( + // // selectedBox.symbol, + // // selectedBox.period, + // // selectedBox.from // + // // ) + + // // 1; + // // result = IsValidIndex(fromIndex); + + // // // + // // // To Index ... + // // int toIndex = GetBarIndex( + // // selectedBox.symbol, + // // selectedBox.period, + // // selectedBox.to // + // // ); + // // if (toIndex < 1) + // // { + // // toIndex = 1; + // // } + // // result = IsValidIndex(toIndex); + + // // // + // // // Now we Have Retrieve X121Conditions between from and to Indexes ... + // // // for Check States ... + + // // // + // // bool hasNewValeUnderLast = false; + // // bool isStrSwitchedToBullish = false; + // // bool isSarSwitchedToBullish = false; + // // bool hasValueGoldenZoneBreak = false; + // // bool isSMHKSwitchedToBullish = false; + // // bool isVWapSwitchedToBullishState = false; + // // bool isX3MaSwitchedToBullishState = false; + // // bool isVWapSwitchedToBullishOrdered = false; + // // bool isX3MaSwitchedToBullishOrdered = false; + + // // // + // // bool hasNewPeakOverLast = false; + // // bool isStrSwitchedToBearish = false; + // // bool isSarSwitchedToBearish = false; + // // bool hasPeakGoldenZoneBreak = false; + // // bool isSMHKSwitchedToBearish = false; + // // bool isVWapSwitchedToBearishState = false; + // // bool isX3MaSwitchedToBearishState = false; + // // bool isVWapSwitchedToBearishOrdered = false; + // // bool isX3MaSwitchedToBearishOrdered = false; + + // // // + // // for (int i = fromIndex; i >= toIndex; i--) + // // { + // // // + // // XOHCL iBar; + // // has = iBar.Init( + // // cState.symbol, + // // cState.period, + // // i // + // // ); + // // X121Conditions iConditions; + // // has = has && + // // cHelper.mX121Helper.GetConditions( + // // iConditions, + // // i // + // // ); + // // if (!has) + // // { + // // continue; + // // } + + // // // + // // // Bullish ... + + // // // + // // if (!hasNewValeUnderLast) + // // { + // // hasNewValeUnderLast = iConditions.isNewValeUnderLast; + // // } + + // // // + // // if (!isStrSwitchedToBullish) + // // { + // // isStrSwitchedToBullish = iConditions.isStrSwitchedToBullish; + // // } + + // // // + // // if (!isSarSwitchedToBullish) + // // { + // // isSarSwitchedToBullish = iConditions.isSarSwitchedToBullish; + // // } + + // // // + // // if (!hasValueGoldenZoneBreak) + // // { + // // // + // // hasValueGoldenZoneBreak = + // // iBar.IsBullish() && + // // iBar.GetUp() > iConditions.valesGoldenBuffer[1] && + // // iBar.GetDown() < iConditions.valesGoldenBuffer[1]; + // // } + + // // // + // // if (!isSMHKSwitchedToBullish) + // // { + // // isSMHKSwitchedToBullish = iConditions.isSMHKSwitchedToBullish; + // // } + + // // // + // // if (!isVWapSwitchedToBullishState) + // // { + // // isVWapSwitchedToBullishState = iConditions.isVWapSwitchedToBullishState; + // // } + + // // // + // // if (!isX3MaSwitchedToBullishState) + // // { + // // isX3MaSwitchedToBullishState = iConditions.isX3MaSwitchedToBullishState; + // // } + + // // // + // // if (!isVWapSwitchedToBullishOrdered) + // // { + // // isVWapSwitchedToBullishOrdered = iConditions.isVWapSwitchedToBullishOrdered; + // // } + + // // // + // // if (!isX3MaSwitchedToBullishOrdered) + // // { + // // isX3MaSwitchedToBullishOrdered = iConditions.isX3MaSwitchedToBullishOrdered; + // // } + + // // // + // // // Bearish ... + + // // // + // // if (!hasNewPeakOverLast) + // // { + // // hasNewPeakOverLast = iConditions.isNewPeakOverLast; + // // } + + // // // + // // if (!isStrSwitchedToBearish) + // // { + // // isStrSwitchedToBearish = iConditions.isStrSwitchedToBearish; + // // } + + // // // + // // if (!isSarSwitchedToBearish) + // // { + // // isSarSwitchedToBearish = iConditions.isSarSwitchedToBearish; + // // } + + // // // + // // if (!hasPeakGoldenZoneBreak) + // // { + // // // + // // hasPeakGoldenZoneBreak = + // // iBar.IsBearish() && + // // iBar.GetUp() > iConditions.peaksGoldenBuffer[1] && + // // iBar.GetDown() < iConditions.peaksGoldenBuffer[1]; + // // } + + // // // + // // if (!isSMHKSwitchedToBearish) + // // { + // // isSMHKSwitchedToBearish = iConditions.isSMHKSwitchedToBearish; + // // } + + // // // + // // if (!isVWapSwitchedToBearishState) + // // { + // // isVWapSwitchedToBearishState = iConditions.isVWapSwitchedToBearishState; + // // } + + // // // + // // if (!isX3MaSwitchedToBearishState) + // // { + // // isX3MaSwitchedToBearishState = iConditions.isX3MaSwitchedToBearishState; + // // } + + // // // + // // if (!isVWapSwitchedToBearishOrdered) + // // { + // // isVWapSwitchedToBearishOrdered = iConditions.isVWapSwitchedToBearishOrdered; + // // } + + // // // + // // if (!isX3MaSwitchedToBearishOrdered) + // // { + // // isX3MaSwitchedToBearishOrdered = iConditions.isX3MaSwitchedToBearishOrdered; + // // } + + // // // + // // iConditions.Clean(); + // // } + + // // // + // // // Bullish Conditions Summary ... + + // // // + // // bool hasBullishOrConditions = + // // hasNewValeUnderLast || + // // isStrSwitchedToBullish || + // // isSarSwitchedToBullish || + // // hasValueGoldenZoneBreak || + // // isSMHKSwitchedToBullish || + // // isVWapSwitchedToBullishState || + // // isX3MaSwitchedToBullishState || + // // isVWapSwitchedToBullishOrdered || + // // isX3MaSwitchedToBullishOrdered; + + // // // + // // bool hasBullishAndConditions = + // // hasNewValeUnderLast && + // // hasValueGoldenZoneBreak && + // // (isStrSwitchedToBullish || + // // isSarSwitchedToBullish || + // // isSMHKSwitchedToBullish || + // // isVWapSwitchedToBullishState || + // // isX3MaSwitchedToBullishState || + // // isVWapSwitchedToBullishOrdered || + // // isX3MaSwitchedToBullishOrdered); + + // // // + // // // Bearish Conditions Summary ... + + // // // + // // bool hasBearishOrConditions = + // // hasNewPeakOverLast || + // // isStrSwitchedToBearish || + // // isSarSwitchedToBearish || + // // hasPeakGoldenZoneBreak || + // // isSMHKSwitchedToBearish || + // // isVWapSwitchedToBearishState || + // // isX3MaSwitchedToBearishState || + // // isVWapSwitchedToBearishOrdered || + // // isX3MaSwitchedToBearishOrdered; + + // // // + // // bool hasBearishAndConditions = + // // hasNewPeakOverLast && + // // hasPeakGoldenZoneBreak && + // // (isStrSwitchedToBearish || + // // isSarSwitchedToBearish || + // // isSMHKSwitchedToBearish || + // // isVWapSwitchedToBearishState || + // // isX3MaSwitchedToBearishState || + // // isVWapSwitchedToBearishOrdered || + // // isX3MaSwitchedToBearishOrdered); + + // // + // bool isBullish = + // isBoxBullish + // // && + // // !hasBearishOrConditions && + // // hasBullishOrConditions + // ; + + // // + // bool isBearish = + // !isBoxBullish + // // && + // // !hasBullishOrConditions && + // // hasBearishOrConditions + // ; + + // // + // result = isBullish || + // isBearish; + + // // + // // if (result) + // // { + // // // + // // XCBoxObject *iBoxObj; + // // XCBoxObject *iInBoxObj; + + // // // + // // has = provider + // // .verificationCycleHelper + // // .mPOIDrawer + // // .DrawBox( + // // box, + // // iBoxObj // + // // ); + // // if (has) + // // { + // // // + // // iBoxObj.BoxWidth(2); + // // iBoxObj.BoxStyle(STYLE_SOLID); + // // } + + // // // + // // has = provider + // // .verificationCycleHelper + // // .mPOIDrawer + // // .DrawBox( + // // selectedBox, + // // iInBoxObj // + // // ); + // // if (has) + // // { + // // // + // // iInBoxObj.BoxWidth(2); + // // iInBoxObj.BoxStyle(STYLE_DASH); + // // } + + // // // + // // Print("Inside Selected Box ..."); + // // } + // } + + // + // Cleanup Resources ... + + // + cState.Clean(); + Clean(tmpBoxes); + selectedBox.Clean(); + ZeroMemory(cHelper); + cConditions.Clean(); + cXConditions.Clean(); + cStateEvents.Clean(); + + // + return result; +} + +///////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// diff --git a/Documents/BKP/Indicators/x-saherelm.x121.xstr.helper.mq5 b/Documents/BKP/Indicators/x-saherelm.x121.xstr.helper.mq5 new file mode 100644 index 00000000..bdfc79ed --- /dev/null +++ b/Documents/BKP/Indicators/x-saherelm.x121.xstr.helper.mq5 @@ -0,0 +1,1142 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCX121XSTRHelper +// 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 ... + +// +// Definitions ... +enum ENUM_X121_XSTR_BUFFERS +{ + // + X121_XSTR_LINE = 0, + X121_XSTR_UP_LINE = 2, + X121_XSTR_DOWN_LINE = 3, + X121_XSTR_ATR_LINE = 4, + X121_XSTR_PRICE_LINE = 5, + X121_XSTR_STATE_LINE = 6, +}; + +// +// Input Models ... +struct X121XSTRInputs +{ + // + // Props ... + + int strLength; // Length + double strMultiplier; // Multiplier + ENUM_APPLIED_PRICE strAppliedTo; // Applied To + + // + bool showStr; // Show Upper Zone + bool showStrUpper; // Show Str Upper + bool showStrLower; // Show Str Lower + + // + // Constructor(s) ... + X121XSTRInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + strLength = 0; + strMultiplier = 0.0; + strAppliedTo = PRICE_MEDIAN; + + // + showStr = false; + showStrUpper = false; + showStrLower = false; + + // + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + strLength = 14; + strMultiplier = 3.0; + strAppliedTo = PRICE_CLOSE; + + // + showStr = true; + showStrUpper = true; + showStrLower = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + strLength > 0 && + strMultiplier > 0 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(1, strLength); + + // + return result; + } +}; + +// +// Conditions ... +struct X121XSTRConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + double strBuffer[]; + double atrBuffer[]; + double strPriceBuffer[]; + double strUpBuffer[]; + double strDownBuffer[]; + double strStateBuffer[]; + + // + // Conditions ... + + // + bool isStrBullish; + bool isStrBearish; + + // + bool isStrSwitchedToBullish; + bool isStrSwitchedToBearish; + + // + // bool isCloseLower + + // + // Constructor ... + X121XSTRConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + symbol = NULL; + period = NULL; + time = NULL; + + // + // Buffers ... + + // + Clean(strBuffer); + Clean(atrBuffer); + Clean(strPriceBuffer); + Clean(strUpBuffer); + Clean(strDownBuffer); + Clean(strStateBuffer); + + // + ArraySetAsSeries(strBuffer, true); + ArraySetAsSeries(atrBuffer, true); + ArraySetAsSeries(strPriceBuffer, true); + ArraySetAsSeries(strUpBuffer, true); + ArraySetAsSeries(strDownBuffer, true); + ArraySetAsSeries(strStateBuffer, true); + + // + // Conditions ... + + // + isStrBullish = false; + isStrBearish = false; + + // + isStrSwitchedToBullish = false; + isStrSwitchedToBearish = false; + + // + ZeroMemory(this); + } + + /** + * Generate Conditions Scores ... + * + * @param bullishScore: Double, Directional Scores Reference ... + * @param bearishScore: Double, Directional Scores Reference ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + double score = 1; + double minScore = 0.5; + double highScore = 1.5; + + // + if (isStrBullish) + { + bullishScore += minScore; + } + if (isStrSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isStrBearish) + { + bearishScore += minScore; + } + if (isStrSwitchedToBearish) + { + bearishScore += score; + } + } + + /** + * Generate Summary String for Represent Conditions State ... + * + * @param onlyCommons: Boolean, Just Generate Only Commons Conditions ... + * @param onlyConditions: Boolean, Just Generate Only Conditions ... + * @param includeScores: Boolean, Attach Scores Representations on Result ... + * @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ... + * @param separator: String, Separate Lines ... + * + * @return ( string ) + */ + 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 = + // + "-----------------------" + separator + + "XSTR: " + separator + + "-----------------------" + separator + + ToString("isStrBullish", isStrBullish, ignoreFalseConditions, separator) + + ToString("isStrBearish", isStrBearish, ignoreFalseConditions, separator) + + ToString("isStrSwitchedToBullish", isStrSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isStrSwitchedToBearish", isStrSwitchedToBearish, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Retrieve nique Tag Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + return GetTypeName(this); + } + + // +}; + +// +// Class ... +class XCX121XSTRHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCX121XSTRHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121XSTRHelper() + { + // + mInputs.Clean(); + + // + Clean(strBuffer); + Clean(atrBuffer); + Clean(strPriceBuffer); + Clean(strUpBuffer); + Clean(strDownBuffer); + Clean(strStateBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121XSTRInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + ArraySetAsSeries(strBuffer, true); + ArraySetAsSeries(atrBuffer, true); + ArraySetAsSeries(strPriceBuffer, true); + ArraySetAsSeries(strUpBuffer, true); + ArraySetAsSeries(strDownBuffer, true); + ArraySetAsSeries(strStateBuffer, true); + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xstr", + // + // Inputs ... + // + // Market ... + "", + mInputs.strLength, + mInputs.strMultiplier, + mInputs.strAppliedTo, + // + // Presentation ... + "", + mInputs.showStr, + mInputs.showStrUpper, + mInputs.showStrLower + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X121XSTRInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121XSTRInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Readers ... + + // + // ATR ... + + // + double GetATR( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(atrBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return atrBuffer[barIndex]; + } + + // + int CopyATR( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + atrBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTR( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strBuffer[barIndex]; + } + + // + int CopySTR( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTRState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strStateBuffer[barIndex]; + } + + // + int CopySTRState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strStateBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTRPrice( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strPriceBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strPriceBuffer[barIndex]; + } + + // + int CopySTRPrice( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strPriceBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTRUp( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strUpBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strUpBuffer[barIndex]; + } + + // + int CopySTRUp( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strUpBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTRDown( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strDownBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strDownBuffer[barIndex]; + } + + // + int CopySTRDown( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strDownBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLastSTR( + ENUM_X_DIRECTION dir, + int barIndex = 0 // + ) + { + // + double result = 0; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (!HasDirection(dir)) + { + return result; + } + + // + int index = barIndex; + bool isBullish = IsBullish(dir); + + // + bool canContinue = true; + while (canContinue) + { + // + double iStr = GetSTR(index); + double iState = GetSTRState(index); + + // + canContinue = + isBullish + ? iState < 0 + : iState > 0; + if (!canContinue) + { + // + result = iStr; + break; + } + + // + index++; + } + + // + return result; + } + + // + void Free() override + { + Cleanup(10); + } + + // + bool GetConditions( + X121XSTRConditions &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; + + // + XOHCL zBar; + result = zBar.Init( + mSymbol, + mPeriod, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + mSymbol, + mPeriod, + pIndex // + ); + if (!result) + { + return result; + } + + // + // Buffers ... + + // + CopyATR( + zIndex, + loopback, + conditions.atrBuffer // + ); + + // + CopySTR( + zIndex, + loopback, + conditions.strBuffer // + ); + + // + CopySTRState( + zIndex, + loopback, + conditions.strStateBuffer // + ); + + // + CopySTRPrice( + zIndex, + loopback, + conditions.strPriceBuffer // + ); + + // + CopySTRUp( + zIndex, + loopback, + conditions.strUpBuffer // + ); + + // + CopySTRDown( + zIndex, + loopback, + conditions.strDownBuffer // + ); + + // + // Conditions ... + + // + int cIDX = 1; + int pIDX = cIDX + 1; + + // + bool isStrBullish = strStateBuffer[cIDX] > 0; + bool isStrBullishPrev = strStateBuffer[pIDX] > 0; + + // + bool isStrBearish = strStateBuffer[cIDX] < 0; + bool isStrBearishPrev = strStateBuffer[pIDX] < 0; + + // + bool isStrSwitchedToBullish = isStrBullish && + !isStrBullishPrev; + bool isStrSwitchedToBearish = isStrBearish && + !isStrBearishPrev; + + // + conditions.isStrBullish = isStrBullish; + conditions.isStrBearish = isStrBearish; + conditions.isStrSwitchedToBullish = isStrSwitchedToBullish; + conditions.isStrSwitchedToBearish = isStrSwitchedToBearish; + + // + Cleanup(); + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121XSTRInputs mInputs; // Inputs ... + + // + // Buffers ... + double strBuffer[]; + double atrBuffer[]; + double strPriceBuffer[]; + double strUpBuffer[]; + double strDownBuffer[]; + double strStateBuffer[]; + + // + void Calculate( + int barIndex = 0, + int maxRequiredBars = 100 // + ) + { + // + // Buffers ... + if (barIndex < 0) + { + barIndex = 0; + } + + // + // STR ... + CopyBuffer( + mHandler, + X121_XSTR_LINE, + barIndex, + maxRequiredBars, + strBuffer + // + ); + + // + // State ... + CopyBuffer( + mHandler, + X121_XSTR_STATE_LINE, + barIndex, + maxRequiredBars, + strStateBuffer + // + ); + + // + // Price ... + CopyBuffer( + mHandler, + X121_XSTR_PRICE_LINE, + barIndex, + maxRequiredBars, + strPriceBuffer + // + ); + + // + // Up ... + CopyBuffer( + mHandler, + X121_XSTR_UP_LINE, + barIndex, + maxRequiredBars, + strUpBuffer + // + ); + + // + // STR ... + CopyBuffer( + mHandler, + X121_XSTR_DOWN_LINE, + barIndex, + maxRequiredBars, + strDownBuffer + // + ); + + // + // ATR ... + + // + CopyBuffer( + mHandler, + X121_XSTR_ATR_LINE, + barIndex, + maxRequiredBars, + atrBuffer + // + ); + } + + // + void Cleanup( + int maxAllowed = 100 // + ) + { + // + CleanupArray( + strBuffer, + maxAllowed // + ); + + // + CleanupArray( + atrBuffer, + maxAllowed // + ); + + // + CleanupArray( + strPriceBuffer, + maxAllowed // + ); + + // + CleanupArray( + strUpBuffer, + maxAllowed // + ); + + // + CleanupArray( + strDownBuffer, + maxAllowed // + ); + + // + CleanupArray( + strStateBuffer, + maxAllowed // + ); + + // + } + + // +}; + +// +// Tools ... \ No newline at end of file diff --git a/Documents/BKP/Indicators/x-saherelm.x121.xstr.mq5 b/Documents/BKP/Indicators/x-saherelm.x121.xstr.mq5 new file mode 100644 index 00000000..bd69c202 --- /dev/null +++ b/Documents/BKP/Indicators/x-saherelm.x121.xstr.mq5 @@ -0,0 +1,637 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XSTR +// Description: XSTR ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121 XSTR Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 XSTR" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int strLength = 14; // Length +input double strMultiplier = 3; // Multiplier +input ENUM_APPLIED_PRICE strAppliedTo = PRICE_MEDIAN; // Applied To + +// +input group "Presentation"; + +// +input bool showStr = true; // Show Str +input bool showStrUpper = true; // Show Str Upper +input bool showStrLower = true; // Show Str Lower + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +#property indicator_chart_window + +// +#property indicator_buffers 7 +#property indicator_plots 3 + +// +// STR ... +#define strBufferIndex 0 +double strBuffer[]; + +#define strColorBufferIndex 1 +double strColorBuffer[]; + +// +#define strPlotBufferIndex 0 +#property indicator_label1 "X121 STR" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_style1 STYLE_SOLID +#property indicator_width1 2 + +// +// Up ... +#define strUpBufferIndex 2 +double strUpBuffer[]; + +// +#define strUpPlotBufferIndex 1 +#property indicator_label2 "X121 STR U" +#property indicator_type2 DRAW_LINE +#property indicator_color2 C'255,106,0' +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// Down ... +#define strDownBufferIndex 3 +double strDownBuffer[]; + +// +#define strDownPlotBufferIndex 2 +#property indicator_label3 "X121 STR D" +#property indicator_type3 DRAW_LINE +#property indicator_color3 C'255,106,0' +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +// Data Buffers ... + +// +int mLastBufferIndex = 3; + +// +// STR ... + +// +// Atr ... +#define atrBufferIndex mLastBufferIndex + 1 +double atrBuffer[]; + +// +// Price ... +#define strPriceBufferIndex mLastBufferIndex + 2 +double strPriceBuffer[]; + +// +// Trend ... +#define strStateBufferIndex mLastBufferIndex + 3 +double strStateBuffer[]; + +// +// Variables, Properties and etc ... + +// +// this counts Available Bars ... +int limit; + +// +int maxLength; + +// +// ATR Handler ... +int atrHandler = INVALID_HANDLE; + +// +bool isStrTrendChanged; +bool isStrStartBearishTrend; +bool isStrStartBullishTrend; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize Indicator Handlers ... + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + strLength // + ); + bool isInited = atrHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // 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; +} + +/** + * De Initialize Indicator ... + * + * @param reason: Integer, De Initialization Reason ... + */ +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 + + // + IndicatorRelease(atrHandler); +} + +/** + * Calculate Bars ... + * + * @param rates_total: Integer, Total Bars on Chart ... + * @param prev_calculated: Integer, Total Calculated Bars on Charts ... + * @param time: DateTime Array, History of Open Time ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param low: Double Array, History of Low Prices ... + * @param close: Double Array, History of Close Prices ... + * @param tick_volume: Long, History of Tick Volumes on Bar ... + * @param volume: Long, History of Trade Volumes ... + * @param spread: Double, History of Spread Price ... + * + * @return ( int ) + */ +int OnCalculate( + const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[] // +) +{ + // + // Prepare Buffers ... + + // + // Validate Calculated Bars ... + + // + // ATR ... + int atrCalculatedBars = BarsCalculated(atrHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // ATR ... + atrCalculatedBars >= 0 + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + // + // checking for the limit start of calculation of an indicator ... + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? maxLength + : prev_calculated - 1; + + // + // Buffers Copy ... + + // + // ATR ... + int copiedAtrs = CopyBuffer(atrHandler, 0, 0, rates_total, atrBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // ATR ... + copiedAtrs >= 0 + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = + // + // STR ... + strLength > 0 && + strMultiplier > 0 + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(1, strLength); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // STR ... + SetIndexBuffer(strBufferIndex, strBuffer, INDICATOR_DATA); + SetIndexBuffer(strColorBufferIndex, strColorBuffer, INDICATOR_COLOR_INDEX); + + // + ENUM_DRAW_TYPE strUpDrawType = showStrUpper ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strUpBufferIndex, strUpBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strUpPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_SHOW_DATA, showStrUpper); + PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_DRAW_TYPE, strUpDrawType); + + // + ENUM_DRAW_TYPE strDownDrawType = showStrLower ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strDownBufferIndex, strDownBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strDownPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_SHOW_DATA, showStrLower); + PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_DRAW_TYPE, strDownDrawType); + + // + // Data Buffers ... + + // + // STR ... + + // + SetIndexBuffer(strPriceBufferIndex, strPriceBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(strStateBufferIndex, strStateBuffer, INDICATOR_CALCULATIONS); +} + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Calculate Custom Buffers ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + * @param tickVolume: Long, History of Tick Volumes on Bar ... + */ +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + CalculateStr( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low // + ); +} + +// +// Custom ... + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + // STR ... + strBuffer[barIndex] = 0; + strUpBuffer[barIndex] = 0; + strDownBuffer[barIndex] = 0; + strPriceBuffer[barIndex] = 0; + strColorBuffer[barIndex] = hideColorIDX; + strStateBuffer[barIndex] = hideColorIDX; +} + +/** + * Calculate STR ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + */ +void CalculateStr( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[] // +) +{ + // + // Calculated Price ... + ENUM_X_PRICE mPTYpe = ToXPrice(strAppliedTo); + double price = GetAppliedPrice( + mPTYpe, + open, + high, + low, + close, + bar_index // + ); + strPriceBuffer[bar_index] = price; + + // + double atr = atrBuffer[bar_index]; + + // + // Up ... + strUpBuffer[bar_index] = price + (strMultiplier * atr); + + // + // Down ... + strDownBuffer[bar_index] = price - (strMultiplier * atr); + + // + if (close[bar_index] > strUpBuffer[bar_index - 1]) + { + // + strStateBuffer[bar_index] = 1; + if (strStateBuffer[bar_index - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[bar_index] < strDownBuffer[bar_index - 1]) + { + // + strStateBuffer[bar_index] = -1; + if (strStateBuffer[bar_index - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (strStateBuffer[bar_index - 1] == 1) + { + // + strStateBuffer[bar_index] = 1; + changeOfTrend = 0; + } + else if (strStateBuffer[bar_index - 1] == -1) + { + // + strStateBuffer[bar_index] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (strStateBuffer[bar_index] < 0 && strStateBuffer[bar_index - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (strStateBuffer[bar_index] > 0 && strStateBuffer[bar_index - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (strStateBuffer[bar_index] > 0 && strDownBuffer[bar_index] < strDownBuffer[bar_index - 1]) + { + strDownBuffer[bar_index] = strDownBuffer[bar_index - 1]; + } + + // + if (strStateBuffer[bar_index] < 0 && strUpBuffer[bar_index] > strUpBuffer[bar_index - 1]) + { + strUpBuffer[bar_index] = strUpBuffer[bar_index - 1]; + } + + // + if (startBearishTrend == 1) + { + strUpBuffer[bar_index] = strPriceBuffer[bar_index] + (strMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + strDownBuffer[bar_index] = strPriceBuffer[bar_index] - (strMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = hideColorIDX; + strColorBuffer[bar_index] = colorIDX; + + // + if (strStateBuffer[bar_index] == 1) + { + // + strBuffer[bar_index] = strDownBuffer[bar_index]; + if (changeOfTrend == 1) + { + strBuffer[bar_index - 1] = strBuffer[bar_index - 2]; + changeOfTrend = 0; + } + + // + colorIDX = bullishColorIDX; + } + else if (strStateBuffer[bar_index] == -1) + { + // + strBuffer[bar_index] = strUpBuffer[bar_index]; + if (changeOfTrend == 1) + { + // + strBuffer[bar_index - 1] = strBuffer[bar_index - 2]; + changeOfTrend = 0; + } + + // + colorIDX = bearishColorIDX; + } + + // + if (showStr) + { + strColorBuffer[bar_index] = colorIDX; + } +} + +// \ No newline at end of file diff --git a/Documents/BKP/Indicators/x-saherelm.x121.xstr.v2.mq5 b/Documents/BKP/Indicators/x-saherelm.x121.xstr.v2.mq5 new file mode 100644 index 00000000..915dd23b --- /dev/null +++ b/Documents/BKP/Indicators/x-saherelm.x121.xstr.v2.mq5 @@ -0,0 +1,793 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XSTR +// Description: XSTR ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121 XSTR Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 XSTR" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int strLength = 14; // Length +input double strMultiplier = 3; // Multiplier +input ENUM_MA_METHOD strBoundaryMode = MODE_SMA; // Boundary Mode +input ENUM_APPLIED_PRICE strAppliedTo = PRICE_MEDIAN; // Applied To + +// +input group "Presentation"; +input bool showStr = true; // Show Str +input bool showStrMid = true; // Show Str Mid +input bool showStrUpper = true; // Show Str Upper +input bool showStrLower = true; // Show Str Lower +input bool showStrLowMa = true; // Show Low Smoothed Buffer +input bool showStrHighMa = true; // Show High Smoothed Buffer + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +#define emptyValue 0.0 + +// +#property indicator_chart_window + +// +#property indicator_buffers 11 +#property indicator_plots 6 + +// +// STR ... +#define strBufferIndex 0 +double strBuffer[]; + +#define strColorBufferIndex 1 +double strColorBuffer[]; + +// +#define strPlotBufferIndex 0 +#property indicator_label1 "X121 STR" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_style1 STYLE_SOLID +#property indicator_width1 2 + +// +// Up ... +#define strUpBufferIndex 2 +double strUpBuffer[]; + +// +#define strUpPlotBufferIndex 1 +#property indicator_label2 "X121 STR U" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrBlueViolet +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// Down ... +#define strDownBufferIndex 3 +double strDownBuffer[]; + +// +#define strDownPlotBufferIndex 2 +#property indicator_label3 "X121 STR D" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrBlueViolet +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +// High MA ... +#define strHighMaBufferIndex 4 +double strHighMaBuffer[]; + +// +#define strHighMaPlotBufferIndex 3 +#property indicator_label4 "X121 STR HSM" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrAqua +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +// Low Ma ... +#define strLowMaBufferIndex 5 +double strLowMaBuffer[]; + +// +#define strLowMaPlotBufferIndex 4 +#property indicator_label5 "X121 STR LSM" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrMagenta +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +// STR Mmid ... +#define strMidBufferIndex 6 +double strMidBuffer[]; + +#define strMidColorBufferIndex 7 +double strMidColorBuffer[]; + +// +#define strMidPlotBufferIndex 5 +#property indicator_label6 "X121 STR Mid" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// Data Buffers ... + +// +int mLastBufferIndex = 7; + +// +// STR ... + +// +// Atr ... +#define atrBufferIndex mLastBufferIndex + 1 +double atrBuffer[]; + +// +// Price ... +#define strPriceBufferIndex mLastBufferIndex + 2 +double strPriceBuffer[]; + +// +// Trend ... +#define strStateBufferIndex mLastBufferIndex + 3 +double strStateBuffer[]; + +// +// Variables, Properties and etc ... + +// +// this counts Available Bars ... +int limit; + +// +int maxLength; + +// +// ATR Handler ... +int atrHandler = INVALID_HANDLE; + +// +// MA Handler ... +int lowMaHandler = INVALID_HANDLE; +int highMaHandler = INVALID_HANDLE; + +// +bool isStrTrendChanged; +bool isStrStartBearishTrend; +bool isStrStartBullishTrend; + +// +int changeOfTrend; +int startBearishTrend; +int startBullishTrend; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize Indicator Handlers ... + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + strLength // + ); + bool isInited = atrHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // Low Ma ... + lowMaHandler = iMA( + _Symbol, + _Period, + strLength, + 0, + strBoundaryMode, + PRICE_LOW // + ); + isInited = lowMaHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // High Ma ... + highMaHandler = iMA( + _Symbol, + _Period, + strLength, + 0, + strBoundaryMode, + PRICE_HIGH // + ); + isInited = highMaHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // 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; +} + +/** + * De Initialize Indicator ... + * + * @param reason: Integer, De Initialization Reason ... + */ +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 + + // + IndicatorRelease(atrHandler); + IndicatorRelease(lowMaHandler); + IndicatorRelease(highMaHandler); +} + +/** + * Calculate Bars ... + * + * @param rates_total: Integer, Total Bars on Chart ... + * @param prev_calculated: Integer, Total Calculated Bars on Charts ... + * @param time: DateTime Array, History of Open Time ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param low: Double Array, History of Low Prices ... + * @param close: Double Array, History of Close Prices ... + * @param tick_volume: Long, History of Tick Volumes on Bar ... + * @param volume: Long, History of Trade Volumes ... + * @param spread: Double, History of Spread Price ... + * + * @return ( int ) + */ +int OnCalculate( + const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[] // +) +{ + // + // Prepare Buffers ... + + // + // Validate Calculated Bars ... + + // + // ATR ... + int atrCalculatedBars = BarsCalculated(atrHandler); + + // + // Low Ma ... + int lowMaCalculatedBars = BarsCalculated(lowMaHandler); + + // + // High Ma ... + int highMaCalculatedBars = BarsCalculated(highMaHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // ATR ... + atrCalculatedBars >= 0 && + // + // Low Ma ... + lowMaCalculatedBars >= 0 && + // + // High Ma ... + highMaCalculatedBars >= 0 + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + // + // checking for the limit start of calculation of an indicator ... + limit = + (prev_calculated > rates_total || prev_calculated <= 0) + ? maxLength + : prev_calculated - 1; + + // + // Buffers Copy ... + + // + // ATR ... + int copiedAtrs = CopyBuffer(atrHandler, 0, 0, rates_total, atrBuffer); + + // + // Low Ma ... + int copiedLowMas = CopyBuffer(lowMaHandler, 0, 0, rates_total, strLowMaBuffer); + + // + // High Ma ... + int copiedHighMas = CopyBuffer(highMaHandler, 0, 0, rates_total, strHighMaBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // ATR ... + copiedAtrs >= 0 && + // + // Low Ma ... + copiedLowMas >= 0 && + // + // Hig Ma ... + copiedHighMas >= 0 + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = + // + // STR ... + strLength > 0 && + strMultiplier > 0 + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(1, strLength); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // STR ... + SetIndexBuffer(strBufferIndex, strBuffer, INDICATOR_DATA); + SetIndexBuffer(strColorBufferIndex, strColorBuffer, INDICATOR_COLOR_INDEX); + + // + ENUM_DRAW_TYPE strUpDrawType = showStrUpper ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strUpBufferIndex, strUpBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strUpPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_SHOW_DATA, showStrUpper); + PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_DRAW_TYPE, strUpDrawType); + + // + ENUM_DRAW_TYPE strDownDrawType = showStrLower ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strDownBufferIndex, strDownBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strDownPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_SHOW_DATA, showStrLower); + PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_DRAW_TYPE, strDownDrawType); + + // + ENUM_DRAW_TYPE strLowMaDrawType = showStrLowMa ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strLowMaBufferIndex, strLowMaBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strLowMaPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strLowMaPlotBufferIndex, PLOT_SHOW_DATA, showStrLowMa); + PlotIndexSetInteger(strLowMaPlotBufferIndex, PLOT_DRAW_TYPE, strLowMaDrawType); + + // + ENUM_DRAW_TYPE strHighMaDrawType = showStrHighMa ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strHighMaBufferIndex, strHighMaBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strHighMaPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strHighMaPlotBufferIndex, PLOT_SHOW_DATA, showStrHighMa); + PlotIndexSetInteger(strHighMaPlotBufferIndex, PLOT_DRAW_TYPE, strHighMaDrawType); + + // + ENUM_DRAW_TYPE strMidDrawType = showStrMid ? DRAW_COLOR_LINE : DRAW_NONE; + SetIndexBuffer(strMidBufferIndex, strMidBuffer, INDICATOR_DATA); + SetIndexBuffer(strMidColorBufferIndex, strMidColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetDouble(strMidPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strMidPlotBufferIndex, PLOT_SHOW_DATA, showStrMid); + PlotIndexSetInteger(strMidPlotBufferIndex, PLOT_DRAW_TYPE, strMidDrawType); + + // + // Data Buffers ... + + // + SetIndexBuffer(strPriceBufferIndex, strPriceBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(strStateBufferIndex, strStateBuffer, INDICATOR_CALCULATIONS); +} + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Calculate Custom Buffers ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + * @param tickVolume: Long, History of Tick Volumes on Bar ... + */ +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + CalculateStr( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low // + ); +} + +// +// Custom ... + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + // STR ... + strBuffer[barIndex] = emptyValue; + strUpBuffer[barIndex] = emptyValue; + strMidBuffer[barIndex] = emptyValue; + strMidBuffer[barIndex] = emptyValue; + strDownBuffer[barIndex] = emptyValue; + strPriceBuffer[barIndex] = emptyValue; + strLowMaBuffer[barIndex] = emptyValue; + strHighMaBuffer[barIndex] = emptyValue; + + // + strColorBuffer[barIndex] = hideColorIDX; + strStateBuffer[barIndex] = hideColorIDX; +} + +/** + * Calculate STR ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + */ +void CalculateStr( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[] // +) +{ + // + // Calculated Price ... + ENUM_X_PRICE mPType = ToXPrice(strAppliedTo); + double price = GetAppliedPrice( + mPType, + open, + high, + low, + close, + bar_index // + ); + strPriceBuffer[bar_index] = price; + + // + double atr = atrBuffer[bar_index]; + + // + // Up ... + strUpBuffer[bar_index] = price + (strMultiplier * atr); + + // + // Down ... + strDownBuffer[bar_index] = price - (strMultiplier * atr); + + // + if (close[bar_index] > strUpBuffer[bar_index - 1]) + { + // + strStateBuffer[bar_index] = 1; + if (strStateBuffer[bar_index - 1] == -1) + { + changeOfTrend = 1; + } + } + else if (close[bar_index] < strDownBuffer[bar_index - 1]) + { + // + strStateBuffer[bar_index] = -1; + if (strStateBuffer[bar_index - 1] == 1) + { + changeOfTrend = 1; + } + } + else if (strStateBuffer[bar_index - 1] == 1) + { + // + strStateBuffer[bar_index] = 1; + changeOfTrend = 0; + } + else if (strStateBuffer[bar_index - 1] == -1) + { + // + strStateBuffer[bar_index] = -1; + changeOfTrend = 0; + } + + // + // Down Trend Starting ... + if (strStateBuffer[bar_index] < 0 && strStateBuffer[bar_index - 1] > 0) + { + startBearishTrend = 1; + } + else + { + startBearishTrend = 0; + } + + // + // Up Trend Starting ... + if (strStateBuffer[bar_index] > 0 && strStateBuffer[bar_index - 1] < 0) + { + startBullishTrend = 1; + } + else + { + startBullishTrend = 0; + } + + // + if (strStateBuffer[bar_index] > 0 && strDownBuffer[bar_index] < strDownBuffer[bar_index - 1]) + { + strDownBuffer[bar_index] = strDownBuffer[bar_index - 1]; + } + + // + if (strStateBuffer[bar_index] < 0 && strUpBuffer[bar_index] > strUpBuffer[bar_index - 1]) + { + strUpBuffer[bar_index] = strUpBuffer[bar_index - 1]; + } + + // + if (startBearishTrend == 1) + { + strUpBuffer[bar_index] = strPriceBuffer[bar_index] + (strMultiplier * atr); + } + + // + if (startBullishTrend == 1) + { + strDownBuffer[bar_index] = strPriceBuffer[bar_index] - (strMultiplier * atr); + } + + // + // Draw the indicator ... + + // + double colorIDX = hideColorIDX; + strColorBuffer[bar_index] = colorIDX; + + // + if (strStateBuffer[bar_index] == 1) + { + // + strBuffer[bar_index] = strDownBuffer[bar_index]; + if (changeOfTrend == 1) + { + strBuffer[bar_index - 1] = strBuffer[bar_index - 2]; + changeOfTrend = 0; + } + + // + colorIDX = bullishColorIDX; + } + else if (strStateBuffer[bar_index] == -1) + { + // + strBuffer[bar_index] = strUpBuffer[bar_index]; + if (changeOfTrend == 1) + { + // + strBuffer[bar_index - 1] = strBuffer[bar_index - 2]; + changeOfTrend = 0; + } + + // + colorIDX = bearishColorIDX; + } + + // + if (showStr) + { + strColorBuffer[bar_index] = colorIDX; + } + + // + // Str Mid ... + + // + double iStrMid = strDownBuffer[bar_index] + ((strUpBuffer[bar_index] - strDownBuffer[bar_index]) / 2); + strMidBuffer[bar_index] = iStrMid; + + // + double iStrColor = close[bar_index] > strMidBuffer[bar_index] + ? bullishColorIDX + : close[bar_index] < strMidBuffer[bar_index] + ? bearishColorIDX + : neuturalColorIDX; + strMidColorBuffer[bar_index] = iStrColor; + + // +} + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index bc77fb69..cd87eb7c 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -172,7 +172,7 @@ struct X121Conditions string symbol; ENUM_TIMEFRAMES period; datetime time; - + // // XCC ... @@ -356,9 +356,13 @@ struct X121Conditions // double strBuffer[]; double strUpBuffer[]; + double strMidBuffer[]; double strDownBuffer[]; double strPriceBuffer[]; double strStateBuffer[]; + double strSMLowBuffer[]; + double strSMHighBuffer[]; + double strMidStateBuffer[]; // // Conditions ... @@ -774,9 +778,13 @@ struct X121Conditions // Clean(strBuffer); Clean(strUpBuffer); + Clean(strMidBuffer); Clean(strDownBuffer); Clean(strPriceBuffer); Clean(strStateBuffer); + Clean(strSMLowBuffer); + Clean(strSMHighBuffer); + Clean(strMidStateBuffer); // // Set As Series ... @@ -784,9 +792,13 @@ struct X121Conditions // ArraySetAsSeries(strBuffer, true); ArraySetAsSeries(strUpBuffer, true); + ArraySetAsSeries(strMidBuffer, true); ArraySetAsSeries(strDownBuffer, true); ArraySetAsSeries(strPriceBuffer, true); ArraySetAsSeries(strStateBuffer, true); + ArraySetAsSeries(strSMLowBuffer, true); + ArraySetAsSeries(strSMHighBuffer, true); + ArraySetAsSeries(strMidStateBuffer, true); // // Conditions ... @@ -2771,6 +2783,12 @@ class XCX121Helper : public XCBase conditions.strBuffer // ); + // + Copy( + xstrConditions.strMidBuffer, + conditions.strMidBuffer // + ); + // Copy( xstrConditions.strUpBuffer, @@ -2795,6 +2813,24 @@ class XCX121Helper : public XCBase conditions.strStateBuffer // ); + // + Copy( + xstrConditions.strSMLowBuffer, + conditions.strSMLowBuffer // + ); + + // + Copy( + xstrConditions.strSMHighBuffer, + conditions.strSMHighBuffer // + ); + + // + Copy( + xstrConditions.strMidStateBuffer, + conditions.strMidStateBuffer // + ); + // // Conditions ... diff --git a/Helpers/x-saherelm.x121.xstr.helper.mq5 b/Helpers/x-saherelm.x121.xstr.helper.mq5 index bdfc79ed..cf5298d5 100644 --- a/Helpers/x-saherelm.x121.xstr.helper.mq5 +++ b/Helpers/x-saherelm.x121.xstr.helper.mq5 @@ -35,9 +35,13 @@ enum ENUM_X121_XSTR_BUFFERS X121_XSTR_LINE = 0, X121_XSTR_UP_LINE = 2, X121_XSTR_DOWN_LINE = 3, - X121_XSTR_ATR_LINE = 4, - X121_XSTR_PRICE_LINE = 5, - X121_XSTR_STATE_LINE = 6, + X121_XSTR_HSM_LINE = 4, + X121_XSTR_LSM_LINE = 5, + X121_XSTR_MID_LINE = 6, + X121_XSTR_MID_STATE_LINE = 7, + X121_XSTR_ATR_LINE = 8, + X121_XSTR_PRICE_LINE = 9, + X121_XSTR_STATE_LINE = 10, }; // @@ -49,12 +53,16 @@ struct X121XSTRInputs int strLength; // Length double strMultiplier; // Multiplier + ENUM_MA_METHOD strBoundaryMode; // Boundary Mode ENUM_APPLIED_PRICE strAppliedTo; // Applied To // - bool showStr; // Show Upper Zone - bool showStrUpper; // Show Str Upper - bool showStrLower; // Show Str Lower + bool showStr; // Show Str + bool showStrMid; // Show Str Mid + bool showStrUpper; // Show Str Upper + bool showStrLower; // Show Str Lower + bool showStrSMLow; // Show Str SM Low + bool showStrSMHigh; // Show Str SM High // // Constructor(s) ... @@ -74,12 +82,16 @@ struct X121XSTRInputs // strLength = 0; strMultiplier = 0.0; + strBoundaryMode = MODE_SMA; strAppliedTo = PRICE_MEDIAN; // showStr = false; + showStrMid = false; showStrUpper = false; showStrLower = false; + showStrSMLow = false; + showStrSMHigh = false; // ZeroMemory(this); @@ -92,12 +104,16 @@ struct X121XSTRInputs // strLength = 14; strMultiplier = 3.0; + strBoundaryMode = MODE_SMA; strAppliedTo = PRICE_CLOSE; // showStr = true; + showStrMid = true; showStrUpper = true; showStrLower = true; + showStrSMLow = true; + showStrSMHigh = true; } // @@ -148,10 +164,14 @@ struct X121XSTRConditions // Buffers ... double strBuffer[]; double atrBuffer[]; - double strPriceBuffer[]; double strUpBuffer[]; + double strMidBuffer[]; double strDownBuffer[]; + double strPriceBuffer[]; double strStateBuffer[]; + double strSMLowBuffer[]; + double strSMHighBuffer[]; + double strMidStateBuffer[]; // // Conditions ... @@ -194,18 +214,26 @@ struct X121XSTRConditions // Clean(strBuffer); Clean(atrBuffer); - Clean(strPriceBuffer); Clean(strUpBuffer); + Clean(strMidBuffer); Clean(strDownBuffer); + Clean(strPriceBuffer); Clean(strStateBuffer); + Clean(strSMLowBuffer); + Clean(strSMHighBuffer); + Clean(strMidStateBuffer); // ArraySetAsSeries(strBuffer, true); ArraySetAsSeries(atrBuffer, true); - ArraySetAsSeries(strPriceBuffer, true); ArraySetAsSeries(strUpBuffer, true); + ArraySetAsSeries(strMidBuffer, true); ArraySetAsSeries(strDownBuffer, true); + ArraySetAsSeries(strPriceBuffer, true); ArraySetAsSeries(strStateBuffer, true); + ArraySetAsSeries(strSMLowBuffer, true); + ArraySetAsSeries(strSMHighBuffer, true); + ArraySetAsSeries(strMidStateBuffer, true); // // Conditions ... @@ -419,10 +447,14 @@ class XCX121XSTRHelper : public XCBaseHelper // ArraySetAsSeries(strBuffer, true); ArraySetAsSeries(atrBuffer, true); - ArraySetAsSeries(strPriceBuffer, true); ArraySetAsSeries(strUpBuffer, true); + ArraySetAsSeries(strMidBuffer, true); ArraySetAsSeries(strDownBuffer, true); + ArraySetAsSeries(strPriceBuffer, true); ArraySetAsSeries(strStateBuffer, true); + ArraySetAsSeries(strSMLowBuffer, true); + ArraySetAsSeries(strSMHighBuffer, true); + ArraySetAsSeries(strMidStateBuffer, true); // mInputs = inputs; @@ -439,13 +471,17 @@ class XCX121XSTRHelper : public XCBaseHelper "", mInputs.strLength, mInputs.strMultiplier, + mInputs.strBoundaryMode, mInputs.strAppliedTo, // // Presentation ... "", mInputs.showStr, + mInputs.showStrMid, mInputs.showStrUpper, - mInputs.showStrLower + mInputs.showStrLower, + mInputs.showStrSMLow, + mInputs.showStrSMHigh // ); result = mHandler != INVALID_HANDLE; @@ -634,6 +670,104 @@ class XCX121XSTRHelper : public XCBaseHelper ); } + // + double GetSTRMid( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strMidBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strMidBuffer[barIndex]; + } + + // + int CopySTRMid( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strMidBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTRMidState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strMidStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strMidStateBuffer[barIndex]; + } + + // + int CopySTRMidState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strMidStateBuffer, + buffer, + forceClean + // + ); + } + // double GetSTRPrice( int barIndex // Bar Index @@ -781,6 +915,104 @@ class XCX121XSTRHelper : public XCBaseHelper ); } + // + double GetSTRSMLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strSMLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strSMLowBuffer[barIndex]; + } + + // + int CopySTRSMLow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strSMLowBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSTRSMHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(strSMHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return strSMHighBuffer[barIndex]; + } + + // + int CopySTRSMHigh( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + strSMHighBuffer, + buffer, + forceClean + // + ); + } + // double GetLastSTR( ENUM_X_DIRECTION dir, @@ -930,6 +1162,20 @@ class XCX121XSTRHelper : public XCBaseHelper conditions.strStateBuffer // ); + // + CopySTRMid( + zIndex, + loopback, + conditions.strMidBuffer // + ); + + // + CopySTRMidState( + zIndex, + loopback, + conditions.strMidStateBuffer // + ); + // CopySTRPrice( zIndex, @@ -951,6 +1197,20 @@ class XCX121XSTRHelper : public XCBaseHelper conditions.strDownBuffer // ); + // + CopySTRSMLow( + zIndex, + loopback, + conditions.strSMLowBuffer // + ); + + // + CopySTRSMHigh( + zIndex, + loopback, + conditions.strSMHighBuffer // + ); + // // Conditions ... @@ -1004,10 +1264,14 @@ class XCX121XSTRHelper : public XCBaseHelper // Buffers ... double strBuffer[]; double atrBuffer[]; - double strPriceBuffer[]; double strUpBuffer[]; + double strMidBuffer[]; double strDownBuffer[]; + double strPriceBuffer[]; double strStateBuffer[]; + double strSMLowBuffer[]; + double strSMHighBuffer[]; + double strMidStateBuffer[]; // void Calculate( @@ -1044,6 +1308,26 @@ class XCX121XSTRHelper : public XCBaseHelper // ); + // + CopyBuffer( + mHandler, + X121_XSTR_MID_LINE, + barIndex, + maxRequiredBars, + strMidBuffer + // + ); + + // + CopyBuffer( + mHandler, + X121_XSTR_MID_STATE_LINE, + barIndex, + maxRequiredBars, + strMidStateBuffer + // + ); + // // Price ... CopyBuffer( @@ -1077,6 +1361,26 @@ class XCX121XSTRHelper : public XCBaseHelper // ); + // + CopyBuffer( + mHandler, + X121_XSTR_LSM_LINE, + barIndex, + maxRequiredBars, + strSMLowBuffer + // + ); + + // + CopyBuffer( + mHandler, + X121_XSTR_HSM_LINE, + barIndex, + maxRequiredBars, + strSMHighBuffer + // + ); + // // ATR ... @@ -1110,13 +1414,13 @@ class XCX121XSTRHelper : public XCBaseHelper // CleanupArray( - strPriceBuffer, + strUpBuffer, maxAllowed // ); // CleanupArray( - strUpBuffer, + strMidBuffer, maxAllowed // ); @@ -1126,6 +1430,12 @@ class XCX121XSTRHelper : public XCBaseHelper maxAllowed // ); + // + CleanupArray( + strPriceBuffer, + maxAllowed // + ); + // CleanupArray( strStateBuffer, @@ -1133,6 +1443,22 @@ class XCX121XSTRHelper : public XCBaseHelper ); // + CleanupArray( + strSMLowBuffer, + maxAllowed // + ); + + // + CleanupArray( + strSMHighBuffer, + maxAllowed // + ); + + // + CleanupArray( + strMidStateBuffer, + maxAllowed // + ); } // diff --git a/Indicators/x-saherelm.x121.xstr.mq5 b/Indicators/x-saherelm.x121.xstr.mq5 index bd69c202..915dd23b 100644 --- a/Indicators/x-saherelm.x121.xstr.mq5 +++ b/Indicators/x-saherelm.x121.xstr.mq5 @@ -37,15 +37,17 @@ input group "Market"; input int strLength = 14; // Length input double strMultiplier = 3; // Multiplier +input ENUM_MA_METHOD strBoundaryMode = MODE_SMA; // Boundary Mode input ENUM_APPLIED_PRICE strAppliedTo = PRICE_MEDIAN; // Applied To // input group "Presentation"; - -// -input bool showStr = true; // Show Str -input bool showStrUpper = true; // Show Str Upper -input bool showStrLower = true; // Show Str Lower +input bool showStr = true; // Show Str +input bool showStrMid = true; // Show Str Mid +input bool showStrUpper = true; // Show Str Upper +input bool showStrLower = true; // Show Str Lower +input bool showStrLowMa = true; // Show Low Smoothed Buffer +input bool showStrHighMa = true; // Show High Smoothed Buffer // // Buffers ... @@ -56,12 +58,15 @@ input bool showStrLower = true; // Show Str Lower #define bearishColorIDX 2 #define neuturalColorIDX 3 +// +#define emptyValue 0.0 + // #property indicator_chart_window // -#property indicator_buffers 7 -#property indicator_plots 3 +#property indicator_buffers 11 +#property indicator_plots 6 // // STR ... @@ -88,7 +93,7 @@ double strUpBuffer[]; #define strUpPlotBufferIndex 1 #property indicator_label2 "X121 STR U" #property indicator_type2 DRAW_LINE -#property indicator_color2 C'255,106,0' +#property indicator_color2 clrBlueViolet #property indicator_style2 STYLE_SOLID #property indicator_width2 1 @@ -101,15 +106,57 @@ double strDownBuffer[]; #define strDownPlotBufferIndex 2 #property indicator_label3 "X121 STR D" #property indicator_type3 DRAW_LINE -#property indicator_color3 C'255,106,0' +#property indicator_color3 clrBlueViolet #property indicator_style3 STYLE_SOLID #property indicator_width3 1 +// +// High MA ... +#define strHighMaBufferIndex 4 +double strHighMaBuffer[]; + +// +#define strHighMaPlotBufferIndex 3 +#property indicator_label4 "X121 STR HSM" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrAqua +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +// Low Ma ... +#define strLowMaBufferIndex 5 +double strLowMaBuffer[]; + +// +#define strLowMaPlotBufferIndex 4 +#property indicator_label5 "X121 STR LSM" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrMagenta +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +// STR Mmid ... +#define strMidBufferIndex 6 +double strMidBuffer[]; + +#define strMidColorBufferIndex 7 +double strMidColorBuffer[]; + +// +#define strMidPlotBufferIndex 5 +#property indicator_label6 "X121 STR Mid" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + // // Data Buffers ... // -int mLastBufferIndex = 3; +int mLastBufferIndex = 7; // // STR ... @@ -143,6 +190,11 @@ int maxLength; // ATR Handler ... int atrHandler = INVALID_HANDLE; +// +// MA Handler ... +int lowMaHandler = INVALID_HANDLE; +int highMaHandler = INVALID_HANDLE; + // bool isStrTrendChanged; bool isStrStartBearishTrend; @@ -186,6 +238,38 @@ int OnInit() return INIT_FAILED; } + // + // Low Ma ... + lowMaHandler = iMA( + _Symbol, + _Period, + strLength, + 0, + strBoundaryMode, + PRICE_LOW // + ); + isInited = lowMaHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // High Ma ... + highMaHandler = iMA( + _Symbol, + _Period, + strLength, + 0, + strBoundaryMode, + PRICE_HIGH // + ); + isInited = highMaHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + // // because in some cases we may have more than one input for // calculation and we must prevent any calculation @@ -227,6 +311,8 @@ void OnDeinit(const int reason) // IndicatorRelease(atrHandler); + IndicatorRelease(lowMaHandler); + IndicatorRelease(highMaHandler); } /** @@ -268,11 +354,25 @@ int OnCalculate( // ATR ... int atrCalculatedBars = BarsCalculated(atrHandler); + // + // Low Ma ... + int lowMaCalculatedBars = BarsCalculated(lowMaHandler); + + // + // High Ma ... + int highMaCalculatedBars = BarsCalculated(highMaHandler); + // bool isPassedRequiredCalculatedBars = // // ATR ... - atrCalculatedBars >= 0 + atrCalculatedBars >= 0 && + // + // Low Ma ... + lowMaCalculatedBars >= 0 && + // + // High Ma ... + highMaCalculatedBars >= 0 // ; if (!isPassedRequiredCalculatedBars) @@ -295,12 +395,26 @@ int OnCalculate( // ATR ... int copiedAtrs = CopyBuffer(atrHandler, 0, 0, rates_total, atrBuffer); + // + // Low Ma ... + int copiedLowMas = CopyBuffer(lowMaHandler, 0, 0, rates_total, strLowMaBuffer); + + // + // High Ma ... + int copiedHighMas = CopyBuffer(highMaHandler, 0, 0, rates_total, strHighMaBuffer); + // // Validate Copied Items ... bool isPassedRequiredCopiedItems = // // ATR ... - copiedAtrs >= 0 + copiedAtrs >= 0 && + // + // Low Ma ... + copiedLowMas >= 0 && + // + // Hig Ma ... + copiedHighMas >= 0 // ; if (!isPassedRequiredCopiedItems) @@ -383,22 +497,41 @@ void DefineBuffers() // ENUM_DRAW_TYPE strUpDrawType = showStrUpper ? DRAW_LINE : DRAW_NONE; SetIndexBuffer(strUpBufferIndex, strUpBuffer, INDICATOR_DATA); - PlotIndexSetDouble(strUpPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetDouble(strUpPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_SHOW_DATA, showStrUpper); PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_DRAW_TYPE, strUpDrawType); // ENUM_DRAW_TYPE strDownDrawType = showStrLower ? DRAW_LINE : DRAW_NONE; SetIndexBuffer(strDownBufferIndex, strDownBuffer, INDICATOR_DATA); - PlotIndexSetDouble(strDownPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); + PlotIndexSetDouble(strDownPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_SHOW_DATA, showStrLower); PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_DRAW_TYPE, strDownDrawType); // - // Data Buffers ... + ENUM_DRAW_TYPE strLowMaDrawType = showStrLowMa ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strLowMaBufferIndex, strLowMaBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strLowMaPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strLowMaPlotBufferIndex, PLOT_SHOW_DATA, showStrLowMa); + PlotIndexSetInteger(strLowMaPlotBufferIndex, PLOT_DRAW_TYPE, strLowMaDrawType); // - // STR ... + ENUM_DRAW_TYPE strHighMaDrawType = showStrHighMa ? DRAW_LINE : DRAW_NONE; + SetIndexBuffer(strHighMaBufferIndex, strHighMaBuffer, INDICATOR_DATA); + PlotIndexSetDouble(strHighMaPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strHighMaPlotBufferIndex, PLOT_SHOW_DATA, showStrHighMa); + PlotIndexSetInteger(strHighMaPlotBufferIndex, PLOT_DRAW_TYPE, strHighMaDrawType); + + // + ENUM_DRAW_TYPE strMidDrawType = showStrMid ? DRAW_COLOR_LINE : DRAW_NONE; + SetIndexBuffer(strMidBufferIndex, strMidBuffer, INDICATOR_DATA); + SetIndexBuffer(strMidColorBufferIndex, strMidColorBuffer, INDICATOR_COLOR_INDEX); + PlotIndexSetDouble(strMidPlotBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(strMidPlotBufferIndex, PLOT_SHOW_DATA, showStrMid); + PlotIndexSetInteger(strMidPlotBufferIndex, PLOT_DRAW_TYPE, strMidDrawType); + + // + // Data Buffers ... // SetIndexBuffer(strPriceBufferIndex, strPriceBuffer, INDICATOR_CALCULATIONS); @@ -460,10 +593,16 @@ void FillBuffersZero(int barIndex) { // // STR ... - strBuffer[barIndex] = 0; - strUpBuffer[barIndex] = 0; - strDownBuffer[barIndex] = 0; - strPriceBuffer[barIndex] = 0; + strBuffer[barIndex] = emptyValue; + strUpBuffer[barIndex] = emptyValue; + strMidBuffer[barIndex] = emptyValue; + strMidBuffer[barIndex] = emptyValue; + strDownBuffer[barIndex] = emptyValue; + strPriceBuffer[barIndex] = emptyValue; + strLowMaBuffer[barIndex] = emptyValue; + strHighMaBuffer[barIndex] = emptyValue; + + // strColorBuffer[barIndex] = hideColorIDX; strStateBuffer[barIndex] = hideColorIDX; } @@ -491,9 +630,9 @@ void CalculateStr( { // // Calculated Price ... - ENUM_X_PRICE mPTYpe = ToXPrice(strAppliedTo); + ENUM_X_PRICE mPType = ToXPrice(strAppliedTo); double price = GetAppliedPrice( - mPTYpe, + mPType, open, high, low, @@ -632,6 +771,23 @@ void CalculateStr( { strColorBuffer[bar_index] = colorIDX; } + + // + // Str Mid ... + + // + double iStrMid = strDownBuffer[bar_index] + ((strUpBuffer[bar_index] - strDownBuffer[bar_index]) / 2); + strMidBuffer[bar_index] = iStrMid; + + // + double iStrColor = close[bar_index] > strMidBuffer[bar_index] + ? bullishColorIDX + : close[bar_index] < strMidBuffer[bar_index] + ? bearishColorIDX + : neuturalColorIDX; + strMidColorBuffer[bar_index] = iStrColor; + + // } // \ No newline at end of file diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 1af61492..9faf9f94 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -1074,7 +1074,8 @@ bool IsBoxInside( */ bool IsBoxInsideOr( XBoxZone &source, - XBoxZone &dest // + XBoxZone &dest, + bool forceInside = false // ) { // @@ -1090,19 +1091,25 @@ bool IsBoxInsideOr( } // - bool isLowerInside = - source.lower > dest.lower && - source.lower < dest.upper && - (source.upper < dest.upper || - source.upper > dest.upper); + bool isInside = + source.upper <= dest.upper && + source.upper >= dest.lower && + source.lower >= dest.lower && + source.lower <= dest.upper; bool isUpperInside = - source.upper < dest.upper && - source.upper > dest.lower && - (source.lower > dest.lower || - source.lower < dest.lower); + source.upper <= dest.upper && + source.upper >= dest.lower; + bool isLowerInside = + source.lower >= dest.lower && + source.lower <= dest.upper; + + // result = - isLowerInside || - isUpperInside; + forceInside + ? isInside + : (isInside || + isLowerInside || + isUpperInside); // return result; diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 585c77c9..35c08fd5 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -5301,18 +5301,35 @@ struct XBoxZone return result; } + /** + * Check Box is Bullish or not ... + * + * @return ( bool ) + */ bool IsBullish() { return IsValid() && IsBullish(dir); } + /** + * Check Box is Bearish or not ... + * + * @return ( bool ) + */ bool IsBearish() { return IsValid() && IsBearish(dir); } + /** + * Check Box is Same as Other ... + * + * @param item: XBoxZone instance Resource ... + * + * @return ( bool ) + */ bool IsSameAs(XBoxZone &item) { // @@ -5364,6 +5381,76 @@ struct XBoxZone return result; } + /** + * To Bar Index ... + * + * @return ( int ) + */ + int ToIndex( + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = GetBarIndex( + symbol, + forPeriod, + to // + ); + + // + return result; + } + + /** + * From Bar Index ... + * + * @return ( int ) + */ + int FromIndex( + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = GetBarIndex( + symbol, + forPeriod, + from // + ); + + // + return result; + } + /** * Retrieve Unique Identifier ... * diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index 2e43524b..0abcd78a 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -90,6 +90,356 @@ enum ENUM_X_CYCLE_EVENTS VALE_PIVOT_ENDED, }; +// +// XPV Pivot ... + +// +enum ENUM_X_PV_PIVOT +{ + X_PV_NONE, // None + X_PV_PEAK, // Peak + X_PV_VALE, // Vale +}; + +// +bool IsValid(ENUM_X_PV_PIVOT value) +{ + // + bool result = false; + + // + result = value != X_PV_NONE; + + // + return result; +} + +// +string ToString(ENUM_X_PV_PIVOT value) +{ + // + string result = NULL; + + // + result = EnumToString(value); + + // + return result; +} + +// +struct XPVPivot +{ + // + // Props ... + datetime to; + double value; + double golden; + datetime from; + string symbol; + ENUM_X_PV_PIVOT type; + ENUM_TIMEFRAMES period; + + // + // Constructor ... + XPVPivot() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup Model ... + */ + void Clean() + { + // + to = NULL; + value = 0; + from = NULL; + symbol = NULL; + period = NULL; + type = X_PV_NONE; + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + from < to && + value > 0 && + IsValid(to) && + IsValid(type) && + IsValid(from) && + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } + + /** + * Retrieve Model Direction ... + * + * @return ( ENUM_X_DIRECTION ) + */ + ENUM_X_DIRECTION GetDirection() + { + // + ENUM_X_DIRECTION result = X_DIRECTION_NONE; + + // + if (!IsValid()) + { + return result; + } + + // + switch (type) + { + // + case X_PV_PEAK: + result = X_DIRECTION_BEARISH; + break; + + // + case X_PV_VALE: + result = X_DIRECTION_BULLISH; + break; + } + + // + return result; + } + + /** + * Check Direction is Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION dir = GetDirection(); + result = IsBullish(dir); + + // + return result; + } + + /** + * Check Direction is Bearish ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION dir = GetDirection(); + result = IsBearish(dir); + + // + return result; + } + + /** + * To Bar Index ... + * + * @return ( int ) + */ + int ToIndex( + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = GetBarIndex( + symbol, + forPeriod, + to // + ); + + // + return result; + } + + /** + * From Bar Index ... + * + * @return ( int ) + */ + int FromIndex( + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = GetBarIndex( + symbol, + forPeriod, + from // + ); + + // + return result; + } + + /** + * Check two Pivot is Same or Not ... + * + * @param item: XPVPivot instance Reference ... + * + * @return ( bool ) + */ + bool IsSameAs(XPVPivot &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid(); + if (!result) + { + return result; + } + + // + result = + // + to == item.to && + from == item.from && + type == item.type && + value == item.value && + golden == item.golden && + symbol == item.symbol && + period == item.period + // + ; + + // + return result; + } + + /** + * Conerts to XBoxZone ... + * + * @param box: XBoxZone instance Reference ... + * + * @return ( bool ) + */ + bool AsBox(XBoxZone &box) + { + // + bool result = false; + + // + box.Clean(); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + box.to = to; + box.from = from; + box.symbol = symbol; + box.period = period; + box.dir = GetDirection(); + box.type = ToString(type); + + // + if (IsBullish()) + { + // + box.lower = value; + box.upper = golden; + } + else if (IsBearish()) + { + // + box.upper = value; + box.lower = golden; + } + + // + result = box.IsValid(); + if (!result) + { + box.Clean(); + } + + // + return result; + } + + // +}; + // // Cycle Helper ... class XC121SMCCycleHelper : public XCBase @@ -478,137 +828,6 @@ class XC121SMCCycleHelper : public XCBase // // Tools ... - // - bool GeneratePVBox( - XBoxZone &box, - int barIndex = 0 // - ) - { - // - bool result = false; - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - box.Clean(); - box.symbol = GetSymbol(); - box.period = GetPeriod(); - - // - int index = barIndex; - - // - // Peak ... - datetime peaksSameFrom = NULL; - double peak = mX121Helper.xpvHelper.GetPeak(index); - double prevPeak = mX121Helper.xpvHelper.GetPeak(index + 1); - bool startsByPeak = peak == prevPeak; - - // - // Vale ... - datetime valesSameFrom = NULL; - double vale = mX121Helper.xpvHelper.GetVale(index); - double prevVale = mX121Helper.xpvHelper.GetVale(index + 1); - bool startsByVale = - !startsByPeak && - vale == prevVale; - - // - bool canBreak = false; - while (!canBreak) - { - // - index++; - - // - datetime cTime = iTime( - box.symbol, - box.period, - index // - ); - - // - // Peak ... - double iPeak = mX121Helper.xpvHelper.GetPeak(index); - - // - // Vale ... - double iVale = mX121Helper.xpvHelper.GetVale(index); - - // - // Start By Peak or Value ... - bool isSame = false; - if (startsByPeak) - { - // - isSame = iPeak == peak; - bool canSetVale = vale == 0 - ? true - : iVale > vale; - if (canSetVale) - { - vale = iVale; - } - } - else if (startsByVale) - { - // - isSame = iVale == vale; - bool canSetPeak = peak == 0 - ? true - : iPeak < peak; - if (canSetPeak) - { - peak = iPeak; - } - } - - // - if (isSame) - { - // - box.from = cTime; - box.upper = peak; - box.lower = vale; - } - else if (IsValid(box.from)) - { - // - // Complete Box ... - box.to = iTime( - box.symbol, - box.period, - barIndex // - ); - - // - box.type = "XPVBox"; - box.dir = startsByPeak - ? X_DIRECTION_BEARISH - : startsByVale - ? X_DIRECTION_BULLISH - : X_DIRECTION_NONE; - } - - // - canBreak = !isSame; - } - - // - result = box.IsValid(); - if (!result) - { - box.Clean(); - } - - // - return result; - } - // int DetectRejections( XBoxZone &rejections[], @@ -1095,7 +1314,7 @@ class XC121SMCCycleHelper : public XCBase bool mShowBidLine = true; // show bid line bool mShowAskLine = true; // show ask line bool mShowGrid = false; // show grids on chart - bool mShowVolumes = false; // show volumes + bool mShowVolumes = false; // show volumes bool mShowTradeLevels = true; // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) bool mAutoScroll = true; // chart autoscroll bool mQuickNavigation = true; // chart quick navigation state diff --git a/X121SMCEA/Signals/x-121.smc.xind.signal.class.mq5 b/X121SMCEA/Signals/x-121.smc.xind.signal.class.mq5 index 4802c102..2b3efc4b 100644 --- a/X121SMCEA/Signals/x-121.smc.xind.signal.class.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xind.signal.class.mq5 @@ -35,11 +35,12 @@ class XCX121SMCXINDSignalDetector : public XCBase // // Props ... bool useGuards; - double rfRewar; + double rfReward; bool isPassedBoxes; XBoxZone mWaitingBoxes[]; XBoxZone mBreakedBoxes[]; XBoxZone mActivatedBoxes[]; + bool continuesRFTillTarget; XBoxZone mUnAvailableBoxes[]; X121SMCStrategyXINDSignalConditions mConditions; X121SMCStrategyXINDSignalConditions mConditionsCollection[]; @@ -78,12 +79,16 @@ class XCX121SMCXINDSignalDetector : public XCBase */ bool DetectSignalSetup( X121SMCStrategySignalProviderData &provider, + double tpReward = 3, double maxAllowedSLDistanceInPoint = 300 // ) { // bool result = false; + // + tpReward = NormalizeDouble(tpReward, 2); + // // Validate Cycle Helpers ... result = provider.IsValid(); @@ -330,11 +335,11 @@ class XCX121SMCXINDSignalDetector : public XCBase { // iAtr = provider.decisionXConditions.atrBuffer[1]; - iAtr *= 0.5; + iAtr *= 0; // // Fix rf Reward ... - rfRewar = 2; + rfReward = 2; } // @@ -368,10 +373,10 @@ class XCX121SMCXINDSignalDetector : public XCBase // // Reward to RF ... - if (rfRewar > 0) + if (rfReward > 0) { // - double iRFReward = rfRewar * risk; + double iRFReward = rfReward * risk; double iRFTP = isBullish ? entry + iRFReward : entry - iRFReward; @@ -381,6 +386,31 @@ class XCX121SMCXINDSignalDetector : public XCBase iRFTP, targets // ); + + // + if (continuesRFTillTarget && + rfReward < tpReward) + { + // + double iReward = rfReward + 1; + while (iReward < tpReward - 1) + { + // + iRFReward = iReward * risk; + iRFTP = isBullish + ? entry + iRFReward + : entry - iRFReward; + + // + Add( + iRFTP, + targets // + ); + + // + iReward++; + } + } } // @@ -1094,7 +1124,8 @@ class XCX121SMCXINDSignalDetector : public XCBase int UpdateWaitingBoxes( ENUM_X_CYCLES cycle, ENUM_X_CYCLES vCycle, - X121SMCStrategySignalProviderData &provider // + X121SMCStrategySignalProviderData &provider, + int maxAllowedAge = 0 // ) { // @@ -1321,6 +1352,31 @@ class XCX121SMCXINDSignalDetector : public XCBase iBox.period // ); + // + // Checking Box Age ... + int age = iBox.GetAge(); + bool isAgeBreaked = + maxAllowedAge > 0 && + age > maxAllowedAge; + if (isAgeBreaked) + { + // + Add( + i, + mustRemove // + ); + + // + AddRef( + iBox, + mUnAvailableBoxes // + ); + + // + iBox.Clean(); + continue; + } + // // Box Waiting ... if (isValid) @@ -1396,6 +1452,31 @@ class XCX121SMCXINDSignalDetector : public XCBase // XBoxZone iBox = mActivatedBoxes[i]; + // + // Checking Box Age ... + int age = iBox.GetAge(); + bool isAgeBreaked = + maxAllowedAge > 0 && + age > maxAllowedAge; + if (isAgeBreaked) + { + // + Add( + i, + mustRemove // + ); + + // + AddRef( + iBox, + mUnAvailableBoxes // + ); + + // + iBox.Clean(); + continue; + } + // // Check Breaked ... bool isBreaked = IsBoxBreaked( @@ -1918,9 +1999,10 @@ class XCX121SMCXINDSignalDetector : public XCBase void Init() { // - rfRewar = 2; + rfReward = 2; useGuards = false; isPassedBoxes = false; + continuesRFTillTarget = true; } /** diff --git a/X121SMCEA/Signals/x-121.smc.xind.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xind.signal.lib.mq5 index 408073d6..d439c15e 100644 --- a/X121SMCEA/Signals/x-121.smc.xind.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xind.signal.lib.mq5 @@ -346,322 +346,6 @@ bool IsFVGBoxValid( // result = hasSelectedBox; - // - if (result) - { - // - - // - // From Index ... - int fromIndex = GetBarIndex( - selectedBox.symbol, - selectedBox.period, - selectedBox.from // - ) + - 1; - result = IsValidIndex(fromIndex); - - // - // To Index ... - int toIndex = GetBarIndex( - selectedBox.symbol, - selectedBox.period, - selectedBox.to // - ); - if (toIndex < 1) - { - toIndex = 1; - } - result = IsValidIndex(toIndex); - - // - // Now we Have Retrieve X121Conditions between from and to Indexes ... - // for Check States ... - - // - bool hasNewValeUnderLast = false; - bool isStrSwitchedToBullish = false; - bool isSarSwitchedToBullish = false; - bool hasValueGoldenZoneBreak = false; - bool isSMHKSwitchedToBullish = false; - bool isVWapSwitchedToBullishState = false; - bool isX3MaSwitchedToBullishState = false; - bool isVWapSwitchedToBullishOrdered = false; - bool isX3MaSwitchedToBullishOrdered = false; - - // - bool hasNewPeakOverLast = false; - bool isStrSwitchedToBearish = false; - bool isSarSwitchedToBearish = false; - bool hasPeakGoldenZoneBreak = false; - bool isSMHKSwitchedToBearish = false; - bool isVWapSwitchedToBearishState = false; - bool isX3MaSwitchedToBearishState = false; - bool isVWapSwitchedToBearishOrdered = false; - bool isX3MaSwitchedToBearishOrdered = false; - - // - for (int i = fromIndex; i >= toIndex; i--) - { - // - XOHCL iBar; - has = iBar.Init( - cState.symbol, - cState.period, - i // - ); - X121Conditions iConditions; - has = has && - cHelper.mX121Helper.GetConditions( - iConditions, - i // - ); - if (!has) - { - continue; - } - - // - // Bullish ... - - // - if (!hasNewValeUnderLast) - { - hasNewValeUnderLast = iConditions.isNewValeUnderLast; - } - - // - if (!isStrSwitchedToBullish) - { - isStrSwitchedToBullish = iConditions.isStrSwitchedToBullish; - } - - // - if (!isSarSwitchedToBullish) - { - isSarSwitchedToBullish = iConditions.isSarSwitchedToBullish; - } - - // - if (!hasValueGoldenZoneBreak) - { - // - hasValueGoldenZoneBreak = - iBar.IsBullish() && - iBar.GetUp() > iConditions.valesGoldenBuffer[1] && - iBar.GetDown() < iConditions.valesGoldenBuffer[1]; - } - - // - if (!isSMHKSwitchedToBullish) - { - isSMHKSwitchedToBullish = iConditions.isSMHKSwitchedToBullish; - } - - // - if (!isVWapSwitchedToBullishState) - { - isVWapSwitchedToBullishState = iConditions.isVWapSwitchedToBullishState; - } - - // - if (!isX3MaSwitchedToBullishState) - { - isX3MaSwitchedToBullishState = iConditions.isX3MaSwitchedToBullishState; - } - - // - if (!isVWapSwitchedToBullishOrdered) - { - isVWapSwitchedToBullishOrdered = iConditions.isVWapSwitchedToBullishOrdered; - } - - // - if (!isX3MaSwitchedToBullishOrdered) - { - isX3MaSwitchedToBullishOrdered = iConditions.isX3MaSwitchedToBullishOrdered; - } - - // - // Bearish ... - - // - if (!hasNewPeakOverLast) - { - hasNewPeakOverLast = iConditions.isNewPeakOverLast; - } - - // - if (!isStrSwitchedToBearish) - { - isStrSwitchedToBearish = iConditions.isStrSwitchedToBearish; - } - - // - if (!isSarSwitchedToBearish) - { - isSarSwitchedToBearish = iConditions.isSarSwitchedToBearish; - } - - // - if (!hasPeakGoldenZoneBreak) - { - // - hasPeakGoldenZoneBreak = - iBar.IsBearish() && - iBar.GetUp() > iConditions.peaksGoldenBuffer[1] && - iBar.GetDown() < iConditions.peaksGoldenBuffer[1]; - } - - // - if (!isSMHKSwitchedToBearish) - { - isSMHKSwitchedToBearish = iConditions.isSMHKSwitchedToBearish; - } - - // - if (!isVWapSwitchedToBearishState) - { - isVWapSwitchedToBearishState = iConditions.isVWapSwitchedToBearishState; - } - - // - if (!isX3MaSwitchedToBearishState) - { - isX3MaSwitchedToBearishState = iConditions.isX3MaSwitchedToBearishState; - } - - // - if (!isVWapSwitchedToBearishOrdered) - { - isVWapSwitchedToBearishOrdered = iConditions.isVWapSwitchedToBearishOrdered; - } - - // - if (!isX3MaSwitchedToBearishOrdered) - { - isX3MaSwitchedToBearishOrdered = iConditions.isX3MaSwitchedToBearishOrdered; - } - - // - iConditions.Clean(); - } - - // - // Bullish Conditions Summary ... - - // - bool hasBullishOrConditions = - hasNewValeUnderLast || - isStrSwitchedToBullish || - isSarSwitchedToBullish || - hasValueGoldenZoneBreak || - isSMHKSwitchedToBullish || - isVWapSwitchedToBullishState || - isX3MaSwitchedToBullishState || - isVWapSwitchedToBullishOrdered || - isX3MaSwitchedToBullishOrdered; - - // - bool hasBullishAndConditions = - hasNewValeUnderLast && - hasValueGoldenZoneBreak && - (isStrSwitchedToBullish || - isSarSwitchedToBullish || - isSMHKSwitchedToBullish || - isVWapSwitchedToBullishState || - isX3MaSwitchedToBullishState || - isVWapSwitchedToBullishOrdered || - isX3MaSwitchedToBullishOrdered); - - // - // Bearish Conditions Summary ... - - // - bool hasBearishOrConditions = - hasNewPeakOverLast || - isStrSwitchedToBearish || - isSarSwitchedToBearish || - hasPeakGoldenZoneBreak || - isSMHKSwitchedToBearish || - isVWapSwitchedToBearishState || - isX3MaSwitchedToBearishState || - isVWapSwitchedToBearishOrdered || - isX3MaSwitchedToBearishOrdered; - - // - bool hasBearishAndConditions = - hasNewPeakOverLast && - hasPeakGoldenZoneBreak && - (isStrSwitchedToBearish || - isSarSwitchedToBearish || - isSMHKSwitchedToBearish || - isVWapSwitchedToBearishState || - isX3MaSwitchedToBearishState || - isVWapSwitchedToBearishOrdered || - isX3MaSwitchedToBearishOrdered); - - // - bool isBullish = - isBoxBullish && - !hasBearishOrConditions && - hasBullishOrConditions; - - // - bool isBearish = - !isBoxBullish && - !hasBullishOrConditions && - hasBearishOrConditions; - - // - result = isBullish || - isBearish; - - // - // if (result) - // { - // // - // XCBoxObject *iBoxObj; - // XCBoxObject *iInBoxObj; - - // // - // has = provider - // .verificationCycleHelper - // .mPOIDrawer - // .DrawBox( - // box, - // iBoxObj // - // ); - // if (has) - // { - // // - // iBoxObj.BoxWidth(2); - // iBoxObj.BoxStyle(STYLE_SOLID); - // } - - // // - // has = provider - // .verificationCycleHelper - // .mPOIDrawer - // .DrawBox( - // selectedBox, - // iInBoxObj // - // ); - // if (has) - // { - // // - // iInBoxObj.BoxWidth(2); - // iInBoxObj.BoxStyle(STYLE_DASH); - // } - - // // - // Print("Inside Selected Box ..."); - // } - } - - // - // Cleanup Resources ... - // cState.Clean(); Clean(tmpBoxes); @@ -675,6 +359,107 @@ bool IsFVGBoxValid( return result; } +// +bool CheckConsolidationPassedBox( + XBoxZone &consolidationBox, + XBoxZone &box, + XPOIState &state // +) +{ + // + bool result = false; + + // + result = box.IsValid(); + if (!result) + { + return result; + } + + // + int idx = -1; + int count = 0; + bool has = false; + + // + XBoxZone selectedBox; + has = state.HasConsolidationZones(); + if (has) + { + // + count = state.CountConsolidationZones(); + for (int i = 0; i < count; i++) + { + // + XConsolidationZone iZone = state.consolidationZones[i]; + has = ToBox( + selectedBox, + iZone // + ); + if (!has) + { + // + iZone.Clean(); + selectedBox.Clean(); + continue; + }; + + // + // Check Selected Box is Related to BOX or not ... + bool isValid = + // + // Direction Passed ... + selectedBox.dir == box.dir && + // + // Time Passe ... + selectedBox.to > box.from && + selectedBox.from < box.from && + // + // Place Passed ... + ( + // + // Upper Inside ... + (selectedBox.upper >= box.lower && + selectedBox.upper <= box.upper) + // + || + // + // Lower Inside ... + (selectedBox.lower <= box.upper && + selectedBox.lower >= box.lower) + // + || + // + // Fully Inside ... + (selectedBox.upper <= box.upper && + selectedBox.lower >= box.lower) + // + ); + if (isValid) + { + // + iZone.Clean(); + break; + } + + // + iZone.Clean(); + selectedBox.Clean(); + } + } + + // + result = selectedBox.IsValid(); + if (result) + { + consolidationBox = selectedBox; + } + selectedBox.Clean(); + + // + return result; +} + // // Signalling Conditions Parsers ... @@ -795,6 +580,9 @@ bool HasXINDConditions( return result; } + // + XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer; + // // Select Waiting Box ... XBoxZone selectedBox; @@ -802,6 +590,8 @@ bool HasXINDConditions( bool useWaitingBoxes = true; bool useActivtedBoxes = true; bool useBreakedBoxes = false; + XBoxZone selectedConsolidationBox; + bool hasSelectedConsolidationBox = false; if (useWaitingBoxes && IsValidSize(waitingBoxesCount)) { // @@ -811,6 +601,7 @@ bool HasXINDConditions( XBoxZone iBox = waitingBoxes[i]; // + // Check PV Passed Box ... has = IsBoxPVPassed( iBox, cXConditions // @@ -825,6 +616,23 @@ bool HasXINDConditions( break; } + // + // Check Consolidation Passed Box ... + has = CheckConsolidationPassedBox( + selectedConsolidationBox, + iBox, + cState // + ); + if (has) + { + // + selectedBox = iBox; + iBox.Clean(); + + // + break; + } + // iBox.Clean(); } @@ -835,6 +643,13 @@ bool HasXINDConditions( { selectedBox.Clean(); } + + // + hasSelectedConsolidationBox = selectedConsolidationBox.IsValid(); + if (!hasSelectedConsolidationBox) + { + selectedConsolidationBox.Clean(); + } } if (useActivtedBoxes && !hasSelectedBox && IsValidSize(activatedBoxesCount)) { @@ -845,6 +660,7 @@ bool HasXINDConditions( XBoxZone iBox = activatedBoxes[i]; // + // Check PV Passed Box ... has = IsBoxPVPassed( iBox, cXConditions // @@ -859,6 +675,23 @@ bool HasXINDConditions( break; } + // + // Check Consolidation Passed Box ... + has = CheckConsolidationPassedBox( + selectedConsolidationBox, + iBox, + cState // + ); + if (has) + { + // + selectedBox = iBox; + iBox.Clean(); + + // + break; + } + // iBox.Clean(); } @@ -869,6 +702,13 @@ bool HasXINDConditions( { selectedBox.Clean(); } + + // + hasSelectedConsolidationBox = selectedConsolidationBox.IsValid(); + if (!hasSelectedConsolidationBox) + { + selectedConsolidationBox.Clean(); + } } if (useBreakedBoxes && !hasSelectedBox && IsValidSize(breakedBoxesCount)) { @@ -891,11 +731,54 @@ bool HasXINDConditions( } // - XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer; + double selectedBoxMid = 0; + double selectedBoxStr = 0; if (hasSelectedBox) { + // + selectedBoxMid = (selectedBox.lower + ((selectedBox.upper - selectedBox.lower) / 2)); + // selectedBox.to = zBar.time; + CheckBoxStr( + cHelper, + selectedBox, + selectedBoxStr // + ); + + // + if (selectedBoxStr != 0) + { + // + long chartId = drawer.ChartIdentification(); + int subWindow = drawer.SubWindowIdentification(); + string name = selectedBox.GetTag() + "_SUPRES"; + + // + CChartObjectTrend *iObj; + iObj = new CChartObjectTrend(); + has = iObj.Create( + chartId, + name, + subWindow, + selectedBox.from, + selectedBoxStr, + selectedBox.to, + selectedBoxStr // + ); + if (has) + { + // + color lineColor = + selectedBox.IsBullish() + ? clrLime + : clrRed; + iObj.Color(lineColor); + iObj.Width(2); + } + } + + // XCBoxObject *iObj; has = drawer.DrawBox( selectedBox, @@ -912,7 +795,74 @@ bool HasXINDConditions( Print("Selected Box ..."); } } - ZeroMemory(drawer); + + // + if (hasSelectedConsolidationBox) + { + // + XCBoxObject *iObj; + has = drawer.DrawBox( + selectedConsolidationBox, + iObj // + ); + if (has) + { + // + iObj.BoxWidth(2); + iObj.BoxStyle(STYLE_SOLID); + } + } + + // + // Detect Bullish and Bearish Consolidation Zones ... + XBoxZone consolidationBox; + bool hasConsolidationBox = false; + if (!hasConsolidationBox) + { + // + hasConsolidationBox = cStateEvents.hasNewConsolidationZone; + if (hasConsolidationBox) + { + // + idx = GetYoungest(cState.consolidationZones); + has = IsValidIndex(idx); + if (has) + { + // + XConsolidationZone cZone = cState.consolidationZones[idx]; + + // + ToBox( + consolidationBox, + cZone // + ); + } + } + + // + hasConsolidationBox = consolidationBox.IsValid(); + // if (hasConsolidationBox) + // { + // // + // XCBoxObject *iObj; + // has = drawer.DrawBox( + // consolidationBox, + // iObj // + // ); + // if (has) + // { + // // + // color crlBox = consolidationBox.IsBullish() + // ? clrBlue + // : clrDarkRed; + + // // + // iObj.BoxWidth(2); + // iObj.BoxColor(crlBox); + // iObj.BoxStyle(STYLE_SOLID); + // } + // } + } // // @@ -922,53 +872,615 @@ bool HasXINDConditions( // Reading Resources ... // - double priceChange = cXConditions.priceChangeBuffer[cIDX]; + double sarZ = cXConditions.sarBuffer[zIDX]; + double sarC = cXConditions.sarBuffer[cIDX]; + double sarP = cXConditions.sarBuffer[pIDX]; + double sarPP = cXConditions.sarBuffer[ppIDX]; + + // + double peakZ = cXConditions.peaksBuffer[zIDX]; + double peakC = cXConditions.peaksBuffer[cIDX]; + double peakP = cXConditions.peaksBuffer[pIDX]; + double peakPP = cXConditions.peaksBuffer[ppIDX]; + + // + double valeZ = cXConditions.valesBuffer[zIDX]; + double valeC = cXConditions.valesBuffer[cIDX]; + double valeP = cXConditions.valesBuffer[pIDX]; + double valePP = cXConditions.valesBuffer[ppIDX]; + + // + double strZ = cXConditions.strBuffer[zIDX]; + double strC = cXConditions.strBuffer[cIDX]; + double strP = cXConditions.strBuffer[pIDX]; + double strPP = cXConditions.strBuffer[ppIDX]; + + // double priceChangeZ = cXConditions.priceChangeBuffer[zIDX]; + double priceChangeC = cXConditions.priceChangeBuffer[cIDX]; double priceChangeP = cXConditions.priceChangeBuffer[pIDX]; double priceChangePP = cXConditions.priceChangeBuffer[ppIDX]; + // + double peaksGoldenZ = cXConditions.peaksGoldenBuffer[zIDX]; + double peaksGoldenC = cXConditions.peaksGoldenBuffer[cIDX]; + double peaksGoldenP = cXConditions.peaksGoldenBuffer[pIDX]; + double peaksGoldenPP = cXConditions.peaksGoldenBuffer[ppIDX]; + + // + double valesGoldenZ = cXConditions.valesGoldenBuffer[zIDX]; + double valesGoldenC = cXConditions.valesGoldenBuffer[cIDX]; + double valesGoldenP = cXConditions.valesGoldenBuffer[pIDX]; + double valesGoldenPP = cXConditions.valesGoldenBuffer[ppIDX]; + // // Generate Conditions ... + // + bool isPBarBullishPriceChangeVPattern = + priceChangeP > priceChangePP && + priceChangeP > priceChangeC; + + // + bool isPBarBearishPriceChangeVPattern = + priceChangeP < priceChangePP && + priceChangeP < priceChangeC; + // bool isCBarBullishPriceChangeVPattern = - priceChange > priceChangeP && - priceChange > priceChangeZ; + priceChangeC > priceChangeP && + priceChangeC > priceChangeZ; // bool isCBarBearishPriceChangeVPattern = - priceChange < priceChangeP && - priceChange < priceChangeZ; + priceChangeC < priceChangeP && + priceChangeC < priceChangeZ; // + bool isCPriceChangeUnderSelectedBoxMid = + selectedBoxMid > 0 && + priceChangeC < selectedBoxMid; + // + bool isCPriceChangeOverSelectedBoxMid = + selectedBoxMid > 0 && + priceChangeC > selectedBoxMid; + // + bool isPPriceChangeUnderSelectedBoxMid = + selectedBoxMid > 0 && + priceChangeP < selectedBoxMid; + + // + bool isPPriceChangeOverSelectedBoxMid = + selectedBoxMid > 0 && + priceChangeP > selectedBoxMid; + + // + bool isPriceChangeUnderSelectedBoxMid = + isCPriceChangeUnderSelectedBoxMid || + isPPriceChangeUnderSelectedBoxMid; + + // + bool isPriceChangeOverSelectedBoxMid = + isCPriceChangeOverSelectedBoxMid || + isPPriceChangeOverSelectedBoxMid; + + // + bool isBarBullishPriceChangeVPattern = + isPBarBullishPriceChangeVPattern || + isCBarBullishPriceChangeVPattern; + + // + bool isBarBearishPriceChangeVPattern = + isPBarBearishPriceChangeVPattern || + isCBarBearishPriceChangeVPattern; + + // + bool isPriceChangeBullishRejectedStr = + // + cXConditions.strStateBuffer[zIDX] > 0 && + cXConditions.strStateBuffer[cIDX] > 0 && + cXConditions.strStateBuffer[pIDX] > 0 && + // + cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[cIDX] && + cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[pIDX] && + // + ((priceChangeP < strC && + priceChangeC > strC) || + (priceChangeC < strC && + priceChangeZ > strC)) + // + ; + + // + bool isPriceChangeBearishRejectedStr = + // + cXConditions.strStateBuffer[zIDX] < 0 && + cXConditions.strStateBuffer[cIDX] < 0 && + cXConditions.strStateBuffer[pIDX] < 0 && + // + cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[cIDX] && + cXConditions.strBuffer[zIDX] == cXConditions.strBuffer[pIDX] && + // + ((priceChangeP > strC && + priceChangeC < strC) || + (priceChangeC > strC && + priceChangeZ > strC)) + // + ; + + // + bool isCBarBullishRejectedStr = + cBar.low < strC && + cBar.GetDown() > strC; + + // + bool isPBarBullishRejectedStr = + pBar.low < strP && + pBar.GetDown() > strP; + + // + bool isBarBullishRejectedStr = + isCBarBullishRejectedStr || + isPBarBullishRejectedStr; + + // + bool isCBarBearishRejectedStr = + cBar.high > strC && + cBar.GetUp() < strC; + + // + bool isPBarBearishRejectedStr = + pBar.high > strP && + pBar.GetUp() < strP; + + // + bool isBarBearishRejectedStr = + isCBarBearishRejectedStr || + isPBarBearishRejectedStr; + + // + bool isCPVsPeakSame = + provider.decisionXConditions.peaksBuffer[cIDX] == provider.analyseXConditions.peaksBuffer[cIDX] && + provider.analyseXConditions.peaksBuffer[cIDX] == provider.consolidationXConditions.peaksBuffer[cIDX]; + + bool isPPVsPeakSame = + provider.decisionXConditions.peaksBuffer[pIDX] == provider.analyseXConditions.peaksBuffer[pIDX] && + provider.analyseXConditions.peaksBuffer[pIDX] == provider.consolidationXConditions.peaksBuffer[pIDX]; + + // + bool isCPVsValeSame = + provider.decisionXConditions.valesBuffer[cIDX] == provider.analyseXConditions.valesBuffer[cIDX] && + provider.analyseXConditions.valesBuffer[cIDX] == provider.consolidationXConditions.valesBuffer[cIDX]; + + bool isPPVsValeSame = + provider.decisionXConditions.valesBuffer[pIDX] == provider.analyseXConditions.valesBuffer[pIDX] && + provider.analyseXConditions.valesBuffer[pIDX] == provider.consolidationXConditions.valesBuffer[pIDX]; + + // + bool isPeaksSame = isCPVsPeakSame && isPPVsPeakSame; + bool isValesSame = isCPVsValeSame && isPPVsValeSame; + + // + // Bars Conditions ... + + // + ENUM_X_DIRECTION cBarDir; + + // + // Hammer ... + bool isCBarHammer = cHelper + .mBarAnalyser + .IsHammer( + cBar, + cBarDir // + ); + bool isCBarBullishHammer = + isCBarHammer && + IsBullish(cBarDir); + bool isCBarBearishHammer = + isCBarHammer && + IsBearish(cBarDir); + + // + // Rejected ... + bool isCBarRejected = cHelper + .mBarAnalyser + .IsRejected( + cBar, + cBarDir, + false, // Force Type ... + true // Force Fibo Pressure ... + ); + bool isCBarBullishRejected = + isCBarRejected && + IsBullish(cBarDir); + bool isCBarBearishRejected = + isCBarRejected && + IsBearish(cBarDir); + + // + // Engulfed ... + bool isCBarEngulfed = cHelper + .mBarAnalyser + .IsEngulfed( + cBar, + cBarDir // + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarDir); + + // + // Momentum ... + bool isCBarMomentum = cHelper + .mBarAnalyser + .IsMomentum( + cBar, + cBarDir, + 1 // + ); + bool isCBarBullishMomentum = + isCBarMomentum && + IsBullish(cBarDir); + bool isCBarBearishMomentum = + isCBarMomentum && + IsBearish(cBarDir); + + // + // Bar Sumarise ... + + // + bool isCBarValidForBullish = + (isCBarBullishHammer || + isCBarBullishRejected || + isCBarBullishMomentum || + isCBarBullishEngulfed); + + // + bool isCBarValidForBearish = + (isCBarBearishHammer || + isCBarBearishRejected || + isCBarBearishMomentum || + isCBarBearishEngulfed); + + // + bool isCBarBreakUpLastPeak = + cBar.IsBullish() && + cBar.GetUp() > peakP && + cBar.GetDown() < peakP; + + // + bool isCBarBreakDownLastPeak = + cBar.IsBearish() && + cBar.GetUp() > peakP && + cBar.GetDown() < peakP; + + // + bool isCBarBreakUpLastVale = + cBar.IsBullish() && + cBar.GetUp() > valeP && + cBar.GetDown() < valeP; + + // + bool isCBarBreakDownLastVale = + cBar.IsBearish() && + cBar.GetUp() > valeP && + cBar.GetDown() < valeP; + + // + bool isCBarBreakUpPeakGolden = + cBar.IsBullish() && + cBar.GetUp() > peaksGoldenC && + cBar.GetDown() < peaksGoldenC; + + // + bool isCBarBreakDownPeakGolden = + cBar.IsBearish() && + cBar.GetUp() > peaksGoldenC && + cBar.GetDown() < peaksGoldenC; + + // + bool isCBarBreakUpValeGolden = + cBar.IsBullish() && + cBar.GetUp() > valesGoldenC && + cBar.GetDown() < valesGoldenC; + + // + bool isCBarBreakDownValeGolden = + cBar.IsBearish() && + cBar.GetUp() > valesGoldenC && + cBar.GetDown() < valesGoldenC; // // Summarize Conditions ... // - isBullish = - // - // false + bool isBoxSignalBullish = // hasSelectedBox && - selectedBox.IsBullish() && - isCBarBullishPriceChangeVPattern + selectedBox.IsBullish() + // + ; + + // + bool isBoxSignalBearish = + // + hasSelectedBox && + selectedBox.IsBearish() + // + ; + + // + bool isConsolidationBoxSignalBullish = + isBoxSignalBullish && + hasSelectedConsolidationBox && + selectedConsolidationBox.IsBullish(); + + // + bool isConsolidationBoxSignalBearish = + isBoxSignalBearish && + hasSelectedConsolidationBox && + selectedConsolidationBox.IsBearish(); + + // + // + // + + // + bool isCond1Bullish = + // + isBoxSignalBullish && + selectedBoxStr > 0 && + isCBarValidForBullish && + (cXConditions.isStrBullish + ? isBarBullishRejectedStr + : true) && + !hasSelectedConsolidationBox && + isBarBullishPriceChangeVPattern + // + ; + + // + bool isCond1Bearish = + // + isBoxSignalBearish && + selectedBoxStr > 0 && + isCBarValidForBearish && + (cXConditions.isStrBearish + ? isBarBearishRejectedStr + : true) && + !hasSelectedConsolidationBox && + isBarBearishPriceChangeVPattern + // + ; + + // + bool isCond2Bullish = + // + isCBarValidForBullish && + isBarBullishPriceChangeVPattern && + isConsolidationBoxSignalBullish && + (isPriceChangeBullishRejectedStr || + isPriceChangeUnderSelectedBoxMid) + // + ; + + bool isCond2Bearish = + // + isCBarValidForBearish && + isBarBearishPriceChangeVPattern && + isConsolidationBoxSignalBearish && + (isPriceChangeBearishRejectedStr || + isPriceChangeOverSelectedBoxMid) + // + ; + + // + bool isCond3Bullish = + // + false + // + ; + + bool isCond3Bearish = + // + false + // + ; + + // + // + // + + // + isBullish = + // + isCond1Bullish || + isCond2Bullish || + isCond3Bullish // ; // isBearish = // - // false - // - hasSelectedBox && - selectedBox.IsBearish() && - isCBarBearishPriceChangeVPattern + isCond1Bearish || + isCond2Bearish || + isCond3Bearish // ; + // // + // if (isBoxSignalBullish || isBoxSignalBearish) + // { + // Print("Box Has Signal ..."); + // } + + // + // if (isPeaksSame || + // isValesSame) + // { + // // + // long chartId = drawer.ChartIdentification(); + // int subWindow = drawer.SubWindowIdentification(); + + // // + // string name1 = "decision_"; + // string name2 = "analyse_"; + // string name3 = "consolidation_"; + + // // + // CChartObjectTrend *t1Obj; + // t1Obj = new CChartObjectTrend(); + + // // + // CChartObjectTrend *t2Obj; + // t2Obj = new CChartObjectTrend(); + + // // + // CChartObjectTrend *t3Obj; + // t3Obj = new CChartObjectTrend(); + + // // + // color tValeColor = clrAqua; + // color tPeakColor = clrMagenta; + + // // + // datetime from = pBar.time; + // datetime to = zBar.time; + + // // + // if (isPeaksSame) + // { + // // + // // Prepare Names ... + // name1 = name1 + "_Vale"; + // name2 = name2 + "_Vale"; + // name3 = name3 + "_Vale"; + + // // + // // T1 ... + // has = t1Obj.Create( + // chartId, + // name1, + // subWindow, + // from, + // provider.decisionXConditions.valesBuffer[cIDX], + // to, + // provider.decisionXConditions.valesBuffer[cIDX] // + // ); + // if (has) + // { + // t1Obj.Color(tValeColor); + // } + + // // + // // T2 ... + // has = t2Obj.Create( + // chartId, + // name2, + // subWindow, + // from, + // provider.analyseXConditions.valesBuffer[cIDX], + // to, + // provider.analyseXConditions.valesBuffer[cIDX] // + // ); + // if (has) + // { + // t2Obj.Color(tValeColor); + // } + + // // + // // T3 ... + // has = t3Obj.Create( + // chartId, + // name1, + // subWindow, + // from, + // provider.consolidationXConditions.valesBuffer[cIDX], + // to, + // provider.consolidationXConditions.valesBuffer[cIDX] // + // ); + // if (has) + // { + // t3Obj.Color(tValeColor); + // } + // } + + // // + // if (isValesSame) + // { + // // + // // Prepare Names ... + // name1 = name1 + "_Peak"; + // name2 = name2 + "_Peak"; + // name3 = name3 + "_Peak"; + + // // + // // T1 ... + // has = t1Obj.Create( + // chartId, + // name1, + // subWindow, + // from, + // provider.decisionXConditions.peaksBuffer[cIDX], + // to, + // provider.decisionXConditions.peaksBuffer[cIDX] // + // ); + // if (has) + // { + // t1Obj.Color(tPeakColor); + // } + + // // + // // T2 ... + // has = t2Obj.Create( + // chartId, + // name2, + // subWindow, + // from, + // provider.analyseXConditions.peaksBuffer[cIDX], + // to, + // provider.analyseXConditions.peaksBuffer[cIDX] // + // ); + // if (has) + // { + // t2Obj.Color(tPeakColor); + // } + + // // + // // T3 ... + // has = t3Obj.Create( + // chartId, + // name1, + // subWindow, + // from, + // provider.consolidationXConditions.peaksBuffer[cIDX], + // to, + // provider.consolidationXConditions.peaksBuffer[cIDX] // + // ); + // if (has) + // { + // t3Obj.Color(tPeakColor); + // } + // } + + // // + // Print("PVS Same ..."); + // } + + // + if (isConsolidationBoxSignalBullish || + isConsolidationBoxSignalBearish) + { + Print("Has Consolidation Selected Box ..."); + } + // // Filling Requirements ... result = @@ -994,10 +1506,55 @@ bool HasXINDConditions( // // Usually is Preffered SL ... - double pivot = - isBullish - ? selectedBox.lower - : selectedBox.upper; + double pivot = 0; + if (isBullish) + { + // + if (isCond1Bullish) + { + pivot = selectedBoxStr; + } + else if (isCond2Bullish) + { + pivot = selectedBoxMid; + } + else if (hasSelectedBox) + { + // + // Default Box SL ... + pivot = selectedBox.lower; + } + else + { + // + // Default Non Box SL ... + pivot = cBar.low; + } + } + else if (isBearish) + { + // + if (isCond1Bearish) + { + pivot = selectedBoxStr; + } + else if (isCond2Bearish) + { + pivot = selectedBoxMid; + } + else if (hasSelectedBox) + { + // + // Default Box SL ... + pivot = selectedBox.upper; + } + else + { + // + // Default Non Box SL ... + pivot = cBar.high; + } + } // // Usually is Current Price or Entry Price ... @@ -1020,30 +1577,6 @@ bool HasXINDConditions( // zone = selectedBox; - - // - // XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer; - // bool drawBoxes = true; - // if (drawBoxes) - // { - // // - // if (box.IsValid()) - // { - // // - // XCBoxObject *iObj; - // bool isCreated = drawer.DrawBox( - // box, - // iObj // - // ); - - // // - // if (isCreated) - // { - // // - // // TODO: ... - // } - // } - // } } // @@ -1068,6 +1601,9 @@ bool HasXINDConditions( cStateEvents.Clean(); cXConditions.Clean(); + // + ZeroMemory(drawer); + // return result; } @@ -1093,18 +1629,18 @@ bool IsBoxPVPassed( } // - double boxMid = box.lower + ((box.upper - box.lower) / 2); + // double boxValue = box.lower + ((box.upper - box.lower) / 2); // bool isBullishPassed = box.IsBullish() && - conditions.valesBuffer[0] < boxMid && + conditions.valesBuffer[0] < box.upper && conditions.valesBuffer[0] > box.lower; // bool isBearishPassed = box.IsBearish() && - conditions.peaksBuffer[0] > boxMid && + conditions.peaksBuffer[0] > box.lower && conditions.peaksBuffer[0] < box.upper; // @@ -1115,4 +1651,85 @@ bool IsBoxPVPassed( return result; } +// +void CheckBoxStr( + XC121SMCCycleHelper *helper, + XBoxZone &box, + double &value // +) +{ + // + value = 0; + + // + if (!box.IsValid()) + { + return; + } + + // + ENUM_TIMEFRAMES _period = helper.GetPeriod(); + + // + int toIDX = box.ToIndex(_period); + int fromIDX = box.FromIndex(_period); + if (!IsValidIndex(toIDX) || + !IsValidIndex(fromIDX)) + { + return; + } + + // + bool isBullish = box.IsBullish(); + XCX121XSTRHelper *strHelper = helper.mX121Helper.xstrHelper; + for (int i = fromIDX; i >= toIDX; i--) + { + // + double iStr = strHelper.GetSTR(i); + double iPStr = strHelper.GetSTR(i); + double iStrState = strHelper.GetSTRState(i); + + // + bool isSame = iStr == iPStr; + bool isStrBullish = iStrState > 0; + bool isStrBearish = iStrState < 0; + bool isStrInBox = + iStr <= box.upper && + iStr >= box.lower; + + // + if (isSame && isStrInBox) + { + // + if (isBullish && isStrBullish) + { + // + // Min Bullish Str as Support ... + value = + value <= 0 + ? iStr + : value > iStr + ? iStr + : value; + } + else if (!isBullish && isStrBearish) + { + // + // Max Bearish Str as Resistance ... + value = + value <= 0 + ? iStr + : value < iStr + ? iStr + : value; + } + } + } + + // + ZeroMemory(strHelper); + + // +} + // \ No newline at end of file diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 008c1ab0..7d1ce163 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -732,7 +732,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // XICH Signal ... bool DetectXINDSignal( X121SMCStrategyConditions &conditions, - X121SMCStrategyXINDSignalConditions &xICHConditions // + X121SMCStrategyXINDSignalConditions &xINDConditions // ) { // @@ -769,7 +769,8 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // Detect Signal Setup ... isSetuped = mXINDSignalDetector.DetectSignalSetup( - cycleProvider // + cycleProvider, + R2R() // ); // @@ -893,7 +894,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy ); // - xICHConditions = mConditions; + xINDConditions = mConditions; // mConditions.Clean(); @@ -1018,7 +1019,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // // Presentations ... x121Inputs.xhkInputs.drawRawXHKCandles = showAll || false; - x121Inputs.xhkInputs.drawSmoothedXHKCandles = showAll || true; + x121Inputs.xhkInputs.drawSmoothedXHKCandles = showAll || false; // // XMAS ... @@ -1051,7 +1052,7 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // Presentations ... x121Inputs.xatrInputs.showAtrUpper = showAll || false; x121Inputs.xatrInputs.showAtrLower = showAll || false; - x121Inputs.xatrInputs.showRSIChange = showAll || false; + x121Inputs.xatrInputs.showRSIChange = showAll || true; x121Inputs.xatrInputs.showPriceChange = showAll || true; x121Inputs.xatrInputs.showSmoothedAtrUpper = showAll || false; x121Inputs.xatrInputs.showSmoothedAtrLower = showAll || false; @@ -1065,13 +1066,17 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // Configurations ... x121Inputs.xstrInputs.strMultiplier = 5; x121Inputs.xstrInputs.strLength = swingLength; + x121Inputs.xstrInputs.strBoundaryMode = MODE_SMA; x121Inputs.xstrInputs.strAppliedTo = PRICE_TYPICAL; // // Presentations ... x121Inputs.xstrInputs.showStr = showAll || true; + x121Inputs.xstrInputs.showStrMid = showAll || false; x121Inputs.xstrInputs.showStrUpper = showAll || false; x121Inputs.xstrInputs.showStrLower = showAll || false; + x121Inputs.xstrInputs.showStrSMLow = showAll || false; + x121Inputs.xstrInputs.showStrSMHigh = showAll || false; // // XCHE ...