mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-16 17:48:05 +00:00
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:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user