/// <summary> /// 计算区间最大值、最小值、振幅,计算好的结果直接设置在trend上 /// </summary> /// <param name="trend">Trend.</param> /// <param name="lk">Lk.</param> /// <param name="start">Start.</param> /// <param name="end">End.</param> public static void CalHighLowValue(KTrend trend, MAType type, IList<KJapaneseData> lk, int start, int end) { decimal hi = trend.StartValue, lo = trend.StartValue; for (int i = start + 1; i <= end; i++){ decimal v = 0; switch (type){ case MAType.MAShort: case MAType.MALong: v = lk[i].ClosePrice; break; case MAType.VMAShort: case MAType.VMALong: v = lk[i].Volume; break; } if (lk[i].ClosePrice > hi) hi = lk[i].ClosePrice; if (lk[i].ClosePrice < lo) lo = lk[i].ClosePrice; } trend.HighValue = hi; trend.LowValue = lo; trend.Amplitude = CalNetChange(lo, hi); }
/// <summary> /// /// </summary> /// <param name="values">值列表,必须保证start前至少有n*round个元素,end后至少有n*round个元素</param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="n"></param> /// <param name="round">需要重复计算几轮</param> /// <param name="type"></param> /// <returns>返回结果均值列表,结果列表中索引0到最后的一个值分别对应values中索引start到end元素的计算结果均值。<br /> /// 每经过一轮计算,返回的结果列表元素个数比values减少2n个(头、为各减少n个)</returns> private static IList<decimal> CalculateMA(IList<decimal> values, int start, int end, int n, int round, MAType type, int weight) { int s=start, e=end; for(int loop=round; loop>=1; loop--){ //注意: //1.CalcCusMA需要的是计算起始点、终止点在values中的索引,而start、end是在kdatas中的索引,不能使用start和end; //2.每经历1次CalcCusMA调用,values中的元素个数减少2n个; values = CalculateMA(values, s, e, n, type, weight); //第一次使用入参start、end作为CalcCusMA的start、end //执行1次CalcCusMA后,values中前后多余的元素已经被移除,后续再调用CalcCusMA时,参数start、end即变成固定值 s = n; e = values.Count-1-n; } return values; }
public static RetCode Bbands(int startIdx, int endIdx, double[] inReal, int optInTimePeriod, double optInNbDevUp, double optInNbDevDn, MAType optInMAType, ref int outBegIdx, ref int outNBElement, double[] outRealUpperBand, double[] outRealMiddleBand, double[] outRealLowerBand) { int i; double tempReal2; double tempReal; double[] tempBuffer2; double[] tempBuffer1; if (startIdx < 0) { return(RetCode.OutOfRangeStartIndex); } if ((endIdx < 0) || (endIdx < startIdx)) { return(RetCode.OutOfRangeEndIndex); } if (inReal == null) { return(RetCode.BadParam); } if (optInTimePeriod == -2147483648) { optInTimePeriod = 5; } else if ((optInTimePeriod < 2) || (optInTimePeriod > 0x186a0)) { return(RetCode.BadParam); } if (optInNbDevUp == -4E+37) { optInNbDevUp = 2.0; } else if ((optInNbDevUp < -3E+37) || (optInNbDevUp > 3E+37)) { return(RetCode.BadParam); } if (optInNbDevDn == -4E+37) { optInNbDevDn = 2.0; } else if ((optInNbDevDn < -3E+37) || (optInNbDevDn > 3E+37)) { return(RetCode.BadParam); } if (outRealUpperBand == null) { return(RetCode.BadParam); } if (outRealMiddleBand == null) { return(RetCode.BadParam); } if (outRealLowerBand == null) { return(RetCode.BadParam); } if (inReal == outRealUpperBand) { tempBuffer1 = outRealMiddleBand; tempBuffer2 = outRealLowerBand; } else if (inReal == outRealLowerBand) { tempBuffer1 = outRealMiddleBand; tempBuffer2 = outRealUpperBand; } else if (inReal == outRealMiddleBand) { tempBuffer1 = outRealLowerBand; tempBuffer2 = outRealUpperBand; } else { tempBuffer1 = outRealMiddleBand; tempBuffer2 = outRealUpperBand; } if ((tempBuffer1 == inReal) || (tempBuffer2 == inReal)) { return(RetCode.BadParam); } RetCode retCode = MovingAverage(startIdx, endIdx, inReal, optInTimePeriod, optInMAType, ref outBegIdx, ref outNBElement, tempBuffer1); if ((retCode != RetCode.Success) || (outNBElement == 0)) { outNBElement = 0; return(retCode); } if (optInMAType == MAType.Sma) { TA_INT_stddev_using_precalc_ma(inReal, tempBuffer1, outBegIdx, outNBElement, optInTimePeriod, tempBuffer2); } else { retCode = StdDev(outBegIdx, endIdx, inReal, optInTimePeriod, 1.0, ref outBegIdx, ref outNBElement, tempBuffer2); if (retCode != RetCode.Success) { outNBElement = 0; return(retCode); } } if (tempBuffer1 != outRealMiddleBand) { Array.Copy(tempBuffer1, 0, outRealMiddleBand, 0, outNBElement); } if (optInNbDevUp != optInNbDevDn) { if (optInNbDevUp != 1.0) { if (optInNbDevDn != 1.0) { i = 0; while (i < outNBElement) { tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + (tempReal * optInNbDevUp); outRealLowerBand[i] = tempReal2 - (tempReal * optInNbDevDn); i++; } goto Label_02B1; } i = 0; goto Label_025E; } i = 0; } else { if (optInNbDevUp != 1.0) { i = 0; } else { i = 0; while (i < outNBElement) { tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + tempReal; outRealLowerBand[i] = tempReal2 - tempReal; i++; } goto Label_02B1; } while (i < outNBElement) { tempReal = tempBuffer2[i] * optInNbDevUp; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + tempReal; outRealLowerBand[i] = tempReal2 - tempReal; i++; } goto Label_02B1; } while (true) { if (i >= outNBElement) { goto Label_02B1; } tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + tempReal; outRealLowerBand[i] = tempReal2 - (tempReal * optInNbDevDn); i++; } Label_025E: while (i < outNBElement) { tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealLowerBand[i] = tempReal2 - tempReal; outRealUpperBand[i] = tempReal2 + (tempReal * optInNbDevUp); i++; } Label_02B1: return(RetCode.Success); }
public static RetCode Mavp(decimal[] inReal, decimal[] inPeriods, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement, MAType optInMAType = MAType.Sma, int optInMinPeriod = 2, int optInMaxPeriod = 30) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || inPeriods == null || outReal == null || optInMinPeriod < 2 || optInMinPeriod > 100000 || optInMaxPeriod < 2 || optInMaxPeriod > 100000) { return(RetCode.BadParam); } int lookbackTotal = MavpLookback(optInMAType, optInMaxPeriod); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return(RetCode.Success); } var tempInt = lookbackTotal > startIdx ? lookbackTotal : startIdx; if (tempInt > endIdx) { return(RetCode.Success); } int outputSize = endIdx - tempInt + 1; var localOutputArray = new decimal[outputSize]; int[] localPeriodArray = new int[outputSize]; for (var i = 0; i < outputSize; i++) { tempInt = (int)inPeriods[startIdx + i]; if (tempInt < optInMinPeriod) { tempInt = optInMinPeriod; } else if (tempInt > optInMaxPeriod) { tempInt = optInMaxPeriod; } localPeriodArray[i] = tempInt; } for (var i = 0; i < outputSize; i++) { int curPeriod = localPeriodArray[i]; if (curPeriod != 0) { RetCode retCode = Ma(inReal, startIdx, endIdx, localOutputArray, out _, out _, optInMAType, curPeriod); if (retCode != RetCode.Success) { return(retCode); } outReal[i] = localOutputArray[i]; for (var j = i + 1; j < outputSize; j++) { if (localPeriodArray[j] == curPeriod) { localPeriodArray[j] = 0; outReal[j] = localOutputArray[j]; } } } } outBegIdx = startIdx; outNbElement = outputSize; return(RetCode.Success); }
public static RetCode StochF(int startIdx, int endIdx, double[] inHigh, double[] inLow, double[] inClose, MAType optInFastDMAType, ref int outBegIdx, ref int outNBElement, double[] outFastK, double[] outFastD, int optInFastKPeriod = 5, int optInFastDPeriod = 3) { if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inHigh == null || inLow == null || inClose == null || outFastK == null || outFastD == null || optInFastKPeriod < 1 || optInFastKPeriod > 100000 || optInFastDPeriod < 1 || optInFastDPeriod > 100000) { return(RetCode.BadParam); } int lookbackK = optInFastKPeriod - 1; int lookbackFastD = MaLookback(optInFastDMAType, optInFastDPeriod); int lookbackTotal = lookbackK + lookbackFastD; if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } int outIdx = default; int trailingIdx = startIdx - lookbackTotal; int today = trailingIdx + lookbackK; int highestIdx = -1; int lowestIdx = highestIdx; double highest, lowest; double diff = highest = lowest = default; double[] tempBuffer; if (outFastK == inHigh || outFastK == inLow || outFastK == inClose) { tempBuffer = outFastK; } else if (outFastD == inHigh || outFastD == inLow || outFastD == inClose) { tempBuffer = outFastD; } else { tempBuffer = new double[endIdx - today + 1]; } while (today <= endIdx) { double tmp = inLow[today]; if (lowestIdx < trailingIdx) { lowestIdx = trailingIdx; lowest = inLow[lowestIdx]; int i = lowestIdx; while (++i <= today) { tmp = inLow[i]; if (tmp < lowest) { lowestIdx = i; lowest = tmp; } } diff = (highest - lowest) / 100.0; } else if (tmp <= lowest) { lowestIdx = today; lowest = tmp; diff = (highest - lowest) / 100.0; } tmp = inHigh[today]; if (highestIdx < trailingIdx) { highestIdx = trailingIdx; highest = inHigh[highestIdx]; int i = highestIdx; while (++i <= today) { tmp = inHigh[i]; if (tmp > highest) { highestIdx = i; highest = tmp; } } diff = (highest - lowest) / 100.0; } else if (tmp >= highest) { highestIdx = today; highest = tmp; diff = (highest - lowest) / 100.0; } tempBuffer[outIdx++] = !diff.Equals(0.0) ? (inClose[today] - lowest) / diff : 0.0; trailingIdx++; today++; } RetCode retCode = Ma(0, outIdx - 1, tempBuffer, optInFastDMAType, ref outBegIdx, ref outNBElement, outFastD, optInFastDPeriod); if (retCode != RetCode.Success || outNBElement == 0) { outBegIdx = 0; outNBElement = 0; return(retCode); } Array.Copy(tempBuffer, lookbackFastD, outFastK, 0, outNBElement); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } outBegIdx = startIdx; return(RetCode.Success); }
public static RetCode Stoch(int startIdx, int endIdx, double[] inHigh, double[] inLow, double[] inClose, int optInFastK_Period, int optInSlowK_Period, MAType optInSlowK_MAType, int optInSlowD_Period, MAType optInSlowD_MAType, ref int outBegIdx, ref int outNBElement, double[] outSlowK, double[] outSlowD) { double[] tempBuffer; if (startIdx < 0) { return(RetCode.OutOfRangeStartIndex); } if ((endIdx < 0) || (endIdx < startIdx)) { return(RetCode.OutOfRangeEndIndex); } if (((inHigh == null) || (inLow == null)) || (inClose == null)) { return(RetCode.BadParam); } if (optInFastK_Period == -2147483648) { optInFastK_Period = 5; } else if ((optInFastK_Period < 1) || (optInFastK_Period > 0x186a0)) { return(RetCode.BadParam); } if (optInSlowK_Period == -2147483648) { optInSlowK_Period = 3; } else if ((optInSlowK_Period < 1) || (optInSlowK_Period > 0x186a0)) { return(RetCode.BadParam); } if (optInSlowD_Period == -2147483648) { optInSlowD_Period = 3; } else if ((optInSlowD_Period < 1) || (optInSlowD_Period > 0x186a0)) { return(RetCode.BadParam); } if (outSlowK == null) { return(RetCode.BadParam); } if (outSlowD == null) { return(RetCode.BadParam); } int lookbackK = optInFastK_Period - 1; int lookbackKSlow = MovingAverageLookback(optInSlowK_Period, optInSlowK_MAType); int lookbackDSlow = MovingAverageLookback(optInSlowD_Period, optInSlowD_MAType); int lookbackTotal = (lookbackK + lookbackDSlow) + lookbackKSlow; if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } int outIdx = 0; int trailingIdx = startIdx - lookbackTotal; int today = trailingIdx + lookbackK; int highestIdx = -1; int lowestIdx = highestIdx; double lowest = 0.0; double highest = lowest; double diff = highest; if (((outSlowK == inHigh) || (outSlowK == inLow)) || (outSlowK == inClose)) { tempBuffer = outSlowK; } else if (((outSlowD == inHigh) || (outSlowD == inLow)) || (outSlowD == inClose)) { tempBuffer = outSlowD; } else { tempBuffer = new double[(endIdx - today) + 1]; } Label_0156: if (today > endIdx) { RetCode retCode = MovingAverage(0, outIdx - 1, tempBuffer, optInSlowK_Period, optInSlowK_MAType, ref outBegIdx, ref outNBElement, tempBuffer); if ((retCode != RetCode.Success) || (outNBElement == 0)) { outBegIdx = 0; outNBElement = 0; return(retCode); } retCode = MovingAverage(0, outNBElement - 1, tempBuffer, optInSlowD_Period, optInSlowD_MAType, ref outBegIdx, ref outNBElement, outSlowD); Array.Copy(tempBuffer, lookbackDSlow, outSlowK, 0, outNBElement); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } outBegIdx = startIdx; return(RetCode.Success); } double tmp = inLow[today]; if (lowestIdx >= trailingIdx) { if (tmp <= lowest) { lowestIdx = today; lowest = tmp; diff = (highest - lowest) / 100.0; } goto Label_01B5; } lowestIdx = trailingIdx; lowest = inLow[lowestIdx]; int i = lowestIdx; Label_0173: i++; if (i <= today) { tmp = inLow[i]; if (tmp < lowest) { lowestIdx = i; lowest = tmp; } goto Label_0173; } diff = (highest - lowest) / 100.0; Label_01B5: tmp = inHigh[today]; if (highestIdx >= trailingIdx) { if (tmp >= highest) { highestIdx = today; highest = tmp; diff = (highest - lowest) / 100.0; } goto Label_0212; } highestIdx = trailingIdx; highest = inHigh[highestIdx]; i = highestIdx; Label_01CC: i++; if (i <= today) { tmp = inHigh[i]; if (tmp > highest) { highestIdx = i; highest = tmp; } goto Label_01CC; } diff = (highest - lowest) / 100.0; Label_0212: if (diff != 0.0) { tempBuffer[outIdx] = (inClose[today] - lowest) / diff; outIdx++; } else { tempBuffer[outIdx] = 0.0; outIdx++; } trailingIdx++; today++; goto Label_0156; }
public static PpoResult Ppo(int startIdx, int endIdx, double[] real, int fastPeriod, int slowPeriod, MAType maType) { int outBegIdx = default; int outNBElement = default; double[] outReal = new double[endIdx - startIdx + 1]; RetCode retCode = TACore.Ppo( startIdx, endIdx, real, fastPeriod, slowPeriod, maType, ref outBegIdx, ref outNBElement, ref outReal); return(new(retCode, outBegIdx, outNBElement, outReal)); }
public static int MacdExtLookback(MAType optInFastMAType, MAType optInSlowMAType, MAType optInSignalMAType, int optInFastPeriod = 12, int optInSlowPeriod = 26, int optInSignalPeriod = 9) { if (optInFastPeriod < 2 || optInFastPeriod > 100000 || optInSlowPeriod < 2 || optInSlowPeriod > 100000 || optInSignalPeriod < 1 || optInSignalPeriod > 100000) { return(-1); } int lookbackLargest = MaLookback(optInFastMAType, optInFastPeriod); int tempInteger = MaLookback(optInSlowMAType, optInSlowPeriod); if (tempInteger > lookbackLargest) { lookbackLargest = tempInteger; } return(lookbackLargest + MaLookback(optInSignalMAType, optInSignalPeriod)); }
private static RetCode TA_INT_PO(int startIdx, int endIdx, decimal[] inReal0, int optInFastPeriod0, int optInSlowPeriod1, MAType optInMethod2, ref int outBegIdx, ref int outNbElement, decimal[] outReal0, decimal[] tempBuffer, int doPercentageOutput) { int tempInteger; int outBegIdx2 = default; int outNbElement2 = default; if (optInSlowPeriod1 < optInFastPeriod0) { tempInteger = optInSlowPeriod1; optInSlowPeriod1 = optInFastPeriod0; optInFastPeriod0 = tempInteger; } RetCode retCode = Ma(startIdx, endIdx, inReal0, optInMethod2, ref outBegIdx2, ref outNbElement2, tempBuffer, optInFastPeriod0); if (retCode == RetCode.Success) { int outNbElement1 = default; int outBegIdx1 = default; retCode = Ma(startIdx, endIdx, inReal0, optInMethod2, ref outBegIdx1, ref outNbElement1, outReal0, optInSlowPeriod1); if (retCode == RetCode.Success) { int i; int j; tempInteger = outBegIdx1 - outBegIdx2; if (doPercentageOutput == 0) { i = 0; j = tempInteger; while (i < outNbElement1) { outReal0[i] = tempBuffer[j] - outReal0[i]; i++; j++; } } else { i = 0; for (j = tempInteger; i < outNbElement1; j++) { decimal tempReal = outReal0[i]; if (-1E-08m >= tempReal || tempReal >= 1E-08m) { outReal0[i] = (tempBuffer[j] - tempReal) / tempReal * 100m; } else { outReal0[i] = Decimal.Zero; } i++; } } outBegIdx = outBegIdx1; outNbElement = outNbElement1; } } if (retCode != RetCode.Success) { outBegIdx = 0; outNbElement = 0; } return(retCode); }
public static PpoResult Ppo(int startIdx, int endIdx, float[] real, int fastPeriod, int slowPeriod, MAType maType) => Ppo(startIdx, endIdx, real.ToDouble(), fastPeriod, slowPeriod, maType);
public static RetCode MovingAverage(int startIdx, int endIdx, float[] inReal, int optInTimePeriod, MAType optInMAType, ref int outBegIdx, ref int outNBElement, double[] outReal) { if (startIdx < 0) { return(RetCode.OutOfRangeStartIndex); } if ((endIdx < 0) || (endIdx < startIdx)) { return(RetCode.OutOfRangeEndIndex); } if (inReal == null) { return(RetCode.BadParam); } if (optInTimePeriod == -2147483648) { optInTimePeriod = 30; } else if ((optInTimePeriod < 1) || (optInTimePeriod > 0x186a0)) { return(RetCode.BadParam); } if (outReal == null) { return(RetCode.BadParam); } if (optInTimePeriod != 1) { switch (optInMAType) { case MAType.Sma: return(Sma(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal)); case MAType.Ema: return(Ema(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal)); case MAType.Wma: return(Wma(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal)); case MAType.Dema: return(Dema(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal)); case MAType.Tema: return(Tema(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal)); case MAType.Trima: return(Trima(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal)); case MAType.Kama: return(Kama(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal)); case MAType.Mama: { double[] dummyBuffer = new double[(endIdx - startIdx) + 1]; if (dummyBuffer != null) { return(Mama(startIdx, endIdx, inReal, 0.5, 0.05, ref outBegIdx, ref outNBElement, outReal, dummyBuffer)); } return(RetCode.AllocErr); } case MAType.T3: return(T3(startIdx, endIdx, inReal, optInTimePeriod, 0.7, ref outBegIdx, ref outNBElement, outReal)); } return(RetCode.BadParam); } int nbElement = (endIdx - startIdx) + 1; outNBElement = nbElement; int todayIdx = startIdx; int outIdx = 0; while (outIdx < nbElement) { outReal[outIdx] = inReal[todayIdx]; outIdx++; todayIdx++; } outBegIdx = startIdx; return(RetCode.Success); }
public StandardDeviation(double[] x, MAType type = MAType.SMA, int period = 14) { double var = new Variance(x: x, period: period, type: type).Value; sd = Math.Sqrt(var); }
public static RetCode Ppo( int startIdx, int endIdx, float[] inReal, int optInFastPeriod, int optInSlowPeriod, MAType optInMAType, ref int outBegIdx, ref int outNBElement, double[] outReal) { if (startIdx < 0) { return(RetCode.OutOfRangeStartIndex); } if ((endIdx < 0) || (endIdx < startIdx)) { return(RetCode.OutOfRangeEndIndex); } if (inReal == null) { return(RetCode.BadParam); } if (optInFastPeriod == -2147483648) { optInFastPeriod = 12; } else if ((optInFastPeriod < 2) || (optInFastPeriod > 0x186a0)) { return(RetCode.BadParam); } if (optInSlowPeriod == -2147483648) { optInSlowPeriod = 0x1a; } else if ((optInSlowPeriod < 2) || (optInSlowPeriod > 0x186a0)) { return(RetCode.BadParam); } if (outReal == null) { return(RetCode.BadParam); } double[] tempBuffer = new double[(endIdx - startIdx) + 1]; if (tempBuffer == null) { return(RetCode.AllocErr); } return(TA_INT_PO( startIdx, endIdx, inReal, optInFastPeriod, optInSlowPeriod, optInMAType, ref outBegIdx, ref outNBElement, outReal, tempBuffer, 1)); }
public static RetCode Ma(decimal[] inReal, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement, MAType optInMAType, int optInTimePeriod = 30) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outReal == null || optInTimePeriod < 1 || optInTimePeriod > 100000) { return(RetCode.BadParam); } if (optInTimePeriod != 1) { switch (optInMAType) { case MAType.Sma: return(Sma(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); case MAType.Ema: return(Ema(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); case MAType.Wma: return(Wma(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); case MAType.Dema: return(Dema(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); case MAType.Tema: return(Tema(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); case MAType.Trima: return(Trima(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); case MAType.Kama: return(Kama(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); case MAType.Mama: var dummyBuffer = new decimal[endIdx - startIdx + 1]; return(Mama(inReal, startIdx, endIdx, outReal, dummyBuffer, out outBegIdx, out outNbElement)); case MAType.T3: return(T3(inReal, startIdx, endIdx, outReal, out outBegIdx, out outNbElement, optInTimePeriod)); } return(RetCode.BadParam); } int nbElement = endIdx - startIdx + 1; outNbElement = nbElement; int todayIdx = startIdx; int outIdx = default; while (outIdx < nbElement) { outReal[outIdx] = inReal[todayIdx]; outIdx++; todayIdx++; } outBegIdx = startIdx; return(RetCode.Success); }
public static RetCode Bbands(double[] inReal, int startIdx, int endIdx, double[] outRealUpperBand, double[] outRealMiddleBand, double[] outRealLowerBand, out int outBegIdx, out int outNbElement, MAType optInMAType, int optInTimePeriod = 5, double optInNbDevUp = 2.0, double optInNbDevDn = 2.0) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outRealUpperBand == null || outRealMiddleBand == null || outRealLowerBand == null || optInTimePeriod < 2 || optInTimePeriod > 100000) { return(RetCode.BadParam); } double[] tempBuffer1; double[] tempBuffer2; if (inReal == outRealUpperBand) { tempBuffer1 = outRealMiddleBand; tempBuffer2 = outRealLowerBand; } else if (inReal == outRealLowerBand) { tempBuffer1 = outRealMiddleBand; tempBuffer2 = outRealUpperBand; } else if (inReal == outRealMiddleBand) { tempBuffer1 = outRealLowerBand; tempBuffer2 = outRealUpperBand; } else { tempBuffer1 = outRealMiddleBand; tempBuffer2 = outRealUpperBand; } if (tempBuffer1 == inReal || tempBuffer2 == inReal) { return(RetCode.BadParam); } RetCode retCode = Ma(inReal, startIdx, endIdx, tempBuffer1, out outBegIdx, out outNbElement, optInMAType, optInTimePeriod); if (retCode != RetCode.Success || outNbElement == 0) { return(retCode); } if (optInMAType == MAType.Sma) { TA_INT_StdDevUsingPrecalcMA(inReal, tempBuffer1, outBegIdx, outNbElement, tempBuffer2, optInTimePeriod); } else { retCode = StdDev(inReal, outBegIdx, endIdx, tempBuffer2, out outBegIdx, out outNbElement, optInTimePeriod); if (retCode != RetCode.Success) { outNbElement = 0; return(retCode); } } if (tempBuffer1 != outRealMiddleBand) { Array.Copy(tempBuffer1, 0, outRealMiddleBand, 0, outNbElement); } double tempReal; double tempReal2; if (optInNbDevUp.Equals(optInNbDevDn)) { if (optInNbDevUp.Equals(1.0)) { for (var i = 0; i < outNbElement; i++) { tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + tempReal; outRealLowerBand[i] = tempReal2 - tempReal; } } else { for (var i = 0; i < outNbElement; i++) { tempReal = tempBuffer2[i] * optInNbDevUp; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + tempReal; outRealLowerBand[i] = tempReal2 - tempReal; } } } else if (optInNbDevUp.Equals(1.0)) { for (var i = 0; i < outNbElement; i++) { tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + tempReal; outRealLowerBand[i] = tempReal2 - tempReal * optInNbDevDn; } } else if (optInNbDevDn.Equals(1.0)) { for (var i = 0; i < outNbElement; i++) { tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealLowerBand[i] = tempReal2 - tempReal; outRealUpperBand[i] = tempReal2 + tempReal * optInNbDevUp; } } else { for (var i = 0; i < outNbElement; i++) { tempReal = tempBuffer2[i]; tempReal2 = outRealMiddleBand[i]; outRealUpperBand[i] = tempReal2 + tempReal * optInNbDevUp; outRealLowerBand[i] = tempReal2 - tempReal * optInNbDevDn; } } return(RetCode.Success); }
private static RetCode TA_INT_PO(decimal[] inReal, int startIdx, int endIdx, decimal[] outReal, out int outBegIdx, out int outNbElement, int optInFastPeriod, int optInSlowPeriod, MAType optInMethod, decimal[] tempBuffer, bool doPercentageOutput) { outBegIdx = outNbElement = 0; int tempInteger; if (optInSlowPeriod < optInFastPeriod) { tempInteger = optInSlowPeriod; optInSlowPeriod = optInFastPeriod; optInFastPeriod = tempInteger; } RetCode retCode = Ma(inReal, startIdx, endIdx, tempBuffer, out var outBegIdx2, out _, optInMethod, optInFastPeriod); if (retCode != RetCode.Success) { return(retCode); } retCode = Ma(inReal, startIdx, endIdx, outReal, out var outBegIdx1, out var outNbElement1, optInMethod, optInSlowPeriod); if (retCode != RetCode.Success) { return(retCode); } tempInteger = outBegIdx1 - outBegIdx2; for (int i = 0, j = tempInteger; i < outNbElement1; i++, j++) { if (doPercentageOutput) { decimal tempReal = outReal[i]; outReal[i] = !TA_IsZero(tempReal) ? (tempBuffer[j] - tempReal) / tempReal * 100m : Decimal.Zero; } else { outReal[i] = tempBuffer[j] - outReal[i]; } } outBegIdx = outBegIdx1; outNbElement = outNbElement1; return(retCode); }
public static RetCode MovingAverageVariablePeriod( int startIdx, int endIdx, double[] inReal, double[] inPeriods, int optInMinPeriod, int optInMaxPeriod, MAType optInMAType, ref int outBegIdx, ref int outNBElement, double[] outReal) { int i; int tempInt = 0; if (startIdx < 0) { return(RetCode.OutOfRangeStartIndex); } if ((endIdx < 0) || (endIdx < startIdx)) { return(RetCode.OutOfRangeEndIndex); } if (inReal == null) { return(RetCode.BadParam); } if (inPeriods == null) { return(RetCode.BadParam); } if (optInMinPeriod == -2147483648) { optInMinPeriod = 2; } else if ((optInMinPeriod < 2) || (optInMinPeriod > 0x186a0)) { return(RetCode.BadParam); } if (optInMaxPeriod == -2147483648) { optInMaxPeriod = 30; } else if ((optInMaxPeriod < 2) || (optInMaxPeriod > 0x186a0)) { return(RetCode.BadParam); } if (outReal == null) { return(RetCode.BadParam); } int lookbackTotal = MovingAverageLookback(optInMaxPeriod, optInMAType); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } if (lookbackTotal > startIdx) { tempInt = lookbackTotal; } else { tempInt = startIdx; } if (tempInt > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } int outputSize = (endIdx - tempInt) + 1; double[] localOutputArray = new double[outputSize]; int[] localPeriodArray = new int[outputSize]; for (i = 0; i < outputSize; i++) { tempInt = (int)inPeriods[startIdx + i]; if (tempInt < optInMinPeriod) { tempInt = optInMinPeriod; } else if (tempInt > optInMaxPeriod) { tempInt = optInMaxPeriod; } localPeriodArray[i] = tempInt; } i = 0; while (true) { if (i >= outputSize) { outBegIdx = startIdx; outNBElement = outputSize; return(RetCode.Success); } int curPeriod = localPeriodArray[i]; if (curPeriod != 0) { int localNbElement = 0; int localBegIdx = 0; RetCode retCode = MovingAverage( startIdx, endIdx, inReal, curPeriod, optInMAType, ref localBegIdx, ref localNbElement, localOutputArray); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } outReal[i] = localOutputArray[i]; for (int j = i + 1; j < outputSize; j++) { if (localPeriodArray[j] == curPeriod) { localPeriodArray[j] = 0; outReal[j] = localOutputArray[j]; } } } i++; } }
public static RetCode MacdExt(int startIdx, int endIdx, double[] inReal, MAType optInFastMAType, MAType optInSlowMAType, MAType optInSignalMAType, ref int outBegIdx, ref int outNBElement, double[] outMACD, double[] outMACDSignal, double[] outMACDHist, int optInFastPeriod = 12, int optInSlowPeriod = 26, int optInSignalPeriod = 9) { if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outMACD == null || outMACDSignal == null || outMACDHist == null || optInFastPeriod < 2 || optInFastPeriod > 100000 || optInSlowPeriod < 2 || optInSlowPeriod > 100000 || optInSignalPeriod < 1 || optInSignalPeriod > 100000) { return(RetCode.BadParam); } int tempInteger; if (optInSlowPeriod < optInFastPeriod) { tempInteger = optInSlowPeriod; optInSlowPeriod = optInFastPeriod; optInFastPeriod = tempInteger; MAType tempMAType = optInSlowMAType; optInSlowMAType = optInFastMAType; optInFastMAType = tempMAType; } int lookbackLargest = MaLookback(optInFastMAType, optInFastPeriod); tempInteger = MaLookback(optInSlowMAType, optInSlowPeriod); if (tempInteger > lookbackLargest) { lookbackLargest = tempInteger; } int lookbackSignal = MaLookback(optInSignalMAType, optInSignalPeriod); int lookbackTotal = lookbackSignal + lookbackLargest; if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } int outNbElement1 = default; int outNbElement2 = default; int outBegIdx2 = default; int outBegIdx1 = default; tempInteger = endIdx - startIdx + 1 + lookbackSignal; var fastMABuffer = new double[tempInteger]; var slowMABuffer = new double[tempInteger]; tempInteger = startIdx - lookbackSignal; RetCode retCode = Ma(tempInteger, endIdx, inReal, optInSlowMAType, ref outBegIdx1, ref outNbElement1, slowMABuffer, optInSlowPeriod); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } retCode = Ma(tempInteger, endIdx, inReal, optInFastMAType, ref outBegIdx2, ref outNbElement2, fastMABuffer, optInFastPeriod); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } if (outBegIdx1 != tempInteger || outBegIdx2 != tempInteger || outNbElement1 != outNbElement2 || outNbElement1 != endIdx - startIdx + 1 + lookbackSignal) { outBegIdx = 0; outNBElement = 0; return(RetCode.InternalError); } for (var i = 0; i < outNbElement1; i++) { fastMABuffer[i] -= slowMABuffer[i]; } Array.Copy(fastMABuffer, lookbackSignal, outMACD, 0, endIdx - startIdx + 1); retCode = Ma(0, outNbElement1 - 1, fastMABuffer, optInSignalMAType, ref outBegIdx2, ref outNbElement2, outMACDSignal, optInSignalPeriod); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } for (var i = 0; i < outNbElement2; i++) { outMACDHist[i] = outMACD[i] - outMACDSignal[i]; } outBegIdx = startIdx; outNBElement = outNbElement2; return(RetCode.Success); }
public MovingAverage(double[] movingAverage, MAType maType) { MA = movingAverage; this.maType = maType; }
public static int StochLookback(int optInFastK_Period, int optInSlowK_Period, MAType optInSlowK_MAType, int optInSlowD_Period, MAType optInSlowD_MAType) { if (optInFastK_Period == -2147483648) { optInFastK_Period = 5; } else if ((optInFastK_Period < 1) || (optInFastK_Period > 0x186a0)) { return(-1); } if (optInSlowK_Period == -2147483648) { optInSlowK_Period = 3; } else if ((optInSlowK_Period < 1) || (optInSlowK_Period > 0x186a0)) { return(-1); } if (optInSlowD_Period == -2147483648) { optInSlowD_Period = 3; } else if ((optInSlowD_Period < 1) || (optInSlowD_Period > 0x186a0)) { return(-1); } int retValue = optInFastK_Period - 1; retValue += MovingAverageLookback(optInSlowK_Period, optInSlowK_MAType); return(retValue + MovingAverageLookback(optInSlowD_Period, optInSlowD_MAType)); }
public static int MacdExtLookback(int optInFastPeriod, MAType optInFastMAType, int optInSlowPeriod, MAType optInSlowMAType, int optInSignalPeriod, MAType optInSignalMAType) { if (optInFastPeriod == -2147483648) { optInFastPeriod = 12; } else if ((optInFastPeriod < 2) || (optInFastPeriod > 0x186a0)) { return(-1); } if (optInSlowPeriod == -2147483648) { optInSlowPeriod = 0x1a; } else if ((optInSlowPeriod < 2) || (optInSlowPeriod > 0x186a0)) { return(-1); } if (optInSignalPeriod == -2147483648) { optInSignalPeriod = 9; } else if ((optInSignalPeriod < 1) || (optInSignalPeriod > 0x186a0)) { return(-1); } int lookbackLargest = MovingAverageLookback(optInFastPeriod, optInFastMAType); int tempInteger = MovingAverageLookback(optInSlowPeriod, optInSlowMAType); if (tempInteger > lookbackLargest) { lookbackLargest = tempInteger; } return(lookbackLargest + MovingAverageLookback(optInSignalPeriod, optInSignalMAType)); }
public static int BbandsLookback(int optInTimePeriod, double optInNbDevUp, double optInNbDevDn, MAType optInMAType) { if (optInTimePeriod == -2147483648) { optInTimePeriod = 5; } else if ((optInTimePeriod < 2) || (optInTimePeriod > 0x186a0)) { return(-1); } if (optInNbDevUp == -4E+37) { optInNbDevUp = 2.0; } else if ((optInNbDevUp < -3E+37) || (optInNbDevUp > 3E+37)) { return(-1); } if (optInNbDevDn == -4E+37) { optInNbDevDn = 2.0; } else if ((optInNbDevDn < -3E+37) || (optInNbDevDn > 3E+37)) { return(-1); } return(MovingAverageLookback(optInTimePeriod, optInMAType)); }
public static RetCode MacdExt(int startIdx, int endIdx, double[] inReal, int optInFastPeriod, MAType optInFastMAType, int optInSlowPeriod, MAType optInSlowMAType, int optInSignalPeriod, MAType optInSignalMAType, ref int outBegIdx, ref int outNBElement, double[] outMACD, double[] outMACDSignal, double[] outMACDHist) { int i; int tempInteger = 0; int outNbElement1 = 0; int outNbElement2 = 0; int outBegIdx2 = 0; int outBegIdx1 = 0; if (startIdx < 0) { return(RetCode.OutOfRangeStartIndex); } if ((endIdx < 0) || (endIdx < startIdx)) { return(RetCode.OutOfRangeEndIndex); } if (inReal == null) { return(RetCode.BadParam); } if (optInFastPeriod == -2147483648) { optInFastPeriod = 12; } else if ((optInFastPeriod < 2) || (optInFastPeriod > 0x186a0)) { return(RetCode.BadParam); } if (optInSlowPeriod == -2147483648) { optInSlowPeriod = 0x1a; } else if ((optInSlowPeriod < 2) || (optInSlowPeriod > 0x186a0)) { return(RetCode.BadParam); } if (optInSignalPeriod == -2147483648) { optInSignalPeriod = 9; } else if ((optInSignalPeriod < 1) || (optInSignalPeriod > 0x186a0)) { return(RetCode.BadParam); } if (outMACD == null) { return(RetCode.BadParam); } if (outMACDSignal == null) { return(RetCode.BadParam); } if (outMACDHist == null) { return(RetCode.BadParam); } if (optInSlowPeriod < optInFastPeriod) { tempInteger = optInSlowPeriod; optInSlowPeriod = optInFastPeriod; optInFastPeriod = tempInteger; MAType tempMAType = optInSlowMAType; optInSlowMAType = optInFastMAType; optInFastMAType = tempMAType; } int lookbackLargest = MovingAverageLookback(optInFastPeriod, optInFastMAType); tempInteger = MovingAverageLookback(optInSlowPeriod, optInSlowMAType); if (tempInteger > lookbackLargest) { lookbackLargest = tempInteger; } int lookbackSignal = MovingAverageLookback(optInSignalPeriod, optInSignalMAType); int lookbackTotal = lookbackSignal + lookbackLargest; if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } tempInteger = ((endIdx - startIdx) + 1) + lookbackSignal; double[] fastMABuffer = new double[tempInteger]; if (fastMABuffer == null) { outBegIdx = 0; outNBElement = 0; return(RetCode.AllocErr); } double[] slowMABuffer = new double[tempInteger]; if (slowMABuffer == null) { outBegIdx = 0; outNBElement = 0; return(RetCode.AllocErr); } tempInteger = startIdx - lookbackSignal; RetCode retCode = MovingAverage(tempInteger, endIdx, inReal, optInSlowPeriod, optInSlowMAType, ref outBegIdx1, ref outNbElement1, slowMABuffer); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } retCode = MovingAverage(tempInteger, endIdx, inReal, optInFastPeriod, optInFastMAType, ref outBegIdx2, ref outNbElement2, fastMABuffer); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } if (((outBegIdx1 != tempInteger) || (outBegIdx2 != tempInteger)) || ((outNbElement1 != outNbElement2) || (outNbElement1 != (((endIdx - startIdx) + 1) + lookbackSignal)))) { outBegIdx = 0; outNBElement = 0; return(RetCode.InternalError); } for (i = 0; i < outNbElement1; i++) { fastMABuffer[i] -= slowMABuffer[i]; } Array.Copy(fastMABuffer, lookbackSignal, outMACD, 0, (endIdx - startIdx) + 1); retCode = MovingAverage(0, outNbElement1 - 1, fastMABuffer, optInSignalPeriod, optInSignalMAType, ref outBegIdx2, ref outNbElement2, outMACDSignal); if (retCode != RetCode.Success) { outBegIdx = 0; outNBElement = 0; return(retCode); } for (i = 0; i < outNbElement2; i++) { outMACDHist[i] = outMACD[i] - outMACDSignal[i]; } outBegIdx = startIdx; outNBElement = outNbElement2; return(RetCode.Success); }
public static MovingAverageResult MovingAverage(int startIdx, int endIdx, float[] real, int timePeriod, MAType maType) => MovingAverage(startIdx, endIdx, real.ToDouble(), timePeriod, maType);
public static int StochRsiLookback(int optInTimePeriod, int optInFastK_Period, int optInFastD_Period, MAType optInFastD_MAType) { if (optInTimePeriod == -2147483648) { optInTimePeriod = 14; } else if ((optInTimePeriod < 2) || (optInTimePeriod > 0x186a0)) { return(-1); } if (optInFastK_Period == -2147483648) { optInFastK_Period = 5; } else if ((optInFastK_Period < 1) || (optInFastK_Period > 0x186a0)) { return(-1); } if (optInFastD_Period == -2147483648) { optInFastD_Period = 3; } else if ((optInFastD_Period < 1) || (optInFastD_Period > 0x186a0)) { return(-1); } return(RsiLookback(optInTimePeriod) + StochFLookback(optInFastK_Period, optInFastD_Period, optInFastD_MAType)); }
private static RetCode TA_INT_PO(int startIdx, int endIdx, double[] inReal_0, int optInFastPeriod_0, int optInSlowPeriod_1, MAType optInMethod_2, ref int outBegIdx, ref int outNbElement, double[] outReal_0, double[] tempBuffer, int doPercentageOutput) { int tempInteger = 0; int outBegIdx2 = 0; int outNbElement2 = 0; if (optInSlowPeriod_1 < optInFastPeriod_0) { tempInteger = optInSlowPeriod_1; optInSlowPeriod_1 = optInFastPeriod_0; optInFastPeriod_0 = tempInteger; } RetCode retCode = MovingAverage(startIdx, endIdx, inReal_0, optInFastPeriod_0, optInMethod_2, ref outBegIdx2, ref outNbElement2, tempBuffer); if (retCode == RetCode.Success) { int outNbElement1 = 0; int outBegIdx1 = 0; retCode = MovingAverage(startIdx, endIdx, inReal_0, optInSlowPeriod_1, optInMethod_2, ref outBegIdx1, ref outNbElement1, outReal_0); if (retCode == RetCode.Success) { int i; int j; tempInteger = outBegIdx1 - outBegIdx2; if (doPercentageOutput == 0) { i = 0; j = tempInteger; while (i < outNbElement1) { outReal_0[i] = tempBuffer[j] - outReal_0[i]; i++; j++; } } else { i = 0; for (j = tempInteger; i < outNbElement1; j++) { double tempReal = outReal_0[i]; if ((-1E-08 >= tempReal) || (tempReal >= 1E-08)) { outReal_0[i] = ((tempBuffer[j] - tempReal) / tempReal) * 100.0; } else { outReal_0[i] = 0.0; } i++; } } outBegIdx = outBegIdx1; outNbElement = outNbElement1; } } if (retCode != RetCode.Success) { outBegIdx = 0; outNbElement = 0; } return(retCode); }
public static RetCode StochRsi(int startIdx, int endIdx, float[] inReal, int optInTimePeriod, int optInFastK_Period, int optInFastD_Period, MAType optInFastD_MAType, ref int outBegIdx, ref int outNBElement, double[] outFastK, double[] outFastD) { int outNbElement1 = 0; int outBegIdx2 = 0; int outBegIdx1 = 0; if (startIdx < 0) { return(RetCode.OutOfRangeStartIndex); } if ((endIdx < 0) || (endIdx < startIdx)) { return(RetCode.OutOfRangeEndIndex); } if (inReal == null) { return(RetCode.BadParam); } if (optInTimePeriod == -2147483648) { optInTimePeriod = 14; } else if ((optInTimePeriod < 2) || (optInTimePeriod > 0x186a0)) { return(RetCode.BadParam); } if (optInFastK_Period == -2147483648) { optInFastK_Period = 5; } else if ((optInFastK_Period < 1) || (optInFastK_Period > 0x186a0)) { return(RetCode.BadParam); } if (optInFastD_Period == -2147483648) { optInFastD_Period = 3; } else if ((optInFastD_Period < 1) || (optInFastD_Period > 0x186a0)) { return(RetCode.BadParam); } if (outFastK == null) { return(RetCode.BadParam); } if (outFastD == null) { return(RetCode.BadParam); } outBegIdx = 0; outNBElement = 0; int lookbackSTOCHF = StochFLookback(optInFastK_Period, optInFastD_Period, optInFastD_MAType); int lookbackTotal = RsiLookback(optInTimePeriod) + lookbackSTOCHF; if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { outBegIdx = 0; outNBElement = 0; return(RetCode.Success); } outBegIdx = startIdx; int tempArraySize = ((endIdx - startIdx) + 1) + lookbackSTOCHF; double[] tempRSIBuffer = new double[tempArraySize]; RetCode retCode = Rsi(startIdx - lookbackSTOCHF, endIdx, inReal, optInTimePeriod, ref outBegIdx1, ref outNbElement1, tempRSIBuffer); if ((retCode != RetCode.Success) || (outNbElement1 == 0)) { outBegIdx = 0; outNBElement = 0; return(retCode); } retCode = StochF(0, tempArraySize - 1, tempRSIBuffer, tempRSIBuffer, tempRSIBuffer, optInFastK_Period, optInFastD_Period, optInFastD_MAType, ref outBegIdx2, ref outNBElement, outFastK, outFastD); if ((retCode != RetCode.Success) || (outNBElement == 0)) { outBegIdx = 0; outNBElement = 0; return(retCode); } return(RetCode.Success); }
private static void CalculateMA(IList<KJapaneseData> impList, int impStart, int impEnd, MAType type) { //初始化参数 int n = 0, round = 0, weight = 0; switch(type){ case MAType.MAShort: n = 2; round = 1; weight = 2; break; case MAType.MALong: n = 4; round = 2; weight = 1; break; case MAType.VMAShort: n = 2; round = 1; weight = 1; break; case MAType.VMALong: n = 2; round = 3; weight = 1; break; } //待计算的节点从impStart到impEnd,因此而受影响、需要重新计算的节点从start到end int start = impStart - n*round, end = impEnd; //初始化计算节点原始值 //注意:因为计算均量时会忽略一字板涨跌停日期,因此values中元素个数可能小于end-start+1。 IList<decimal> values = new List<decimal>(end - start + 1 + n*2*round); //前、后多取n个节点,乘以2 switch(type){ case MAType.MAShort: case MAType.MALong: //为了计算start到end的均价、均量值,需前、后追加n*round个k线数据 for(int i=start-n*round; i<=end+n*round; i++){ values.Add(impList[i].ClosePrice); } break; case MAType.VMAShort: case MAType.VMALong: //忽略一字板涨跌停 //头部追加部分 for(int i=impStart-1; i>=0 && values.Count < n*round*2; i--){ //从start开始往前推,尝试找到2*n*round个非1字板数据 if(!ShouldBeIgnored(impList[i])) values.Insert(0, Convert.ToDecimal(impList[i].Volume)); if(values.Count<=n*round) start = i; //因为忽略1字板涨跌停,不像计算均价情况下开始位置是固定的,这里动态确定开始位置 } //待计算节点部分 for(int i=impStart; i<=end+n*round; i++){ //尾部通过clone追加的节点一定符合条件,因此可以确保尾部追加了n*round个节点 if(!ShouldBeIgnored(impList[i])) values.Add(Convert.ToDecimal(impList[i].Volume)); } break; } //进行计算 //注意:CalcCusMA需要的是计算起始点、终止点在values中的索引,而start、end是在kdatas中的索引,需要转换 IList<decimal> result = CalculateMA(values, n, values.Count-1-n, n, round, type, weight); //设置计算结果 int resultIndex = 0; //计算节点结果值的索引 for(int i=start; i<=end; i++){ switch(type){ case MAType.MAShort: impList[i].MAShort = result[resultIndex++]; //注意:计算节点的结果值在result中从索引0开始 break; case MAType.MALong: impList[i].MALong = result[resultIndex++]; break; case MAType.VMAShort: if(ShouldBeIgnored(impList[i])) impList[i].VMAShort = impList[i-1].VMAShort; else impList[i].VMAShort = Convert.ToInt64(result[resultIndex++]); break; case MAType.VMALong: if(ShouldBeIgnored(impList[i])) impList[i].VMALong = impList[i-1].VMALong; else impList[i].VMALong = Convert.ToInt64(result[resultIndex++]); break; } } }
public static RetCode Stoch(decimal[] inHigh, decimal[] inLow, decimal[] inClose, int startIdx, int endIdx, decimal[] outSlowK, decimal[] outSlowD, out int outBegIdx, out int outNbElement, MAType optInSlowKMAType = MAType.Sma, MAType optInSlowDMAType = MAType.Sma, int optInFastKPeriod = 5, int optInSlowKPeriod = 3, int optInSlowDPeriod = 3) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inHigh == null || inLow == null || inClose == null || outSlowK == null || outSlowD == null || optInFastKPeriod < 1 || optInFastKPeriod > 100000 || optInSlowKPeriod < 1 || optInSlowKPeriod > 100000 || optInSlowDPeriod < 1 || optInSlowDPeriod > 100000) { return(RetCode.BadParam); } int lookbackK = optInFastKPeriod - 1; int lookbackDSlow = MaLookback(optInSlowDMAType, optInSlowDPeriod); int lookbackTotal = StochLookback(optInSlowKMAType, optInSlowDMAType, optInFastKPeriod, optInSlowKPeriod, optInSlowDPeriod); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return(RetCode.Success); } int outIdx = default; int trailingIdx = startIdx - lookbackTotal; int today = trailingIdx + lookbackK; int highestIdx = -1; int lowestIdx = highestIdx; decimal highest, lowest; decimal diff = highest = lowest = default; decimal[] tempBuffer; if (outSlowK == inHigh || outSlowK == inLow || outSlowK == inClose) { tempBuffer = outSlowK; } else if (outSlowD == inHigh || outSlowD == inLow || outSlowD == inClose) { tempBuffer = outSlowD; } else { tempBuffer = new decimal[endIdx - today + 1]; } while (today <= endIdx) { decimal tmp = inLow[today]; if (lowestIdx < trailingIdx) { lowestIdx = trailingIdx; lowest = inLow[lowestIdx]; int i = lowestIdx; while (++i <= today) { tmp = inLow[i]; if (tmp < lowest) { lowestIdx = i; lowest = tmp; } } diff = (highest - lowest) / 100m; } else if (tmp <= lowest) { lowestIdx = today; lowest = tmp; diff = (highest - lowest) / 100m; } tmp = inHigh[today]; if (highestIdx < trailingIdx) { highestIdx = trailingIdx; highest = inHigh[highestIdx]; int i = highestIdx; while (++i <= today) { tmp = inHigh[i]; if (tmp > highest) { highestIdx = i; highest = tmp; } } diff = (highest - lowest) / 100m; } else if (tmp >= highest) { highestIdx = today; highest = tmp; diff = (highest - lowest) / 100m; } tempBuffer[outIdx++] = diff != Decimal.Zero ? (inClose[today] - lowest) / diff : Decimal.Zero; trailingIdx++; today++; } RetCode retCode = Ma(tempBuffer, 0, outIdx - 1, tempBuffer, out _, out outNbElement, optInSlowKMAType, optInSlowKPeriod); if (retCode != RetCode.Success || outNbElement == 0) { return(retCode); } retCode = Ma(tempBuffer, 0, outNbElement - 1, outSlowD, out _, out outNbElement, optInSlowDMAType, optInSlowDPeriod); Array.Copy(tempBuffer, lookbackDSlow, outSlowK, 0, outNbElement); if (retCode != RetCode.Success) { outNbElement = 0; return(retCode); } outBegIdx = startIdx; return(RetCode.Success); }
/// <summary> /// 计算定制化移动均线值 /// </summary> /// <param name="values">值列表,必须保证start前至少有n个元素,end后至少有n个元素</param> /// <param name="start">起始点在values中的索引位置</param> /// <param name="end">终止点在values中的索引位置</param> /// <param name="n">相对于计算节点,分别取前、后几个节点值计算均值。计算9日均价,n传4。</param> /// <param name="type"></param> /// <returns>返回结果均值列表,结果列表中索引0到最后的一个值分别对应values中索引start到end元素的计算结果均值。<br /> /// 每经过一轮计算,返回的结果列表元素个数比values减少2n个(头、为各减少n个)</returns> private static IList<decimal> CalculateMA(IList<decimal> values, int start, int end, int n, MAType type, int weight) { List<decimal> r = new List<decimal>(end - start + 1); decimal ma; if(weight<=1) weight=1; int count = 2*n+1 + weight-1; //参与均值计算的节点个数 for(int i=start; i<=end; i++){ switch(type){ case MAType.MAShort: case MAType.MALong: //均值 ma = values [i] * weight; for (int j = 1; j <= n; j++) { ma = ma + values [i + j] + values [i - j]; } r.Add(ma / count); break; case MAType.VMAShort: case MAType.VMALong: //均方根值 ma = values [i] * values [i] * weight; for (int j = 1; j <= n; j++) { ma = ma + values [i + j] * values [i + j] + values [i - j] * values [i - j]; } r.Add (Convert.ToDecimal (Math.Sqrt (Convert.ToDouble (ma) / count))); break; } } return r; }
public static RetCode MacdExt(double[] inReal, int startIdx, int endIdx, double[] outMacd, double[] outMacdSignal, double[] outMacdHist, out int outBegIdx, out int outNbElement, MAType optInFastMAType, MAType optInSlowMAType, MAType optInSignalMAType, int optInFastPeriod = 12, int optInSlowPeriod = 26, int optInSignalPeriod = 9) { outBegIdx = outNbElement = 0; if (startIdx < 0 || endIdx < 0 || endIdx < startIdx) { return(RetCode.OutOfRangeStartIndex); } if (inReal == null || outMacd == null || outMacdSignal == null || outMacdHist == null || optInFastPeriod < 2 || optInFastPeriod > 100000 || optInSlowPeriod < 2 || optInSlowPeriod > 100000 || optInSignalPeriod < 1 || optInSignalPeriod > 100000) { return(RetCode.BadParam); } int tempInteger; if (optInSlowPeriod < optInFastPeriod) { tempInteger = optInSlowPeriod; optInSlowPeriod = optInFastPeriod; optInFastPeriod = tempInteger; MAType tempMAType = optInSlowMAType; optInSlowMAType = optInFastMAType; optInFastMAType = tempMAType; } int lookbackSignal = MaLookback(optInSignalMAType, optInSignalPeriod); int lookbackTotal = MacdExtLookback(optInFastMAType, optInSlowMAType, optInSignalMAType, optInFastPeriod, optInSlowPeriod, optInSignalPeriod); if (startIdx < lookbackTotal) { startIdx = lookbackTotal; } if (startIdx > endIdx) { return(RetCode.Success); } tempInteger = endIdx - startIdx + 1 + lookbackSignal; var fastMABuffer = new double[tempInteger]; var slowMABuffer = new double[tempInteger]; tempInteger = startIdx - lookbackSignal; RetCode retCode = Ma(inReal, tempInteger, endIdx, slowMABuffer, out var outBegIdx1, out var outNbElement1, optInSlowMAType, optInSlowPeriod); if (retCode != RetCode.Success) { return(retCode); } retCode = Ma(inReal, tempInteger, endIdx, fastMABuffer, out var outBegIdx2, out var outNbElement2, optInFastMAType, optInFastPeriod); if (retCode != RetCode.Success) { return(retCode); } if (outBegIdx1 != tempInteger || outBegIdx2 != tempInteger || outNbElement1 != outNbElement2 || outNbElement1 != endIdx - startIdx + 1 + lookbackSignal) { return(RetCode.InternalError); } for (var i = 0; i < outNbElement1; i++) { fastMABuffer[i] -= slowMABuffer[i]; } Array.Copy(fastMABuffer, lookbackSignal, outMacd, 0, endIdx - startIdx + 1); retCode = Ma(fastMABuffer, 0, outNbElement1 - 1, outMacdSignal, out _, out outNbElement2, optInSignalMAType, optInSignalPeriod); if (retCode != RetCode.Success) { return(retCode); } for (var i = 0; i < outNbElement2; i++) { outMacdHist[i] = outMacd[i] - outMacdSignal[i]; } outBegIdx = startIdx; outNbElement = outNbElement2; return(RetCode.Success); }