private static int Bbands(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { var period = (int)options[0]; if (period < 1) { return(TI_INVALID_OPTION); } if (size <= BbandsStart(options)) { return(TI_OKAY); } decimal[] input = inputs[0]; decimal[] lower = outputs[0]; decimal[] middle = outputs[1]; decimal[] upper = outputs[2]; decimal sum = default; decimal sum2 = default; for (var i = 0; i < period; ++i) { sum += input[i]; sum2 += input[i] * input[i]; } decimal stddev = options[1]; decimal scale = Decimal.One / period; decimal sd = DecimalMath.Sqrt(sum2 * scale - sum * scale * sum * scale); int lowerIndex = default; int middleIndex = default; int upperIndex = default; middle[middleIndex++] = sum * scale; lower[lowerIndex++] = middle[0] - stddev * sd; upper[upperIndex++] = middle[0] + stddev * sd; for (var i = period; i < size; ++i) { sum += input[i]; sum2 += input[i] * input[i]; sum -= input[i - period]; sum2 -= input[i - period] * input[i - period]; sd = DecimalMath.Sqrt(sum2 * scale - sum * scale * sum * scale); middle[middleIndex] = sum * scale; upper[upperIndex++] = middle[middleIndex] + stddev * sd; lower[lowerIndex++] = middle[middleIndex] - stddev * sd; ++middleIndex; } return(TI_OKAY); }
private static int StdErr(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { var period = (int)options[0]; if (period < 1) { return(TI_INVALID_OPTION); } if (size <= StdErrStart(options)) { return(TI_OKAY); } var input = inputs[0]; var output = outputs[0]; decimal sum = default; decimal sum2 = default; for (var i = 0; i < period; ++i) { sum += input[i]; sum2 += input[i] * input[i]; } decimal scale = Decimal.One / period; decimal s2S2 = sum2 * scale - sum * scale * sum * scale; if (s2S2 > Decimal.Zero) { s2S2 = DecimalMath.Sqrt(s2S2); } decimal mul = Decimal.One / DecimalMath.Sqrt(period); int outputIndex = default; output[outputIndex++] = mul * s2S2; for (var i = period; i < size; ++i) { sum += input[i]; sum2 += input[i] * input[i]; sum -= input[i - period]; sum2 -= input[i - period] * input[i - period]; s2S2 = sum2 * scale - sum * scale * sum * scale; if (s2S2 > Decimal.Zero) { s2S2 = DecimalMath.Sqrt(s2S2); } output[outputIndex++] = mul * s2S2; } return(TI_OKAY); }
private static int Kama(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { var period = (int)options[0]; if (period < 1) { return(TI_INVALID_OPTION); } if (size <= KamaStart(options)) { return(TI_OKAY); } decimal[] input = inputs[0]; decimal[] output = outputs[0]; decimal sum = default; for (var i = 1; i < period; ++i) { sum += Math.Abs(input[i] - input[i - 1]); } // The caller selects the period used in the efficiency ratio. The fast and slow periods are hard set by the algorithm. const decimal shortPer = 2m / (2 + 1); const decimal longPer = 2m / (30 + 1); decimal kama = input[period - 1]; int outputIndex = default; output[outputIndex++] = kama; for (var i = period; i < size; ++i) { sum += Math.Abs(input[i] - input[i - 1]); if (i > period) { sum -= Math.Abs(input[i - period] - input[i - period - 1]); } decimal er = sum != Decimal.Zero ? Math.Abs(input[i] - input[i - period]) / sum : Decimal.One; decimal sc = DecimalMath.PowerN(er * (shortPer - longPer) + longPer, 2); kama += sc * (input[i] - kama); output[outputIndex++] = kama; } return(TI_OKAY); }
private static int Volatility(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { var period = (int)options[0]; if (period < 1) { return(TI_INVALID_OPTION); } if (size <= VolatilityStart(options)) { return(TI_OKAY); } var input = inputs[0]; var output = outputs[0]; decimal sum = default; decimal sum2 = default; for (var i = 1; i <= period; ++i) { decimal c = input[i] / input[i - 1] - Decimal.One; sum += c; sum2 += c * c; } decimal scale = Decimal.One / period; decimal annual = DecimalMath.Sqrt(252m); // Multiplier, number of trading days in year. int outputIndex = default; output[outputIndex++] = DecimalMath.Sqrt(sum2 * scale - sum * scale * sum * scale) * annual; for (var i = period + 1; i < size; ++i) { decimal c = input[i] / input[i - 1] - Decimal.One; sum += c; sum2 += c * c; decimal cp = input[i - period] / input[i - period - 1] - Decimal.One; sum -= cp; sum2 -= cp * cp; output[outputIndex++] = DecimalMath.Sqrt(sum2 * scale - sum * scale * sum * scale) * annual; } return(TI_OKAY); }
private static int Sqrt(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { Simple1(size, inputs[0], outputs[0], d => DecimalMath.Sqrt(d)); return(TI_OKAY); }
private static int Fisher(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { var period = (int)options[0]; if (period < 1) { return(TI_INVALID_OPTION); } if (size <= FisherStart(options)) { return(TI_OKAY); } decimal[] high = inputs[0]; decimal[] low = inputs[1]; decimal[] fisher = outputs[0]; decimal[] signal = outputs[1]; var maxi = -1; var mini = -1; decimal max = 0.5m * (high[0] + low[0]); decimal min = 0.5m * (high[0] + low[0]); decimal val1 = default; decimal fish = default; int fisherIndex = default; int signalIndex = default; for (int i = period - 1, trail = 0; i < size; ++i, ++trail) { // Maintain highest. decimal bar = 0.5m * (high[i] + low[i]); if (maxi < trail) { maxi = trail; max = 0.5m * (high[maxi] + low[maxi]); int j = trail; while (++j <= i) { bar = 0.5m * (high[j] + low[j]); if (bar >= max) { max = bar; maxi = j; } } } else if (bar >= max) { maxi = i; max = bar; } // Maintain lowest. bar = 0.5m * (high[i] + low[i]); if (mini < trail) { mini = trail; min = 0.5m * (high[mini] + low[mini]); int j = trail; while (++j <= i) { bar = 0.5m * (high[j] + low[j]); if (bar <= min) { min = bar; mini = j; } } } else if (bar <= min) { mini = i; min = bar; } decimal mm = max - min; if (mm == Decimal.Zero) { mm = 0.001m; } val1 = 0.66m * ((0.5m * (high[i] + low[i]) - min) / mm - 0.5m) + 0.67m * val1; if (val1 > 0.99m) { val1 = 0.999m; } if (val1 < -0.99m) { val1 = -0.999m; } signal[signalIndex++] = fish; fish = 0.5m * DecimalMath.Log((Decimal.One + val1) / (Decimal.One - val1)) + 0.5m * fish; fisher[fisherIndex++] = fish; } return(TI_OKAY); }
private static int Msw(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { var period = (int)options[0]; if (period < 1) { return(TI_INVALID_OPTION); } if (size <= MswStart(options)) { return(TI_OKAY); } decimal[] input = inputs[0]; decimal[] sine = outputs[0]; decimal[] lead = outputs[1]; const decimal tpi = 2m * DecimalMath.PI; int sineIndex = default; int leadIndex = default; for (var i = period; i < size; ++i) { decimal rp = default; decimal ip = default; for (var j = 0; j < period; ++j) { decimal weight = input[i - j]; rp += DecimalMath.Cos(tpi * j / period) * weight; ip += DecimalMath.Sin(tpi * j / period) * weight; } decimal phase; if (Math.Abs(rp) > .001m) { phase = DecimalMath.Atan(ip / rp); } else { phase = tpi / 2m * (ip < 0 ? Decimal.MinusOne : Decimal.One); } if (rp < Decimal.Zero) { phase += DecimalMath.PI; } phase += DecimalMath.PI / 2m; if (phase < Decimal.Zero) { phase += tpi; } if (phase > tpi) { phase -= tpi; } sine[sineIndex++] = DecimalMath.Sin(phase); lead[leadIndex++] = DecimalMath.Sin(phase + DecimalMath.PI / 4m); } return(TI_OKAY); }
private static int Vidya(int size, decimal[][] inputs, decimal[] options, decimal[][] outputs) { int shortPeriod = (int)options[0]; int longPeriod = (int)options[1]; decimal alpha = options[2]; if (shortPeriod < 1 || longPeriod < shortPeriod || longPeriod < 2 || alpha < Decimal.Zero || alpha > Decimal.One) { return(TI_INVALID_OPTION); } if (size <= VidyaStart(options)) { return(TI_OKAY); } decimal[] input = inputs[0]; decimal[] output = outputs[0]; decimal shortSum = default; decimal shortSum2 = default; decimal longSum = default; decimal longSum2 = default; for (var i = 0; i < longPeriod; ++i) { longSum += input[i]; longSum2 += input[i] * input[i]; if (i >= longPeriod - shortPeriod) { shortSum += input[i]; shortSum2 += input[i] * input[i]; } } decimal shortDiv = Decimal.One / shortPeriod; decimal longDiv = Decimal.One / longPeriod; decimal val = input[longPeriod - 2]; int outputIndex = default; output[outputIndex++] = val; if (longPeriod - 1 < size) { var shortStdDev = DecimalMath.Sqrt(shortSum2 * shortDiv - shortSum * shortDiv * shortSum * shortDiv); var longStdDev = DecimalMath.Sqrt(longSum2 * longDiv - longSum * longDiv * longSum * longDiv); decimal k = shortStdDev / longStdDev; k *= alpha; val = (input[longPeriod - 1] - val) * k + val; output[outputIndex++] = val; } for (var i = longPeriod; i < size; ++i) { longSum += input[i]; longSum2 += input[i] * input[i]; shortSum += input[i]; shortSum2 += input[i] * input[i]; longSum -= input[i - longPeriod]; longSum2 -= input[i - longPeriod] * input[i - longPeriod]; shortSum -= input[i - shortPeriod]; shortSum2 -= input[i - shortPeriod] * input[i - shortPeriod]; decimal shortStdDev = DecimalMath.Sqrt(shortSum2 * shortDiv - shortSum * shortDiv * shortSum * shortDiv); decimal longStdDev = DecimalMath.Sqrt(longSum2 * longDiv - longSum * longDiv * longSum * longDiv); decimal k = shortStdDev / longStdDev; k *= alpha; val = (input[i] - val) * k + val; output[outputIndex++] = val; } return(TI_OKAY); }