refactor structs to records, add new classes for financial calculations, implement EMA and SMA with circular buffer. Generate random financial data using GBM model. Also, test the SMA calculation with sample data.

This commit is contained in:
Miha Kralj
2024-07-28 21:26:44 -07:00
parent ef534393db
commit 3455baaf6c
95 changed files with 8661 additions and 7012 deletions
+100 -80
View File
@@ -15,103 +15,123 @@ TSeries is the cornerstone of all QuanTAlib classes.
- includes publishing and subscribing methods that attach to events
</summary> */
public class TSeriesEventArgs : EventArgs {
public bool update { get; set; }
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 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 int Length => Count;
public string Name { get; set; }
public int Keep = 0;
public TSeries() {
this.Name = "data";
}
public TSeries()
{
this.Name = "data";
}
public TSeries(string Name) {
this.Name = Name;
}
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(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);
}
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;
}
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));
}
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);
}
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(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 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 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 delegate void NewEventHandler(object source, TSeriesEventArgs args);
public event NewEventHandler Pub;
public event NewEventHandler Pub;
protected virtual void OnEvent(bool update = false)
{
if (Keep > 0) {
TrimToSize(keep:Keep);
}
Pub?.Invoke(this, new TSeriesEventArgs {update = update});
}
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() {
}
/// 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
}
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);
}
// Remove elements from the beginning of the list
int elementsToRemove = this.Count - keep;
RemoveRange(0, elementsToRemove);
}
}