public static RetCode Atan(decimal[] inReal, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outReal == null) { return(RetCode.BadParam); } int outIdx = default; for (int i = startIdx; i <= endIdx; i++) { outReal[outIdx++] = DecimalMath.Atan(inReal[i]); } outBegIdx = startIdx; outNbElement = outIdx; return(RetCode.Success); }
public static RetCode LinearRegAngle(decimal[] inReal, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement, int optInTimePeriod = 14) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outReal == null || optInTimePeriod < 2 || optInTimePeriod > 100000) { return(RetCode.BadParam); } int lookbackTotal = LinearRegAngleLookback(optInTimePeriod); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return(RetCode.Success); } int outIdx = default; int today = startIdx; decimal sumX = optInTimePeriod * (optInTimePeriod - 1) * 0.5m; decimal sumXSqr = optInTimePeriod * (optInTimePeriod - 1) * (optInTimePeriod * 2 - 1) / 6m; decimal divisor = sumX * sumX - optInTimePeriod * sumXSqr; while (today <= endIdx) { decimal sumXY = default; decimal sumY = default; for (int i = optInTimePeriod; i != 0; i--) { decimal tempValue1 = inReal[today - i]; sumY += tempValue1; sumXY += i * tempValue1; } decimal m = (optInTimePeriod * sumXY - sumX * sumY) / divisor; outReal[outIdx++] = DecimalMath.Atan(m) * 180m / DecimalMath.PI; today++; } outBegIdx = startIdx; outNbElement = outIdx; return(RetCode.Success); }
public static RetCode HtDcPhase(decimal[] inReal, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return RetCode.OutOfRangeStartIndex; } if (inReal == null || outReal == null) { return RetCode.BadParam; } int lookbackTotal = HtDcPhaseLookback(); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return RetCode.Success; } const int smoothPriceSize = 50; var smoothPrice = new decimal[smoothPriceSize]; const decimal rad2Deg = 180m / DecimalMath.PI; const decimal constDeg2RadBy360 = 2m * DecimalMath.PI; outBegIdx = startIdx; int trailingWMAIdx = startIdx - lookbackTotal; int today = trailingWMAIdx; decimal tempReal = inReal[today++]; decimal periodWMASub = tempReal; decimal periodWMASum = tempReal; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 2m; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 3m; decimal trailingWMAValue = default; var i = 34; do { tempReal = inReal[today++]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, tempReal, out _); } while (--i != 0); int hilbertIdx = default; int smoothPriceIdx = default; var hilbertVariables = InitHilbertVariables<decimal>(); int outIdx = default; decimal prevI2, prevQ2, re, im, i1ForOddPrev3, i1ForEvenPrev3, i1ForOddPrev2, i1ForEvenPrev2, smoothPeriod, dcPhase; decimal period = prevI2 = prevQ2 = re = im = i1ForOddPrev3 = i1ForEvenPrev3 = i1ForOddPrev2 = i1ForEvenPrev2 = smoothPeriod = dcPhase = default; while (today <= endIdx) { decimal i2; decimal q2; decimal adjustedPrevPeriod = 0.075m * period + 0.54m; decimal todayValue = inReal[today]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, todayValue, out var smoothedValue); smoothPrice[smoothPriceIdx] = smoothedValue; if (today % 2 == 0) { DoHilbertEven(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jI", i1ForEvenPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); if (++hilbertIdx == 3) { hilbertIdx = 0; } q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForEvenPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForOddPrev3 = i1ForOddPrev2; i1ForOddPrev2 = hilbertVariables["detrender"]; } else { DoHilbertOdd(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jI", i1ForOddPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForOddPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForEvenPrev3 = i1ForEvenPrev2; i1ForEvenPrev2 = hilbertVariables["detrender"]; } re = 0.2m * (i2 * prevI2 + q2 * prevQ2) + 0.8m * re; im = 0.2m * (i2 * prevQ2 - q2 * prevI2) + 0.8m * im; prevQ2 = q2; prevI2 = i2; tempReal = period; if (im != Decimal.Zero && re != Decimal.Zero) { period = 360m / (DecimalMath.Atan(im / re) * rad2Deg); } decimal tempReal2 = 1.5m * tempReal; if (period > tempReal2) { period = tempReal2; } tempReal2 = 0.67m * tempReal; if (period < tempReal2) { period = tempReal2; } if (period < 6m) { period = 6m; } else if (period > 50m) { period = 50m; } period = 0.2m * period + 0.8m * tempReal; smoothPeriod = 0.33m * period + 0.67m * smoothPeriod; decimal dcPeriod = smoothPeriod + 0.5m; int dcPeriodInt = (int) dcPeriod; decimal realPart = default; decimal imagPart = default; int idx = smoothPriceIdx; for (i = 0; i < dcPeriodInt; i++) { tempReal = i * constDeg2RadBy360 / dcPeriodInt; tempReal2 = smoothPrice[idx]; realPart += DecimalMath.Sin(tempReal) * tempReal2; imagPart += DecimalMath.Cos(tempReal) * tempReal2; if (idx == 0) { idx = smoothPriceSize - 1; } else { idx--; } } tempReal = Math.Abs(imagPart); if (tempReal > Decimal.Zero) { dcPhase = DecimalMath.Atan(realPart / imagPart) * rad2Deg; } else if (tempReal <= 0.01m) { if (realPart < Decimal.Zero) { dcPhase -= 90m; } else if (realPart > Decimal.Zero) { dcPhase += 90m; } } dcPhase += 90m; dcPhase += 360m / smoothPeriod; if (imagPart < Decimal.Zero) { dcPhase += 180m; } if (dcPhase > 315m) { dcPhase -= 360m; } if (today >= startIdx) { outReal[outIdx++] = dcPhase; } if (++smoothPriceIdx > smoothPriceSize - 1) { smoothPriceIdx = 0; } today++; } outNbElement = outIdx; return RetCode.Success; }
public static RetCode Mama(decimal[] inReal, int startIdx, int endIdx, decimal[] outMama, decimal[] outFama, out int outBegIdx, out int outNbElement, decimal optInFastLimit = 0.5m, decimal optInSlowLimit = 0.05m) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outMama == null || outFama == null || optInFastLimit < 0.01m || optInFastLimit > 0.99m || optInSlowLimit < 0.01m || optInSlowLimit > 0.99m) { return(RetCode.BadParam); } int lookbackTotal = MamaLookback(); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return(RetCode.Success); } const decimal rad2Deg = 180m / DecimalMath.PI; outBegIdx = startIdx; int trailingWMAIdx = startIdx - lookbackTotal; int today = trailingWMAIdx; decimal tempReal = inReal[today++]; decimal periodWMASub = tempReal; decimal periodWMASum = tempReal; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 2m; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 3m; decimal trailingWMAValue = default; int i = 9; do { tempReal = inReal[today]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, tempReal, out _); } while (--i != 0); int hilbertIdx = default; var hilbertVariables = InitHilbertVariables <decimal>(); int outIdx = default; decimal prevI2, prevQ2, re, im, mama, fama, i1ForOddPrev3, i1ForEvenPrev3, i1ForOddPrev2, i1ForEvenPrev2, prevPhase; decimal period = prevI2 = prevQ2 = re = im = mama = fama = i1ForOddPrev3 = i1ForEvenPrev3 = i1ForOddPrev2 = i1ForEvenPrev2 = prevPhase = default; while (today <= endIdx) { decimal tempReal2; decimal i2; decimal q2; decimal adjustedPrevPeriod = 0.075m * period + 0.54m; decimal todayValue = inReal[today]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, todayValue, out var smoothedValue); if (today % 2 == 0) { DoHilbertEven(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jI", i1ForEvenPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); if (++hilbertIdx == 3) { hilbertIdx = 0; } q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForEvenPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForOddPrev3 = i1ForOddPrev2; i1ForOddPrev2 = hilbertVariables["detrender"]; if (i1ForEvenPrev3 != Decimal.Zero) { tempReal2 = DecimalMath.Atan(hilbertVariables["q1"] / i1ForEvenPrev3) * rad2Deg; } else { tempReal2 = Decimal.Zero; } } else { DoHilbertOdd(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jI", i1ForOddPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForOddPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForEvenPrev3 = i1ForEvenPrev2; i1ForEvenPrev2 = hilbertVariables["detrender"]; if (i1ForOddPrev3 != Decimal.Zero) { tempReal2 = DecimalMath.Atan(hilbertVariables["q1"] / i1ForOddPrev3) * rad2Deg; } else { tempReal2 = Decimal.Zero; } } tempReal = prevPhase - tempReal2; prevPhase = tempReal2; if (tempReal < Decimal.One) { tempReal = Decimal.One; } if (tempReal > Decimal.One) { tempReal = optInFastLimit / tempReal; if (tempReal < optInSlowLimit) { tempReal = optInSlowLimit; } } else { tempReal = optInFastLimit; } mama = tempReal * todayValue + (Decimal.One - tempReal) * mama; tempReal *= 0.5m; fama = tempReal * mama + (Decimal.One - tempReal) * fama; if (today >= startIdx) { outMama[outIdx] = mama; outFama[outIdx] = fama; outIdx++; } re = 0.2m * (i2 * prevI2 + q2 * prevQ2) + 0.8m * re; im = 0.2m * (i2 * prevQ2 - q2 * prevI2) + 0.8m * im; prevQ2 = q2; prevI2 = i2; tempReal = period; if (im != Decimal.Zero && re != Decimal.Zero) { period = 360m / (DecimalMath.Atan(im / re) * rad2Deg); } tempReal2 = 1.5m * tempReal; if (period > tempReal2) { period = tempReal2; } tempReal2 = 0.67m * tempReal; if (period < tempReal2) { period = tempReal2; } if (period < 6m) { period = 6m; } else if (period > 50m) { period = 50m; } period = 0.2m * period + 0.8m * tempReal; today++; } outNbElement = outIdx; return(RetCode.Success); }
public static RetCode HtPhasor(int startIdx, int endIdx, decimal[] inReal, ref int outBegIdx, ref int outNBElement, decimal[] outInPhase, decimal[] outQuadrature) { if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outInPhase == null || outQuadrature == null) { return(RetCode.BadParam); } int lookbackTotal = HtPhasorLookback(); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } const decimal rad2Deg = 180m / DecimalMath.PI; outBegIdx = startIdx; int trailingWMAIdx = startIdx - lookbackTotal; int today = trailingWMAIdx; decimal tempReal = inReal[today++]; decimal periodWMASub = tempReal; decimal periodWMASum = tempReal; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 2m; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 3m; decimal trailingWMAValue = default; int i = 9; do { tempReal = inReal[today++]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, out var _, tempReal); } while (--i != 0); int hilbertIdx = default; var hilbertVariables = InitHilbertVariables <decimal>(); int outIdx = default; decimal prevI2, prevQ2, re, im, i1ForOddPrev3, i1ForEvenPrev3, i1ForOddPrev2, i1ForEvenPrev2, smoothPeriod; decimal period = prevI2 = prevQ2 = re = im = i1ForOddPrev3 = i1ForEvenPrev3 = i1ForOddPrev2 = i1ForEvenPrev2 = smoothPeriod = default; while (today <= endIdx) { decimal i2; decimal q2; decimal adjustedPrevPeriod = 0.075m * period + 0.54m; decimal todayValue = inReal[today]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, out var smoothedValue, todayValue); if (today % 2 == 0) { DoHilbertEven(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); if (today >= startIdx) { outQuadrature[outIdx] = hilbertVariables["q1"]; outInPhase[outIdx++] = i1ForEvenPrev3; } DoHilbertEven(hilbertVariables, "jI", i1ForEvenPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); if (++hilbertIdx == 3) { hilbertIdx = 0; } q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForEvenPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForOddPrev3 = i1ForOddPrev2; i1ForOddPrev2 = hilbertVariables["detrender"]; } else { DoHilbertOdd(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); if (today >= startIdx) { outQuadrature[outIdx] = hilbertVariables["q1"]; outInPhase[outIdx++] = i1ForOddPrev3; } DoHilbertOdd(hilbertVariables, "jI", i1ForEvenPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); if (++hilbertIdx == 3) { hilbertIdx = 0; } q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForEvenPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForEvenPrev3 = i1ForEvenPrev2; i1ForEvenPrev2 = hilbertVariables["detrender"]; } re = 0.2m * (i2 * prevI2 + q2 * prevQ2) + 0.8m * re; im = 0.2m * (i2 * prevQ2 - q2 * prevI2) + 0.8m * im; prevQ2 = q2; prevI2 = i2; tempReal = period; if (im != Decimal.Zero && re != Decimal.Zero) { period = 360m / (DecimalMath.Atan(im / re) * rad2Deg); } decimal tempReal2 = 1.5m * tempReal; if (period > tempReal2) { period = tempReal2; } tempReal2 = 0.67m * tempReal; if (period < tempReal2) { period = tempReal2; } if (period < 6m) { period = 6m; } else if (period > 50m) { period = 50m; } period = 0.2m * period + 0.8m * tempReal; today++; } outNBElement = outIdx; return(RetCode.Success); }
public static RetCode HtTrendline(decimal[] inReal, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outReal == null) { return(RetCode.BadParam); } int lookbackTotal = HtTrendlineLookback(); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return(RetCode.Success); } const int smoothPriceSize = 50; var smoothPrice = new decimal[smoothPriceSize]; decimal iTrend2, iTrend1; decimal iTrend3 = iTrend2 = iTrend1 = default; const decimal rad2Deg = 180m / DecimalMath.PI; outBegIdx = startIdx; int trailingWMAIdx = startIdx - lookbackTotal; int today = trailingWMAIdx; decimal tempReal = inReal[today++]; decimal periodWMASub = tempReal; decimal periodWMASum = tempReal; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 2m; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 3m; decimal trailingWMAValue = default; var i = 34; do { tempReal = inReal[today++]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, tempReal, out _); } while (--i != 0); int hilbertIdx = default; int smoothPriceIdx = default; var hilbertVariables = InitHilbertVariables <decimal>(); int outIdx = default; decimal prevI2, prevQ2, re, im, i1ForOddPrev3, i1ForEvenPrev3, i1ForOddPrev2, i1ForEvenPrev2, smoothPeriod; decimal period = prevI2 = prevQ2 = re = im = i1ForOddPrev3 = i1ForEvenPrev3 = i1ForOddPrev2 = i1ForEvenPrev2 = smoothPeriod = default; while (today <= endIdx) { decimal i2; decimal q2; decimal adjustedPrevPeriod = 0.075m * period + 0.54m; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, inReal[today], out var smoothedValue); smoothPrice[smoothPriceIdx] = smoothedValue; if (today % 2 == 0) { DoHilbertEven(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jI", i1ForEvenPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); if (++hilbertIdx == 3) { hilbertIdx = 0; } q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForEvenPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForOddPrev3 = i1ForOddPrev2; i1ForOddPrev2 = hilbertVariables["detrender"]; } else { DoHilbertOdd(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jI", i1ForOddPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForOddPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForEvenPrev3 = i1ForEvenPrev2; i1ForEvenPrev2 = hilbertVariables["detrender"]; } re = 0.2m * (i2 * prevI2 + q2 * prevQ2) + 0.8m * re; im = 0.2m * (i2 * prevQ2 - q2 * prevI2) + 0.8m * im; prevQ2 = q2; prevI2 = i2; tempReal = period; if (im != Decimal.Zero && re != Decimal.Zero) { period = 360m / (DecimalMath.Atan(im / re) * rad2Deg); } decimal tempReal2 = 1.5m * tempReal; if (period > tempReal2) { period = tempReal2; } tempReal2 = 0.67m * tempReal; if (period < tempReal2) { period = tempReal2; } if (period < 6m) { period = 6m; } else if (period > 50m) { period = 50m; } period = 0.2m * period + 0.8m * tempReal; smoothPeriod = 0.33m * period + 0.67m * smoothPeriod; decimal dcPeriod = smoothPeriod + 0.5m; var dcPeriodInt = (int)dcPeriod; int idx = today; tempReal = default; for (i = 0; i < dcPeriodInt; i++) { tempReal += inReal[idx--]; } if (dcPeriodInt > 0) { tempReal /= dcPeriodInt; } tempReal2 = (4m * tempReal + 3m * iTrend1 + 2m * iTrend2 + iTrend3) / 10m; iTrend3 = iTrend2; iTrend2 = iTrend1; iTrend1 = tempReal; if (today >= startIdx) { outReal[outIdx++] = tempReal2; } if (++smoothPriceIdx > smoothPriceSize - 1) { smoothPriceIdx = 0; } today++; } outNbElement = outIdx; return(RetCode.Success); }
public static RetCode HtTrendMode(int startIdx, int endIdx, decimal[] inReal, ref int outBegIdx, ref int outNBElement, int[] outInteger) { if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outInteger == null) { return(RetCode.BadParam); } const int smoothPriceSize = 50; var smoothPrice = new decimal[smoothPriceSize]; const decimal rad2Deg = 180m / DecimalMath.PI; const decimal deg2Rad = Decimal.One / rad2Deg; const decimal constDeg2RadBy360 = 2m * DecimalMath.PI; decimal iTrend3 = default; decimal iTrend2 = iTrend3; decimal iTrend1 = iTrend2; int daysInTrend = default; decimal sine = default; decimal leadSine = default; int lookbackTotal = HtTrendModeLookback(); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } outBegIdx = startIdx; int trailingWMAIdx = startIdx - lookbackTotal; int today = trailingWMAIdx; decimal tempReal = inReal[today++]; decimal periodWMASub = tempReal; decimal periodWMASum = tempReal; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 2m; tempReal = inReal[today++]; periodWMASub += tempReal; periodWMASum += tempReal * 3m; decimal trailingWMAValue = default; int i = 34; do { tempReal = inReal[today++]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, out var _, tempReal); } while (--i != 0); int hilbertIdx = default; int smoothPriceIdx = default; var hilbertVariables = InitHilbertVariables <decimal>(); int outIdx = default; decimal prevI2, prevQ2, re, im, i1ForOddPrev3, i1ForEvenPrev3, i1ForOddPrev2, i1ForEvenPrev2, smoothPeriod, dcPhase; decimal period = prevI2 = prevQ2 = re = im = i1ForOddPrev3 = i1ForEvenPrev3 = i1ForOddPrev2 = i1ForEvenPrev2 = smoothPeriod = dcPhase = default; while (today <= endIdx) { decimal i2; decimal q2; decimal adjustedPrevPeriod = 0.075m * period + 0.54m; decimal todayValue = inReal[today]; DoPriceWma(inReal, ref trailingWMAIdx, ref periodWMASub, ref periodWMASum, ref trailingWMAValue, out var smoothedValue, todayValue); smoothPrice[smoothPriceIdx] = smoothedValue; if (today % 2 == 0) { DoHilbertEven(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jI", i1ForEvenPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertEven(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); if (++hilbertIdx == 3) { hilbertIdx = 0; } q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForEvenPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForOddPrev3 = i1ForOddPrev2; i1ForOddPrev2 = hilbertVariables["detrender"]; } else { DoHilbertOdd(hilbertVariables, "detrender", smoothedValue, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "q1", hilbertVariables["detrender"], hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jI", i1ForOddPrev3, hilbertIdx, adjustedPrevPeriod); DoHilbertOdd(hilbertVariables, "jQ", hilbertVariables["q1"], hilbertIdx, adjustedPrevPeriod); q2 = 0.2m * (hilbertVariables["q1"] + hilbertVariables["jI"]) + 0.8m * prevQ2; i2 = 0.2m * (i1ForOddPrev3 - hilbertVariables["jQ"]) + 0.8m * prevI2; i1ForEvenPrev3 = i1ForEvenPrev2; i1ForEvenPrev2 = hilbertVariables["detrender"]; } re = 0.2m * (i2 * prevI2 + q2 * prevQ2) + 0.8m * re; im = 0.2m * (i2 * prevQ2 - q2 * prevI2) + 0.8m * im; prevQ2 = q2; prevI2 = i2; tempReal = period; if (im != Decimal.Zero && re != Decimal.Zero) { period = 360m / (DecimalMath.Atan(im / re) * rad2Deg); } decimal tempReal2 = 1.5m * tempReal; if (period > tempReal2) { period = tempReal2; } tempReal2 = 0.67m * tempReal; if (period < tempReal2) { period = tempReal2; } if (period < 6m) { period = 6m; } else if (period > 50m) { period = 50m; } period = 0.2m * period + 0.8m * tempReal; smoothPeriod = 0.33m * period + 0.67m * smoothPeriod; decimal prevDCPhase = dcPhase; decimal dcPeriod = smoothPeriod + 0.5m; int dcPeriodInt = (int)dcPeriod; decimal realPart = default; decimal imagPart = default; int idx = smoothPriceIdx; for (i = 0; i < dcPeriodInt; i++) { tempReal = i * constDeg2RadBy360 / dcPeriodInt; tempReal2 = smoothPrice[idx]; realPart += DecimalMath.Sin(tempReal) * tempReal2; imagPart += DecimalMath.Cos(tempReal) * tempReal2; if (idx == 0) { idx = smoothPriceSize - 1; } else { idx--; } } tempReal = Math.Abs(imagPart); if (tempReal > Decimal.Zero) { dcPhase = DecimalMath.Atan(realPart / imagPart) * rad2Deg; } else if (tempReal <= 0.01m) { if (realPart < Decimal.Zero) { dcPhase -= 90m; } else if (realPart > Decimal.Zero) { dcPhase += 90m; } } dcPhase += 90m; dcPhase += 360m / smoothPeriod; if (imagPart < Decimal.Zero) { dcPhase += 180m; } if (dcPhase > 315m) { dcPhase -= 360m; } decimal prevSine = sine; decimal prevLeadSine = leadSine; sine = DecimalMath.Sin(dcPhase * deg2Rad); leadSine = DecimalMath.Sin((dcPhase + 45m) * deg2Rad); dcPeriod = smoothPeriod + 0.5m; dcPeriodInt = (int)dcPeriod; idx = today; tempReal = default; for (i = 0; i < dcPeriodInt; i++) { tempReal += inReal[idx--]; } if (dcPeriodInt > 0) { tempReal /= dcPeriodInt; } decimal trendline = (4m * tempReal + 3m * iTrend1 + 2m * iTrend2 + iTrend3) / 10m; iTrend3 = iTrend2; iTrend2 = iTrend1; iTrend1 = tempReal; int trend = 1; if (sine > leadSine && prevSine <= prevLeadSine || sine < leadSine && prevSine >= prevLeadSine) { daysInTrend = 0; trend = 0; } if (++daysInTrend < 0.5m * smoothPeriod) { trend = 0; } tempReal = dcPhase - prevDCPhase; if (smoothPeriod != Decimal.Zero && tempReal > 0.67m * 360m / smoothPeriod && tempReal < 1.5m * 360m / smoothPeriod) { trend = 0; } tempReal = smoothPrice[smoothPriceIdx]; if (trendline != Decimal.Zero && Math.Abs((tempReal - trendline) / trendline) >= 0.015m) { trend = 1; } if (today >= startIdx) { outInteger[outIdx++] = trend; } if (++smoothPriceIdx > smoothPriceSize - 1) { smoothPriceIdx = 0; } today++; } outNBElement = outIdx; return(RetCode.Success); }