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); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
public static double[] OBV(SymbolInformation symbol, SourceType sourceType) { return(OBV(symbol.Data(sourceType), symbol.Volume)); }
public static double[] DIX(SymbolInformation symbol, SourceType sourceType, int period) { return(DIX(symbol.Data(sourceType), period)); }
public static double[] KAMA(SymbolInformation symbol, SourceType sourceType, int length) { return(KAMA(symbol.Data(sourceType), length)); }
public static (double[] Upper, double[] Lower, double[] Middle) BB(SymbolInformation symbol, SourceType sourceType, int period, double factor) { return(BB(symbol.Data(sourceType), period, factor)); }
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); }
public static double[] VWMA(SymbolInformation symbol, SourceType sourceType, int period) { return(VWMA(symbol.Data(sourceType), symbol.Volume, period)); }
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); }
public static void Save( SymbolInformation symbol, EvaluationResult result, IList <(string Name, double[] Values, bool IsLine, bool IsDot)> curveData,
public static double[] LL(SymbolInformation symbol, int period) { return(LL(symbol.Low, period)); }