Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 13 additions & 23 deletions src/TechnicalAnalysis.Common/Abstractions/CandleIndicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,34 @@ namespace TechnicalAnalysis.Common;
/// <summary>
/// Represents an abstract base class for candlestick pattern recognition indicators.
/// </summary>
public abstract class CandleIndicator<T>
/// <typeparam name="T">The floating-point type the price arrays are expressed in.</typeparam>
/// <param name="open">An array of open prices.</param>
/// <param name="high">An array of high prices.</param>
/// <param name="low">An array of low prices.</param>
/// <param name="close">An array of close prices.</param>
public abstract class CandleIndicator<T>(T[] open, T[] high, T[] low, T[] close)
where T : IFloatingPoint<T>
{
/// <summary>
/// An array of open prices.
/// </summary>
protected T[] Open { get; }
protected T[] Open { get; } = open;

/// <summary>
/// An array of high prices.
/// </summary>
protected T[] High { get; }
protected T[] High { get; } = high;

/// <summary>
/// An array of low prices.
/// </summary>
protected T[] Low { get; }
protected T[] Low { get; } = low;

/// <summary>
/// An array of close prices.
/// </summary>
protected T[] Close { get; }

/// <summary>
/// Initializes a new instance of the CandleIndicator class.
/// </summary>
/// <param name="open">An array of open prices.</param>
/// <param name="high">An array of high prices.</param>
/// <param name="low">An array of low prices.</param>
/// <param name="close">An array of close prices.</param>
protected CandleIndicator(T[] open, T[] high, T[] low, T[] close)
{
Open = open;
High = high;
Low = low;
Close = close;
}

protected T[] Close { get; } = close;

/// <summary>
/// Returns the lookback period for the indicator.
/// </summary>
Expand Down
41 changes: 12 additions & 29 deletions src/TechnicalAnalysis.Common/Helpers/ValidationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,9 @@ public static class ValidationHelper
/// </returns>
public static RetCode ValidateIndexRange(int startIdx, int endIdx)
{
if (startIdx < 0)
{
return OutOfRangeStartIndex;
}

if (endIdx < 0 || endIdx < startIdx)
{
return OutOfRangeEndIndex;
}

return Success;
return startIdx < 0 ? OutOfRangeStartIndex
: endIdx < 0 || endIdx < startIdx ? OutOfRangeEndIndex
: Success;
}

/// <summary>
Expand Down Expand Up @@ -151,24 +143,15 @@ public static RetCode ValidateSingleInputIndicator(
int minPeriod = 2,
int maxPeriod = 100000)
{
RetCode indexCheck = ValidateIndexRange(startIdx, endIdx);
if (indexCheck != Success)
{
return indexCheck;
}

RetCode arrayCheck = ValidateArrays(inReal, outReal);
if (arrayCheck != Success)
{
return arrayCheck;
}

if (optInTimePeriod.HasValue)
{
return ValidatePeriodRange(optInTimePeriod.Value, minPeriod, maxPeriod);
}

return Success;
// ValidateAll runs these in order and stops at the first failure, which is what the
// hand-rolled guard chain did — but as one expression, and matching how the indicators
// themselves compose their validation.
return ValidateAll(
() => ValidateIndexRange(startIdx, endIdx),
() => ValidateArrays(inReal, outReal),
() => optInTimePeriod.HasValue
? ValidatePeriodRange(optInTimePeriod.Value, minPeriod, maxPeriod)
: Success);
}

/// <summary>
Expand Down
10 changes: 0 additions & 10 deletions src/TechnicalAnalysis.Functions/Correl/CorrelResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,4 @@ public CorrelResult(RetCode retCode, int begIdx, int nbElement, double[] real)
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of correlation coefficient values.
/// </summary>
/// <value>
/// An array of doubles representing the correlation values, ranging from -1 to +1.
/// Values near +1 indicate strong positive correlation, values near -1 indicate
/// strong negative correlation, and values near 0 indicate weak or no linear relationship.
/// These values are essential for risk management and portfolio optimization.
/// </value>
}
11 changes: 5 additions & 6 deletions src/TechnicalAnalysis.Functions/Dx/DxResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ namespace TechnicalAnalysis.Functions;
/// Represents the result of the Directional Movement Index (DX) indicator calculation.
/// DX measures the strength of a trend regardless of its direction, derived from comparing directional movements.
/// </summary>
/// <remarks>
/// The <see cref="SingleOutputResult.Real"/> array holds the Directional Movement Index values.
/// Values range from 0 to 100, where higher values indicate stronger trends (either up or down).
/// Values below 20 typically indicate weak trends, while values above 40 suggest strong trends.
/// </remarks>
public record DxResult : SingleOutputResult
{
/// <summary>
Expand All @@ -23,10 +28,4 @@ public DxResult(RetCode retCode, int begIdx, int nbElement, double[] real)
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of Directional Movement Index values.
/// Values range from 0 to 100, where higher values indicate stronger trends (either up or down).
/// Values below 20 typically indicate weak trends, while values above 40 suggest strong trends.
/// </summary>
}
11 changes: 5 additions & 6 deletions src/TechnicalAnalysis.Functions/HtDcPeriod/HtDcPeriodResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace TechnicalAnalysis.Functions;
/// This indicator identifies the dominant cycle period of market data using Hilbert Transform techniques,
/// providing insight into the cyclical nature of price movements.
/// </summary>
/// <remarks>
/// The <see cref="SingleOutputResult.Real"/> array holds the dominant cycle period values.
/// Each value represents the period (in bars) of the dominant market cycle at that point in time.
/// Values typically range from 10 to 50 bars, depending on market conditions.
/// </remarks>
public record HtDcPeriodResult : SingleOutputResult
{
/// <summary>
Expand All @@ -24,10 +29,4 @@ public HtDcPeriodResult(RetCode retCode, int begIdx, int nbElement, double[] rea
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of dominant cycle period values.
/// Each value represents the period (in bars) of the dominant market cycle at that point in time.
/// Values typically range from 10 to 50 bars, depending on market conditions.
/// </summary>
}
11 changes: 5 additions & 6 deletions src/TechnicalAnalysis.Functions/HtDcPhase/HtDcPhaseResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace TechnicalAnalysis.Functions;
/// This indicator measures the phase angle of the dominant market cycle using Hilbert Transform techniques,
/// helping to identify the current position within a price cycle.
/// </summary>
/// <remarks>
/// The <see cref="SingleOutputResult.Real"/> array holds the dominant cycle phase values.
/// Each value represents the phase angle in degrees (-180 to +180) of the dominant cycle.
/// Positive values indicate the cycle is in an upward phase, while negative values indicate a downward phase.
/// </remarks>
public record HtDcPhaseResult : SingleOutputResult
{
/// <summary>
Expand All @@ -24,10 +29,4 @@ public HtDcPhaseResult(RetCode retCode, int begIdx, int nbElement, double[] real
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of dominant cycle phase values.
/// Each value represents the phase angle in degrees (-180 to +180) of the dominant cycle.
/// Positive values indicate the cycle is in an upward phase, while negative values indicate a downward phase.
/// </summary>
}
11 changes: 5 additions & 6 deletions src/TechnicalAnalysis.Functions/HtTrendline/HtTrendlineResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace TechnicalAnalysis.Functions;
/// This indicator creates a smooth trendline by removing the dominant cycle component from price data,
/// effectively filtering out short-term fluctuations to reveal the underlying trend.
/// </summary>
/// <remarks>
/// The <see cref="SingleOutputResult.Real"/> array holds the instantaneous trendline values.
/// These values represent a smoothed version of the price with dominant cycles filtered out,
/// providing a clear view of the underlying trend direction and strength.
/// </remarks>
public record HtTrendlineResult : SingleOutputResult
{
/// <summary>
Expand All @@ -24,10 +29,4 @@ public HtTrendlineResult(RetCode retCode, int begIdx, int nbElement, double[] re
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of instantaneous trendline values.
/// These values represent a smoothed version of the price with dominant cycles filtered out,
/// providing a clear view of the underlying trend direction and strength.
/// </summary>
}
11 changes: 5 additions & 6 deletions src/TechnicalAnalysis.Functions/LinearReg/LinearRegResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace TechnicalAnalysis.Functions;
/// This indicator calculates the linear regression line value at each point, providing a statistical
/// best-fit line through the price data over a specified period.
/// </summary>
/// <remarks>
/// The <see cref="SingleOutputResult.Real"/> array holds the linear regression line values.
/// Each value represents the y-coordinate of the regression line at that point in time,
/// calculated using least squares method over the specified lookback period.
/// </remarks>
public record LinearRegResult : SingleOutputResult
{
/// <summary>
Expand All @@ -24,10 +29,4 @@ public LinearRegResult(RetCode retCode, int begIdx, int nbElement, double[] real
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of linear regression line values.
/// Each value represents the y-coordinate of the regression line at that point in time,
/// calculated using least squares method over the specified lookback period.
/// </summary>
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace TechnicalAnalysis.Functions;
/// This indicator calculates the angle of the linear regression line in degrees, providing insight
/// into the strength and direction of the trend over a specified period.
/// </summary>
/// <remarks>
/// Gets the array of linear regression angle values in degrees.
/// Positive angles indicate an upward trend, negative angles indicate a downward trend.
/// The magnitude of the angle reflects the steepness of the trend.
/// </remarks>
public record LinearRegAngleResult : SingleOutputResult
{
/// <summary>
Expand All @@ -24,10 +29,4 @@ public LinearRegAngleResult(RetCode retCode, int begIdx, int nbElement, double[]
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of linear regression angle values in degrees.
/// Positive angles indicate an upward trend, negative angles indicate a downward trend.
/// The magnitude of the angle reflects the steepness of the trend.
/// </summary>
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace TechnicalAnalysis.Functions;
/// This indicator calculates the y-intercept of the linear regression line, representing where
/// the regression line would cross the y-axis if extended backward.
/// </summary>
/// <remarks>
/// The <see cref="SingleOutputResult.Real"/> array holds the linear regression intercept values.
/// Each value represents the y-intercept of the regression line calculated over the lookback period,
/// useful for projecting the regression line and understanding price levels.
/// </remarks>
public record LinearRegInterceptResult : SingleOutputResult
{
/// <summary>
Expand All @@ -24,10 +29,4 @@ public LinearRegInterceptResult(RetCode retCode, int begIdx, int nbElement, doub
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of linear regression intercept values.
/// Each value represents the y-intercept of the regression line calculated over the lookback period,
/// useful for projecting the regression line and understanding price levels.
/// </summary>
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace TechnicalAnalysis.Functions;
/// This indicator calculates the slope of the linear regression line, indicating the rate of change
/// in price over the specified period.
/// </summary>
/// <remarks>
/// The <see cref="SingleOutputResult.Real"/> array holds the linear regression slope values.
/// Each value represents the slope (rate of change per bar) of the regression line.
/// Positive values indicate rising prices, negative values indicate falling prices.
/// </remarks>
public record LinearRegSlopeResult : SingleOutputResult
{
/// <summary>
Expand All @@ -24,10 +29,4 @@ public LinearRegSlopeResult(RetCode retCode, int begIdx, int nbElement, double[]
: base(retCode, begIdx, nbElement, real)
{
}

/// <summary>
/// Gets the array of linear regression slope values.
/// Each value represents the slope (rate of change per bar) of the regression line.
/// Positive values indicate rising prices, negative values indicate falling prices.
/// </summary>
}
3 changes: 2 additions & 1 deletion src/TechnicalAnalysis.Functions/MacdFix/TAMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ public static MacdFixResult MacdFix(int startIdx, int endIdx, double[] real, int
/// <param name="startIdx">The starting index for the calculation range.</param>
/// <param name="endIdx">The ending index for the calculation range.</param>
/// <param name="real">Array of input values (usually closing prices).</param>
/// <param name="signalPeriod">The signal line period. Defaults to 9.</param>
/// <returns>A MacdFixResult containing the MACD line, signal line, and histogram values.</returns>
/// <remarks>
/// Uses fixed values: fastPeriod=12, slowPeriod=26, signalPeriod=9.
/// The fast and slow periods are fixed at 12 and 26; only the signal period is adjustable.
/// </remarks>
public static MacdFixResult MacdFix(int startIdx, int endIdx, float[] real, int signalPeriod = 9)
=> TAMathHelper.Execute(startIdx, endIdx, real, (s, e, r) => MacdFix(s, e, r, signalPeriod));
Expand Down
1 change: 1 addition & 0 deletions src/TechnicalAnalysis.Functions/MidPrice/TAMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public static MidPriceResult MidPrice(int startIdx, int endIdx, double[] high, d
/// <param name="endIdx">The ending index for the calculation range.</param>
/// <param name="high">Array of high prices.</param>
/// <param name="low">Array of low prices.</param>
/// <param name="timePeriod">The number of periods in each rolling window. Defaults to 14.</param>
/// <returns>A MidPriceResult containing the midprice values over each rolling window.</returns>
/// <remarks>
/// This overload uses a default time period of 14.
Expand Down
1 change: 1 addition & 0 deletions src/TechnicalAnalysis.Functions/Natr/TAMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public static NatrResult Natr(int startIdx, int endIdx, double[] high, double[]
/// <param name="high">An array of high prices.</param>
/// <param name="low">An array of low prices.</param>
/// <param name="close">An array of closing prices.</param>
/// <param name="timePeriod">The number of periods to average over. Defaults to 14.</param>
/// <returns>A NatrResult object containing the calculated values.</returns>
/// <remarks>Uses the default time period of 14.</remarks>
public static NatrResult Natr(int startIdx, int endIdx, float[] high, float[] low, float[] close, int timePeriod = 14)
Expand Down
1 change: 1 addition & 0 deletions src/TechnicalAnalysis.Functions/ZigZag/TAMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static ZigZagResult ZigZag(
/// <param name="endIdx">The ending index for the calculation.</param>
/// <param name="high">Array of high prices.</param>
/// <param name="low">Array of low prices.</param>
/// <param name="deviation">The minimum percentage move required to start a new leg. Defaults to 5.0.</param>
/// <returns>A ZigZagResult object containing the calculated values and metadata.</returns>
public static ZigZagResult ZigZag(int startIdx, int endIdx, float[] high, float[] low, double deviation = 5.0)
=> TAMathHelper.Execute(startIdx, endIdx, high, low, (s, e, h, l) => ZigZag(s, e, h, l, deviation));
Expand Down
Loading