Files

160 lines
5.2 KiB
C#
Raw Permalink Normal View History

2024-10-27 16:11:08 -07:00
using System.Runtime.CompilerServices;
2024-09-22 17:31:24 -07:00
namespace QuanTAlib;
/// <summary>
/// Provides a base implementation for financial indicators in the QuanTAlib library.
/// </summary>
2024-10-05 15:20:13 -07:00
/// <remarks>
/// This abstract class implements the iTValue interface and defines common properties
/// and methods used by inheriting indicator types. It handles the basic flow of
/// receiving data, performing calculations, and publishing results.
/// </remarks>
2024-10-06 14:44:43 -07:00
public abstract class AbstractBase : ITValue
2024-09-22 17:31:24 -07:00
{
2024-10-27 16:11:08 -07:00
public System.DateTime Time { get; set; }
2024-09-22 17:31:24 -07:00
public double Value { get; set; }
public bool IsNew { get; set; }
public bool IsHot { get; set; }
public TValue Input { get; set; }
2024-10-07 21:41:26 -07:00
public TValue Input2 { get; set; }
public TBar BarInput { get; set; }
public TBar BarInput2 { get; set; }
2024-10-27 16:11:08 -07:00
public string Name { get; set; } = "";
2024-09-22 17:31:24 -07:00
public int WarmupPeriod { get; set; }
2024-10-05 15:20:13 -07:00
public TValue Tick => new(Time, Value, IsNew, IsHot);
public event ValueSignal Pub = delegate { };
protected int _index;
2024-09-22 17:31:24 -07:00
protected double _lastValidValue;
protected AbstractBase()
2024-10-05 15:20:13 -07:00
{
// Add parameters into constructor if needed
2024-09-22 17:31:24 -07:00
}
/// <summary>
2024-10-27 16:11:08 -07:00
/// Checks if the input value is valid (not NaN or Infinity).
2024-09-22 17:31:24 -07:00
/// </summary>
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected static bool IsValidValue(double value)
{
return !double.IsNaN(value) && !double.IsInfinity(value);
}
/// <summary>
/// Creates a new TValue with the current state.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-11-04 18:08:33 -08:00
protected static TValue CreateTValue(System.DateTime time, double value, bool isNew, bool isHot = false)
2024-10-27 16:11:08 -07:00
{
return new TValue(time, value, isNew, isHot);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-22 17:31:24 -07:00
public void Sub(object source, in ValueEventArgs args) => Calc(args.Tick);
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-07 21:41:26 -07:00
public void Sub(object source1, object source2, in ValueEventArgs args1, in ValueEventArgs args2) =>
Calc(args1.Tick, args2.Tick);
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-07 21:41:26 -07:00
public void Sub(object source, in TBarEventArgs args) => Calc(args.Bar);
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-22 17:31:24 -07:00
public virtual void Init()
{
_index = 0;
_lastValidValue = 0;
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-07 21:41:26 -07:00
public virtual TValue Calc(TValue input)
{
Input = input;
2024-10-27 16:11:08 -07:00
Input2 = CreateTValue(input.Time, double.NaN, input.IsNew, input.IsHot);
2024-10-13 11:19:27 -07:00
return Process(input.Value, input.Time, input.IsNew);
2024-10-07 21:41:26 -07:00
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public virtual TValue Calc(double value, bool isNew)
2024-10-21 16:06:47 -07:00
{
2024-10-27 16:11:08 -07:00
Input = CreateTValue(Time, value, isNew);
Input2 = CreateTValue(Time, double.NaN, false);
2024-10-21 16:06:47 -07:00
return Process(Input.Value, Input.Time, Input.IsNew);
}
2024-10-07 21:41:26 -07:00
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-07 21:41:26 -07:00
public virtual TValue Calc(TBar barInput)
{
BarInput = barInput;
2024-10-13 11:19:27 -07:00
return Process(barInput.Close, barInput.Time, barInput.IsNew);
2024-10-07 21:41:26 -07:00
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-07 21:41:26 -07:00
public virtual TValue Calc(TValue input1, TValue input2)
{
Input = input1;
Input2 = input2;
2024-10-13 11:19:27 -07:00
return Process(input1.Value, input2.Value, input1.Time, input1.IsNew);
2024-10-07 21:41:26 -07:00
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-07 21:41:26 -07:00
public virtual TValue Calc(TBar input1, TBar input2)
{
BarInput = input1;
BarInput2 = input2;
2024-10-13 11:19:27 -07:00
return Process(input1.Close, input2.Close, input1.Time, input1.IsNew);
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-13 11:19:27 -07:00
public virtual TValue Calc(double value1, double value2)
{
2024-10-27 16:11:08 -07:00
var now = System.DateTime.Now;
Input = CreateTValue(now, value1, true, true);
Input2 = CreateTValue(now, value2, true, true);
2024-10-13 11:19:27 -07:00
return Process(value1, value2, now, true);
2024-10-07 21:41:26 -07:00
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected virtual TValue Process(double value, System.DateTime time, bool isNew)
2024-09-22 17:31:24 -07:00
{
2024-10-27 16:11:08 -07:00
if (!IsValidValue(value))
2024-10-07 21:41:26 -07:00
{
2024-10-27 16:11:08 -07:00
return Process(CreateTValue(time, GetLastValid(), isNew, IsHot));
2024-10-07 21:41:26 -07:00
}
2024-10-27 16:11:08 -07:00
Value = Calculation();
return Process(CreateTValue(time, Value, isNew, IsHot));
2024-10-07 21:41:26 -07:00
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected virtual TValue Process(double value1, double value2, System.DateTime time, bool isNew)
2024-10-07 21:41:26 -07:00
{
2024-10-27 16:11:08 -07:00
if (!IsValidValue(value1) || !IsValidValue(value2))
2024-09-22 17:31:24 -07:00
{
2024-10-27 16:11:08 -07:00
return Process(CreateTValue(time, GetLastValid(), isNew, IsHot));
2024-09-22 17:31:24 -07:00
}
2024-10-27 16:11:08 -07:00
Value = Calculation();
return Process(CreateTValue(time, Value, isNew, IsHot));
2024-09-22 17:31:24 -07:00
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-13 11:19:27 -07:00
protected virtual TValue Process(TValue value)
{
2024-10-27 16:11:08 -07:00
Time = value.Time;
Value = value.Value;
IsNew = value.IsNew;
IsHot = value.IsHot;
2024-10-13 11:19:27 -07:00
Pub?.Invoke(this, new ValueEventArgs(value));
return value;
}
2024-10-27 16:11:08 -07:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-09-22 17:31:24 -07:00
protected virtual double GetLastValid()
{
2024-10-27 16:11:08 -07:00
return Value;
2024-09-22 17:31:24 -07:00
}
2024-10-05 15:20:13 -07:00
2024-09-22 17:31:24 -07:00
protected abstract void ManageState(bool isNew);
2024-10-05 15:20:13 -07:00
2024-09-22 17:31:24 -07:00
protected abstract double Calculation();
}