mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-08 14:07:44 +00:00
xml doc rewrite
This commit is contained in:
+50
-50
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user