mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-20 11:38:05 +00:00
style: format code with dotnet-format
This commit fixes the style issues introduced in 1e77eb8 according to the output
from dotnet-format.
Details: None
This commit is contained in:
+23
-11
@@ -10,7 +10,8 @@ namespace QuanTAlib;
|
||||
/// efficiently. It also implements a decay mechanism to adjust the minimum value over
|
||||
/// time, allowing for a more responsive indicator in changing market conditions.
|
||||
/// </remarks>
|
||||
public class Min : AbstractBase {
|
||||
public class Min : AbstractBase
|
||||
{
|
||||
private readonly int Period;
|
||||
private readonly CircularBuffer _buffer;
|
||||
private readonly double _halfLife;
|
||||
@@ -25,11 +26,14 @@ public class Min : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 1 or decay is negative.
|
||||
/// </exception>
|
||||
public Min(int period, double decay = 0) : base() {
|
||||
if (period < 1) {
|
||||
public Min(int period, double decay = 0) : base()
|
||||
{
|
||||
if (period < 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1.");
|
||||
}
|
||||
if (decay < 0) {
|
||||
if (decay < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(decay), "Half-life must be non-negative.");
|
||||
}
|
||||
Period = period;
|
||||
@@ -46,7 +50,8 @@ public class Min : AbstractBase {
|
||||
/// <param name="source">The source object to subscribe to for value updates.</param>
|
||||
/// <param name="period">The period over which to calculate the minimum value.</param>
|
||||
/// <param name="decay">The decay factor to apply to older values (default is 0).</param>
|
||||
public Min(object source, int period, double decay = 0) : this(period, decay) {
|
||||
public Min(object source, int period, double decay = 0) : this(period, decay)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -54,7 +59,8 @@ public class Min : AbstractBase {
|
||||
/// <summary>
|
||||
/// Initializes the Min instance by setting initial values.
|
||||
/// </summary>
|
||||
public override void Init() {
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_currentMin = double.MaxValue;
|
||||
_timeSinceNewMin = 0;
|
||||
@@ -64,14 +70,18 @@ public class Min : AbstractBase {
|
||||
/// Manages the state of the Min instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_p_currentMin = _currentMin;
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
_timeSinceNewMin++;
|
||||
_p_timeSinceNewMin = _timeSinceNewMin;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentMin = _p_currentMin;
|
||||
_timeSinceNewMin = _p_timeSinceNewMin;
|
||||
}
|
||||
@@ -87,11 +97,13 @@ public class Min : AbstractBase {
|
||||
/// The decay rate is calculated using an exponential function based on the time since
|
||||
/// the last new minimum and the specified half-life.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
if (Input.Value <= _currentMin) {
|
||||
if (Input.Value <= _currentMin)
|
||||
{
|
||||
_currentMin = Input.Value;
|
||||
_timeSinceNewMin = 0;
|
||||
}
|
||||
|
||||
+19
-9
@@ -9,7 +9,8 @@ namespace QuanTAlib;
|
||||
/// efficiently. Before the specified period is reached, it returns the average of
|
||||
/// the available values as an approximation.
|
||||
/// </remarks>
|
||||
public class Mode : AbstractBase {
|
||||
public class Mode : AbstractBase
|
||||
{
|
||||
private readonly int Period;
|
||||
private readonly CircularBuffer _buffer;
|
||||
|
||||
@@ -20,8 +21,10 @@ public class Mode : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 1.
|
||||
/// </exception>
|
||||
public Mode(int period) : base() {
|
||||
if (period < 1) {
|
||||
public Mode(int period) : base()
|
||||
{
|
||||
if (period < 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 1.");
|
||||
}
|
||||
Period = period;
|
||||
@@ -36,7 +39,8 @@ public class Mode : AbstractBase {
|
||||
/// </summary>
|
||||
/// <param name="source">The source object to subscribe to for value updates.</param>
|
||||
/// <param name="period">The period over which to calculate the mode.</param>
|
||||
public Mode(object source, int period) : this(period) {
|
||||
public Mode(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -45,8 +49,10 @@ public class Mode : AbstractBase {
|
||||
/// Manages the state of the Mode instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
}
|
||||
@@ -64,12 +70,14 @@ public class Mode : AbstractBase {
|
||||
/// the available values as an approximation of the mode. Once the period is
|
||||
/// reached, it calculates the true mode by grouping and counting the values.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
double mode;
|
||||
if (_index >= Period) {
|
||||
if (_index >= Period)
|
||||
{
|
||||
var values = _buffer.GetSpan().ToArray();
|
||||
var groupedValues = values.GroupBy(v => v)
|
||||
.OrderByDescending(g => g.Count())
|
||||
@@ -82,7 +90,9 @@ public class Mode : AbstractBase {
|
||||
.ToList();
|
||||
|
||||
mode = modes.Average(); // If there are multiple modes, we return their average
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = _buffer.Average(); // Use average until we have enough data points
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ namespace QuanTAlib;
|
||||
/// between two data points. Before the specified period is reached, it returns the
|
||||
/// average of the available values as an approximation.
|
||||
/// </remarks>
|
||||
public class Percentile : AbstractBase {
|
||||
public class Percentile : AbstractBase
|
||||
{
|
||||
private readonly int Period;
|
||||
private readonly double Percent;
|
||||
private readonly CircularBuffer _buffer;
|
||||
@@ -23,11 +24,14 @@ public class Percentile : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 2 or percent is not between 0 and 100.
|
||||
/// </exception>
|
||||
public Percentile(int period, double percent) : base() {
|
||||
if (period < 2) {
|
||||
public Percentile(int period, double percent) : base()
|
||||
{
|
||||
if (period < 2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 2 for percentile calculation.");
|
||||
}
|
||||
if (percent < 0 || percent > 100) {
|
||||
if (percent < 0 || percent > 100)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(percent), "Percent must be between 0 and 100.");
|
||||
}
|
||||
Period = period;
|
||||
@@ -44,7 +48,8 @@ public class Percentile : AbstractBase {
|
||||
/// <param name="source">The source object to subscribe to for value updates.</param>
|
||||
/// <param name="period">The period over which to calculate the percentile.</param>
|
||||
/// <param name="percent">The percentile to calculate (between 0 and 100).</param>
|
||||
public Percentile(object source, int period, double percent) : this(period, percent) {
|
||||
public Percentile(object source, int period, double percent) : this(period, percent)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -52,7 +57,8 @@ public class Percentile : AbstractBase {
|
||||
/// <summary>
|
||||
/// Initializes the Percentile instance by clearing the buffer.
|
||||
/// </summary>
|
||||
public override void Init() {
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_buffer.Clear();
|
||||
}
|
||||
@@ -61,8 +67,10 @@ public class Percentile : AbstractBase {
|
||||
/// Manages the state of the Percentile instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
}
|
||||
@@ -80,12 +88,14 @@ public class Percentile : AbstractBase {
|
||||
/// as an approximation. Once the period is reached, it calculates the true percentile by
|
||||
/// sorting the values and interpolating as necessary.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
double result;
|
||||
if (_buffer.Count >= Period) {
|
||||
if (_buffer.Count >= Period)
|
||||
{
|
||||
var values = _buffer.GetSpan().ToArray();
|
||||
Array.Sort(values);
|
||||
|
||||
@@ -93,16 +103,21 @@ public class Percentile : AbstractBase {
|
||||
int lowerIndex = (int)Math.Floor(position);
|
||||
int upperIndex = (int)Math.Ceiling(position);
|
||||
|
||||
if (lowerIndex == upperIndex) {
|
||||
if (lowerIndex == upperIndex)
|
||||
{
|
||||
result = values[lowerIndex];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the two nearest values
|
||||
double lowerValue = values[lowerIndex];
|
||||
double upperValue = values[upperIndex];
|
||||
double fraction = position - lowerIndex;
|
||||
result = lowerValue + (upperValue - lowerValue) * fraction;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use average for insufficient data, like the Median class
|
||||
result = _buffer.Average();
|
||||
}
|
||||
|
||||
+22
-11
@@ -10,7 +10,8 @@ namespace QuanTAlib;
|
||||
/// for sample skewness calculation. A minimum of 3 data points is required for the
|
||||
/// calculation.
|
||||
/// </remarks>
|
||||
public class Skew : AbstractBase {
|
||||
public class Skew : AbstractBase
|
||||
{
|
||||
private readonly int Period;
|
||||
private readonly CircularBuffer _buffer;
|
||||
|
||||
@@ -21,8 +22,10 @@ public class Skew : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 3.
|
||||
/// </exception>
|
||||
public Skew(int period) : base() {
|
||||
if (period < 3) {
|
||||
public Skew(int period) : base()
|
||||
{
|
||||
if (period < 3)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 3 for skewness calculation.");
|
||||
}
|
||||
Period = period;
|
||||
@@ -37,7 +40,8 @@ public class Skew : AbstractBase {
|
||||
/// </summary>
|
||||
/// <param name="source">The source object to subscribe to for value updates.</param>
|
||||
/// <param name="period">The period over which to calculate the skewness.</param>
|
||||
public Skew(object source, int period) : this(period) {
|
||||
public Skew(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -45,7 +49,8 @@ public class Skew : AbstractBase {
|
||||
/// <summary>
|
||||
/// Initializes the Skew instance by clearing the buffer.
|
||||
/// </summary>
|
||||
public override void Init() {
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_buffer.Clear();
|
||||
}
|
||||
@@ -54,8 +59,10 @@ public class Skew : AbstractBase {
|
||||
/// Manages the state of the Skew instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
}
|
||||
@@ -73,13 +80,15 @@ public class Skew : AbstractBase {
|
||||
/// calculation. If there are fewer than 3 data points, or if the standard
|
||||
/// deviation is zero, the method returns 0.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
double skew = 0;
|
||||
if (_buffer.Count >= 3) { // We need at least 3 data points for skewness
|
||||
if (_buffer.Count >= 3)
|
||||
{ // We need at least 3 data points for skewness
|
||||
var values = _buffer.GetSpan().ToArray();
|
||||
double mean = values.Average();
|
||||
double n = values.Length;
|
||||
@@ -87,7 +96,8 @@ public class Skew : AbstractBase {
|
||||
double sumCubedDeviations = 0;
|
||||
double sumSquaredDeviations = 0;
|
||||
|
||||
foreach (var value in values) {
|
||||
foreach (var value in values)
|
||||
{
|
||||
double deviation = value - mean;
|
||||
sumCubedDeviations += Math.Pow(deviation, 3);
|
||||
sumSquaredDeviations += Math.Pow(deviation, 2);
|
||||
@@ -98,7 +108,8 @@ public class Skew : AbstractBase {
|
||||
double m2 = sumSquaredDeviations / n;
|
||||
double s3 = Math.Pow(m2, 1.5);
|
||||
|
||||
if (s3 != 0) { // Avoid division by zero
|
||||
if (s3 != 0)
|
||||
{ // Avoid division by zero
|
||||
skew = (Math.Sqrt(n * (n - 1)) / (n - 2)) * (m3 / s3);
|
||||
}
|
||||
}
|
||||
|
||||
+29
-14
@@ -8,7 +8,8 @@ namespace QuanTAlib;
|
||||
/// statistical measures such as intercept, standard deviation, R-squared, and the last
|
||||
/// point on the regression line. It uses the least squares method for calculation.
|
||||
/// </remarks>
|
||||
public class Slope : AbstractBase {
|
||||
public class Slope : AbstractBase
|
||||
{
|
||||
private readonly int _period;
|
||||
private readonly CircularBuffer _buffer;
|
||||
private readonly CircularBuffer _timeBuffer;
|
||||
@@ -24,8 +25,10 @@ public class Slope : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than or equal to 1.
|
||||
/// </exception>
|
||||
public Slope(int period) {
|
||||
if (period <= 1) {
|
||||
public Slope(int period)
|
||||
{
|
||||
if (period <= 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), period,
|
||||
"Period must be greater than 1 for Slope/Linear Regression.");
|
||||
}
|
||||
@@ -43,7 +46,8 @@ public class Slope : AbstractBase {
|
||||
/// </summary>
|
||||
/// <param name="source">The source object to subscribe to for value updates.</param>
|
||||
/// <param name="period">The period over which to calculate the slope.</param>
|
||||
public Slope(object source, int period) : this(period) {
|
||||
public Slope(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -51,7 +55,8 @@ public class Slope : AbstractBase {
|
||||
/// <summary>
|
||||
/// Initializes the Slope instance by clearing buffers and resetting calculated values.
|
||||
/// </summary>
|
||||
public override void Init() {
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_buffer.Clear();
|
||||
_timeBuffer.Clear();
|
||||
@@ -65,8 +70,10 @@ public class Slope : AbstractBase {
|
||||
/// Manages the state of the Slope instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
}
|
||||
@@ -84,7 +91,8 @@ public class Slope : AbstractBase {
|
||||
/// If there are fewer than 2 data points, or if the sum of squared x deviations is 0,
|
||||
/// the method returns 0 and sets the additional properties to null.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
@@ -92,7 +100,8 @@ public class Slope : AbstractBase {
|
||||
|
||||
double slope = 0;
|
||||
|
||||
if (_buffer.Count < 2) {
|
||||
if (_buffer.Count < 2)
|
||||
{
|
||||
return slope; // Return 0 when there are fewer than 2 points
|
||||
}
|
||||
|
||||
@@ -101,7 +110,8 @@ public class Slope : AbstractBase {
|
||||
|
||||
// Calculate averages
|
||||
double sumX = 0, sumY = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
sumX += i + 1;
|
||||
sumY += values[i];
|
||||
}
|
||||
@@ -110,7 +120,8 @@ public class Slope : AbstractBase {
|
||||
|
||||
// Least squares method
|
||||
double sumSqX = 0, sumSqY = 0, sumSqXY = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
double devX = (i + 1) - avgX;
|
||||
double devY = values[i] - avgY;
|
||||
sumSqX += devX * devX;
|
||||
@@ -118,7 +129,8 @@ public class Slope : AbstractBase {
|
||||
sumSqXY += devX * devY;
|
||||
}
|
||||
|
||||
if (sumSqX > 0) {
|
||||
if (sumSqX > 0)
|
||||
{
|
||||
slope = sumSqXY / sumSqX;
|
||||
Intercept = avgY - (slope * avgX);
|
||||
|
||||
@@ -127,14 +139,17 @@ public class Slope : AbstractBase {
|
||||
double stdDevY = Math.Sqrt(sumSqY / count);
|
||||
StdDev = stdDevY;
|
||||
|
||||
if (stdDevX * stdDevY != 0) {
|
||||
if (stdDevX * stdDevY != 0)
|
||||
{
|
||||
double r = sumSqXY / (stdDevX * stdDevY) / count;
|
||||
RSquared = r * r;
|
||||
}
|
||||
|
||||
// Calculate last Line value (y = mx + b)
|
||||
Line = (slope * count) + Intercept;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Intercept = null;
|
||||
StdDev = null;
|
||||
RSquared = null;
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace QuanTAlib;
|
||||
/// standard deviation based on the isPopulation parameter. It uses a circular buffer
|
||||
/// to efficiently manage the data points within the specified period.
|
||||
/// </remarks>
|
||||
public class Stddev : AbstractBase {
|
||||
public class Stddev : AbstractBase
|
||||
{
|
||||
private readonly int Period;
|
||||
private readonly bool IsPopulation;
|
||||
private readonly CircularBuffer _buffer;
|
||||
@@ -25,8 +26,10 @@ public class Stddev : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 2.
|
||||
/// </exception>
|
||||
public Stddev(int period, bool isPopulation = false) : base() {
|
||||
if (period < 2) {
|
||||
public Stddev(int period, bool isPopulation = false) : base()
|
||||
{
|
||||
if (period < 2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 2.");
|
||||
}
|
||||
Period = period;
|
||||
@@ -46,7 +49,8 @@ public class Stddev : AbstractBase {
|
||||
/// <param name="isPopulation">
|
||||
/// A flag indicating whether to calculate population (true) or sample (false) standard deviation.
|
||||
/// </param>
|
||||
public Stddev(object source, int period, bool isPopulation = false) : this(period, isPopulation) {
|
||||
public Stddev(object source, int period, bool isPopulation = false) : this(period, isPopulation)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -54,7 +58,8 @@ public class Stddev : AbstractBase {
|
||||
/// <summary>
|
||||
/// Initializes the Stddev instance by clearing the buffer.
|
||||
/// </summary>
|
||||
public override void Init() {
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_buffer.Clear();
|
||||
}
|
||||
@@ -63,8 +68,10 @@ public class Stddev : AbstractBase {
|
||||
/// Manages the state of the Stddev instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
}
|
||||
@@ -83,13 +90,15 @@ public class Stddev : AbstractBase {
|
||||
/// where x is each value, mean is the average of all values, and n is the number of values.
|
||||
/// If there's only one value in the buffer, the method returns 0.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
double stddev = 0;
|
||||
if (_buffer.Count > 1) {
|
||||
if (_buffer.Count > 1)
|
||||
{
|
||||
var values = _buffer.GetSpan().ToArray();
|
||||
double mean = values.Average();
|
||||
double sumOfSquaredDifferences = values.Sum(x => Math.Pow(x - mean, 2));
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace QuanTAlib;
|
||||
/// variance based on the isPopulation parameter. It uses a circular buffer
|
||||
/// to efficiently manage the data points within the specified period.
|
||||
/// </remarks>
|
||||
public class Variance : AbstractBase {
|
||||
public class Variance : AbstractBase
|
||||
{
|
||||
private readonly int Period;
|
||||
private readonly bool IsPopulation;
|
||||
private readonly CircularBuffer _buffer;
|
||||
@@ -25,8 +26,10 @@ public class Variance : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 2.
|
||||
/// </exception>
|
||||
public Variance(int period, bool isPopulation = false) : base() {
|
||||
if (period < 2) {
|
||||
public Variance(int period, bool isPopulation = false) : base()
|
||||
{
|
||||
if (period < 2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 2.");
|
||||
}
|
||||
Period = period;
|
||||
@@ -46,7 +49,8 @@ public class Variance : AbstractBase {
|
||||
/// <param name="isPopulation">
|
||||
/// A flag indicating whether to calculate population (true) or sample (false) variance.
|
||||
/// </param>
|
||||
public Variance(object source, int period, bool isPopulation = false) : this(period, isPopulation) {
|
||||
public Variance(object source, int period, bool isPopulation = false) : this(period, isPopulation)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -54,7 +58,8 @@ public class Variance : AbstractBase {
|
||||
/// <summary>
|
||||
/// Initializes the Variance instance by clearing the buffer.
|
||||
/// </summary>
|
||||
public override void Init() {
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_buffer.Clear();
|
||||
}
|
||||
@@ -63,8 +68,10 @@ public class Variance : AbstractBase {
|
||||
/// Manages the state of the Variance instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
}
|
||||
@@ -83,13 +90,15 @@ public class Variance : AbstractBase {
|
||||
/// where x is each value, mean is the average of all values, and n is the number of values.
|
||||
/// If there's only one value in the buffer, the method returns 0.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
double variance = 0;
|
||||
if (_buffer.Count > 1) {
|
||||
if (_buffer.Count > 1)
|
||||
{
|
||||
var values = _buffer.GetSpan().ToArray();
|
||||
double mean = values.Average();
|
||||
double sumOfSquaredDifferences = values.Sum(x => Math.Pow(x - mean, 2));
|
||||
|
||||
+20
-10
@@ -9,7 +9,8 @@ namespace QuanTAlib;
|
||||
/// the most recent value in a given period. It uses a circular buffer to
|
||||
/// efficiently manage the data points within the specified period.
|
||||
/// </remarks>
|
||||
public class Zscore : AbstractBase {
|
||||
public class Zscore : AbstractBase
|
||||
{
|
||||
private readonly int Period;
|
||||
private readonly CircularBuffer _buffer;
|
||||
|
||||
@@ -20,8 +21,10 @@ public class Zscore : AbstractBase {
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 2.
|
||||
/// </exception>
|
||||
public Zscore(int period) : base() {
|
||||
if (period < 2) {
|
||||
public Zscore(int period) : base()
|
||||
{
|
||||
if (period < 2)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(period), "Period must be greater than or equal to 2 for Z-score calculation.");
|
||||
}
|
||||
Period = period;
|
||||
@@ -36,7 +39,8 @@ public class Zscore : AbstractBase {
|
||||
/// </summary>
|
||||
/// <param name="source">The source object to subscribe to for value updates.</param>
|
||||
/// <param name="period">The period over which to calculate the Z-score.</param>
|
||||
public Zscore(object source, int period) : this(period) {
|
||||
public Zscore(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
@@ -44,7 +48,8 @@ public class Zscore : AbstractBase {
|
||||
/// <summary>
|
||||
/// Initializes the Zscore instance by clearing the buffer.
|
||||
/// </summary>
|
||||
public override void Init() {
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_buffer.Clear();
|
||||
}
|
||||
@@ -53,8 +58,10 @@ public class Zscore : AbstractBase {
|
||||
/// Manages the state of the Zscore instance based on whether a new value is being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current input is a new value.</param>
|
||||
protected override void ManageState(bool isNew) {
|
||||
if (isNew) {
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
{
|
||||
_lastValidValue = Input.Value;
|
||||
_index++;
|
||||
}
|
||||
@@ -72,13 +79,15 @@ public class Zscore : AbstractBase {
|
||||
/// where x is the input value, μ is the mean of the period, and σ is the sample standard deviation.
|
||||
/// If there are fewer than 2 data points or if the standard deviation is 0, the method returns 0.
|
||||
/// </remarks>
|
||||
protected override double Calculation() {
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
|
||||
_buffer.Add(Input.Value, Input.IsNew);
|
||||
|
||||
double zScore = 0;
|
||||
if (_buffer.Count >= 2) { // We need at least 2 data points for Z-score
|
||||
if (_buffer.Count >= 2)
|
||||
{ // We need at least 2 data points for Z-score
|
||||
var values = _buffer.GetSpan().ToArray();
|
||||
double mean = values.Average();
|
||||
double n = values.Length;
|
||||
@@ -86,7 +95,8 @@ public class Zscore : AbstractBase {
|
||||
double sumSquaredDeviations = values.Sum(x => Math.Pow(x - mean, 2));
|
||||
double standardDeviation = Math.Sqrt(sumSquaredDeviations / (n - 1)); // Sample standard deviation
|
||||
|
||||
if (standardDeviation != 0) { // Avoid division by zero
|
||||
if (standardDeviation != 0)
|
||||
{ // Avoid division by zero
|
||||
zScore = (Input.Value - mean) / standardDeviation;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user