mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-06 04:57:44 +00:00
xml doc rewrite
This commit is contained in:
+39
-1
@@ -1,11 +1,44 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// Huber Loss: A robust error metric that combines squared error for small deviations
|
||||
/// and absolute error for large deviations. This provides a balance between the high
|
||||
/// sensitivity of MSE to outliers and the constant gradient of MAE.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Huber Loss calculation process:
|
||||
/// 1. For each point, calculates error between actual and predicted values
|
||||
/// 2. If absolute error ≤ delta: uses squared error (like MSE)
|
||||
/// 3. If absolute error > delta: uses linear error (like MAE)
|
||||
/// 4. Averages the losses over the period
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Combines benefits of MSE and MAE
|
||||
/// - Less sensitive to outliers than MSE
|
||||
/// - More sensitive to small errors than MAE
|
||||
/// - Differentiable at all points
|
||||
/// - Adjustable via delta parameter
|
||||
///
|
||||
/// Formula:
|
||||
/// For error e = actual - predicted:
|
||||
/// L(e) = 0.5 * e² if |e| ≤ δ
|
||||
/// L(e) = δ * (|e| - 0.5δ) if |e| > δ
|
||||
///
|
||||
/// Sources:
|
||||
/// Peter J. Huber - "Robust Estimation of a Location Parameter"
|
||||
/// https://projecteuclid.org/euclid.aoms/1177703732
|
||||
/// </remarks>
|
||||
|
||||
public class Huber : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
private readonly double _delta;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the loss.</param>
|
||||
/// <param name="delta">The threshold between squared and linear loss (default 1.0).</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1 or delta is not positive.</exception>
|
||||
public Huber(int period, double delta = 1.0)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -24,6 +57,9 @@ public class Huber : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the loss.</param>
|
||||
/// <param name="delta">The threshold between squared and linear loss (default 1.0).</param>
|
||||
public Huber(object source, int period, double delta = 1.0) : this(period, delta)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -53,6 +89,7 @@ public class Huber : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
@@ -70,10 +107,12 @@ public class Huber : AbstractBase
|
||||
|
||||
if (absError <= _delta)
|
||||
{
|
||||
// Squared error for small deviations
|
||||
sumLoss += 0.5 * error * error;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Linear error for large deviations
|
||||
sumLoss += _delta * (absError - 0.5 * _delta);
|
||||
}
|
||||
}
|
||||
@@ -84,5 +123,4 @@ public class Huber : AbstractBase
|
||||
IsHot = _index >= WarmupPeriod;
|
||||
return huberloss;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+33
-1
@@ -1,10 +1,40 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// MAE: Mean Absolute Error
|
||||
/// A straightforward error metric that measures the average magnitude of errors
|
||||
/// between predicted and actual values, without considering their direction.
|
||||
/// MAE treats all individual differences equally in the average.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MAE calculation process:
|
||||
/// 1. Calculates absolute difference between each actual and predicted value
|
||||
/// 2. Sums all absolute differences
|
||||
/// 3. Divides by the number of observations
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Linear scale (all differences weighted equally)
|
||||
/// - Robust to outliers compared to MSE
|
||||
/// - Easy to interpret (same units as data)
|
||||
/// - Constant gradient for optimization
|
||||
/// - Less sensitive to large errors than MSE
|
||||
///
|
||||
/// Formula:
|
||||
/// MAE = (1/n) * Σ|actual - predicted|
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Mean_absolute_error
|
||||
/// https://www.statisticshowto.com/absolute-error/
|
||||
/// </remarks>
|
||||
|
||||
public class Mae : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the MAE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Mae(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +48,8 @@ public class Mae : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MAE.</param>
|
||||
public Mae(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +79,7 @@ public class Mae : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
@@ -68,5 +101,4 @@ public class Mae : AbstractBase
|
||||
IsHot = _index >= WarmupPeriod;
|
||||
return mae;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+35
-1
@@ -1,10 +1,42 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// MAPD: Mean Absolute Percentage Deviation
|
||||
/// A percentage-based error metric that measures the average absolute percentage
|
||||
/// difference between predicted and actual values. MAPD expresses accuracy as a
|
||||
/// percentage, making it scale-independent and easy to interpret.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MAPD calculation process:
|
||||
/// 1. Calculates absolute percentage difference for each point
|
||||
/// 2. Sums all absolute percentage differences
|
||||
/// 3. Divides by the number of observations
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent (percentage-based)
|
||||
/// - Easy to interpret (0-100% range)
|
||||
/// - Useful for comparing different scales
|
||||
/// - Cannot handle zero actual values
|
||||
/// - Asymmetric (treats over/under predictions differently)
|
||||
///
|
||||
/// Formula:
|
||||
/// MAPD = (1/n) * Σ|((actual - predicted) / actual)|
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
|
||||
/// https://www.statisticshowto.com/mean-absolute-percentage-error-mape/
|
||||
///
|
||||
/// Note: Also known as MAPE (Mean Absolute Percentage Error) in some contexts
|
||||
/// </remarks>
|
||||
|
||||
public class Mapd : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the MAPD.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Mapd(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +50,8 @@ public class Mapd : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MAPD.</param>
|
||||
public Mapd(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +81,7 @@ public class Mapd : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
@@ -71,5 +106,4 @@ public class Mapd : AbstractBase
|
||||
IsHot = _index >= WarmupPeriod;
|
||||
return mapd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,42 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// MAPE: Mean Absolute Percentage Error
|
||||
/// A percentage-based error metric that measures the average absolute percentage
|
||||
/// difference between predicted and actual values. MAPE expresses accuracy as a
|
||||
/// percentage, making it scale-independent and easy to interpret.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MAPE calculation process:
|
||||
/// 1. Calculates absolute percentage error for each point
|
||||
/// 2. Sums all absolute percentage errors
|
||||
/// 3. Divides by the number of observations
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent (percentage-based)
|
||||
/// - Easy to interpret (0-100% range)
|
||||
/// - Useful for comparing different scales
|
||||
/// - Cannot handle zero actual values
|
||||
/// - Asymmetric (treats over/under predictions differently)
|
||||
///
|
||||
/// Formula:
|
||||
/// MAPE = (1/n) * Σ|((actual - predicted) / actual)| * 100%
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
|
||||
/// https://www.statisticshowto.com/mean-absolute-percentage-error-mape/
|
||||
///
|
||||
/// Note: Also known as MAPD (Mean Absolute Percentage Deviation) in some contexts
|
||||
/// </remarks>
|
||||
|
||||
public class Mape : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the MAPE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Mape(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +50,8 @@ public class Mape : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MAPE.</param>
|
||||
public Mape(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +81,7 @@ public class Mape : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
+41
-22
@@ -1,20 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the Mean Absolute Scaled Error (MASE) calculation.
|
||||
/// MASE: Mean Absolute Scaled Error
|
||||
/// A scale-free error metric that compares the mean absolute error of the forecast
|
||||
/// with the mean absolute error of the naive forecast. MASE is particularly useful
|
||||
/// for comparing forecast accuracy across different datasets.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MASE calculation process:
|
||||
/// 1. Calculates mean absolute error of the forecast
|
||||
/// 2. Calculates mean absolute error of naive forecast (using previous value)
|
||||
/// 3. Divides forecast error by naive forecast error
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-free (independent of data scale)
|
||||
/// - Handles zero values unlike percentage errors
|
||||
/// - Symmetric (treats over/under predictions equally)
|
||||
/// - Easy interpretation (MASE < 1 means better than naive forecast)
|
||||
/// - Robust to outliers
|
||||
///
|
||||
/// Formula:
|
||||
/// MASE = MAE(forecast) / MAE(naive_forecast)
|
||||
/// where naive_forecast[t] = actual[t-1]
|
||||
///
|
||||
/// Sources:
|
||||
/// Rob J. Hyndman - "Another Look at Forecast-Accuracy Metrics for Intermittent Demand"
|
||||
/// https://robjhyndman.com/papers/another-look-at-measures-of-forecast-accuracy/
|
||||
/// </remarks>
|
||||
|
||||
public class Mase : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
private readonly CircularBuffer _naiveBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Mase class.
|
||||
/// </summary>
|
||||
/// <param name="period">The period for MASE calculation.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MASE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Mase(int period)
|
||||
{
|
||||
@@ -30,20 +51,14 @@ public class Mase : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Mase class with a source object.
|
||||
/// </summary>
|
||||
/// <param name="source">The source object for event subscription.</param>
|
||||
/// <param name="period">The period for MASE calculation.</param>
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MASE.</param>
|
||||
public Mase(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Mase instance.
|
||||
/// </summary>
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
@@ -52,10 +67,6 @@ public class Mase : AbstractBase
|
||||
_naiveBuffer.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages the state of the Mase instance.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates if the input is new.</param>
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
@@ -65,10 +76,6 @@ public class Mase : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the MASE calculation.
|
||||
/// </summary>
|
||||
/// <returns>The calculated MASE value.</returns>
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
@@ -76,9 +83,11 @@ public class Mase : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
// Naive forecast uses previous actual value
|
||||
if (_actualBuffer.Count > 1)
|
||||
{
|
||||
_naiveBuffer.Add(_actualBuffer.GetSpan()[^2], Input.IsNew);
|
||||
@@ -90,6 +99,10 @@ public class Mase : AbstractBase
|
||||
return mase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the MASE value by comparing forecast error to naive forecast error.
|
||||
/// </summary>
|
||||
/// <returns>The calculated MASE value, or positive infinity if naive error is zero.</returns>
|
||||
private double CalculateMase()
|
||||
{
|
||||
if (_actualBuffer.Count <= 1) return 0;
|
||||
@@ -104,6 +117,9 @@ public class Mase : AbstractBase
|
||||
return _naiveForecastError != 0 ? (sumAbsoluteError / _actualBuffer.Count) / _naiveForecastError : double.PositiveInfinity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the sum of absolute errors between actual and predicted values.
|
||||
/// </summary>
|
||||
private static double CalculateSumAbsoluteError(ReadOnlySpan<double> actualValues, ReadOnlySpan<double> predictedValues)
|
||||
{
|
||||
double sum = 0;
|
||||
@@ -114,6 +130,9 @@ public class Mase : AbstractBase
|
||||
return sum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the naive forecast error using the previous value as prediction.
|
||||
/// </summary>
|
||||
private static double CalculateNaiveForecastError(ReadOnlySpan<double> actualValues, ReadOnlySpan<double> naiveValues)
|
||||
{
|
||||
double sum = 0;
|
||||
|
||||
@@ -1,10 +1,42 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// MDA: Mean Directional Accuracy
|
||||
/// A metric that measures how well a forecast predicts the direction of change
|
||||
/// rather than the magnitude. MDA focuses on whether the predicted movement
|
||||
/// (up or down) matches the actual movement.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MDA calculation process:
|
||||
/// 1. For each consecutive pair of points:
|
||||
/// - Calculate direction of actual change
|
||||
/// - Calculate direction of predicted change
|
||||
/// - Compare directions (match = 1, mismatch = 0)
|
||||
/// 2. Average the directional matches
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent (only considers direction)
|
||||
/// - Range is 0 to 1 (easy interpretation)
|
||||
/// - Useful for trend prediction evaluation
|
||||
/// - Ignores magnitude of changes
|
||||
/// - Equal weight to all directional changes
|
||||
///
|
||||
/// Formula:
|
||||
/// MDA = (1/(n-1)) * Σ(sign(actual[t] - actual[t-1]) == sign(pred[t] - pred[t-1]))
|
||||
///
|
||||
/// Sources:
|
||||
/// https://www.sciencedirect.com/science/article/abs/pii/S0169207016000121
|
||||
/// "Evaluating Forecasting Performance" - International Journal of Forecasting
|
||||
/// </remarks>
|
||||
|
||||
public class Mda : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the MDA.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Mda(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +50,8 @@ public class Mda : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MDA.</param>
|
||||
public Mda(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +81,7 @@ public class Mda : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,42 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// ME: Mean Error
|
||||
/// A basic error metric that measures the average difference between actual and
|
||||
/// predicted values. Unlike MAE, it allows positive and negative errors to cancel
|
||||
/// out, making it useful for detecting systematic bias in predictions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The ME calculation process:
|
||||
/// 1. Calculates error (actual - predicted) for each point
|
||||
/// 2. Sums all errors (allowing cancellation)
|
||||
/// 3. Divides by the number of observations
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Same units as input data
|
||||
/// - Can detect systematic bias
|
||||
/// - Positive ME indicates underprediction
|
||||
/// - Negative ME indicates overprediction
|
||||
/// - Errors can cancel out
|
||||
///
|
||||
/// Formula:
|
||||
/// ME = (1/n) * Σ(actual - predicted)
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Mean_signed_difference
|
||||
/// https://www.statisticshowto.com/mean-error/
|
||||
///
|
||||
/// Note: Also known as Mean Bias Error (MBE) or Mean Signed Difference (MSD)
|
||||
/// </remarks>
|
||||
|
||||
public class Me : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the ME.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Me(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +50,8 @@ public class Me : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the ME.</param>
|
||||
public Me(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +81,7 @@ public class Me : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,43 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// MPE: Mean Percentage Error
|
||||
/// A percentage-based error metric that measures the average percentage difference
|
||||
/// between actual and predicted values. Like ME, it allows positive and negative
|
||||
/// errors to cancel out, but expresses the bias in percentage terms.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MPE calculation process:
|
||||
/// 1. Calculates percentage error for each point
|
||||
/// 2. Sums all percentage errors (allowing cancellation)
|
||||
/// 3. Divides by the number of observations
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent (percentage-based)
|
||||
/// - Can detect systematic bias
|
||||
/// - Positive MPE indicates underprediction
|
||||
/// - Negative MPE indicates overprediction
|
||||
/// - Cannot handle zero actual values
|
||||
/// - Errors can cancel out
|
||||
///
|
||||
/// Formula:
|
||||
/// MPE = (1/n) * Σ((actual - predicted) / actual) * 100%
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Mean_percentage_error
|
||||
/// https://www.statisticshowto.com/mean-percentage-error/
|
||||
///
|
||||
/// Note: Similar to MAPE but allows error cancellation
|
||||
/// </remarks>
|
||||
|
||||
public class Mpe : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the MPE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Mpe(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +51,8 @@ public class Mpe : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MPE.</param>
|
||||
public Mpe(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +82,7 @@ public class Mpe : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
+31
-34
@@ -1,25 +1,42 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Mean Squared Error calculator that measures the average of the squares
|
||||
/// of the differences between actual values and predicted values.
|
||||
/// MSE: Mean Squared Error
|
||||
/// A fundamental error metric that measures the average of squared differences
|
||||
/// between predicted and actual values. MSE heavily penalizes large errors due
|
||||
/// to the squaring operation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Mse class calculates the Mean Squared Error using a circular buffer
|
||||
/// to efficiently manage the data points within the specified period.
|
||||
/// The MSE calculation process:
|
||||
/// 1. Calculates error (actual - predicted) for each point
|
||||
/// 2. Squares each error value
|
||||
/// 3. Averages the squared errors
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Heavily penalizes large errors
|
||||
/// - Always non-negative
|
||||
/// - Units are squared (harder to interpret)
|
||||
/// - More sensitive to outliers than MAE
|
||||
/// - Differentiable (useful for optimization)
|
||||
///
|
||||
/// Formula:
|
||||
/// MSE = (1/n) * Σ(actual - predicted)²
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Mean_squared_error
|
||||
/// https://www.statisticshowto.com/probability-and-statistics/statistics-definitions/mean-squared-error/
|
||||
///
|
||||
/// Note: Often used in optimization due to its mathematical properties
|
||||
/// </remarks>
|
||||
|
||||
public class Mse : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Mse class with the specified period.
|
||||
/// </summary>
|
||||
/// <param name="period">The period over which to calculate the Mean Squared Error.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// Thrown when period is less than 1.
|
||||
/// </exception>
|
||||
/// <param name="period">The number of points over which to calculate the MSE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Mse(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -33,20 +50,14 @@ public class Mse : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Mse class with the specified source and period.
|
||||
/// </summary>
|
||||
/// <param name="source">The source object to subscribe to for value updates.</param>
|
||||
/// <param name="period">The period over which to calculate the Mean Squared Error.</param>
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MSE.</param>
|
||||
public Mse(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Mse instance by clearing the buffers.
|
||||
/// </summary>
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
@@ -54,10 +65,6 @@ public class Mse : AbstractBase
|
||||
_predictedBuffer.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages the state of the Mse instance based on whether new values are being processed.
|
||||
/// </summary>
|
||||
/// <param name="isNew">Indicates whether the current inputs are new values.</param>
|
||||
protected override void ManageState(bool isNew)
|
||||
{
|
||||
if (isNew)
|
||||
@@ -67,17 +74,6 @@ public class Mse : AbstractBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the Mean Squared Error calculation for the current period.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The calculated Mean Squared Error value for the current period.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// This method calculates the Mean Squared Error using the formula:
|
||||
/// MSE = sum((actual - predicted)^2) / n
|
||||
/// where actual is each actual value, predicted is each predicted value, and n is the number of values.
|
||||
/// </remarks>
|
||||
protected override double Calculation()
|
||||
{
|
||||
ManageState(Input.IsNew);
|
||||
@@ -85,6 +81,7 @@ public class Mse : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,43 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// MSLE: Mean Squared Logarithmic Error
|
||||
/// A variation of MSE that operates on log-transformed values. MSLE is particularly
|
||||
/// useful for data with exponential growth or when errors in larger values should
|
||||
/// not be penalized more heavily than errors in smaller values.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The MSLE calculation process:
|
||||
/// 1. Adds 1 to both actual and predicted values (to handle zeros)
|
||||
/// 2. Takes natural log of both values
|
||||
/// 3. Calculates squared difference of logs
|
||||
/// 4. Averages the squared differences
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent due to log transformation
|
||||
/// - Penalizes underestimates more than overestimates
|
||||
/// - Handles exponential trends well
|
||||
/// - More sensitive to relative differences
|
||||
/// - Can handle zero values (adds 1 before log)
|
||||
///
|
||||
/// Formula:
|
||||
/// MSLE = (1/n) * Σ(log(actual + 1) - log(predicted + 1))²
|
||||
///
|
||||
/// Sources:
|
||||
/// https://scikit-learn.org/stable/modules/model_evaluation.html#mean-squared-logarithmic-error
|
||||
/// https://medium.com/analytics-vidhya/root-mean-square-log-error-rmse-vs-rmlse-935c6cc1802a
|
||||
///
|
||||
/// Note: Often used in cases where target values follow exponential growth
|
||||
/// </remarks>
|
||||
|
||||
public class Msle : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the MSLE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Msle(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +51,8 @@ public class Msle : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the MSLE.</param>
|
||||
public Msle(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +82,7 @@ public class Msle : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,42 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// RAE: Relative Absolute Error
|
||||
/// A normalized error metric that compares the total absolute error to the total
|
||||
/// magnitude of actual values. RAE provides a scale-independent measure of error
|
||||
/// that is robust to the overall magnitude of the data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The RAE calculation process:
|
||||
/// 1. Calculates sum of absolute errors
|
||||
/// 2. Calculates sum of absolute actual values
|
||||
/// 3. Divides total error by total actual magnitude
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent (normalized by actual values)
|
||||
/// - Range typically between 0 and 1
|
||||
/// - Easy to interpret (0 is perfect, 1 means error equals data magnitude)
|
||||
/// - Robust to data scale changes
|
||||
/// - Less sensitive to outliers than squared errors
|
||||
///
|
||||
/// Formula:
|
||||
/// RAE = Σ|actual - predicted| / Σ|actual|
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Relative_absolute_error
|
||||
/// https://www.sciencedirect.com/topics/engineering/relative-absolute-error
|
||||
///
|
||||
/// Note: Values greater than 1 indicate predictions worse than using zero
|
||||
/// </remarks>
|
||||
|
||||
public class Rae : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the RAE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Rae(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +50,8 @@ public class Rae : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the RAE.</param>
|
||||
public Rae(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +81,7 @@ public class Rae : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,43 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// RMSE: Root Mean Square Error
|
||||
/// A widely used error metric that measures the square root of the average squared
|
||||
/// differences between predicted and actual values. RMSE provides error measurements
|
||||
/// in the same units as the original data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The RMSE calculation process:
|
||||
/// 1. Calculates error (actual - predicted) for each point
|
||||
/// 2. Squares each error value
|
||||
/// 3. Averages the squared errors
|
||||
/// 4. Takes the square root of the average
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Same units as input data (unlike MSE)
|
||||
/// - Penalizes large errors more than small ones
|
||||
/// - Always non-negative
|
||||
/// - More interpretable than MSE
|
||||
/// - Commonly used in regression problems
|
||||
///
|
||||
/// Formula:
|
||||
/// RMSE = √((1/n) * Σ(actual - predicted)²)
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Root-mean-square_deviation
|
||||
/// https://www.statisticshowto.com/probability-and-statistics/regression-analysis/rmse-root-mean-square-error/
|
||||
///
|
||||
/// Note: Square root of MSE, making it more interpretable in original units
|
||||
/// </remarks>
|
||||
|
||||
public class Rmse : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the RMSE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Rmse(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +51,8 @@ public class Rmse : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the RMSE.</param>
|
||||
public Rmse(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +82,7 @@ public class Rmse : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,44 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// RMSLE: Root Mean Square Logarithmic Error
|
||||
/// A variation of RMSE that operates on log-transformed values. RMSLE is particularly
|
||||
/// useful for data with exponential growth or when relative errors in larger values
|
||||
/// should be treated similarly to relative errors in smaller values.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The RMSLE calculation process:
|
||||
/// 1. Adds 1 to both actual and predicted values (to handle zeros)
|
||||
/// 2. Takes natural log of both values
|
||||
/// 3. Calculates squared difference of logs
|
||||
/// 4. Averages the squared differences
|
||||
/// 5. Takes the square root
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent due to log transformation
|
||||
/// - Penalizes underestimates more than overestimates
|
||||
/// - Handles exponential trends well
|
||||
/// - More sensitive to relative differences
|
||||
/// - Can handle zero values (adds 1 before log)
|
||||
///
|
||||
/// Formula:
|
||||
/// RMSLE = √((1/n) * Σ(log(actual + 1) - log(predicted + 1))²)
|
||||
///
|
||||
/// Sources:
|
||||
/// https://www.kaggle.com/wiki/RootMeanSquaredLogarithmicError
|
||||
/// https://medium.com/analytics-vidhya/root-mean-square-log-error-rmse-vs-rmlse-935c6cc1802a
|
||||
///
|
||||
/// Note: Square root of MSLE, useful for data with exponential growth
|
||||
/// </remarks>
|
||||
|
||||
public class Rmsle : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the RMSLE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Rmsle(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +52,8 @@ public class Rmsle : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the RMSLE.</param>
|
||||
public Rmsle(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +83,7 @@ public class Rmsle : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,43 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// RSE: Relative Squared Error
|
||||
/// A normalized error metric that compares the squared error of predictions to
|
||||
/// the variance of actual values. RSE provides a scale-independent measure of
|
||||
/// prediction accuracy relative to the inherent variability in the data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The RSE calculation process:
|
||||
/// 1. Calculates sum of squared prediction errors
|
||||
/// 2. Calculates sum of squared deviations from mean (variance)
|
||||
/// 3. Divides squared error by variance and takes square root
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Scale-independent (normalized by data variance)
|
||||
/// - Range typically between 0 and 1
|
||||
/// - Easy interpretation relative to data variance
|
||||
/// - Penalizes large errors more than small ones
|
||||
/// - Accounts for data variability
|
||||
///
|
||||
/// Formula:
|
||||
/// RSE = √(Σ(actual - predicted)² / Σ(actual - mean(actual))²)
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Relative_squared_error
|
||||
/// https://www.sciencedirect.com/topics/engineering/relative-squared-error
|
||||
///
|
||||
/// Note: Values less than 1 indicate predictions better than using mean
|
||||
/// </remarks>
|
||||
|
||||
public class Rse : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the RSE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Rse(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +51,8 @@ public class Rse : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the RSE.</param>
|
||||
public Rse(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +82,7 @@ public class Rse : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,43 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// R-squared: Coefficient of Determination
|
||||
/// A statistical measure that represents the proportion of variance in the dependent
|
||||
/// variable that is predictable from the independent variable. R-squared provides
|
||||
/// a measure of how well the predictions approximate the actual data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The R-squared calculation process:
|
||||
/// 1. Calculates total sum of squares (variance from mean)
|
||||
/// 2. Calculates residual sum of squares (prediction errors)
|
||||
/// 3. Computes 1 - (residual SS / total SS)
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Range is typically 0 to 1
|
||||
/// - 1 indicates perfect prediction
|
||||
/// - 0 indicates prediction no better than mean
|
||||
/// - Scale-independent
|
||||
/// - Widely used in regression analysis
|
||||
///
|
||||
/// Formula:
|
||||
/// R² = 1 - (Σ(actual - predicted)² / Σ(actual - mean(actual))²)
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Coefficient_of_determination
|
||||
/// https://www.statisticshowto.com/probability-and-statistics/coefficient-of-determination-r-squared/
|
||||
///
|
||||
/// Note: Can be negative if predictions are worse than using the mean
|
||||
/// </remarks>
|
||||
|
||||
public class Rsquared : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the R-squared value.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Rsquared(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +51,8 @@ public class Rsquared : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the R-squared value.</param>
|
||||
public Rsquared(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +82,7 @@ public class Rsquared : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
@@ -1,10 +1,42 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
/// <summary>
|
||||
/// SMAPE: Symmetric Mean Absolute Percentage Error
|
||||
/// A variation of MAPE that treats positive and negative errors symmetrically.
|
||||
/// SMAPE uses the average of actual and predicted values in the denominator,
|
||||
/// making it more robust than MAPE for values close to zero.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The SMAPE calculation process:
|
||||
/// 1. Calculates absolute difference between actual and predicted
|
||||
/// 2. Divides by sum of absolute actual and predicted values
|
||||
/// 3. Averages these ratios and multiplies by 200%
|
||||
///
|
||||
/// Key characteristics:
|
||||
/// - Symmetric treatment of errors
|
||||
/// - Range is 0% to 200%
|
||||
/// - More robust than MAPE near zero
|
||||
/// - Scale-independent
|
||||
/// - Handles both positive and negative values
|
||||
///
|
||||
/// Formula:
|
||||
/// SMAPE = (200/n) * Σ|actual - predicted| / (|actual| + |predicted|)
|
||||
///
|
||||
/// Sources:
|
||||
/// https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error
|
||||
/// https://www.sciencedirect.com/science/article/abs/pii/0169207085900059
|
||||
///
|
||||
/// Note: More stable than MAPE when actual values are close to zero
|
||||
/// </remarks>
|
||||
|
||||
public class Smape : AbstractBase
|
||||
{
|
||||
private readonly CircularBuffer _actualBuffer;
|
||||
private readonly CircularBuffer _predictedBuffer;
|
||||
|
||||
/// <param name="period">The number of points over which to calculate the SMAPE.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||
public Smape(int period)
|
||||
{
|
||||
if (period < 1)
|
||||
@@ -18,6 +50,8 @@ public class Smape : AbstractBase
|
||||
Init();
|
||||
}
|
||||
|
||||
/// <param name="source">The data source object that publishes updates.</param>
|
||||
/// <param name="period">The number of points over which to calculate the SMAPE.</param>
|
||||
public Smape(object source, int period) : this(period)
|
||||
{
|
||||
var pubEvent = source.GetType().GetEvent("Pub");
|
||||
@@ -47,6 +81,7 @@ public class Smape : AbstractBase
|
||||
double actual = Input.Value;
|
||||
_actualBuffer.Add(actual, Input.IsNew);
|
||||
|
||||
// If no predicted value provided, use mean of actual values
|
||||
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
|
||||
_predictedBuffer.Add(predicted, Input.IsNew);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user