Files

138 lines
3.7 KiB
C#

namespace QuanTAlib;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
/* <summary>
TSeries is the cornerstone of all QuanTAlib classes.
TSeries is a single List of tuples (time, value) and contains several operators, casts, overloads
and other helpers that simplify usage of library.
Think of TSeries as an equivalent of Numpy array.
- includes Length property (to mimic array's method)
- includes publishing and subscribing methods that attach to events
</summary> */
public class TSeriesEventArgs : EventArgs
{
public bool update { get; set; }
}
public class TSeries : List<(DateTime t, double v)>
{
private readonly (DateTime t, double v) Default = (DateTime.MinValue, double.NaN);
public IEnumerable<DateTime> t => this.Select(item => item.t);
public IEnumerable<double> v => this.Select(item => item.v);
public (DateTime t, double v) Last => Count > 0 ? this[^1] : Default;
public int Length => Count;
public string Name { get; set; }
public int Keep = 0;
public TSeries()
{
this.Name = "data";
}
public TSeries(string Name)
{
this.Name = Name;
}
public virtual (DateTime t, double v) Add(double v, bool update = false)
{
return Add((t: Count == 0 ? DateTime.Today : this[^1].t.AddDays(1), v), update);
}
public virtual (DateTime t, double v) Add((DateTime t, double v) TValue, bool update = false)
{
if (update)
{
this[^1] = TValue;
}
else
{
base.Add(TValue);
}
OnEvent(update);
return TValue;
}
public virtual (DateTime t, double v) Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update = false)
{
if (update)
{
this[this.Count - 1] = (TBar.t, TBar.c);
}
else
{
base.Add((TBar.t, TBar.c));
}
OnEvent(update);
return (TBar.t, TBar.c);
}
public virtual (DateTime t, double v) Add(TSeries data)
{
foreach (var item in data) { Add(item); }
return data.Last;
}
public virtual (DateTime t, double v) Add(TBars data)
{
foreach (var item in data) { Add(item.c, false); }
return (data.Last.t, data.Last.c);
}
public void Sub(object source, TSeriesEventArgs e)
{
var data = (TSeries)source;
if (data == null) { return; }
foreach (var item in data) { Add(item); }
}
public delegate void NewEventHandler(object source, TSeriesEventArgs args);
public event NewEventHandler Pub;
protected virtual void OnEvent(bool update = false)
{
if (Keep > 0)
{
TrimToSize(keep: Keep);
}
Pub?.Invoke(this, new TSeriesEventArgs { update = update });
}
/// common helpers
public static void BufferTrim(List<double> buffer, double value, int period, bool update)
{
if (!update)
{
buffer.Add(value);
if (buffer.Count > period && period > 0) { buffer.RemoveAt(0); }
return;
}
buffer[^1] = value;
}
public virtual void Reset()
{
}
public void TrimToSize(int keep)
{
if (keep >= this.Count)
{
return; // No need to trim if the series is already smaller than or equal to n
}
// Remove elements from the beginning of the list
int elementsToRemove = this.Count - keep;
RemoveRange(0, elementsToRemove);
}
}