/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using QuantConnect.Logging;
using QuantConnect.Util;
namespace QuantConnect
{
///
/// Chart Series Object - Series data and properties for a chart:
///
[JsonConverter(typeof(SeriesJsonConverter))]
public abstract class BaseSeries
{
/// The index of the last fetch update request to only retrieve the "delta" of the previous request.
private int _updatePosition;
///
/// Name of the series.
///
public string Name { get; set; }
///
/// Axis for the chart series.
///
public string Unit { get; set; }
///
/// Index/position of the series on the chart.
///
public int Index { get; set; }
///
/// Axis name for the chart series.
///
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string IndexName { get; set; }
///
/// Defines the visual Z index of the series on the chart.
///
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public int? ZIndex { get; set; }
///
/// Chart type for the series:
///
public SeriesType SeriesType { get; set; }
///
/// An optional tooltip template
///
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Tooltip { get; set; }
///
/// The series list of values.
/// These values are assumed to be in ascending time order (first points earliest, last points latest)
///
public List Values { get; set; }
///
/// Default constructor for chart series
///
protected BaseSeries()
{
Unit = "$";
Values = new List();
}
///
/// Constructor method for Chart Series
///
/// Name of the chart series
/// Type of the series
protected BaseSeries(string name, SeriesType type)
: this()
{
Name = name;
SeriesType = type;
}
///
/// Foundational constructor on the series class
///
/// Name of the series
/// Type of the series
/// Series index position on the chart
protected BaseSeries(string name, SeriesType type, int index)
: this(name, type)
{
Index = index;
}
///
/// Foundational constructor on the series class
///
/// Name of the series
/// Type of the series
/// Series index position on the chart
/// Unit for the series axis
protected BaseSeries(string name, SeriesType type, int index, string unit)
: this(name, type, index)
{
Unit = unit;
}
///
/// Constructor method for Chart Series
///
/// Name of the chart series
/// Type of the chart series
/// Unit of the series
protected BaseSeries(string name, SeriesType type, string unit)
: this(name, type, 0, unit)
{
}
///
/// Add a new point to this series
///
/// The data point to add
public virtual void AddPoint(ISeriesPoint point)
{
if (Values.Count > 0 && Values[Values.Count - 1].Time == point.Time)
{
// duplicate points at the same time, overwrite the value
Values[Values.Count - 1] = point;
}
else
{
Values.Add(point);
}
}
///
/// Add a new point to this series
///
/// The time of the data point
/// The values of the data point
public abstract void AddPoint(DateTime time, List values);
///
/// Get the updates since the last call to this function.
///
/// List of the updates from the series
public BaseSeries GetUpdates()
{
var copy = Clone(empty: true);
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;
}
///
/// Removes the data from this series and resets the update position to 0
///
public void Purge()
{
Values.Clear();
_updatePosition = 0;
}
///
/// Will sum up all chart points into a new single value, using the time of latest point
///
/// The new chart point
public abstract ISeriesPoint ConsolidateChartPoints();
///
/// Return a new instance clone of this object
///
///
public abstract BaseSeries Clone(bool empty = false);
///
/// Return a list of cloned values
///
///
protected List CloneValues()
{
var clone = new List(Values.Count);
foreach (var point in Values)
{
clone.Add(point.Clone());
}
return clone;
}
///
/// Returns an enumerable of the values of the series cast to the specified type
///
/// An enumerable of the values of the series cast to the specified type
public IEnumerable GetValues()
where T : ISeriesPoint
{
return Values.Cast();
}
///
/// Creates a series according to the specified type.
///
/// The series type
/// The name of the series
/// Series index position on the chart
/// Unit for the series axis
///
/// A if is .
/// A otherwise.
///
public static BaseSeries Create(SeriesType seriesType, string name, int index = 0, string unit = "$")
{
if (!Enum.IsDefined(typeof(SeriesType), seriesType))
{
throw new ArgumentOutOfRangeException(nameof(seriesType), "Series type out of range");
}
if (seriesType == SeriesType.Candle)
{
return new CandlestickSeries(name, index, unit);
}
return new Series(name, seriesType, index, unit);
}
}
///
/// Available types of chart series
///
public enum SeriesType
{
/// Line Plot for Value Types (0)
Line,
/// Scatter Plot for Chart Distinct Types (1)
Scatter,
/// Charts (2)
Candle,
/// Bar chart (3)
Bar,
/// Flag indicators (4)
Flag,
/// 100% area chart showing relative proportions of series values at each time index (5)
StackedArea,
/// Pie chart (6)
Pie,
/// Treemap Plot (7)
Treemap,
/// Heatmap Plot (9) -- NOTE: 8 is reserved
Heatmap = 9,
/// Scatter 3D Plot (10)
Scatter3d
}
}