/// <summary> /// Called at the start of your algorithm to setup your requirements: /// </summary> public override void Initialize() { //Set the date range you want to run your algorithm: SetStartDate(startDate); SetEndDate(endDate); //Set the starting cash for your strategy: SetCash(100000); //Add any stocks you'd like to analyse, and set the resolution: // Find more symbols here: http://quantconnect.com/data AddSecurity(SecurityType.Equity, "SPY", resolution: Resolution.Minute); //Chart - Master Container for the Chart: Chart stockPlot = new Chart("Trade Plot", ChartType.Overlay); //On the Trade Plotter Chart we want 3 series: trades and price: Series buyOrders = new Series("Buy", SeriesType.Scatter); Series sellOrders = new Series("Sell", SeriesType.Scatter); Series assetPrice = new Series("Price", SeriesType.Line); stockPlot.AddSeries(buyOrders); stockPlot.AddSeries(sellOrders); stockPlot.AddSeries(assetPrice); AddChart(stockPlot); Chart avgCross = new Chart("Strategy Equity", ChartType.Stacked); Series fastMA = new Series("FastMA", SeriesType.Line); Series slowMA = new Series("SlowMA", SeriesType.Line); avgCross.AddSeries(fastMA); avgCross.AddSeries(slowMA); AddChart(avgCross); resamplePeriod = TimeSpan.FromMinutes((endDate - startDate).TotalMinutes / 2000); }
/// <summary> /// Add a reference to this chart series: /// </summary> /// <param name="series">Chart series class object</param> public void AddSeries(Series series) { //If we dont already have this series, add to the chrt: if (!Series.ContainsKey(series.Name)) { Series.Add(series.Name, series); } else { throw new Exception("Chart.AddSeries(): Chart series name already exists"); } }
/// <summary> /// Get the updates since the last call to this function. /// </summary> /// <returns>List of the updates from the series</returns> public Series GetUpdates() { Series _copy = new Series(Name, SeriesType); try { //Add the updates since the last for (int i = updatePosition; i < this.Values.Count; i++) { _copy.Values.Add(this.Values[i]); } //Shuffle the update point to now: updatePosition = this.Values.Count; } catch (Exception err) { Log.Error("Series.GetUpdates(): " + err.Message); } return _copy; }
/// <summary> /// Get the updates since the last call to this function. /// </summary> /// <returns>List of the updates from the series</returns> public Series GetUpdates() { var copy = new Series(Name, SeriesType, Index, Unit) { Color = Color, ScatterMarkerSymbol = ScatterMarkerSymbol }; try { //Add the updates since the last for (var i = _updatePosition; i < Values.Count; i++) { copy.Values.Add(Values[i]); } //Shuffle the update point to now: _updatePosition = Values.Count; } catch (Exception err) { Log.Error(err); } return copy; }
/// <summary> /// Samples the given series /// </summary> /// <param name="series">The series to be sampled</param> /// <param name="start">The date to start sampling, if before start of data then start of data will be used</param> /// <param name="stop">The date to stop sampling, if after stop of data, then stop of data will be used</param> /// <returns>The sampled series</returns> public Series Sample(Series series, DateTime start, DateTime stop) { var sampled = new Series(series.Name, series.SeriesType); // chart point times are always in universal, so force it here as well double nextSample = Time.DateTimeToUnixTimeStamp(start.ToUniversalTime()); double unixStopDate = Time.DateTimeToUnixTimeStamp(stop.ToUniversalTime()); // we can't sample a single point and it doesn't make sense to sample scatter plots // in this case just copy the raw data if (series.Values.Count < 2 || series.SeriesType == SeriesType.Scatter) { // we can minimally verify we're within the start/stop interval foreach (var point in series.Values) { if (point.x >= nextSample && point.x <= unixStopDate) { sampled.Values.Add(point); } } return sampled; } var enumerator = series.Values.GetEnumerator(); // initialize current/previous enumerator.MoveNext(); ChartPoint previous = enumerator.Current; enumerator.MoveNext(); ChartPoint current = enumerator.Current; // make sure we don't start sampling before the data begins if (nextSample < previous.x) { nextSample = previous.x; } // make sure to advance into the requestd time frame before sampling while (current.x < nextSample && enumerator.MoveNext()) { previous = current; current = enumerator.Current; } do { // advance our current/previous if (nextSample > current.x) { if (enumerator.MoveNext()) { previous = current; current = enumerator.Current; } else { break; } } // iterate until we pass where we want our next point while (nextSample <= current.x && nextSample <= unixStopDate) { var value = Interpolate(previous, current, (long) nextSample); sampled.Values.Add(new ChartPoint {x = (long) nextSample, y = value}); nextSample += _seconds; } // if we've passed our stop then we're finished sampling if (nextSample > unixStopDate) { break; } } while (true); return sampled; }
/// <summary> /// Create candles from series x,y data: /// </summary> public List<StockPt> CreateCandle(Series series, double lastUpdate) { decimal start = 0; int day = 24 * 60 * 60; decimal dateTime = 0; decimal equity = 0; List<decimal[]> equityCandles = new List<decimal[]>(); decimal[] candleToday = new decimal[0]; var spl = new List<StockPt>(); if (series.Values.Count > 2000) { day = 30 * 24 * 60 * 60; } else if (series.Values.Count > 365) { day = 7* 24 * 60 * 60; } for (int i = 0; i < series.Values.Count; i++) { if (series.Values[i].x < lastUpdate) continue; dateTime = series.Values[i].x; equity = series.Values[i].y; if (start == 0 || (start + day) < dateTime) start = dateTime; if (start == dateTime) { if (candleToday.Length > 0) equityCandles.Add(candleToday); candleToday = new decimal[5] { -1, 0, -1, 999999999, 0 }; candleToday[0] = start; } if (candleToday[1] == 0) candleToday[1] = equity; if (candleToday[2] < equity) candleToday[2] = equity; if (candleToday[3] > equity) candleToday[3] = equity; candleToday[4] = equity; } foreach (var candle in equityCandles) { DateTime time = UnixMsToDateTime((double)candle[0]); StockPt point = new StockPt(time.ToOADate(), Convert.ToDouble(candle[2]), Convert.ToDouble(candle[3]), Convert.ToDouble(candle[1]), Convert.ToDouble(candle[4]), 1000); spl.Add(point); } return spl; }
/// <summary> /// Create a new curve item /// </summary> public CurveItem CreateCurveItem(Series series) { CurveItem item = null; switch (series.SeriesType) { case SeriesType.Candle: JapaneseCandleStickItem candle = new JapaneseCandleStickItem(series.Name, new StockPointList()); candle.Stick.IsAutoSize = true; candle.Stick.Color = Color.FromArgb(46, 56, 59); candle.Stick.RisingFill = new Fill(Color.FromArgb(140, 193, 118)); candle.Stick.FallingFill = new Fill(Color.FromArgb(184, 44, 12)); item = candle; break; case SeriesType.Line: LineItem line = new LineItem(series.Name, new DateTimePointList(), Color.DarkBlue, SymbolType.None); item = line; break; case SeriesType.Scatter: LineItem scatter = new LineItem(series.Name, new DateTimePointList(), Color.Black, SymbolType.Circle); scatter.Line = new Line(); scatter.Line.IsVisible = false; scatter.Symbol.Size = 10; scatter.Symbol.Fill = new Fill(Color.LightGreen); item = scatter; break; } return item; }
/// <summary> /// Initialize the charts /// </summary> private void Initialize(Chart resultChart, Series series) { //Setup Chart: var chart = _chartObjects[resultChart.Name]; chart.Dock = DockStyle.Fill; chart.MasterPane.Border.IsVisible = false; chart.IsSynchronizeXAxes = true; //Based on the QC chart type, draw the panes: switch (resultChart.ChartType) { case ChartType.Overlay: GraphPane overlayPane = CreateGraphPane(resultChart.Name); CurveItem curveItem = CreateCurveItem(series); overlayPane.CurveList.Add(curveItem); _cache[resultChart.Name][series.Name] = curveItem; chart.MasterPane.Add(overlayPane); break; case ChartType.Stacked: GraphPane stackedPane = CreateGraphPane(series.Name); CurveItem stackedCurveItem = CreateCurveItem(series); stackedPane.CurveList.Add(stackedCurveItem); chart.MasterPane.Add(stackedPane); _cache[resultChart.Name][series.Name] = stackedCurveItem; break; } //Refresh it: RefreshChart(ref chart); }
/// <summary> /// Get the updates since the last call to this function. /// </summary> /// <returns>List of the updates from the series</returns> public Series GetUpdates() { var copy = new Series(Name, SeriesType); try { //Add the updates since the last for (var i = _updatePosition; i < Values.Count; i++) { copy.Values.Add(Values[i]); } //Shuffle the update point to now: _updatePosition = Values.Count; } catch (Exception err) { Log.Error("Series.GetUpdates(): " + err.Message); } return copy; }
/// <summary> /// Samples the given series /// </summary> /// <param name="series">The series to be sampled</param> /// <param name="start">The date to start sampling, if before start of data then start of data will be used</param> /// <param name="stop">The date to stop sampling, if after stop of data, then stop of data will be used</param> /// <returns>The sampled series</returns> public Series Sample(Series series, DateTime start, DateTime stop) { var sampled = new Series(series.Name, series.SeriesType); if (series.Values.Count < 2) { // return new instance, but keep the same data sampled.Values.AddRange(series.Values); return sampled; } double nextSample = Time.DateTimeToUnixTimeStamp(start); double unixStopDate = Time.DateTimeToUnixTimeStamp(stop); var enumerator = series.Values.GetEnumerator(); // initialize current/previous enumerator.MoveNext(); ChartPoint previous = enumerator.Current; enumerator.MoveNext(); ChartPoint current = enumerator.Current; // make sure we don't start sampling before the data begins if (nextSample < previous.x) { nextSample = previous.x; } // make sure to advance into the requestd time frame before sampling while (current.x < nextSample && enumerator.MoveNext()) { previous = current; current = enumerator.Current; } do { // advance our current/previous if (nextSample > current.x) { if (enumerator.MoveNext()) { previous = current; current = enumerator.Current; } else { break; } } // iterate until we pass where we want our next point while (nextSample <= current.x && nextSample <= unixStopDate) { var value = Interpolate(previous, current, (long) nextSample); sampled.Values.Add(new ChartPoint {x = (long) nextSample, y = value}); nextSample += _seconds; } // if we've passed our stop then we're finished sampling if (nextSample > unixStopDate) { break; } } while (true); return sampled; }
/// <summary> /// Samples the given series /// </summary> /// <param name="series">The series to be sampled</param> /// <param name="start">The date to start sampling, if before start of data then start of data will be used</param> /// <param name="stop">The date to stop sampling, if after stop of data, then stop of data will be used</param> /// <returns>The sampled series</returns> public Series Sample(Series series, DateTime start, DateTime stop) { var sampled = new Series(series.Name, series.SeriesType); // chart point times are always in universal, so force it here as well double nextSample = Time.DateTimeToUnixTimeStamp(start.ToUniversalTime()); double unixStopDate = Time.DateTimeToUnixTimeStamp(stop.ToUniversalTime()); // we can't sample a single point and it doesn't make sense to sample scatter plots // in this case just copy the raw data if (series.Values.Count < 2 || series.SeriesType == SeriesType.Scatter) { // we can minimally verify we're within the start/stop interval foreach (var point in series.Values) { if (point.x >= nextSample && point.x <= unixStopDate) { sampled.Values.Add(point); } } return(sampled); } var enumerator = series.Values.GetEnumerator(); // initialize current/previous enumerator.MoveNext(); ChartPoint previous = enumerator.Current; enumerator.MoveNext(); ChartPoint current = enumerator.Current; // make sure we don't start sampling before the data begins if (nextSample < previous.x) { nextSample = previous.x; } // make sure to advance into the requestd time frame before sampling while (current.x < nextSample && enumerator.MoveNext()) { previous = current; current = enumerator.Current; } do { // advance our current/previous if (nextSample > current.x) { if (enumerator.MoveNext()) { previous = current; current = enumerator.Current; } else { break; } } // iterate until we pass where we want our next point while (nextSample <= current.x && nextSample <= unixStopDate) { var value = Interpolate(previous, current, (long)nextSample); sampled.Values.Add(new ChartPoint { x = (long)nextSample, y = value }); nextSample += _seconds; } // if we've passed our stop then we're finished sampling if (nextSample > unixStopDate) { break; } }while (true); return(sampled); }