mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-27 17:27:43 +00:00
codefactory corrections
This commit is contained in:
@@ -26,15 +26,6 @@ public class StatisticsUpdateTests
|
||||
return new TBar(DateTime.Now, open, high, low, close, 1000, IsNew);
|
||||
}
|
||||
|
||||
private TBar GetRandomBar(bool IsNew)
|
||||
{
|
||||
double open = GetRandomDouble();
|
||||
double high = open + Math.Abs(GetRandomDouble());
|
||||
double low = open - Math.Abs(GetRandomDouble());
|
||||
double close = low + (high - low) * GetRandomDouble();
|
||||
return new TBar(DateTime.Now, open, high, low, close, 1000, IsNew);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Curvature_Update()
|
||||
{
|
||||
|
||||
@@ -59,110 +59,3 @@ public readonly record struct TBar(DateTime Time, double Open, double High, doub
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override string ToString() => $"[{Time:yyyy-MM-dd HH:mm:ss}: O={Open:F2}, H={High:F2}, L={Low:F2}, C={Close:F2}, V={Volume:F2}]";
|
||||
}
|
||||
|
||||
public delegate void BarSignal(object source, in TBarEventArgs args);
|
||||
|
||||
[SkipLocalsInit]
|
||||
public sealed class TBarEventArgs : EventArgs
|
||||
{
|
||||
public readonly TBar Bar;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TBarEventArgs(TBar bar) => Bar = bar;
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public class TBarSeries : List<TBar>
|
||||
{
|
||||
private static readonly TBar Default = new(DateTime.MinValue, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN);
|
||||
|
||||
public readonly TSeries Open;
|
||||
public readonly TSeries High;
|
||||
public readonly TSeries Low;
|
||||
public readonly TSeries Close;
|
||||
public readonly TSeries Volume;
|
||||
|
||||
public TBar Last => Count > 0 ? this[^1] : Default;
|
||||
public TBar First => Count > 0 ? this[0] : Default;
|
||||
public int Length => Count;
|
||||
public string Name { get; set; }
|
||||
public event BarSignal Pub = delegate { };
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TBarSeries()
|
||||
{
|
||||
Name = "Bar";
|
||||
Open = new TSeries();
|
||||
High = new TSeries();
|
||||
Low = new TSeries();
|
||||
Close = new TSeries();
|
||||
Volume = new TSeries();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TBarSeries(object source) : this()
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void Add(TBar bar)
|
||||
{
|
||||
if (bar.IsNew || base.Count == 0)
|
||||
{
|
||||
base.Add(bar);
|
||||
}
|
||||
else
|
||||
{
|
||||
this[^1] = bar;
|
||||
}
|
||||
|
||||
Pub?.Invoke(this, new TBarEventArgs(bar));
|
||||
|
||||
Open.Add(bar.Time, bar.Open, IsNew: bar.IsNew, IsHot: true);
|
||||
High.Add(bar.Time, bar.High, IsNew: bar.IsNew, IsHot: true);
|
||||
Low.Add(bar.Time, bar.Low, IsNew: bar.IsNew, IsHot: true);
|
||||
Close.Add(bar.Time, bar.Close, IsNew: bar.IsNew, IsHot: true);
|
||||
Volume.Add(bar.Time, bar.Volume, IsNew: bar.IsNew, IsHot: true);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(DateTime Time, double Open, double High, double Low, double Close, double Volume, bool IsNew = true) =>
|
||||
Add(new TBar(Time, Open, High, Low, Close, Volume, IsNew));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(double Open, double High, double Low, double Close, double Volume, bool IsNew = true) =>
|
||||
Add(new TBar(DateTime.Now, Open, High, Low, Close, Volume, IsNew));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(TBarSeries series)
|
||||
{
|
||||
if (series == this)
|
||||
{
|
||||
// If adding itself, create a copy to avoid modification during enumeration
|
||||
var copy = new TBarSeries { Name = Name };
|
||||
copy.AddRange(this);
|
||||
AddRange(copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRange(series);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void AddRange(IEnumerable<TBar> collection)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Sub(object source, in TBarEventArgs args)
|
||||
{
|
||||
Add(args.Bar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace QuanTAlib;
|
||||
|
||||
public delegate void BarSignal(object source, in TBarEventArgs args);
|
||||
|
||||
[SkipLocalsInit]
|
||||
public sealed class TBarEventArgs : EventArgs
|
||||
{
|
||||
public readonly TBar Bar;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TBarEventArgs(TBar bar) => Bar = bar;
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public class TBarSeries : List<TBar>
|
||||
{
|
||||
private static readonly TBar Default = new(DateTime.MinValue, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN);
|
||||
|
||||
public TSeries Open { get; init; }
|
||||
public TSeries High { get; init; }
|
||||
public TSeries Low { get; init; }
|
||||
public TSeries Close { get; init; }
|
||||
public TSeries Volume { get; init; }
|
||||
|
||||
public TBar Last => Count > 0 ? this[^1] : Default;
|
||||
public TBar First => Count > 0 ? this[0] : Default;
|
||||
public int Length => Count;
|
||||
public string Name { get; set; }
|
||||
public event BarSignal Pub = delegate { };
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TBarSeries()
|
||||
{
|
||||
Name = "Bar";
|
||||
Open = new TSeries();
|
||||
High = new TSeries();
|
||||
Low = new TSeries();
|
||||
Close = new TSeries();
|
||||
Volume = new TSeries();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TBarSeries(object source) : this()
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void Add(TBar bar)
|
||||
{
|
||||
if (bar.IsNew || base.Count == 0)
|
||||
{
|
||||
base.Add(bar);
|
||||
}
|
||||
else
|
||||
{
|
||||
this[^1] = bar;
|
||||
}
|
||||
|
||||
Pub?.Invoke(this, new TBarEventArgs(bar));
|
||||
|
||||
Open.Add(bar.Time, bar.Open, IsNew: bar.IsNew, IsHot: true);
|
||||
High.Add(bar.Time, bar.High, IsNew: bar.IsNew, IsHot: true);
|
||||
Low.Add(bar.Time, bar.Low, IsNew: bar.IsNew, IsHot: true);
|
||||
Close.Add(bar.Time, bar.Close, IsNew: bar.IsNew, IsHot: true);
|
||||
Volume.Add(bar.Time, bar.Volume, IsNew: bar.IsNew, IsHot: true);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(DateTime Time, double Open, double High, double Low, double Close, double Volume, bool IsNew = true) =>
|
||||
Add(new TBar(Time, Open, High, Low, Close, Volume, IsNew));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(double Open, double High, double Low, double Close, double Volume, bool IsNew = true) =>
|
||||
Add(new TBar(DateTime.Now, Open, High, Low, Close, Volume, IsNew));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(TBarSeries series)
|
||||
{
|
||||
if (series == this)
|
||||
{
|
||||
// If adding itself, create a copy to avoid modification during enumeration
|
||||
var copy = new TBarSeries { Name = Name };
|
||||
copy.AddRange(this);
|
||||
AddRange(copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRange(series);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void AddRange(IEnumerable<TBar> collection)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Sub(object source, in TBarEventArgs args)
|
||||
{
|
||||
Add(args.Bar);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace QuanTAlib;
|
||||
|
||||
public delegate void ValueSignal(object source, in ValueEventArgs args);
|
||||
|
||||
[SkipLocalsInit]
|
||||
public sealed class ValueEventArgs : EventArgs
|
||||
{
|
||||
public readonly TValue Tick;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ValueEventArgs(TValue value) => Tick = value;
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public class TSeries : List<TValue>
|
||||
{
|
||||
private static readonly TValue Default = new(DateTime.MinValue, double.NaN);
|
||||
|
||||
public IEnumerable<DateTime> t => this.Select(item => item.t);
|
||||
public IEnumerable<double> v => this.Select(item => item.v);
|
||||
public TValue Last => Count > 0 ? this[^1] : Default;
|
||||
public TValue First => Count > 0 ? this[0] : Default;
|
||||
public int Length => Count;
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event that publishes value updates to subscribers. This event is used in the pub/sub pattern
|
||||
/// where TSeries instances can subscribe to updates from other data sources through the Sub method,
|
||||
/// and publish their own updates to downstream subscribers.
|
||||
/// </summary>
|
||||
[SuppressMessage("Minor Code Smell", "S3264:Events should be invoked", Justification = "Event is invoked through delegate")]
|
||||
public event ValueSignal Pub = delegate { };
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TSeries()
|
||||
{
|
||||
Name = "Data";
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TSeries(object source) : this()
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
if (pubEvent != null)
|
||||
{
|
||||
pubEvent.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator List<double>(TSeries series) => series.Select(item => item.Value).ToList();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator double[](TSeries series) => series.Select(item => item.Value).ToArray();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void Add(TValue tick)
|
||||
{
|
||||
if (tick.IsNew || base.Count == 0)
|
||||
{
|
||||
base.Add(tick);
|
||||
}
|
||||
else
|
||||
{
|
||||
this[^1] = tick;
|
||||
}
|
||||
Pub?.Invoke(this, new ValueEventArgs(tick));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Add(DateTime Time, double Value, bool IsNew = true, bool IsHot = true) =>
|
||||
Add(new TValue(Time, Value, IsNew, IsHot));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Add(double Value, bool IsNew = true, bool IsHot = true) =>
|
||||
Add(new TValue(DateTime.UtcNow, Value, IsNew, IsHot));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(IEnumerable<double> values)
|
||||
{
|
||||
var valueList = values.ToList();
|
||||
int count = valueList.Count;
|
||||
DateTime startTime = DateTime.UtcNow - TimeSpan.FromHours(count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Add(startTime, valueList[i]);
|
||||
startTime = startTime.AddHours(1);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(TSeries series)
|
||||
{
|
||||
if (series == this)
|
||||
{
|
||||
// If adding itself, create a copy to avoid modification during enumeration
|
||||
var copy = new TSeries { Name = Name };
|
||||
copy.AddRange(this);
|
||||
AddRange(copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRange(series);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void AddRange(IEnumerable<TValue> collection)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Sub(object source, in ValueEventArgs args) => Add(args.Tick);
|
||||
}
|
||||
@@ -39,114 +39,3 @@ public readonly record struct TValue(DateTime Time, double Value, bool IsNew = t
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override string ToString() => $"[{Time:yyyy-MM-dd HH:mm:ss}, {Value:F2}, IsNew: {IsNew}, IsHot: {IsHot}]";
|
||||
}
|
||||
|
||||
public delegate void ValueSignal(object source, in ValueEventArgs args);
|
||||
|
||||
[SkipLocalsInit]
|
||||
public sealed class ValueEventArgs : EventArgs
|
||||
{
|
||||
public readonly TValue Tick;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ValueEventArgs(TValue value) => Tick = value;
|
||||
}
|
||||
|
||||
[SkipLocalsInit]
|
||||
public class TSeries : List<TValue>
|
||||
{
|
||||
private static readonly TValue Default = new(DateTime.MinValue, double.NaN);
|
||||
|
||||
public IEnumerable<DateTime> t => this.Select(item => item.t);
|
||||
public IEnumerable<double> v => this.Select(item => item.v);
|
||||
public TValue Last => Count > 0 ? this[^1] : Default;
|
||||
public TValue First => Count > 0 ? this[0] : Default;
|
||||
public int Length => Count;
|
||||
public string Name { get; set; }
|
||||
public event ValueSignal Pub = delegate { };
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TSeries()
|
||||
{
|
||||
Name = "Data";
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public TSeries(object source) : this()
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
if (pubEvent != null)
|
||||
{
|
||||
pubEvent.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator List<double>(TSeries series) => series.Select(item => item.Value).ToList();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator double[](TSeries series) => series.Select(item => item.Value).ToArray();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void Add(TValue tick)
|
||||
{
|
||||
if (tick.IsNew || base.Count == 0)
|
||||
{
|
||||
base.Add(tick);
|
||||
}
|
||||
else
|
||||
{
|
||||
this[^1] = tick;
|
||||
}
|
||||
Pub?.Invoke(this, new ValueEventArgs(tick));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Add(DateTime Time, double Value, bool IsNew = true, bool IsHot = true) =>
|
||||
Add(new TValue(Time, Value, IsNew, IsHot));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Add(double Value, bool IsNew = true, bool IsHot = true) =>
|
||||
Add(new TValue(DateTime.UtcNow, Value, IsNew, IsHot));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(IEnumerable<double> values)
|
||||
{
|
||||
var valueList = values.ToList();
|
||||
int count = valueList.Count;
|
||||
DateTime startTime = DateTime.UtcNow - TimeSpan.FromHours(count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Add(startTime, valueList[i]);
|
||||
startTime = startTime.AddHours(1);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Add(TSeries series)
|
||||
{
|
||||
if (series == this)
|
||||
{
|
||||
// If adding itself, create a copy to avoid modification during enumeration
|
||||
var copy = new TSeries { Name = Name };
|
||||
copy.AddRange(this);
|
||||
AddRange(copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRange(series);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public new virtual void AddRange(IEnumerable<TValue> collection)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Sub(object source, in ValueEventArgs args) => Add(args.Tick);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user