public static RetCode Tan(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.Tan(inReal[i]); } outBegIdx = startIdx; outNbElement = outIdx; return(RetCode.Success); }
private static void TA_INT_StdDevUsingPrecalcMA(decimal[] inReal, decimal[] inMovAvg, int inMovAvgBegIdx, int inMovAvgNbElement, decimal[] outReal, int optInTimePeriod) { decimal tempReal; int startSum = inMovAvgBegIdx + 1 - optInTimePeriod; int endSum = inMovAvgBegIdx; decimal periodTotal2 = default; for (int outIdx = startSum; outIdx < endSum; outIdx++) { tempReal = inReal[outIdx]; tempReal *= tempReal; periodTotal2 += tempReal; } for (var outIdx = 0; outIdx < inMovAvgNbElement; outIdx++, startSum++, endSum++) { tempReal = inReal[endSum]; tempReal *= tempReal; periodTotal2 += tempReal; decimal meanValue2 = periodTotal2 / optInTimePeriod; tempReal = inReal[startSum]; tempReal *= tempReal; periodTotal2 -= tempReal; tempReal = inMovAvg[outIdx]; tempReal *= tempReal; meanValue2 -= tempReal; outReal[outIdx] = !TA_IsZeroOrNeg(meanValue2) ? DecimalMath.Sqrt(meanValue2) : Decimal.Zero; } }
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); }
private static void TA_INT_StdDevUsingPrecalcMA(decimal[] inReal, decimal[] inMovAvg, int inMovAvgBegIdx, int inMovAvgNbElement, int timePeriod, decimal[] output) { decimal tempReal; int outIdx; int startSum = inMovAvgBegIdx + 1 - timePeriod; int endSum = inMovAvgBegIdx; decimal periodTotal2 = default; for (outIdx = startSum; outIdx < endSum; outIdx++) { tempReal = inReal[outIdx]; tempReal *= tempReal; periodTotal2 += tempReal; } outIdx = 0; while (outIdx < inMovAvgNbElement) { tempReal = inReal[endSum]; tempReal *= tempReal; periodTotal2 += tempReal; decimal meanValue2 = periodTotal2 / timePeriod; tempReal = inReal[startSum]; tempReal *= tempReal; periodTotal2 -= tempReal; tempReal = inMovAvg[outIdx]; tempReal *= tempReal; meanValue2 -= tempReal; if (meanValue2 >= 1E-08m) { output[outIdx] = DecimalMath.Sqrt(meanValue2); } else { output[outIdx] = Decimal.Zero; } outIdx++; startSum++; endSum++; } }
public static RetCode StdDev(decimal[] inReal, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement, int optInTimePeriod = 5, decimal optInNbDev = 1m) { 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); } RetCode retCode = TA_INT_VAR(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod); if (retCode != RetCode.Success) { return(retCode); } if (optInNbDev != Decimal.One) { for (var i = 0; i < outNbElement; i++) { decimal tempReal = outReal[i]; outReal[i] = !TA_IsZeroOrNeg(tempReal) ? DecimalMath.Sqrt(tempReal) * optInNbDev : Decimal.Zero; } } else { for (var i = 0; i < outNbElement; i++) { decimal tempReal = outReal[i]; outReal[i] = !TA_IsZeroOrNeg(tempReal) ? DecimalMath.Sqrt(tempReal) : Decimal.Zero; } } return(RetCode.Success); }
public static RetCode Cos(int startIdx, int endIdx, decimal[] inReal, ref int outBegIdx, ref int outNBElement, decimal[] outReal) { 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.Cos(inReal[i]); } outNBElement = outIdx; outBegIdx = startIdx; return RetCode.Success; }
public static RetCode Correl(decimal[] inReal0, decimal[] inReal1, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement, int optInTimePeriod = 30) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal0 == null || inReal1 == null || outReal == null || optInTimePeriod < 1 || optInTimePeriod > 100000) { return(RetCode.BadParam); } int lookbackTotal = CorrelLookback(optInTimePeriod); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return(RetCode.Success); } outBegIdx = startIdx; int trailingIdx = startIdx - lookbackTotal; decimal sumX, sumY, sumX2, sumY2; decimal sumXY = sumX = sumY = sumX2 = sumY2 = default; int today; for (today = trailingIdx; today <= startIdx; today++) { decimal x = inReal0[today]; sumX += x; sumX2 += x * x; decimal y = inReal1[today]; sumXY += x * y; sumY += y; sumY2 += y * y; } decimal trailingX = inReal0[trailingIdx]; decimal trailingY = inReal1[trailingIdx++]; decimal tempReal = (sumX2 - sumX * sumX / optInTimePeriod) * (sumY2 - sumY * sumY / optInTimePeriod); outReal[0] = !TA_IsZeroOrNeg(tempReal) ? (sumXY - sumX * sumY / optInTimePeriod) / DecimalMath.Sqrt(tempReal) : Decimal.Zero; int outIdx = 1; while (today <= endIdx) { sumX -= trailingX; sumX2 -= trailingX * trailingX; sumXY -= trailingX * trailingY; sumY -= trailingY; sumY2 -= trailingY * trailingY; decimal x = inReal0[today]; sumX += x; sumX2 += x * x; decimal y = inReal1[today++]; sumXY += x * y; sumY += y; sumY2 += y * y; trailingX = inReal0[trailingIdx]; trailingY = inReal1[trailingIdx++]; tempReal = (sumX2 - sumX * sumX / optInTimePeriod) * (sumY2 - sumY * sumY / optInTimePeriod); outReal[outIdx++] = !TA_IsZeroOrNeg(tempReal) ? (sumXY - sumX * sumY / optInTimePeriod) / DecimalMath.Sqrt(tempReal) : Decimal.Zero; } 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); }