feat: Dpo, Tsi, Vortex, Bpp, Cci, Cfo, Tr, Ui, Vc, Vov, Vr, Vs, Mfi, Nvi, Obv, Pvi, Pvo, Pvol, Pvr, Pvt, Tvi

This commit is contained in:
Miha
2024-10-30 13:45:36 -07:00
parent 06c6875970
commit 6231bab9e5
34 changed files with 3151 additions and 254 deletions
+66
View File
@@ -0,0 +1,66 @@
using System.Runtime.CompilerServices;
namespace QuanTAlib;
/// <summary>
/// BOP: Balance of Power
/// A momentum oscillator that measures the strength of buying and selling pressure by comparing
/// closing prices to their corresponding opening prices.
/// </summary>
/// <remarks>
/// The BOP calculation process:
/// 1. Calculate (Close - Open) / (High - Low) for each period
/// 2. A positive BOP indicates buying pressure (bullish)
/// 3. A negative BOP indicates selling pressure (bearish)
///
/// Key characteristics:
/// - Oscillates above and below zero
/// - No upper or lower bounds
/// - Zero line acts as equilibrium between buying and selling pressure
/// - Can be used to identify potential trend reversals and divergences
///
/// Formula:
/// BOP = (Close - Open) / (High - Low)
///
/// Sources:
/// Igor Livshin (1990s)
/// https://www.investopedia.com/terms/b/bop.asp
/// </remarks>
[SkipLocalsInit]
public sealed class Bop : AbstractBase
{
/// <param name="source">The data source object that publishes updates.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Bop(object source) : this()
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Bop()
{
WarmupPeriod = 1;
Name = "BOP";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void ManageState(bool isNew)
{
if (isNew)
{
_index++;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override double Calculation()
{
ManageState(BarInput.IsNew);
var range = BarInput.High - BarInput.Low;
if (range <= double.Epsilon) return 0;
return (BarInput.Close - BarInput.Open) / range;
}
}
+101
View File
@@ -0,0 +1,101 @@
using System.Runtime.CompilerServices;
namespace QuanTAlib;
/// <summary>
/// CCI: Commodity Channel Index
/// A momentum oscillator used to identify cyclical trends and measure the deviation of price
/// from its statistical mean.
/// </summary>
/// <remarks>
/// The CCI calculation process:
/// 1. Calculate Typical Price (TP) = (High + Low + Close) / 3
/// 2. Calculate Simple Moving Average of TP
/// 3. Calculate Mean Deviation
/// 4. CCI = (TP - SMA(TP)) / (0.015 * Mean Deviation)
///
/// Key characteristics:
/// - Oscillates above and below zero
/// - Typically ranges between +100 and -100
/// - Values above +100 indicate overbought conditions
/// - Values below -100 indicate oversold conditions
/// - Can identify trend strength and reversals
///
/// Formula:
/// CCI = (TypicalPrice - SMA(TypicalPrice, period)) / (0.015 * MeanDeviation)
/// where:
/// - TypicalPrice = (High + Low + Close) / 3
/// - MeanDeviation = Mean(|TP - SMA(TP)|)
///
/// Sources:
/// Donald Lambert (1980)
/// https://www.investopedia.com/terms/c/commoditychannelindex.asp
/// </remarks>
[SkipLocalsInit]
public sealed class Cci : AbstractBase
{
private readonly int _period;
private readonly Sma _sma;
private readonly double[] _typicalPrices;
private readonly double _constant = 0.015;
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The calculation period (default: 20)</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Cci(object source, int period = 20) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Cci(int period = 20)
{
_period = period;
_sma = new Sma(period);
_typicalPrices = new double[period];
WarmupPeriod = period;
Name = "CCI";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void ManageState(bool isNew)
{
if (isNew)
{
_index++;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private double CalculateMeanDeviation(double typicalPrice, double smaValue)
{
var sum = 0.0;
var count = System.Math.Min(_period, _index + 1);
for (var i = 0; i < count; i++)
{
sum += System.Math.Abs(_typicalPrices[i] - smaValue);
}
return sum / count;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override double Calculation()
{
ManageState(BarInput.IsNew);
var typicalPrice = (BarInput.High + BarInput.Low + BarInput.Close) / 3.0;
var idx = _index % _period;
_typicalPrices[idx] = typicalPrice;
var smaValue = _sma.Calc(typicalPrice, BarInput.IsNew);
if (_index < _period - 1) return double.NaN;
var meanDeviation = CalculateMeanDeviation(typicalPrice, smaValue);
if (meanDeviation <= double.Epsilon) return 0;
return (typicalPrice - smaValue) / (_constant * meanDeviation);
}
}
+117
View File
@@ -0,0 +1,117 @@
using System.Runtime.CompilerServices;
namespace QuanTAlib;
/// <summary>
/// CFO: Chande Forecast Oscillator
/// A momentum oscillator that measures the percentage difference between the actual price
/// and its linear regression forecast value.
/// </summary>
/// <remarks>
/// The CFO calculation process:
/// 1. Calculate linear regression forecast value for the current period
/// 2. Calculate percentage difference between actual price and forecast
///
/// Key characteristics:
/// - Oscillates above and below zero
/// - Measures deviation of price from its forecasted value
/// - Positive values indicate price is above forecast (bullish)
/// - Negative values indicate price is below forecast (bearish)
/// - Can identify potential trend reversals and price divergences
///
/// Formula:
/// CFO = ((Price - Forecast) / Price) * 100
/// where:
/// - Price is typically the closing price
/// - Forecast is the linear regression forecast value
///
/// Sources:
/// Tushar Chande (1990s)
/// Technical Analysis of Stocks and Commodities magazine
/// </remarks>
[SkipLocalsInit]
public sealed class Cfo : AbstractBase
{
private readonly int _period;
private readonly double[] _prices;
private double _sumX;
private double _sumY;
private double _sumXY;
private double _sumX2;
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The calculation period (default: 14)</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Cfo(object source, int period = 14) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Cfo(int period = 14)
{
_period = period;
_prices = new double[period];
WarmupPeriod = period;
Name = "CFO";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void ManageState(bool isNew)
{
if (isNew)
{
_index++;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void UpdateSums(double oldPrice, double newPrice, int oldX, int newX)
{
_sumY -= oldPrice;
_sumY += newPrice;
_sumXY -= oldPrice * oldX;
_sumXY += newPrice * newX;
_sumX -= oldX;
_sumX += newX;
_sumX2 -= oldX * oldX;
_sumX2 += newX * newX;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private double CalculateForecast()
{
var count = System.Math.Min(_period, _index + 1);
var n = (double)count;
// Calculate linear regression coefficients
var slope = (n * _sumXY - _sumX * _sumY) / (n * _sumX2 - _sumX * _sumX);
var intercept = (_sumY - slope * _sumX) / n;
// Calculate forecast for next period
return intercept + slope * count;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override double Calculation()
{
ManageState(Input.IsNew);
var price = Input.Value;
var idx = _index % _period;
var oldPrice = _prices[idx];
_prices[idx] = price;
var oldX = idx + 1;
var newX = _index < _period ? idx + 1 : _period;
UpdateSums(oldPrice, price, oldX, newX);
if (_index < _period - 1) return double.NaN;
var forecast = CalculateForecast();
if (price <= double.Epsilon) return 0;
return ((price - forecast) / price) * 100;
}
}
+6 -6
View File
@@ -3,7 +3,7 @@ Done: 6, Todo: 23
✔️ AC - Acceleration Oscillator
✔️ AO - Awesome Oscillator
✔️ AROON - Aroon oscillator
✔️ *AROON - Aroon oscillator (Up, Down)
BOP - Balance of Power
CCI - Commodity Channel Index
CFO - Chande Forcast Oscillator
@@ -17,16 +17,16 @@ DOSC - Derivative Oscillator
EFI - Elder Ray's Force Index
FISHER - Fisher Transform
FOSC - Forecast Oscillator
GATOR - Williams Alliator Oscillator
KDJ - KDJ Indicator (trend reversal)
*GATOR - Williams Alliator Oscillator (Upper Jaw, Lower Jaw, Teeth)
*KDJ - KDJ Indicator (K, D, J lines)
KRI - Kairi Relative Index
✔️ RSI - Relative Strength Index
✔️ RSX - Jurik Trend Strength Index
RVGI - Relative Vigor Index
*RVGI - Relative Vigor Index (RVGI, Signal)
SMI - Stochastic Momentum Index
SRSI - Stochastic RSI
*SRSI - Stochastic RSI (SRSI, Signal)
STC - Schaff Trend Cycle
STOCH - Stochastic Oscillator
*STOCH - Stochastic Oscillator (%K, %D)
TSI - True Strength Index
UO - Ultimate Oscillator
WILLR - Larry Williams' %R