xml doc rewrite

This commit is contained in:
Miha
2024-10-27 09:38:53 -07:00
parent c21b96152c
commit b2fcdda785
71 changed files with 2607 additions and 1102 deletions
+50 -50
View File
@@ -1,34 +1,52 @@
using System;
using System.Linq;
namespace QuanTAlib;
/// <summary>
/// Represents a mode calculator that determines the most frequent value in a specified period.
/// If multiple values have the same highest frequency, it returns their average.
/// MODE: Most Frequent Value Measure
/// A statistical measure that identifies the most frequently occurring value(s)
/// in a dataset. When multiple values share the highest frequency, it returns
/// their average to provide a representative central value.
/// </summary>
/// <remarks>
/// The Mode class uses a circular buffer to store values and calculates the mode
/// efficiently. Before the specified period is reached, it returns the average of
/// the available values as an approximation.
/// The Mode calculation process:
/// 1. Groups values by frequency
/// 2. Identifies highest frequency group(s)
/// 3. Averages multiple modes if present
/// 4. Uses mean until period filled
///
/// In financial analysis, the mode can be useful for:
/// - Identifying the most common price levels, which could indicate support or resistance.
/// - Analyzing the distribution of returns or other financial metrics.
/// - Detecting patterns in trading volume or other discrete financial data.
/// Key characteristics:
/// - Identifies most common values
/// - Handles multiple modes
/// - Robust to distribution shape
/// - Useful for discrete data
/// - Returns actual data points
///
/// Formula:
/// mode = value with highest frequency count
/// if multiple modes: average of mode values
///
/// Market Applications:
/// - Identify common price levels
/// - Detect support/resistance zones
/// - Analyze volume clusters
/// - Find price congestion areas
/// - Pattern recognition
///
/// Sources:
/// https://en.wikipedia.org/wiki/Mode_(statistics)
/// "Statistical Analysis in Financial Markets"
///
/// Note: Particularly useful for price level analysis
/// </remarks>
public class Mode : AbstractBase
{
/// <summary>
/// The number of data points to consider for the mode calculation.
/// </summary>
private readonly int Period;
private readonly CircularBuffer _buffer;
/// <summary>
/// Initializes a new instance of the Mode class with the specified period.
/// </summary>
/// <param name="period">The period over which to calculate the mode.</param>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown when period is less than 1.
/// </exception>
/// <param name="period">The number of points to consider for mode calculation.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mode(int period)
{
if (period < 1)
@@ -42,30 +60,20 @@ public class Mode : AbstractBase
Init();
}
/// <summary>
/// Initializes a new instance of the Mode 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 mode.</param>
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points to consider for mode calculation.</param>
public Mode(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
}
/// <summary>
/// Resets the Mode indicator to its initial state.
/// </summary>
public override void Init()
{
base.Init();
_buffer.Clear();
}
/// <summary>
/// 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)
@@ -75,18 +83,6 @@ public class Mode : AbstractBase
}
}
/// <summary>
/// Performs the mode calculation for the current period.
/// </summary>
/// <returns>
/// The calculated mode (most frequent value) for the current period.
/// If multiple values have the same highest frequency, returns their average.
/// </returns>
/// <remarks>
/// Before the specified period is reached, this method returns the average of
/// 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()
{
ManageState(Input.IsNew);
@@ -95,22 +91,26 @@ public class Mode : AbstractBase
double mode;
if (_index >= Period)
{
// Group values by frequency and order by count
var values = _buffer.GetSpan().ToArray();
var groupedValues = values.GroupBy(v => v)
.OrderByDescending(g => g.Count())
.ThenBy(g => g.Key)
.ToList();
.OrderByDescending(g => g.Count())
.ThenBy(g => g.Key)
.ToList();
// Find all values with highest frequency
int maxCount = groupedValues.First().Count();
var modes = groupedValues.TakeWhile(g => g.Count() == maxCount)
.Select(g => g.Key)
.ToList();
.Select(g => g.Key)
.ToList();
mode = modes.Average(); // If there are multiple modes, we return their average
// Average multiple modes if present
mode = modes.Average();
}
else
{
mode = _buffer.Average(); // Use average until we have enough data points
// Use average until we have enough data points
mode = _buffer.Average();
}
IsHot = _index >= WarmupPeriod;