namespace QuanTAlib; /// /// Provides a base implementation for financial indicators that work with bar data in the QuanTAlib library. /// /// /// 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 bar data, performing calculations, and publishing results. /// public abstract class AbstractBarBase : iTValue { public DateTime Time { get; set; } public double Value { get; set; } public bool IsNew { get; set; } public bool IsHot { get; set; } public TBar Input { get; set; } public String Name { get; set; } = ""; public int WarmupPeriod { get; set; } public TValue Tick => new(Time, Value, IsNew, IsHot); public event ValueSignal Pub = delegate { }; protected int _index; protected double _lastValidValue; protected AbstractBarBase() { // Add parameters into constructor if needed } /// /// Subscribes to bar data updates. /// /// The source of the bar data. /// The event arguments containing the bar data. public void Sub(object source, in TBarEventArgs args) => Calc(args.Bar); /// /// Initializes the indicator's state. /// public virtual void Init() { _index = 0; _lastValidValue = 0; } /// /// Calculates the indicator value based on the input bar. /// /// The input bar data. /// A TValue containing the calculated result. public virtual TValue Calc(TBar input) { Input = input; if (double.IsNaN(input.Close) || double.IsInfinity(input.Close)) { return Process(new TValue(Time: input.Time, Value: GetLastValid(), IsNew: input.IsNew, IsHot: true)); } this.Value = Calculation(); return Process(new TValue(Time: Input.Time, Value: this.Value, IsNew: Input.IsNew, IsHot: this.IsHot)); } /// /// Retrieves the last valid calculated value. /// /// The last valid value of the indicator. protected virtual double GetLastValid() { return this.Value; } /// /// Manages the state of the indicator based on whether a new bar is being processed. /// /// Indicates whether the current input is a new bar. protected abstract void ManageState(bool isNew); /// /// Performs the actual calculation of the indicator value. /// /// The calculated indicator value. protected abstract double Calculation(); /// /// Processes the calculated value, updates the indicator's own state, /// and publishes the result through an event. /// /// The calculated TValue to process. /// The processed TValue. protected virtual TValue Process(TValue value) { this.Time = value.Time; this.Value = value.Value; this.IsNew = value.IsNew; this.IsHot = value.IsHot; Pub?.Invoke(this, new ValueEventArgs(value)); return value; } }