Beispiel #1
0
        public static (double[] StochasticLine, double[] SmoothedLine) FSTOC(SymbolInformation symbol, int periodK, int periodD)
        {
            // n = integer("%%K period", 5)
            // n2 = integer("%%D period", 3)

            // # calculation
            // hh = highest(high, n)
            // ll = lowest(low, n)
            // fstoc = skip((hh == ll) ? 0 : (close - ll) / (hh - ll) * 100, n)
            // smoothed = sma(fstoc, n2)

            var close = symbol.Close;
            var hh    = HH(symbol.High, periodK);
            var ll    = LL(symbol.Low, periodK);

            var fstoc = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                fstoc[index] = hh[index] == ll[index] ? 0 : (close[index] - ll[index]) / (hh[index] - ll[index]) * 100;
            }

            var smoothed = SMA(fstoc, periodD);

            return(fstoc, smoothed);
        }
Beispiel #2
0
        public static double[] CCI(SymbolInformation symbol, int period)
        {
            // n = integer("Period", 20)

            // # calculation
            // tp = (high + low + close) / 3
            // avg = sum(tp, n) / n
            // sAvg = loop((i, res) { res + abs(tp[i] - avg) }, n) / n
            // cci = (sAvg == 0 ? 0 : ((tp - avg) / (0.015 * sAvg)))

            var close = symbol.Close;

            var tp  = TP(symbol);
            var cci = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                var avg = Sum(tp, index, period) / period;
                var res = 0.0;
                for (var i = 0; i < period; i++)
                {
                    res += Math.Abs(tp.At(index + i) - avg);
                }

                var sAvg = res / period;
                cci[index] = (tp[index] - avg) / (0.015 * sAvg);
            }

            return(cci);
        }
Beispiel #3
0
        public static (double[] pK, double[] pD, double[] pJ, double[] pKema) KDJ(SymbolInformation symbol, int lenL, int lenS, int lenK)
        {
            // lenL = integer("Period 1",5)
            // lenS = integer("Period 2", 3)
            // lenK = integer("%%K Smoothing", 3)

            // # calculation
            // pK = 100 * ((close - lowest(close, lenL)) / (highest(high, lenL) - lowest(low, lenL)))
            // pD = 100 * (highest(high, lenS) / lowest(low, lenS))
            // pJ = (3 * pD) - (2 * pK)

            // pKema = ema(pK, lenK)

            var close = symbol.Close;
            var hhL   = HH(symbol.High, lenL);
            var llL   = LL(symbol.Low, lenL);
            var lcL   = LL(symbol.Close, lenL);
            var hhS   = HH(symbol.High, lenS);
            var llS   = LL(symbol.Low, lenS);

            var pK = Create(close.Length);
            var pD = Create(close.Length);
            var pJ = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                pK[index] = 100 * ((close[index] - lcL[index]) / (hhL[index] - llL[index]));
                pD[index] = 100 * (hhS[index] / llS[index]);
                pJ[index] = 3 * pD[index] - 2 * pK[index];
            }

            var pKema = EMA(pK, lenK);

            return(pK, pD, pJ, pKema);
        }
Beispiel #4
0
        public IList <TimeSeries> GetTimeSeries(
            SymbolInformation symbol,
            Const_TIME_SERIES_DAILY.TIME_SERIES_DAILY_outputsize size = Const_TIME_SERIES_DAILY.TIME_SERIES_DAILY_outputsize.full)
        {
            Trace.TraceInformation(
                $"Download {(size == Const_TIME_SERIES_DAILY.TIME_SERIES_DAILY_outputsize.compact ? "compact" : "full")} data for {symbol.ISIN}");
            var list = new List <TimeSeries>();

            IAvapiResponse_TIME_SERIES_DAILY_Content seriesDaily = null;

            var retry = 0;

            while (seriesDaily == null)
            {
                try
                {
                    var response = this.connection.GetQueryObject_TIME_SERIES_DAILY().Query(symbol.Symbol, size);
                    if (response.Data != null)
                    {
                        seriesDaily = response.Data;
                    }
                }
                catch
                {
                    if (retry == 10)
                    {
                        throw;
                    }

                    Thread.Sleep(2000);
                    retry++;
                }
            }

            foreach (var series in seriesDaily.TimeSeries)
            {
                var close  = double.Parse(series.close);
                var open   = double.Parse(series.open);
                var high   = double.Parse(series.high);
                var low    = double.Parse(series.low);
                var volume = int.Parse(series.volume);
                var day    = DateTime.Parse(series.DateTime);

                // ignore missing days or days with same value but no volume (holidays?)
                if (((open == 0.0) && (close == 0.0) && (high == 0.0) && (low == 0.0)) ||
                    ((open == close) && (high == close) && (low == close) && (volume == 0.0)))
                {
                    continue;
                }

                var timeSeries = new TimeSeries {
                    Close = close, High = high, Open = open, Low = low, Volume = volume, Day = day
                };
                list.Add(timeSeries);
            }

            return(list);
        }
Beispiel #5
0
        public static void SaveEquityCurve(
            SymbolInformation symbol,
            EvaluationResult result,
            string folderName)
        {
            var pane = new GraphPane();

            pane.Title.Text           = $"Equity Curve";
            pane.Title.FontSpec.Size  = 8;
            pane.Chart.Fill.IsScaled  = false;
            pane.Chart.Fill.Brush     = new SolidBrush(Color.DimGray);
            pane.Fill.Brush           = new SolidBrush(Color.DimGray);
            pane.Legend.Fill.Brush    = new SolidBrush(Color.DimGray);
            pane.Legend.FontSpec.Size = 6;

            var curve = pane.AddCurve("% Gain", new double[] { }, new double[] { }, LineColors[0], SymbolType.None);

            curve.Line.Width       = 2;
            curve.Line.IsVisible   = true;
            curve.Line.IsAntiAlias = true;

            foreach (var(day, equity) in result.EquityCurve)
            {
                curve.AddPoint(new XDate(day), equity);
            }

            pane.XAxis.Type = AxisType.Date;
            pane.XAxis.Scale.FontSpec.Size = 6;
            pane.XAxis.MinorGrid.IsVisible = true;
            pane.XAxis.MajorGrid.IsVisible = true;

            pane.YAxis.Scale.FontSpec.Size = 6;
            pane.YAxis.MinorGrid.IsVisible = true;
            pane.YAxis.MajorGrid.IsVisible = true;

            // force an axischange to plot all data and recalculate all axis
            // this is normally done by the control, but this is not possible in mvc3
            var bm = new Bitmap(1, 1);

            using (var g = Graphics.FromImage(bm))
            {
                pane.ReSize(g, new RectangleF(0, 0, 1280 * 5, 960 * 5));
                pane.AxisChange(g);
            }

            // create a stream to store a PNG-format image
            var actualFolder = Path.Combine(folderName, symbol.ISIN);

            Directory.CreateDirectory(actualFolder);
            var image = pane.GetImage(true);

            image.Save(
                Path.Combine(
                    actualFolder,
                    $"EquityCurve.png"),
                ImageFormat.Png);
        }
Beispiel #6
0
 public static (double[] MACD, double[] Signal) RelativeMACD(
     SymbolInformation symbol,
     SourceType sourceType,
     int fastPeriod,
     int slowPeriod,
     int signalPeriod,
     MovingAverage movingAverage = MovingAverage.EMA)
 {
     return(RelativeMACD(symbol.Data(sourceType), fastPeriod, slowPeriod, signalPeriod, movingAverage));
 }
Beispiel #7
0
        public static double[] DayOfWeek(SymbolInformation symbol)
        {
            var day       = symbol.Day;
            var dayOfWeek = Create(day.Length);

            for (var index = day.Length - 1; index >= 0; index--)
            {
                dayOfWeek[index] = Convert.ToInt32(day[index].DayOfWeek);
            }

            return(dayOfWeek);
        }
Beispiel #8
0
        public static double[] Month(SymbolInformation symbol)
        {
            var day   = symbol.Day;
            var month = Create(day.Length);

            for (var index = day.Length - 1; index >= 0; index--)
            {
                month[index] = day[index].Month;
            }

            return(month);
        }
Beispiel #9
0
        public static double[] HiLoDiff(SymbolInformation symbol)
        {
            var high     = symbol.High;
            var low      = symbol.Low;
            var hiLoDiff = Create(high.Length);

            for (var index = high.Length - 1; index >= 0; index--)
            {
                hiLoDiff[index] = high[index] - low[index];
            }

            return(hiLoDiff);
        }
Beispiel #10
0
        public static (double[] StochasticLine, double[] TriggerLine) DSSBR(
            SymbolInformation symbol,
            int stochasticPeriod,
            int smoothingPeriod,
            int triggerPeriod)
        {
            // # input
            // n = integer("Stochastic Period", 21)
            // m = integer("Smoothing Period", 3)
            // tr = integer("Trigger Period", 8)

            // # calculation
            // hh = highest(high, n)
            // ll = lowest(low, n)
            // v1 = skip((hh == ll) ? 0 : (close - ll) / (hh - ll) * 100, n - 1)
            // smoothedV1 = ema(v1, m)

            // hh = highest(smoothedV1, n)
            // ll = lowest(smoothedV1, n)
            // v2 = skip((hh == ll) ? 0 : (smoothedV1 - ll) / (hh - ll) * 100, n - 1)

            // sV2 = ema(v2, m)
            // ssV2 = ema(sV2, tr)

            var close = symbol.Close;
            var hh    = HH(symbol.High, stochasticPeriod);
            var ll    = LL(symbol.Low, stochasticPeriod);

            var v = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                v[index] = hh[index] == ll[index] ? 0 : (close[index] - ll[index]) / (hh[index] - ll[index]) * 100;
            }

            var smoothedV1 = EMA(v, smoothingPeriod);

            hh = HH(smoothedV1, stochasticPeriod);
            ll = LL(smoothedV1, stochasticPeriod);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                v[index] = hh[index] == ll[index] ? 0 : (smoothedV1[index] - ll[index]) / (hh[index] - ll[index]) * 100;
            }

            var sV2  = EMA(v, smoothingPeriod);
            var ssV2 = EMA(sV2, triggerPeriod);

            return(sV2, ssV2);
        }
Beispiel #11
0
        public static double[] ADX(SymbolInformation symbol, int period)
        {
            // n = integer("Period", 14)

            // # calculation
            // tr = sum(max(high - low, high - close[1], low - close[1]), n)
            // diPlus = sum(max(high - high[1], 0), n) / tr
            // diMinus = sum(max(high <= high[1] ? low[1] - low : 0, 0), n) / tr
            // dmi = abs((diPlus - diMinus) / (diPlus + diMinus)) * 100
            // adx = sma(dmi, n)

            var(dmi, _, _) = DMI(symbol, period);

            return(SMA(dmi, period));
        }
Beispiel #12
0
        public static double[] AOS(SymbolInformation symbol, int period)
        {
            // aos = aroonUp - aroonDown

            var close     = symbol.Close;
            var aroonUp   = AROUp(symbol.High, period);
            var aroonDown = ARODown(symbol.Low, period);

            var aos = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                aos[index] = aroonUp[index] - aroonDown[index];
            }

            return(aos);
        }
Beispiel #13
0
        public static double[] TP(SymbolInformation symbol)
        {
            // tp = (close + high + low) / 3

            var high  = symbol.High;
            var low   = symbol.Low;
            var close = symbol.Close;

            var tp = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                tp[index] = (close[index] + low[index] + high[index]) / 3;
            }

            return(tp);
        }
Beispiel #14
0
        public static (double[] Smi, double[] signal) SMI(SymbolInformation symbol, int periodK, int periodD)
        {
            // a = integer("K", 5)
            // b = integer("D", 3)

            // # calculation
            // ll = lowest(low, a)
            // hh = highest(high, a)
            // diff = hh - ll

            // rdiff = close - (hh + ll) / 2

            // avgrel = ema(ema(rdiff, b), b)
            // avgdiff = ema(ema(diff, b), b)

            // SMI = avgdiff != 0 ? (avgrel / (avgdiff / 2) * 100) : 0
            // SMIsignal = ema(SMI, b)

            var close = symbol.Close;
            var hh    = HH(symbol, periodK);
            var ll    = LL(symbol, periodK);

            var diff  = Create(close.Length);
            var rdiff = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                diff[index]  = hh[index] - ll[index];
                rdiff[index] = close[index] - (hh[index] + ll[index]) / 2;
            }

            var avgrel  = EMA(EMA(rdiff, periodD), periodD);
            var avgdiff = EMA(EMA(diff, periodD), periodD);

            var smi = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                smi[index] = avgdiff[index] != 0 ? avgrel[index] / (avgdiff[index] / 2) * 100 : 0;
            }

            var signal = EMA(smi, periodD);

            return(smi, signal);
        }
Beispiel #15
0
        public static (double[] StochasticLine, double[] SmoothedLine) SSTOC(SymbolInformation symbol, int KPeriod, int DPeriod, int DPeriod2)
        {
            // n = integer("%%K period", 5)
            // n2 = integer("%%D period", 5)
            // n3 = integer("2th %%D period", 3)

            // # calculation
            // hh = highest(high, n)
            // ll = lowest(low, n)
            // fstoc = (hh == ll) ? 0 : ((close - ll) / (hh - ll) * 100)
            // sstoc = sma(fstoc, n2)
            // smoothed = sma(sstoc, n3)

            var(_, sstoc) = FSTOC(symbol, KPeriod, DPeriod);
            var smoothed = SMA(sstoc, DPeriod2);

            return(sstoc, smoothed);
        }
Beispiel #16
0
        public static double[] ST(SymbolInformation symbol, int period, double factor)
        {
            // p = integer("Period", 10)
            // f = integer("Factor", 3)

            // # calculation
            // atr = sum(max(high - low, high - close[1], close[1] - low), p) / p
            // up = (high + low) / 2 - f * atr
            // down = (high + low) / 2 + f * atr

            // trendUp = close[1] > trendUp[1] ? max(up, trendUp[1]) : up
            // trendDown = close[1] < trendDown[1] ? min(down, trendDown[1]) : down
            // trend = close > trendDown[1] ? 1 : (close < trendUp[1] ? -1 : nn(trend[1], 1))

            // st = skip(trend == 1 ? trendUp : trendDown, p)

            var high  = symbol.High;
            var low   = symbol.Low;
            var close = symbol.Close;

            var atr = ATR(symbol, period);

            var trendUp   = Create(close.Length);
            var trendDown = Create(close.Length);
            var trend     = new int[close.Length];
            var st        = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                var up   = (high[index] + low[index]) / 2 - factor * atr[index];
                var down = (high[index] + low[index]) / 2 + factor * atr[index];

                trendUp[index]   = close.At(index + 1) > trendUp.At(index + 1) ? Math.Max(up, trendUp.At(index + 1)) : up;
                trendDown[index] = close.At(index + 1) < trendDown.At(index + 1) ? Math.Min(down, trendDown.At(index + 1)) : down;
                trend[index]     = close[index] > trendDown.At(index + 1) ? 1 : (close[index] < trendUp.At(index + 1) ? -1 : trend.At(index + 1, 1));

                st[index] = nn(trend[index] == 1 ? trendUp[index] : trendDown[index], close[index]);
            }

            return(st);
        }
Beispiel #17
0
        public static (double[] Bullish, double[] Bearish) ELR(SymbolInformation symbol, int length)
        {
            // x = ema(close, length)
            // bullish = high-x
            // bearish = low-x

            var high  = symbol.High;
            var low   = symbol.Low;
            var close = symbol.Close;

            var x       = EMA(close, length);
            var bullish = Create(close.Length);
            var bearish = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                bullish[index] = high[index] - x[index];
                bearish[index] = low[index] - x[index];
            }

            return(bullish, bearish);
        }
Beispiel #18
0
        public static double[] OBOS(SymbolInformation symbol, int period)
        {
            // n = integer("Period", 14)

            // # calculation
            // denom = highest(high, n) - lowest(low, n)
            // obos = denom == 0 ? 0 : (close - lowest(low, n)) / denom * 100

            var highest = HH(symbol, period);
            var lowest  = LL(symbol, period);
            var close   = symbol.Close;

            var obos = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                var denom = highest[index] - lowest[index];
                obos[index] = nn((close[index] - lowest[index]) / denom * 100);
            }

            return(obos);
        }
Beispiel #19
0
        public static double[] PCR(SymbolInformation symbol, int period)
        {
            // n = integer("%%R period", 14)

            // # calculation
            // hhlld = highest(high, n) - lowest(low, n)
            // pcr = skip(hhlld ? 100 - ((highest(high, n) - close) / hhlld) * 100 : 0, n - 1)

            var close = symbol.Close;
            var hh    = HH(symbol, period);
            var ll    = LL(symbol, period);

            var pcr = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                var hhlld = hh[index] - ll[index];
                pcr[index] = hhlld != 0 ? 100 - (hh[index] - close[index]) / hhlld * 100 : 0;
            }

            return(pcr);
        }
Beispiel #20
0
        public static double[] ATR(SymbolInformation symbol, int period)
        {
            // atr = sum(max(high - low, high - close[1], close[1] - low), n) / n
            var close = symbol.Close;
            var high  = symbol.High;
            var low   = symbol.Low;

            var max = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                max[index] = Math.Max(Math.Max(high[index] - low[index], high[index] - close.At(index + 1)), close.At(index + 1) - low[index]);
            }

            var atr = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                atr[index] = Sum(max, index, period) / period;
            }

            return(atr);
        }
Beispiel #21
0
        public static (double[] DMI, double[] DIPlus, double[] DIMinus) DMI(SymbolInformation symbol, int period)
        {
            // n = integer("Period", 14)

            // # calculation
            // tr = sum(max(high - low, high - close[1], low - close[1]), n)
            // diPlus = sum(max(high - high[1], 0), n) / tr
            // diMinus = sum(max(high <= high[1] ? low[1] - low : 0, 0), n) / tr
            // dmi = abs((diPlus - diMinus) / (diPlus + diMinus)) * 100

            var high  = symbol.High;
            var low   = symbol.Low;
            var close = symbol.Close;
            var tr    = TR(symbol, period);

            var dmi     = Create(close.Length);
            var diPlus  = Create(close.Length);
            var diMinus = Create(close.Length);

            for (var index = close.Length - 1; index >= 0; index--)
            {
                var diP = 0.0;
                var diM = 0.0;
                for (var i = 0; i < period; i++)
                {
                    diP += Math.Max(high.At(index + i) - high.At(index + i + 1), 0);
                    diM += Math.Max(high.At(index + i) <= high.At(index + i + 1) ? low.At(index + i + 1) - low.At(index + i) : 0, 0);
                }

                diPlus[index]  = nn(diP / tr[index] * 100);
                diMinus[index] = nn(diM / tr[index] * 100);
                dmi[index]     = nn(Math.Abs((diPlus[index] - diMinus[index]) / (diPlus[index] + diMinus[index])) * 100);
            }

            return(dmi, diPlus, diMinus);
        }
Beispiel #22
0
 public static double[] OBV(SymbolInformation symbol, SourceType sourceType)
 {
     return(OBV(symbol.Data(sourceType), symbol.Volume));
 }
Beispiel #23
0
 public static double[] DIX(SymbolInformation symbol, SourceType sourceType, int period)
 {
     return(DIX(symbol.Data(sourceType), period));
 }
Beispiel #24
0
 public static double[] KAMA(SymbolInformation symbol, SourceType sourceType, int length)
 {
     return(KAMA(symbol.Data(sourceType), length));
 }
Beispiel #25
0
 public static (double[] Upper, double[] Lower, double[] Middle) BB(SymbolInformation symbol, SourceType sourceType, int period, double factor)
 {
     return(BB(symbol.Data(sourceType), period, factor));
 }
Beispiel #26
0
        public static (double[] ShortStop, double[] LongStop) ELSZ(SymbolInformation symbol, int period, double coeffienct)
        {
            // # input
            // coeff = float("CoEff", 2.5)
            // lookbackLength = integer("LookBackLength", 15)

            // # calculation
            // countShort = high > high[1] ? 1 : 0
            // diffShort = high > high[1] ? high - high[1] : 0
            // totalCountShort = sum(countShort, lookbackLength)
            // totalSumShort = sum(diffShort, lookbackLength)
            // penAvgShort = (totalSumShort / totalCountShort)
            // safetyShort = high[1] + (penAvgShort[1] * coeff)
            // finalSafetyShort = min(min(safetyShort, safetyShort[1]), safetyShort[2])

            // count = low < low[1] ? 1 : 0
            // diff = low < low[1] ? low[1] - low : 0
            // totalCount = sum(count, lookbackLength)
            // totalSum = sum(diff, lookbackLength)
            // penAvg = (totalSum / totalCount)
            // safety = low[1] - (penAvg[1] * coeff)
            // finalSafetyLong = max(max(safety, safety[1]), safety[2])

            var close            = symbol.Close;
            var high             = symbol.High;
            var low              = symbol.Low;
            var finalSafetyShort = Create(close.Length);
            var finalSafetyLong  = Create(close.Length);
            var penAvgShort      = Create(close.Length);
            var safetyShort      = Create(close.Length);
            var penAvgLong       = Create(close.Length);
            var safetyLong       = Create(close.Length);

            for (var index = finalSafetyShort.Length - 1; index >= 0; index--)
            {
                var totalCountShort = 0;
                var totalSumShort   = 0.0;
                var totalCountLong  = 0;
                var totalSumLong    = 0.0;
                for (var i = 0; i < period; i++)
                {
                    var high1 = high.At(index + i + 1);
                    var high0 = high.At(index + i);
                    if (high0 > high1)
                    {
                        totalCountShort++;
                        totalSumShort += high0 - high1;
                    }

                    var low1 = low.At(index + i + 1);
                    var low0 = low.At(index + i);
                    if (low0 < low1)
                    {
                        totalCountLong++;
                        totalSumLong += low1 - low0;
                    }
                }

                penAvgShort[index]      = totalSumShort / totalCountShort;
                safetyShort[index]      = high.At(index + 1) + penAvgShort.At(index + 1) * coeffienct;
                finalSafetyShort[index] = Math.Min(Math.Min(safetyShort[index], safetyShort.At(index + 1)), safetyShort.At(index + 2));

                penAvgLong[index]      = totalSumLong / totalCountLong;
                safetyLong[index]      = low.At(index + 1) - penAvgLong.At(index + 1) * coeffienct;
                finalSafetyLong[index] = Math.Max(Math.Max(safetyLong[index], safetyLong.At(index + 1)), safetyLong.At(index + 2));
            }

            return(finalSafetyShort, finalSafetyLong);
        }
Beispiel #27
0
 public static double[] VWMA(SymbolInformation symbol, SourceType sourceType, int period)
 {
     return(VWMA(symbol.Data(sourceType), symbol.Volume, period));
 }
Beispiel #28
0
        public static double[] PSAR(SymbolInformation symbol, double factor, double increment, double factorMax)
        {
            // Difference of High and Low
            var hiLoDiff = HiLoDiff(symbol);

            // STDEV of differences
            var stDev = hiLoDiff.StandardDeviation();

            var high   = symbol.High;
            var low    = symbol.Low;
            var sarArr = Create(high.Length);

            /* Find first non-NA value */
            var beg = high.Length - 2;

            for (var i = high.Length - 1; i >= 0; i++)
            {
                if ((high[i] == 0) || (low[i] == 0))
                {
                    sarArr[i] = 0;
                    beg--;
                }
                else
                {
                    break;
                }
            }

            /* Initialize values needed by the routine */
            var sig0 = 1;
            var xpt0 = high[beg + 1];
            var af0  = factor;

            sarArr[beg + 1] = low[beg + 1] - stDev;

            for (var idx = beg; idx >= 0; idx--)
            {
                /* Increment signal, extreme point, and acceleration factor */
                var sig1 = sig0;
                var xpt1 = xpt0;
                var af1  = af0;

                /* Local extrema */
                var lmin = low[idx + 1] > low[idx] ? low[idx] : low[idx + 1];
                var lmax = high[idx + 1] > high[idx] ? high[idx + 1] : high[idx];
                /* Create signal and extreme price vectors */
                if (sig1 == 1)
                {
                    /* Previous buy signal */
                    sig0 = low[idx] > sarArr[idx + 1] ? 1 : -1; /* New signal */
                    xpt0 = lmax > xpt1 ? lmax : xpt1;           /* New extreme price */
                }
                else
                {
                    /* Previous sell signal */
                    sig0 = high[idx] < sarArr[idx + 1] ? -1 : 1; /* New signal */
                    xpt0 = lmin > xpt1 ? xpt1 : lmin;            /* New extreme price */
                }

                /*
                 * Calculate acceleration factor (af)
                 * and stop-and-reverse (sar) vector
                 */

                /* No signal change */
                if (sig0 == sig1)
                {
                    /* Initial calculations */
                    sarArr[idx] = sarArr[idx + 1] + (xpt1 - sarArr[idx + 1]) * af1;
                    af0         = af1 >= factorMax ? factorMax : factor + increment;
                    /* Current buy signal */
                    if (sig0 == 1)
                    {
                        af0         = xpt0 > xpt1 ? af0 : af1;                 /* Update acceleration factor */
                        sarArr[idx] = sarArr[idx] > lmin ? lmin : sarArr[idx]; /* Determine sar value */
                    }
                    /* Current sell signal */
                    else
                    {
                        af0         = xpt0 < xpt1 ? af0 : af1;                 /* Update acceleration factor */
                        sarArr[idx] = sarArr[idx] > lmax ? sarArr[idx] : lmax; /* Determine sar value */
                    }
                }
                else /* New signal */
                {
                    af0         = factor; /* reset acceleration factor */
                    sarArr[idx] = xpt0; /* set sar value */
                }
            }

            return(sarArr);
        }
Beispiel #29
0
 public static void Save(
     SymbolInformation symbol,
     EvaluationResult result,
     IList <(string Name, double[] Values, bool IsLine, bool IsDot)> curveData,
Beispiel #30
0
 public static double[] LL(SymbolInformation symbol, int period)
 {
     return(LL(symbol.Low, period));
 }