Skip to content

Instantly share code, notes, and snippets.

@ahancock1
Created September 27, 2020 11:12
Show Gist options
  • Save ahancock1/ada9f03cfbf6f6d183c24949b9b3b503 to your computer and use it in GitHub Desktop.
Save ahancock1/ada9f03cfbf6f6d183c24949b9b3b503 to your computer and use it in GitHub Desktop.
Observable extensible generic trading indicator series
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public interface ISeries
{
void Attach(ISeries series);
void AttachTo(ISeries series);
void Detach(ISeries series);
void DetachFrom(ISeries series);
void Notify();
void OnNext();
void Clear();
}
public interface ISeries<T> : ISeries, IEnumerable<T>
{
int Size { get; }
int Available { get; }
T this[int n] { get; }
void SetValue(T value);
}
public class Series<T> : ISeries<T>
{
private readonly T[] _data;
private readonly Func<T> _evaluator;
private readonly IList<ISeries> _observers =
new List<ISeries>();
private int _index;
private Series(Func<T> evaluator, int count)
: this(count)
{
_evaluator = evaluator;
}
private Series(int count)
{
_index = -1;
_data = new T[count];
Size = count;
}
public int Size { get; }
public int Available { get; private set; }
public T this[int n]
{
get
{
n = Math.Max(Math.Min(n, Available - 1), 0);
var i = (_index + Size - n) % Size;
return _data[i];
}
}
public void Attach(ISeries series)
{
_observers.Add(series);
}
public void AttachTo(ISeries series)
{
series.Attach(this);
}
public void Detach(ISeries series)
{
_observers.Remove(series);
}
public void DetachFrom(ISeries series)
{
series.Detach(this);
}
public void Notify()
{
foreach (var observer in _observers)
{
observer.OnNext();
}
}
public virtual void SetValue(T value)
{
_index = (_index + 1) % Size;
Available = Math.Min(Available + 1, Size);
_data[_index] = value;
Notify();
}
public virtual void OnNext()
{
var value = default(T);
if (_evaluator != null)
{
value = _evaluator.Invoke();
}
SetValue(value);
}
public virtual void Clear()
{
_index = -1;
Available = 0;
foreach (var observer in _observers)
{
observer.Clear();
}
}
public IEnumerator<T> GetEnumerator()
{
return Enumerable
.Range(0, Available)
.Select(x => this[x])
.ToList()
.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public static ISeries<T> Create(int count = 256)
{
return new Series<T>(count);
}
public static ISeries<T> Create(Func<T> evaluator, int count = 256)
{
return new Series<T>(evaluator, count);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment