示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }