mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-07 13:37:44 +00:00
Momentum
charts for Quantower
This commit is contained in:
+33
-6
@@ -12,6 +12,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Averages", "quantower\Avera
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volatility", "quantower\Volatility\_Volatility.csproj", "{B7DC44F7-D3A3-4C70-9025-513E0182B646}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volatility", "quantower\Volatility\_Volatility.csproj", "{B7DC44F7-D3A3-4C70-9025-513E0182B646}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Oscillators", "quantower\Oscillators\_Oscillators.csproj", "{C4D8F5D0-E6A7-4B7D-B8E9-F55C3F8D9D01}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volume", "quantower\Volume\_Volume.csproj", "{D5E9F6D1-B8A8-4C7E-9FA0-F66C3F8D9D02}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Momentum", "quantower\Momentum\_Momentum.csproj", "{E6F0F7D2-C9B9-4D8F-0FA1-F77C4F9D9D03}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Experiments", "quantower\Experiments\_Experiments.csproj", "{F7F1F8D3-DAC0-4E9F-1FB2-F88D5F0E0E04}"
|
||||||
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntheticVendor", "SyntheticVendor\SyntheticVendor.csproj", "{1CF111D9-33E6-4A11-8FEC-F23300A78D15}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntheticVendor", "SyntheticVendor\SyntheticVendor.csproj", "{1CF111D9-33E6-4A11-8FEC-F23300A78D15}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{2D97C971-20BF-40DB-94AA-3279F787D3CB}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{2D97C971-20BF-40DB-94AA-3279F787D3CB}"
|
||||||
@@ -40,12 +48,27 @@ Global
|
|||||||
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release | Any CPU.ActiveCfg = Release | Any CPU
|
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{B7DC44F7-D3A3-4C70-9025-513E0182B646}.Release | Any CPU.Build.0 = Release | Any CPU
|
{C4D8F5D0-E6A7-4B7D-B8E9-F55C3F8D9D01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug | Any CPU.ActiveCfg = Debug | Any CPU
|
{C4D8F5D0-E6A7-4B7D-B8E9-F55C3F8D9D01}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug | Any CPU.Build.0 = Debug | Any CPU
|
{C4D8F5D0-E6A7-4B7D-B8E9-F55C3F8D9D01}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release | Any CPU.ActiveCfg = Release | Any CPU
|
{C4D8F5D0-E6A7-4B7D-B8E9-F55C3F8D9D01}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release | Any CPU.Build.0 = Release | Any CPU
|
{D5E9F6D1-B8A8-4C7E-9FA0-F66C3F8D9D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D5E9F6D1-B8A8-4C7E-9FA0-F66C3F8D9D02}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D5E9F6D1-B8A8-4C7E-9FA0-F66C3F8D9D02}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D5E9F6D1-B8A8-4C7E-9FA0-F66C3F8D9D02}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E6F0F7D2-C9B9-4D8F-0FA1-F77C4F9D9D03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E6F0F7D2-C9B9-4D8F-0FA1-F77C4F9D9D03}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E6F0F7D2-C9B9-4D8F-0FA1-F77C4F9D9D03}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E6F0F7D2-C9B9-4D8F-0FA1-F77C4F9D9D03}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F7F1F8D3-DAC0-4E9F-1FB2-F88D5F0E0E04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F7F1F8D3-DAC0-4E9F-1FB2-F88D5F0E0E04}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F7F1F8D3-DAC0-4E9F-1FB2-F88D5F0E0E04}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F7F1F8D3-DAC0-4E9F-1FB2-F88D5F0E0E04}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1CF111D9-33E6-4A11-8FEC-F23300A78D15}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2D97C971-20BF-40DB-94AA-3279F787D3CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -55,5 +78,9 @@ Global
|
|||||||
{2E9427C7-144F-488E-A29D-789ACC1C32AE} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
{2E9427C7-144F-488E-A29D-789ACC1C32AE} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
||||||
{6BE10C39-4127-446C-818B-7976FCDD51D5} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
{6BE10C39-4127-446C-818B-7976FCDD51D5} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
||||||
{B7DC44F7-D3A3-4C70-9025-513E0182B646} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
{B7DC44F7-D3A3-4C70-9025-513E0182B646} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
||||||
|
{C4D8F5D0-E6A7-4B7D-B8E9-F55C3F8D9D01} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
||||||
|
{D5E9F6D1-B8A8-4C7E-9FA0-F66C3F8D9D02} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
||||||
|
{E6F0F7D2-C9B9-4D8F-0FA1-F77C4F9D9D03} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
||||||
|
{F7F1F8D3-DAC0-4E9F-1FB2-F88D5F0E0E04} = {1B9AC248-76F8-44DD-958D-F1DC08EE1E87}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
+45
-68
@@ -24,10 +24,13 @@ namespace QuanTAlib;
|
|||||||
///
|
///
|
||||||
/// Formula:
|
/// Formula:
|
||||||
/// TR = max(high-low, abs(high-prevClose), abs(low-prevClose))
|
/// TR = max(high-low, abs(high-prevClose), abs(low-prevClose))
|
||||||
/// +DM = if(high-prevHigh > prevLow-low) then max(high-prevHigh, 0) else 0
|
/// +DM = if(high-prevHigh > prevLow-low && high-prevHigh > 0) then high-prevHigh else 0
|
||||||
/// -DM = if(prevLow-low > high-prevHigh) then max(prevLow-low, 0) else 0
|
/// -DM = if(prevLow-low > high-prevHigh && prevLow-low > 0) then prevLow-low else 0
|
||||||
/// +DI = 100 * smoothed(+DM) / smoothed(TR)
|
/// Smoothed TR = Wilder's smoothing of TR (ATR)
|
||||||
/// -DI = 100 * smoothed(-DM) / smoothed(TR)
|
/// Smoothed +DM = Wilder's smoothing of +DM
|
||||||
|
/// Smoothed -DM = Wilder's smoothing of -DM
|
||||||
|
/// +DI = 100 * Smoothed(+DM) / Smoothed(TR)
|
||||||
|
/// -DI = 100 * Smoothed(-DM) / Smoothed(TR)
|
||||||
///
|
///
|
||||||
/// Sources:
|
/// Sources:
|
||||||
/// J. Welles Wilder Jr. - "New Concepts in Technical Trading Systems" (1978)
|
/// J. Welles Wilder Jr. - "New Concepts in Technical Trading Systems" (1978)
|
||||||
@@ -36,49 +39,41 @@ namespace QuanTAlib;
|
|||||||
/// Note: Default period of 14 was recommended by Wilder
|
/// Note: Default period of 14 was recommended by Wilder
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[SkipLocalsInit]
|
[SkipLocalsInit]
|
||||||
public sealed class Dmi : AbstractBarBase
|
public sealed class Dmi : AbstractBase
|
||||||
{
|
{
|
||||||
private readonly Rma _smoothedTr;
|
private readonly Atr _atr;
|
||||||
private readonly Rma _smoothedPlusDm;
|
private readonly Rma _smoothedPlusDm;
|
||||||
private readonly Rma _smoothedMinusDm;
|
private readonly Rma _smoothedMinusDm;
|
||||||
private double _prevHigh, _prevLow, _prevClose;
|
private double _prevHigh, _prevLow;
|
||||||
private double _p_prevHigh, _p_prevLow, _p_prevClose;
|
private double _p_prevHigh, _p_prevLow;
|
||||||
private double _plusDi, _minusDi;
|
private double _plusDi, _minusDi;
|
||||||
private const double ScalingFactor = 100.0;
|
private const double ScalingFactor = 100.0;
|
||||||
private const int DefaultPeriod = 14;
|
private const int DefaultPeriod = 14;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the most recent +DI value
|
|
||||||
/// </summary>
|
|
||||||
public double PlusDI => _plusDi;
|
public double PlusDI => _plusDi;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the most recent -DI value
|
|
||||||
/// </summary>
|
|
||||||
public double MinusDI => _minusDi;
|
public double MinusDI => _minusDi;
|
||||||
|
|
||||||
/// <param name="period">The number of periods used in the DMI calculation (default 14).</param>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public Dmi(int period = DefaultPeriod)
|
public Dmi(int period = DefaultPeriod)
|
||||||
{
|
{
|
||||||
if (period < 1)
|
if (period < 1)
|
||||||
throw new ArgumentOutOfRangeException(nameof(period));
|
throw new ArgumentOutOfRangeException(nameof(period));
|
||||||
_smoothedTr = new(period, useSma: true);
|
_atr = new(period);
|
||||||
_smoothedPlusDm = new(period, useSma: true);
|
_smoothedPlusDm = new(period);
|
||||||
_smoothedMinusDm = new(period, useSma: true);
|
_smoothedMinusDm = new(period);
|
||||||
_index = 0;
|
|
||||||
WarmupPeriod = period + 1;
|
WarmupPeriod = period + 1;
|
||||||
Name = $"DMI({period})";
|
Name = $"DMI({period})";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <param name="source">The data source object that publishes updates.</param>
|
public override void Init()
|
||||||
/// <param name="period">The number of periods used in the DMI calculation.</param>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public Dmi(object source, int period) : this(period)
|
|
||||||
{
|
{
|
||||||
var pubEvent = source.GetType().GetEvent("Pub");
|
base.Init();
|
||||||
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
|
_atr.Init();
|
||||||
|
_smoothedPlusDm.Init();
|
||||||
|
_smoothedMinusDm.Init();
|
||||||
|
_prevHigh = _prevLow = double.NaN;
|
||||||
|
_p_prevHigh = _p_prevLow = double.NaN;
|
||||||
|
_plusDi = _minusDi = 0;
|
||||||
|
_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -89,25 +84,14 @@ public sealed class Dmi : AbstractBarBase
|
|||||||
_index++;
|
_index++;
|
||||||
_p_prevHigh = _prevHigh;
|
_p_prevHigh = _prevHigh;
|
||||||
_p_prevLow = _prevLow;
|
_p_prevLow = _prevLow;
|
||||||
_p_prevClose = _prevClose;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_prevHigh = _p_prevHigh;
|
_prevHigh = _p_prevHigh;
|
||||||
_prevLow = _p_prevLow;
|
_prevLow = _p_prevLow;
|
||||||
_prevClose = _p_prevClose;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
|
||||||
private static double CalculateTrueRange(double high, double low, double prevClose)
|
|
||||||
{
|
|
||||||
double hl = high - low;
|
|
||||||
double hpc = Math.Abs(high - prevClose);
|
|
||||||
double lpc = Math.Abs(low - prevClose);
|
|
||||||
return Math.Max(hl, Math.Max(hpc, lpc));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
private static (double plusDm, double minusDm) CalculateDirectionalMovement(
|
private static (double plusDm, double minusDm) CalculateDirectionalMovement(
|
||||||
double high, double low, double prevHigh, double prevLow)
|
double high, double low, double prevHigh, double prevLow)
|
||||||
@@ -115,13 +99,8 @@ public sealed class Dmi : AbstractBarBase
|
|||||||
double upMove = high - prevHigh;
|
double upMove = high - prevHigh;
|
||||||
double downMove = prevLow - low;
|
double downMove = prevLow - low;
|
||||||
|
|
||||||
double plusDm = 0.0;
|
double plusDm = (upMove > downMove && upMove > 0) ? upMove : 0;
|
||||||
double minusDm = 0.0;
|
double minusDm = (downMove > upMove && downMove > 0) ? downMove : 0;
|
||||||
|
|
||||||
if (upMove > downMove && upMove > 0)
|
|
||||||
plusDm = upMove;
|
|
||||||
else if (downMove > upMove && downMove > 0)
|
|
||||||
minusDm = downMove;
|
|
||||||
|
|
||||||
return (plusDm, minusDm);
|
return (plusDm, minusDm);
|
||||||
}
|
}
|
||||||
@@ -129,38 +108,36 @@ public sealed class Dmi : AbstractBarBase
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
protected override double Calculation()
|
protected override double Calculation()
|
||||||
{
|
{
|
||||||
ManageState(Input.IsNew);
|
ManageState(BarInput.IsNew);
|
||||||
|
|
||||||
if (_index == 1)
|
if (double.IsNaN(_prevHigh))
|
||||||
{
|
{
|
||||||
_prevHigh = Input.High;
|
_prevHigh = BarInput.High;
|
||||||
_prevLow = Input.Low;
|
_prevLow = BarInput.Low;
|
||||||
_prevClose = Input.Close;
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate True Range and Directional Movement
|
// Calculate ATR
|
||||||
double tr = CalculateTrueRange(Input.High, Input.Low, _prevClose);
|
double atr = _atr.Calc(BarInput).Value;
|
||||||
|
|
||||||
|
// Calculate Directional Movement
|
||||||
var (plusDm, minusDm) = CalculateDirectionalMovement(
|
var (plusDm, minusDm) = CalculateDirectionalMovement(
|
||||||
Input.High, Input.Low, _prevHigh, _prevLow);
|
BarInput.High, BarInput.Low, _prevHigh, _prevLow);
|
||||||
|
|
||||||
// Update previous values
|
// Update previous values for next calculation
|
||||||
_prevHigh = Input.High;
|
_prevHigh = BarInput.High;
|
||||||
_prevLow = Input.Low;
|
_prevLow = BarInput.Low;
|
||||||
_prevClose = Input.Close;
|
|
||||||
|
|
||||||
// Smooth the indicators using Wilder's method
|
// Smooth DM values using Wilder's method
|
||||||
_smoothedTr.Calc(tr, Input.IsNew);
|
double smoothedPlusDm = _smoothedPlusDm.Calc(plusDm, BarInput.IsNew).Value;
|
||||||
_smoothedPlusDm.Calc(plusDm, Input.IsNew);
|
double smoothedMinusDm = _smoothedMinusDm.Calc(minusDm, BarInput.IsNew).Value;
|
||||||
_smoothedMinusDm.Calc(minusDm, Input.IsNew);
|
|
||||||
|
|
||||||
// Calculate +DI and -DI
|
// Calculate DI values
|
||||||
double smoothedTr = _smoothedTr.Value;
|
if (atr > 0)
|
||||||
if (smoothedTr > 0)
|
|
||||||
{
|
{
|
||||||
_plusDi = ScalingFactor * _smoothedPlusDm.Value / smoothedTr;
|
_plusDi = ScalingFactor * smoothedPlusDm / atr;
|
||||||
_minusDi = ScalingFactor * _smoothedMinusDm.Value / smoothedTr;
|
_minusDi = ScalingFactor * smoothedMinusDm / atr;
|
||||||
return _plusDi - _minusDi; // Return the difference as main value
|
return _plusDi - _minusDi;
|
||||||
}
|
}
|
||||||
|
|
||||||
_plusDi = 0.0;
|
_plusDi = 0.0;
|
||||||
|
|||||||
+32
-113
@@ -4,16 +4,13 @@ namespace QuanTAlib;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// DMX: Enhanced Directional Movement Index using JMA smoothing
|
/// DMX: Enhanced Directional Movement Index using JMA smoothing
|
||||||
/// An improvement over the traditional DMI indicator that uses Jurik Moving Average (JMA)
|
/// An improvement over the traditional DMI indicator that uses Jurik Moving Average (JMA)
|
||||||
/// for smoothing instead of Wilder's moving average. This enhancement provides better
|
/// for smoothing. This enhancement provides better noise reduction while maintaining
|
||||||
/// noise reduction while maintaining responsiveness to significant price movements.
|
/// responsiveness to significant price movements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The DMX calculation process:
|
/// The DMX calculation process:
|
||||||
/// 1. Calculate True Range (TR)
|
/// 1. Calculate DMI using the standard Dmi class
|
||||||
/// 2. Calculate +DM (Positive Directional Movement)
|
/// 2. Apply JMA smoothing to the +DI and -DI values
|
||||||
/// 3. Calculate -DM (Negative Directional Movement)
|
|
||||||
/// 4. Smooth TR, +DM, and -DM using JMA instead of Wilder's smoothing
|
|
||||||
/// 5. Calculate +DI and -DI as percentages
|
|
||||||
///
|
///
|
||||||
/// Key improvements over DMI:
|
/// Key improvements over DMI:
|
||||||
/// - Uses JMA's adaptive volatility-based smoothing
|
/// - Uses JMA's adaptive volatility-based smoothing
|
||||||
@@ -22,11 +19,9 @@ namespace QuanTAlib;
|
|||||||
/// - Reduced lag through JMA's phase-shifting
|
/// - Reduced lag through JMA's phase-shifting
|
||||||
///
|
///
|
||||||
/// Formula:
|
/// Formula:
|
||||||
/// TR = max(high-low, abs(high-prevClose), abs(low-prevClose))
|
/// DMI calculation as per standard DMI
|
||||||
/// +DM = if(high-prevHigh > prevLow-low) then max(high-prevHigh, 0) else 0
|
/// DMX +DI = JMA(DMI +DI)
|
||||||
/// -DM = if(prevLow-low > high-prevHigh) then max(prevLow-low, 0) else 0
|
/// DMX -DI = JMA(DMI -DI)
|
||||||
/// +DI = 100 * JMA(+DM) / JMA(TR)
|
|
||||||
/// -DI = 100 * JMA(-DM) / JMA(TR)
|
|
||||||
///
|
///
|
||||||
/// Sources:
|
/// Sources:
|
||||||
/// Original DMI by J. Welles Wilder Jr. - "New Concepts in Technical Trading Systems" (1978)
|
/// Original DMI by J. Welles Wilder Jr. - "New Concepts in Technical Trading Systems" (1978)
|
||||||
@@ -35,53 +30,40 @@ namespace QuanTAlib;
|
|||||||
[SkipLocalsInit]
|
[SkipLocalsInit]
|
||||||
public sealed class Dmx : AbstractBarBase
|
public sealed class Dmx : AbstractBarBase
|
||||||
{
|
{
|
||||||
private readonly Jma _smoothedTr;
|
private readonly Dmi _dmi;
|
||||||
private readonly Jma _smoothedPlusDm;
|
private readonly Jma _smoothedPlusDi;
|
||||||
private readonly Jma _smoothedMinusDm;
|
private readonly Jma _smoothedMinusDi;
|
||||||
private double _prevHigh, _prevLow, _prevClose;
|
|
||||||
private double _p_prevHigh, _p_prevLow, _p_prevClose;
|
|
||||||
private double _plusDi, _minusDi;
|
private double _plusDi, _minusDi;
|
||||||
private const double ScalingFactor = 100.0;
|
private const int DefaultDmiPeriod = 14;
|
||||||
private const int DefaultPeriod = 10;
|
private const int DefaultJmaPeriod = 7;
|
||||||
private const int DefaultPhase = 100;
|
private const int DefaultPhase = 100;
|
||||||
private const double DefaultFactor = 0.25;
|
private const double DefaultFactor = 0.25;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the most recent +DI value
|
/// Gets the most recent smoothed +DI value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double PlusDI => _plusDi;
|
public double PlusDI => _plusDi;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the most recent -DI value
|
/// Gets the most recent smoothed -DI value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double MinusDI => _minusDi;
|
public double MinusDI => _minusDi;
|
||||||
|
|
||||||
/// <param name="period">The number of periods used in the DMX calculation (default 14).</param>
|
/// <param name="dmiPeriod">The number of periods used in the DMI calculation (default 14).</param>
|
||||||
/// <param name="phase">The phase for the JMA smoothing (default 0).</param>
|
/// <param name="jmaPeriod">The number of periods used in the JMA smoothing (default 10).</param>
|
||||||
/// <param name="factor">The factor for the JMA smoothing (default 0.45).</param>
|
/// <param name="phase">The phase for the JMA smoothing (default 100).</param>
|
||||||
|
/// <param name="factor">The factor for the JMA smoothing (default 0.25).</param>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Dmx(int period = DefaultPeriod, int phase = DefaultPhase, double factor = DefaultFactor)
|
public Dmx(int period = DefaultDmiPeriod, int jmaPeriod = DefaultJmaPeriod, int phase = DefaultPhase, double factor = DefaultFactor)
|
||||||
{
|
{
|
||||||
if (period < 1)
|
if (period < 1 || jmaPeriod < 1)
|
||||||
throw new ArgumentOutOfRangeException(nameof(period));
|
throw new ArgumentOutOfRangeException(nameof(period), "Periods must be greater than or equal to 1.");
|
||||||
_smoothedTr = new(period, phase, factor);
|
_dmi = new(period);
|
||||||
_smoothedPlusDm = new(period, phase, factor);
|
_smoothedPlusDi = new(jmaPeriod, phase, factor);
|
||||||
_smoothedMinusDm = new(period, phase, factor);
|
_smoothedMinusDi = new(jmaPeriod, phase, factor);
|
||||||
_index = 0;
|
WarmupPeriod = period + jmaPeriod;
|
||||||
WarmupPeriod = period * 2; // JMA needs more warmup periods than RMA
|
Name = $"DMX({period},{jmaPeriod})";
|
||||||
Name = $"DMX({period})";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <param name="source">The data source object that publishes updates.</param>
|
|
||||||
/// <param name="period">The number of periods used in the DMX calculation.</param>
|
|
||||||
/// <param name="phase">The phase for the JMA smoothing.</param>
|
|
||||||
/// <param name="factor">The factor for the JMA smoothing.</param>
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public Dmx(object source, int period, int phase = DefaultPhase, double factor = DefaultFactor) : this(period, phase, factor)
|
|
||||||
{
|
|
||||||
var pubEvent = source.GetType().GetEvent("Pub");
|
|
||||||
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -90,43 +72,7 @@ public sealed class Dmx : AbstractBarBase
|
|||||||
if (isNew)
|
if (isNew)
|
||||||
{
|
{
|
||||||
_index++;
|
_index++;
|
||||||
_p_prevHigh = _prevHigh;
|
|
||||||
_p_prevLow = _prevLow;
|
|
||||||
_p_prevClose = _prevClose;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_prevHigh = _p_prevHigh;
|
|
||||||
_prevLow = _p_prevLow;
|
|
||||||
_prevClose = _p_prevClose;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
|
||||||
private static double CalculateTrueRange(double high, double low, double prevClose)
|
|
||||||
{
|
|
||||||
double hl = high - low;
|
|
||||||
double hpc = Math.Abs(high - prevClose);
|
|
||||||
double lpc = Math.Abs(low - prevClose);
|
|
||||||
return Math.Max(hl, Math.Max(hpc, lpc));
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
|
||||||
private static (double plusDm, double minusDm) CalculateDirectionalMovement(
|
|
||||||
double high, double low, double prevHigh, double prevLow)
|
|
||||||
{
|
|
||||||
double upMove = high - prevHigh;
|
|
||||||
double downMove = prevLow - low;
|
|
||||||
|
|
||||||
double plusDm = 0.0;
|
|
||||||
double minusDm = 0.0;
|
|
||||||
|
|
||||||
if (upMove > downMove && upMove > 0)
|
|
||||||
plusDm = upMove;
|
|
||||||
else if (downMove > upMove && downMove > 0)
|
|
||||||
minusDm = downMove;
|
|
||||||
|
|
||||||
return (plusDm, minusDm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
@@ -134,40 +80,13 @@ public sealed class Dmx : AbstractBarBase
|
|||||||
{
|
{
|
||||||
ManageState(Input.IsNew);
|
ManageState(Input.IsNew);
|
||||||
|
|
||||||
if (_index == 1)
|
// Calculate DMI
|
||||||
{
|
_dmi.Calc(Input);
|
||||||
_prevHigh = Input.High;
|
|
||||||
_prevLow = Input.Low;
|
|
||||||
_prevClose = Input.Close;
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate True Range and Directional Movement
|
// Smooth the DMI values using JMA
|
||||||
double tr = CalculateTrueRange(Input.High, Input.Low, _prevClose);
|
_plusDi = _smoothedPlusDi.Calc(_dmi.PlusDI, Input.IsNew).Value;
|
||||||
var (plusDm, minusDm) = CalculateDirectionalMovement(
|
_minusDi = _smoothedMinusDi.Calc(_dmi.MinusDI, Input.IsNew).Value;
|
||||||
Input.High, Input.Low, _prevHigh, _prevLow);
|
|
||||||
|
|
||||||
// Update previous values
|
return _plusDi - _minusDi; // Return the difference as main value
|
||||||
_prevHigh = Input.High;
|
|
||||||
_prevLow = Input.Low;
|
|
||||||
_prevClose = Input.Close;
|
|
||||||
|
|
||||||
// Smooth the indicators using JMA
|
|
||||||
_smoothedTr.Calc(tr, Input.IsNew);
|
|
||||||
_smoothedPlusDm.Calc(plusDm, Input.IsNew);
|
|
||||||
_smoothedMinusDm.Calc(minusDm, Input.IsNew);
|
|
||||||
|
|
||||||
// Calculate +DI and -DI
|
|
||||||
double smoothedTr = _smoothedTr.Value;
|
|
||||||
if (smoothedTr > 0)
|
|
||||||
{
|
|
||||||
_plusDi = ScalingFactor * _smoothedPlusDm.Value / smoothedTr;
|
|
||||||
_minusDi = ScalingFactor * _smoothedMinusDm.Value / smoothedTr;
|
|
||||||
return _plusDi - _minusDi; // Return the difference as main value
|
|
||||||
}
|
|
||||||
|
|
||||||
_plusDi = 0.0;
|
|
||||||
_minusDi = 0.0;
|
|
||||||
return 0.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-8
@@ -82,12 +82,13 @@ public sealed class Dpo : AbstractBase
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
protected override double Calculation()
|
protected override double Calculation()
|
||||||
{
|
{
|
||||||
|
|
||||||
ManageState(BarInput.IsNew);
|
ManageState(BarInput.IsNew);
|
||||||
|
|
||||||
// Add current price to buffer
|
// Add current price to buffer
|
||||||
_prices.Add(BarInput.Close);
|
_prices.Add(BarInput.Close, BarInput.IsNew);
|
||||||
|
|
||||||
// Need enough prices for the shifted SMA calculation
|
// Need enough prices for the shifted SMA calculation
|
||||||
|
|
||||||
if (_index <= _shift)
|
if (_index <= _shift)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -96,12 +97,6 @@ public sealed class Dpo : AbstractBase
|
|||||||
// Add price from shift periods ago to SMA buffer
|
// Add price from shift periods ago to SMA buffer
|
||||||
_sma.Add(_prices[_shift]);
|
_sma.Add(_prices[_shift]);
|
||||||
|
|
||||||
// Need enough prices for full calculation
|
|
||||||
if (_index <= WarmupPeriod)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate DPO
|
// Calculate DPO
|
||||||
double dpo = BarInput.Close - _sma.Average();
|
double dpo = BarInput.Close - _sma.Average();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
# Momentum indicators
|
# Momentum indicators
|
||||||
Done: 15, Todo: 2
|
|
||||||
|
|
||||||
✔️ ADX - Average Directional Movement Index
|
✔️ ADX - Average Directional Movement Index
|
||||||
✔️ ADXR - Average Directional Movement Index Rating
|
✔️ ADXR - Average Directional Movement Index Rating
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class AfirmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
Name = "AFIRMA - Adaptive Finite Impulse Response Moving Average";
|
Name = "AFIRMA - Adaptive Finite Impulse Response Moving Average";
|
||||||
Description = "Adaptive Finite Impulse Response Moving Average with ARMA component";
|
Description = "Adaptive Finite Impulse Response Moving Average with ARMA component";
|
||||||
|
|
||||||
Series = new(name: $"AFIRMA {Taps}:{Periods}:{Window}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"AFIRMA {Taps}:{Periods}:{Window}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class AlmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "ALMA - Arnaud Legoux Moving Average";
|
Name = "ALMA - Arnaud Legoux Moving Average";
|
||||||
Description = "Arnaud Legoux Moving Average";
|
Description = "Arnaud Legoux Moving Average";
|
||||||
Series = new(name: $"ALMA {Period}:{Offset:F2}:{Sigma:F0}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"ALMA {Period}:{Offset:F2}:{Sigma:F0}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class DemaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "DEMA - Double Exponential Moving Average";
|
Name = "DEMA - Double Exponential Moving Average";
|
||||||
Description = "A faster-responding moving average that reduces lag by applying the EMA twice.";
|
Description = "A faster-responding moving average that reduces lag by applying the EMA twice.";
|
||||||
Series = new(name: $"DEMA {Period}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"DEMA {Period}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class DsmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "DSMA - Deviation Scaled Moving Average";
|
Name = "DSMA - Deviation Scaled Moving Average";
|
||||||
Description = "A moving average that adjusts its responsiveness based on price deviations from the mean.";
|
Description = "A moving average that adjusts its responsiveness based on price deviations from the mean.";
|
||||||
Series = new(name: $"DSMA {Period}:{Scale:F2}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"DSMA {Period}:{Scale:F2}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class DwmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "DWMA - Double Weighted Moving Average";
|
Name = "DWMA - Double Weighted Moving Average";
|
||||||
Description = "A moving average that applies double weighting to recent prices for increased responsiveness.";
|
Description = "A moving average that applies double weighting to recent prices for increased responsiveness.";
|
||||||
Series = new(name: $"DWMA {Period}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"DWMA {Period}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ public class EmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
{
|
{
|
||||||
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
|
[InputParameter("Periods", sortIndex: 1, 1, 1000, 1, 0)]
|
||||||
public int Periods { get; set; } = 10;
|
public int Periods { get; set; } = 10;
|
||||||
[InputParameter("Use SMA for warmup period", sortIndex: 2)]
|
[InputParameter("Use SMA for warmup period", sortIndex: 2)]
|
||||||
public bool UseSMA { get; set; } = false;
|
public bool UseSMA { get; set; } = false;
|
||||||
|
|
||||||
[InputParameter("Data source", sortIndex: 3, variants: [
|
[InputParameter("Data source", sortIndex: 3, variants: [
|
||||||
@@ -42,7 +42,7 @@ public class EmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "EMA - Exponential Moving Average";
|
Name = "EMA - Exponential Moving Average";
|
||||||
Description = "Exponential Moving Average";
|
Description = "Exponential Moving Average";
|
||||||
Series = new(name: $"EMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"EMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class EpmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "EPMA - Exponential Percentage Moving Average";
|
Name = "EPMA - Exponential Percentage Moving Average";
|
||||||
Description = "Exponential Percentage Moving Average";
|
Description = "Exponential Percentage Moving Average";
|
||||||
Series = new(name: $"EPMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"EPMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class FramaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "FRAMA - Fractal Adaptive Moving Average";
|
Name = "FRAMA - Fractal Adaptive Moving Average";
|
||||||
Description = "Fractal Adaptive Moving Average";
|
Description = "Fractal Adaptive Moving Average";
|
||||||
Series = new(name: $"FRAMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"FRAMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class FwmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "FWMA - Fibonacci Weighted Moving Average";
|
Name = "FWMA - Fibonacci Weighted Moving Average";
|
||||||
Description = "Fibonacci Weighted Moving Average";
|
Description = "Fibonacci Weighted Moving Average";
|
||||||
Series = new(name: $"FWMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"FWMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class GmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "GMA - Gaussian Moving Average";
|
Name = "GMA - Gaussian Moving Average";
|
||||||
Description = "Gaussian Moving Average";
|
Description = "Gaussian Moving Average";
|
||||||
Series = new(name: $"GMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"GMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class HmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "HMA - Hull Moving Average";
|
Name = "HMA - Hull Moving Average";
|
||||||
Description = "Hull Moving Average";
|
Description = "Hull Moving Average";
|
||||||
Series = new(name: $"HMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"HMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class HtitIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "HTIT - Hilbert Transform Instantaneous Trendline";
|
Name = "HTIT - Hilbert Transform Instantaneous Trendline";
|
||||||
Description = "Hilbert Transform Instantaneous Trendline (Note: This indicator may not be fully functional)";
|
Description = "Hilbert Transform Instantaneous Trendline (Note: This indicator may not be fully functional)";
|
||||||
Series = new(name: "HTIT", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: "HTIT", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class HwmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "HWMA - Holt-Winter Moving Average";
|
Name = "HWMA - Holt-Winter Moving Average";
|
||||||
Description = "Holt-Winter Moving Average";
|
Description = "Holt-Winter Moving Average";
|
||||||
Series = new(name: $"HWMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"HWMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class JmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
[InputParameter("Phase", sortIndex: 2, -100, 100, 1, 0)]
|
[InputParameter("Phase", sortIndex: 2, -100, 100, 1, 0)]
|
||||||
public int Phase { get; set; } = 0;
|
public int Phase { get; set; } = 0;
|
||||||
|
|
||||||
[InputParameter("Beta factor", sortIndex: 3, minimum: 0, maximum:5 , increment: 0.01, decimalPlaces: 2)]
|
[InputParameter("Beta factor", sortIndex: 3, minimum: 0, maximum: 5, increment: 0.01, decimalPlaces: 2)]
|
||||||
public double Factor { get; set; } = 0.45;
|
public double Factor { get; set; } = 0.45;
|
||||||
|
|
||||||
[InputParameter("Data source", sortIndex: 4, variants: [
|
[InputParameter("Data source", sortIndex: 4, variants: [
|
||||||
@@ -34,7 +34,7 @@ public class JmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
private Jma? ma;
|
private Jma? ma;
|
||||||
protected LineSeries? Series;
|
protected LineSeries? Series;
|
||||||
protected string? SourceName;
|
protected string? SourceName;
|
||||||
public int MinHistoryDepths => Math.Max(65,Periods * 2);
|
public int MinHistoryDepths => Math.Max(65, Periods * 2);
|
||||||
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
public override string ShortName => $"JMA {Periods}:{Phase}:{Factor:F2}:{SourceName}";
|
public override string ShortName => $"JMA {Periods}:{Phase}:{Factor:F2}:{SourceName}";
|
||||||
@@ -46,7 +46,7 @@ public class JmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "JMA - Jurik Moving Average";
|
Name = "JMA - Jurik Moving Average";
|
||||||
Description = "Jurik Moving Average (Note: This indicator may have consistency issues)";
|
Description = "Jurik Moving Average (Note: This indicator may have consistency issues)";
|
||||||
Series = new(name: $"JMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"JMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class KamaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "KAMA - Kaufman's Adaptive Moving Average";
|
Name = "KAMA - Kaufman's Adaptive Moving Average";
|
||||||
Description = "Kaufman's Adaptive Moving Average";
|
Description = "Kaufman's Adaptive Moving Average";
|
||||||
Series = new(name: $"KAMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"KAMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class LtmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "LTMA - Laguerre Time Moving Average";
|
Name = "LTMA - Laguerre Time Moving Average";
|
||||||
Description = "Laguerre Time Moving Average";
|
Description = "Laguerre Time Moving Average";
|
||||||
Series = new(name: $"LTMA {Gamma}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"LTMA {Gamma}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class MaafIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "MAAF - Median Adaptive Averaging Filter";
|
Name = "MAAF - Median Adaptive Averaging Filter";
|
||||||
Description = "Median Adaptive Averaging Filter (Note: This indicator may have consistency issues)";
|
Description = "Median Adaptive Averaging Filter (Note: This indicator may have consistency issues)";
|
||||||
Series = new(name: $"MAAF {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"MAAF {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class MamaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "MAMA - MESA Adaptive Moving Average";
|
Name = "MAMA - MESA Adaptive Moving Average";
|
||||||
Description = "MESA Adaptive Moving Average";
|
Description = "MESA Adaptive Moving Average";
|
||||||
MamaSeries = new(name: "MAMA", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
MamaSeries = new(name: "MAMA", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
FamaSeries = new(name: "FAMA", color: Color.Red, width: 2, style: LineStyle.Solid);
|
FamaSeries = new(name: "FAMA", color: Color.Red, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(MamaSeries);
|
AddLineSeries(MamaSeries);
|
||||||
AddLineSeries(FamaSeries);
|
AddLineSeries(FamaSeries);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class MgdiIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "MGDI - McGinley Dynamic Indicator";
|
Name = "MGDI - McGinley Dynamic Indicator";
|
||||||
Description = "McGinley Dynamic Indicator";
|
Description = "McGinley Dynamic Indicator";
|
||||||
Series = new(name: $"MGDI {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"MGDI {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class MmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "MMA - Modified Moving Average";
|
Name = "MMA - Modified Moving Average";
|
||||||
Description = "Modified Moving Average";
|
Description = "Modified Moving Average";
|
||||||
Series = new(name: $"MMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"MMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class PwmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "PWMA - Pascal's Weighted Moving Average";
|
Name = "PWMA - Pascal's Weighted Moving Average";
|
||||||
Description = "Pascal's Weighted Moving Average";
|
Description = "Pascal's Weighted Moving Average";
|
||||||
Series = new(name: $"PWMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"PWMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class QemaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "QEMA - Quadruple Exponential Moving Average";
|
Name = "QEMA - Quadruple Exponential Moving Average";
|
||||||
Description = "Quadruple Exponential Moving Average";
|
Description = "Quadruple Exponential Moving Average";
|
||||||
Series = new(name: $"QEMA {K1},{K2},{K3},{K4}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"QEMA {K1},{K2},{K3},{K4}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class RemaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "REMA - Regularized Exponential Moving Average";
|
Name = "REMA - Regularized Exponential Moving Average";
|
||||||
Description = "Regularized Exponential Moving Average";
|
Description = "Regularized Exponential Moving Average";
|
||||||
Series = new(name: $"REMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"REMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class RmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "RMA - Relative Moving Average (Wilder's Moving Average)";
|
Name = "RMA - Relative Moving Average (Wilder's Moving Average)";
|
||||||
Description = "Relative Moving Average, also known as Wilder's Moving Average";
|
Description = "Relative Moving Average, also known as Wilder's Moving Average";
|
||||||
Series = new(name: $"RMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"RMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class SinemaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "SINEMA - Sine-Weighted Moving Average";
|
Name = "SINEMA - Sine-Weighted Moving Average";
|
||||||
Description = "Sine-Weighted Moving Average";
|
Description = "Sine-Weighted Moving Average";
|
||||||
Series = new(name: $"SINEMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"SINEMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class SmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "SMA - Simple Moving Average";
|
Name = "SMA - Simple Moving Average";
|
||||||
Description = "Simple Moving Average";
|
Description = "Simple Moving Average";
|
||||||
Series = new(name: $"SMA {Period}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"SMA {Period}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class SmmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "SMMA - Smoothed Moving Average";
|
Name = "SMMA - Smoothed Moving Average";
|
||||||
Description = "Smoothed Moving Average";
|
Description = "Smoothed Moving Average";
|
||||||
Series = new(name: $"SMMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"SMMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class T3Indicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "T3 - Tillson T3 Moving Average";
|
Name = "T3 - Tillson T3 Moving Average";
|
||||||
Description = "Tillson T3 Moving Average";
|
Description = "Tillson T3 Moving Average";
|
||||||
Series = new(name: $"T3 {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"T3 {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class TemaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "TEMA - Triple Exponential Moving Average";
|
Name = "TEMA - Triple Exponential Moving Average";
|
||||||
Description = "Triple Exponential Moving Average";
|
Description = "Triple Exponential Moving Average";
|
||||||
Series = new(name: $"TEMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"TEMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class TrimaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "TRIMA - Triangular Moving Average";
|
Name = "TRIMA - Triangular Moving Average";
|
||||||
Description = "Triangular Moving Average";
|
Description = "Triangular Moving Average";
|
||||||
Series = new(name: $"TRIMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"TRIMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class VidyaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "VIDYA - Variable Index Dynamic Average";
|
Name = "VIDYA - Variable Index Dynamic Average";
|
||||||
Description = "Variable Index Dynamic Average";
|
Description = "Variable Index Dynamic Average";
|
||||||
Series = new(name: $"VIDYA {ShortPeriod}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"VIDYA {ShortPeriod}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class WmaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "WMA - Weighted Moving Average";
|
Name = "WMA - Weighted Moving Average";
|
||||||
Description = "Weighted Moving Average";
|
Description = "Weighted Moving Average";
|
||||||
Series = new(name: $"WMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"WMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class ZlemaIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "ZLEMA - Zero Lag Exponential Moving Average";
|
Name = "ZLEMA - Zero Lag Exponential Moving Average";
|
||||||
Description = "Zero Lag Exponential Moving Average";
|
Description = "Zero Lag Exponential Moving Average";
|
||||||
Series = new(name: $"ZLEMA {Periods}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"ZLEMA {Periods}", color: IndicatorExtensions.Averages, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class TestIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = false;
|
SeparateWindow = false;
|
||||||
Name = "TEST";
|
Name = "TEST";
|
||||||
Description = "test and test and test and more test.";
|
Description = "test and test and test and more test.";
|
||||||
Series = new(name: $"{Name}", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
Series = new(name: $"{Name}", color: IndicatorExtensions.Volatility, width: 2, style: LineStyle.Solid);
|
||||||
AddLineSeries(Series);
|
AddLineSeries(Series);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyName>Experiments</AssemblyName>
|
||||||
|
<AlgoType>Indicator</AlgoType>
|
||||||
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
|
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="..\*.cs" />
|
||||||
|
<Compile Include="*.cs" />
|
||||||
|
<Compile Include="..\..\lib\**\*.cs" Exclude="..\..\lib\bin\**;..\..\lib\obj\**" />
|
||||||
|
<Reference Include="TradingPlatform.BusinessLayer">
|
||||||
|
<HintPath>..\..\.github\TradingPlatform.BusinessLayer.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<None Include="..\..\.github\TradingPlatform.BusinessLayer.xml">
|
||||||
|
<Link>TradingPlatform.BusinessLayer.xml</Link>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="CopyCustomContent" AfterTargets="AfterBuild"
|
||||||
|
Condition="'$(IsLocalBuild)' == 'true' AND $([MSBuild]::IsOSPlatform('Windows'))">
|
||||||
|
<Copy SourceFiles="$(OutputPath)\Experiments.dll" DestinationFolder="$(QuantowerRoot)\Settings\Scripts\Indicators\QuanTAlib\Experiments" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -16,6 +16,12 @@ public enum MaType
|
|||||||
|
|
||||||
public static class IndicatorExtensions
|
public static class IndicatorExtensions
|
||||||
{
|
{
|
||||||
|
public static readonly Color Averages = Color.FromArgb(255, 255, 128); // #FFFF80 - Yellow
|
||||||
|
public static readonly Color Volume = Color.FromArgb(128, 255, 128); // #80FF80 - Green
|
||||||
|
public static readonly Color Volatility = Color.FromArgb(255, 128, 128); // #FF8080 - Red
|
||||||
|
public static readonly Color Statistics = Color.FromArgb(128, 128, 255); // #8080FF - Blue
|
||||||
|
public static readonly Color Oscillators = Color.FromArgb(255, 128, 255); // #FF80FF - Magenta
|
||||||
|
public static readonly Color Momentum = Color.FromArgb(128, 255, 255); // #80FFFF - Cyan
|
||||||
public static TValue GetInputValue(this Indicator indicator, UpdateArgs args, SourceType source)
|
public static TValue GetInputValue(this Indicator indicator, UpdateArgs args, SourceType source)
|
||||||
{
|
{
|
||||||
var historicalData = indicator.HistoricalData;
|
var historicalData = indicator.HistoricalData;
|
||||||
@@ -179,7 +185,6 @@ public static class IndicatorExtensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void DrawText(this Indicator indicator, PaintChartEventArgs args, string text)
|
public static void DrawText(this Indicator indicator, PaintChartEventArgs args, string text)
|
||||||
{
|
{
|
||||||
if (indicator.CurrentChart == null)
|
if (indicator.CurrentChart == null)
|
||||||
@@ -210,7 +215,3 @@ public static class IndicatorExtensions
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class AdxIndicator : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
[InputParameter("Periods", sortIndex: 1, 1, 2000, 1, 0)]
|
||||||
|
public int Periods { get; set; } = 14;
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 21)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
|
private Adx? adx;
|
||||||
|
protected LineSeries? AdxSeries;
|
||||||
|
public int MinHistoryDepths => Math.Max(5, Periods * 3); // Need extra periods for ADX calculation
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
|
public AdxIndicator()
|
||||||
|
{
|
||||||
|
Name = "ADX - Average Directional Movement Index";
|
||||||
|
Description = "Measures the strength of a trend, regardless of its direction.";
|
||||||
|
SeparateWindow = true;
|
||||||
|
|
||||||
|
AdxSeries = new($"ADX {Periods}", color: IndicatorExtensions.Momentum, 2, LineStyle.Solid);
|
||||||
|
AddLineSeries(AdxSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
adx = new Adx(Periods);
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar input = IndicatorExtensions.GetInputBar(this, args);
|
||||||
|
TValue result = adx!.Calc(input);
|
||||||
|
|
||||||
|
AdxSeries!.SetValue(result.Value);
|
||||||
|
AdxSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
|
||||||
|
public override string ShortName => $"ADX ({Periods})";
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
this.PaintSmoothCurve(args, AdxSeries!, adx!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class AdxrIndicator : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
[InputParameter("Periods", sortIndex: 1, 1, 2000, 1, 0)]
|
||||||
|
public int Periods { get; set; } = 14;
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 21)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
|
private Adxr? adxr;
|
||||||
|
protected LineSeries? AdxrSeries;
|
||||||
|
public int MinHistoryDepths => Math.Max(5, Periods * 4); // Need extra periods for ADXR calculation
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
|
public AdxrIndicator()
|
||||||
|
{
|
||||||
|
Name = "ADXR - Average Directional Movement Index Rating";
|
||||||
|
Description = "Measures trend strength by comparing current ADX with historical ADX values.";
|
||||||
|
SeparateWindow = true;
|
||||||
|
|
||||||
|
AdxrSeries = new($"ADXR {Periods}", Color.Blue, 2, LineStyle.Solid);
|
||||||
|
AddLineSeries(AdxrSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
adxr = new Adxr(Periods);
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar input = IndicatorExtensions.GetInputBar(this, args);
|
||||||
|
TValue result = adxr!.Calc(input);
|
||||||
|
|
||||||
|
AdxrSeries!.SetValue(result.Value);
|
||||||
|
AdxrSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
|
||||||
|
public override string ShortName => $"ADXR ({Periods})";
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
this.PaintHLine(args, 25, new Pen(color: IndicatorExtensions.Momentum, width: 1)); // Strong trend line
|
||||||
|
this.PaintHLine(args, 20, new Pen(color: IndicatorExtensions.Momentum, width: 1)); // Weak trend line
|
||||||
|
this.PaintSmoothCurve(args, AdxrSeries!, adxr!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class ApoIndicator : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
[InputParameter("Fast Period", sortIndex: 1, 1, 2000, 1, 0)]
|
||||||
|
public int FastPeriod { get; set; } = 12;
|
||||||
|
|
||||||
|
[InputParameter("Slow Period", sortIndex: 2, 1, 2000, 1, 0)]
|
||||||
|
public int SlowPeriod { get; set; } = 26;
|
||||||
|
|
||||||
|
[InputParameter("Data source", sortIndex: 4, variants: [
|
||||||
|
"Open", SourceType.Open,
|
||||||
|
"High", SourceType.High,
|
||||||
|
"Low", SourceType.Low,
|
||||||
|
"Close", SourceType.Close,
|
||||||
|
"HL/2 (Median)", SourceType.HL2,
|
||||||
|
"OC/2 (Midpoint)", SourceType.OC2,
|
||||||
|
"OHL/3 (Mean)", SourceType.OHL3,
|
||||||
|
"HLC/3 (Typical)", SourceType.HLC3,
|
||||||
|
"OHLC/4 (Average)", SourceType.OHLC4,
|
||||||
|
"HLCC/4 (Weighted)", SourceType.HLCC4
|
||||||
|
])]
|
||||||
|
public SourceType Source { get; set; } = SourceType.Close;
|
||||||
|
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 21)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
|
private Apo? apo;
|
||||||
|
protected LineSeries? ApoSeries;
|
||||||
|
public int MinHistoryDepths => Math.Max(FastPeriod, SlowPeriod) * 2;
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
|
public ApoIndicator()
|
||||||
|
{
|
||||||
|
Name = "APO - Absolute Price Oscillator";
|
||||||
|
Description = "Shows the difference between two moving averages of different periods.";
|
||||||
|
SeparateWindow = true;
|
||||||
|
|
||||||
|
ApoSeries = new($"APO {FastPeriod},{SlowPeriod}", color: IndicatorExtensions.Momentum, 2, LineStyle.Solid);
|
||||||
|
AddLineSeries(ApoSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
apo = new Apo(FastPeriod, SlowPeriod);
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TValue input = this.GetInputValue(args, Source);
|
||||||
|
TValue result = apo!.Calc(input);
|
||||||
|
|
||||||
|
ApoSeries!.SetValue(result.Value);
|
||||||
|
ApoSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
|
||||||
|
public override string ShortName => $"APO ({FastPeriod},{SlowPeriod})";
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
this.PaintSmoothCurve(args, ApoSeries!, apo!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class DmiIndicator : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
[InputParameter("Periods", sortIndex: 1, 1, 2000, 1, 0)]
|
||||||
|
public int Periods { get; set; } = 14;
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 21)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
|
private Dmi? dmi;
|
||||||
|
protected LineSeries? PlusDiSeries;
|
||||||
|
protected LineSeries? MinusDiSeries;
|
||||||
|
public int MinHistoryDepths => Math.Max(5, Periods * 2);
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
|
public DmiIndicator()
|
||||||
|
{
|
||||||
|
Name = "DMI - Directional Movement Index";
|
||||||
|
Description = "Identifies the directional movement of a price by comparing successive highs and lows.";
|
||||||
|
SeparateWindow = true;
|
||||||
|
|
||||||
|
PlusDiSeries = new($"+DI {Periods}", color: Color.Red, 2, LineStyle.Solid);
|
||||||
|
MinusDiSeries = new($"-DI {Periods}", color: Color.Blue, 2, LineStyle.Solid);
|
||||||
|
AddLineSeries(PlusDiSeries);
|
||||||
|
AddLineSeries(MinusDiSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
dmi = new Dmi(Periods);
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar input = IndicatorExtensions.GetInputBar(this, args);
|
||||||
|
var result = dmi!.Calc(input);
|
||||||
|
|
||||||
|
PlusDiSeries!.SetValue(dmi.PlusDI);
|
||||||
|
MinusDiSeries!.SetValue(dmi.MinusDI);
|
||||||
|
PlusDiSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
MinusDiSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
|
||||||
|
public override string ShortName => $"DMI ({Periods})";
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
this.PaintSmoothCurve(args, PlusDiSeries!, dmi!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
this.PaintSmoothCurve(args, MinusDiSeries!, dmi!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class DmxIndicator : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
[InputParameter("DMI Periods", sortIndex: 1, 1, 2000, 1, 0)]
|
||||||
|
public int DmiPeriods { get; set; } = 14;
|
||||||
|
|
||||||
|
[InputParameter("JMA Smoothing Periods", sortIndex: 2, 1, 2000, 1, 0)]
|
||||||
|
public int JmaPeriods { get; set; } = 12;
|
||||||
|
|
||||||
|
[InputParameter("JMA Phase", sortIndex: 3, -100, 100, 1, 0)]
|
||||||
|
public int JmaPhase { get; set; } = 100;
|
||||||
|
|
||||||
|
[InputParameter("JMA Factor", sortIndex: 4, 0.01, 1, 0.01, 2)]
|
||||||
|
public double JmaFactor { get; set; } = 0.3;
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 21)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
|
private Dmx? dmx;
|
||||||
|
protected LineSeries? PlusDiSeries;
|
||||||
|
protected LineSeries? MinusDiSeries;
|
||||||
|
public int MinHistoryDepths => Math.Max(5, (DmiPeriods + JmaPeriods) * 2);
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
|
public DmxIndicator()
|
||||||
|
{
|
||||||
|
Name = "DMX - Enhanced Directional Movement Index";
|
||||||
|
Description = "An enhanced version of DMI using JMA smoothing for better noise reduction and responsiveness.";
|
||||||
|
SeparateWindow = true;
|
||||||
|
|
||||||
|
PlusDiSeries = new($"+DI {DmiPeriods}", color: Color.Red, 2, LineStyle.Solid);
|
||||||
|
MinusDiSeries = new($"-DI {DmiPeriods}", color: Color.Blue, 2, LineStyle.Solid);
|
||||||
|
AddLineSeries(PlusDiSeries);
|
||||||
|
AddLineSeries(MinusDiSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
dmx = new Dmx(DmiPeriods, JmaPeriods, JmaPhase, JmaFactor);
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar input = IndicatorExtensions.GetInputBar(this, args);
|
||||||
|
var result = dmx!.Calc(input);
|
||||||
|
|
||||||
|
PlusDiSeries!.SetValue(dmx.PlusDI);
|
||||||
|
MinusDiSeries!.SetValue(dmx.MinusDI);
|
||||||
|
PlusDiSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
MinusDiSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
|
||||||
|
public override string ShortName => $"DMX ({DmiPeriods})";
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
this.PaintSmoothCurve(args, PlusDiSeries!, dmx!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
this.PaintSmoothCurve(args, MinusDiSeries!, dmx!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class DpoIndicator : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
[InputParameter("Period", sortIndex: 1, 1, 2000, 1, 0)]
|
||||||
|
public int Period { get; set; } = 20;
|
||||||
|
|
||||||
|
[InputParameter("Data source", sortIndex: 2, variants: [
|
||||||
|
"Open", SourceType.Open,
|
||||||
|
"High", SourceType.High,
|
||||||
|
"Low", SourceType.Low,
|
||||||
|
"Close", SourceType.Close,
|
||||||
|
"HL/2 (Median)", SourceType.HL2,
|
||||||
|
"OC/2 (Midpoint)", SourceType.OC2,
|
||||||
|
"OHL/3 (Mean)", SourceType.OHL3,
|
||||||
|
"HLC/3 (Typical)", SourceType.HLC3,
|
||||||
|
"OHLC/4 (Average)", SourceType.OHLC4,
|
||||||
|
"HLCC/4 (Weighted)", SourceType.HLCC4
|
||||||
|
])]
|
||||||
|
public SourceType Source { get; set; } = SourceType.Close;
|
||||||
|
|
||||||
|
[InputParameter("Show cold values", sortIndex: 3)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
|
private Dpo? Dpo;
|
||||||
|
protected LineSeries? DpoSeries;
|
||||||
|
public int MinHistoryDepths => Period * 2;
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
|
public DpoIndicator()
|
||||||
|
{
|
||||||
|
Name = "DPO - Detrended Price Oscillator";
|
||||||
|
Description = "Removes trend from price by comparing current price to a past moving average, helping identify cycles in the price.";
|
||||||
|
SeparateWindow = true;
|
||||||
|
|
||||||
|
DpoSeries = new($"DPO {Period}", color: IndicatorExtensions.Momentum, 2, LineStyle.Solid);
|
||||||
|
AddLineSeries(DpoSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
Dpo = new Dpo(Period);
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar input = this.GetInputBar(args);
|
||||||
|
TValue result = Dpo!.Calc(input);
|
||||||
|
|
||||||
|
DpoSeries!.SetValue(result.Value);
|
||||||
|
DpoSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
|
||||||
|
public override string ShortName => $"DPO ({Period})";
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
this.PaintSmoothCurve(args, DpoSeries!, Dpo!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,9 +36,7 @@ public class MacdIndicator : Indicator, IWatchlistIndicator
|
|||||||
[InputParameter("Show cold values", sortIndex: 21)]
|
[InputParameter("Show cold values", sortIndex: 21)]
|
||||||
public bool ShowColdValues { get; set; } = true;
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
private Ema? slow_ma;
|
private Macd? macd;
|
||||||
private Ema? fast_ma;
|
|
||||||
private Ema? signal_ma;
|
|
||||||
private Slope? histSlope;
|
private Slope? histSlope;
|
||||||
protected LineSeries? MainSeries;
|
protected LineSeries? MainSeries;
|
||||||
protected LineSeries? SignalSeries;
|
protected LineSeries? SignalSeries;
|
||||||
@@ -58,8 +56,8 @@ public class MacdIndicator : Indicator, IWatchlistIndicator
|
|||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
Name = "MACD - Moving Average Convergence Divergence";
|
Name = "MACD - Moving Average Convergence Divergence";
|
||||||
Description = "MACD";
|
Description = "MACD";
|
||||||
MainSeries = new(name: $"MAIN", color: Color.Blue, width: 2, style: LineStyle.Solid);
|
MainSeries = new(name: $"MAIN", color: Color.RoyalBlue, width: 2, style: LineStyle.Solid);
|
||||||
SignalSeries = new(name: $"SIGNAL", color: Color.Yellow, width: 2, style: LineStyle.Solid);
|
SignalSeries = new(name: $"SIGNAL", color: Color.Red, width: 2, style: LineStyle.Solid);
|
||||||
HistogramSeries = new(name: $"HISTOGRAM", color: Color.White, width: 2, style: LineStyle.Solid);
|
HistogramSeries = new(name: $"HISTOGRAM", color: Color.White, width: 2, style: LineStyle.Solid);
|
||||||
HistSlopeSeries = new(name: $"SLOPE", color: Color.Transparent, width: 2, style: LineStyle.Solid);
|
HistSlopeSeries = new(name: $"SLOPE", color: Color.Transparent, width: 2, style: LineStyle.Solid);
|
||||||
HistSlopeSeries.Visible = false;
|
HistSlopeSeries.Visible = false;
|
||||||
@@ -72,9 +70,7 @@ public class MacdIndicator : Indicator, IWatchlistIndicator
|
|||||||
|
|
||||||
protected override void OnInit()
|
protected override void OnInit()
|
||||||
{
|
{
|
||||||
slow_ma = new(Slow, useSma: UseSMA);
|
macd = new(fastPeriod: Fast, slowPeriod: Slow, signalPeriod: Signal);
|
||||||
fast_ma = new(Fast, useSma: UseSMA);
|
|
||||||
signal_ma = new(Signal, useSma: UseSMA);
|
|
||||||
histSlope = new(2);
|
histSlope = new(2);
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
base.OnInit();
|
base.OnInit();
|
||||||
@@ -83,19 +79,22 @@ public class MacdIndicator : Indicator, IWatchlistIndicator
|
|||||||
protected override void OnUpdate(UpdateArgs args)
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
{
|
{
|
||||||
TValue input = this.GetInputValue(args, Source);
|
TValue input = this.GetInputValue(args, Source);
|
||||||
slow_ma!.Calc(input);
|
macd!.Calc(input);
|
||||||
fast_ma!.Calc(input);
|
|
||||||
double main = fast_ma.Value - slow_ma.Value;
|
double main = macd.MacdLine;
|
||||||
double signal = signal_ma!.Calc(main);
|
double signal = macd.SignalLine;
|
||||||
double histogram = main - signal;
|
double histogram = macd.Value;
|
||||||
histSlope!.Calc(histogram);
|
histSlope!.Calc(histogram);
|
||||||
|
|
||||||
MainSeries!.SetValue(main);
|
MainSeries!.SetValue(main);
|
||||||
MainSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
MainSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
||||||
|
|
||||||
SignalSeries!.SetValue(signal);
|
SignalSeries!.SetValue(signal);
|
||||||
SignalSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
SignalSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
||||||
|
|
||||||
HistogramSeries!.SetValue(histogram);
|
HistogramSeries!.SetValue(histogram);
|
||||||
HistogramSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
HistogramSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
||||||
|
|
||||||
HistSlopeSeries!.SetValue(histSlope.Value);
|
HistSlopeSeries!.SetValue(histSlope.Value);
|
||||||
HistSlopeSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
HistSlopeSeries!.SetMarker(0, Color.Transparent); //OnPaintChart draws the line, hidden here
|
||||||
}
|
}
|
||||||
@@ -118,7 +117,7 @@ public class MacdIndicator : Indicator, IWatchlistIndicator
|
|||||||
for (int i = rightIndex; i < leftIndex; i++)
|
for (int i = rightIndex; i < leftIndex; i++)
|
||||||
{
|
{
|
||||||
int barX = (int)converter.GetChartX(this.HistoricalData.Time(i));
|
int barX = (int)converter.GetChartX(this.HistoricalData.Time(i));
|
||||||
int barY = (int)converter.GetChartY(HistogramSeries![i]*2.0);
|
int barY = (int)converter.GetChartY(HistogramSeries![i] * 2.0);
|
||||||
int barY0 = (int)converter.GetChartY(0);
|
int barY0 = (int)converter.GetChartY(0);
|
||||||
int HistBarWidth = this.CurrentChart.BarsWidth - 2;
|
int HistBarWidth = this.CurrentChart.BarsWidth - 2;
|
||||||
|
|
||||||
@@ -139,8 +138,8 @@ public class MacdIndicator : Indicator, IWatchlistIndicator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.PaintSmoothCurve(args, MainSeries!, slow_ma!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.3);
|
this.PaintSmoothCurve(args, MainSeries!, macd!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.3);
|
||||||
this.PaintSmoothCurve(args, SignalSeries!, slow_ma!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
this.PaintSmoothCurve(args, SignalSeries!, macd!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
base.OnPaintChart(args);
|
base.OnPaintChart(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ public class RsiIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures the speed and magnitude of recent price changes to evaluate overbought or oversold conditions.";
|
Description = "Measures the speed and magnitude of recent price changes to evaluate overbought or oversold conditions.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
RsiSeries = new($"RSI {Periods}", Color.Blue, 2, LineStyle.Solid);
|
RsiSeries = new($"RSI {Periods}", color: IndicatorExtensions.Oscillators, 2, LineStyle.Solid);
|
||||||
AddLineSeries(RsiSeries);
|
AddLineSeries(RsiSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ public class RsxIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures the speed and magnitude of recent price changes to evaluate overbought or oversold conditions.";
|
Description = "Measures the speed and magnitude of recent price changes to evaluate overbought or oversold conditions.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
RsxSeries = new($"RSX {Period}", Color.Blue, 2, LineStyle.Solid);
|
RsxSeries = new($"RSX {Period}", color: IndicatorExtensions.Oscillators, 2, LineStyle.Solid);
|
||||||
AddLineSeries(RsxSeries);
|
AddLineSeries(RsxSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ public class CurvatureIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
CurvatureSeries = new("Curvature", Color.Blue, 2, LineStyle.Solid);
|
CurvatureSeries = new("Curvature", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(CurvatureSeries);
|
AddLineSeries(CurvatureSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class EntropyIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
EntropySeries = new("Entropy", Color.Blue, 2, LineStyle.Solid);
|
EntropySeries = new("Entropy", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(EntropySeries);
|
AddLineSeries(EntropySeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class KurtosisIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
KurtosisSeries = new("Kurtosis", Color.Blue, 2, LineStyle.Solid);
|
KurtosisSeries = new("Kurtosis", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(KurtosisSeries);
|
AddLineSeries(KurtosisSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class MaxIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = false;
|
SeparateWindow = false;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
MaxSeries = new("Max", Color.Blue, 2, LineStyle.Solid);
|
MaxSeries = new("Max", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(MaxSeries);
|
AddLineSeries(MaxSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class MedianIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = false;
|
SeparateWindow = false;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
MedianSeries = new("Median", Color.Blue, 2, LineStyle.Solid);
|
MedianSeries = new("Median", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(MedianSeries);
|
AddLineSeries(MedianSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class MinIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = false;
|
SeparateWindow = false;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
MinSeries = new("Min", Color.Blue, 2, LineStyle.Solid);
|
MinSeries = new("Min", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(MinSeries);
|
AddLineSeries(MinSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class ModeIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = false;
|
SeparateWindow = false;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
ModeSeries = new("Mode", Color.Blue, 2, LineStyle.Solid);
|
ModeSeries = new("Mode", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(ModeSeries);
|
AddLineSeries(ModeSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class PercentileIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = false;
|
SeparateWindow = false;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
PercentileSeries = new("Percentile", Color.Blue, 2, LineStyle.Solid);
|
PercentileSeries = new("Percentile", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(PercentileSeries);
|
AddLineSeries(PercentileSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class SkewIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
SkewSeries = new("Skew", Color.Blue, 2, LineStyle.Solid);
|
SkewSeries = new("Skew", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(SkewSeries);
|
AddLineSeries(SkewSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class SlopeIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
SlopeSeries = new("Slope", Color.Blue, 2, LineStyle.Solid);
|
SlopeSeries = new("Slope", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
LineSeries = new("Regression Line", Color.Red, 1, LineStyle.Solid);
|
LineSeries = new("Regression Line", Color.Red, 1, LineStyle.Solid);
|
||||||
AddLineSeries(SlopeSeries);
|
AddLineSeries(SlopeSeries);
|
||||||
AddLineSeries(LineSeries);
|
AddLineSeries(LineSeries);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class StddevIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
StddevSeries = new("StdDev", Color.Blue, 2, LineStyle.Solid);
|
StddevSeries = new("StdDev", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(StddevSeries);
|
AddLineSeries(StddevSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class VarianceIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
VarianceSeries = new("Variance", Color.Blue, 2, LineStyle.Solid);
|
VarianceSeries = new("Variance", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(VarianceSeries);
|
AddLineSeries(VarianceSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class ZscoreIndicator : Indicator, IWatchlistIndicator
|
|||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
|
|
||||||
ZscoreSeries = new("Z-Score", Color.Blue, 2, LineStyle.Solid);
|
ZscoreSeries = new("Z-Score", color: IndicatorExtensions.Statistics, 2, LineStyle.Solid);
|
||||||
AddLineSeries(ZscoreSeries);
|
AddLineSeries(ZscoreSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class AtrIndicator : Indicator, IWatchlistIndicator
|
|||||||
public override void OnPaintChart(PaintChartEventArgs args)
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
{
|
{
|
||||||
base.OnPaintChart(args);
|
base.OnPaintChart(args);
|
||||||
this.PaintHLine(args, 0.05, new Pen(Color.DarkRed, width: 2));
|
this.PaintHLine(args, 0.05, new Pen(color: IndicatorExtensions.Volatility, width: 2));
|
||||||
this.PaintSmoothCurve(args, AtrSeries!, atr!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
this.PaintSmoothCurve(args, AtrSeries!, atr!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class CmoIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures the momentum of price changes using the difference between the sum of recent gains and the sum of recent losses.";
|
Description = "Measures the momentum of price changes using the difference between the sum of recent gains and the sum of recent losses.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
SourceName = Source.ToString();
|
SourceName = Source.ToString();
|
||||||
CmoSeries = new($"CMO {Periods}", Color.Blue, 2, LineStyle.Solid);
|
CmoSeries = new($"CMO {Periods}", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
AddLineSeries(CmoSeries);
|
AddLineSeries(CmoSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class CviIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures the volatility of a financial instrument by comparing the spread between the high and low prices.";
|
Description = "Measures the volatility of a financial instrument by comparing the spread between the high and low prices.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
|
|
||||||
CviSeries = new($"CVI {Periods}", Color.Blue, 2, LineStyle.Solid);
|
CviSeries = new($"CVI {Periods}", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
AddLineSeries(CviSeries);
|
AddLineSeries(CviSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public class CviIndicator : Indicator, IWatchlistIndicator
|
|||||||
public override void OnPaintChart(PaintChartEventArgs args)
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
{
|
{
|
||||||
base.OnPaintChart(args);
|
base.OnPaintChart(args);
|
||||||
this.PaintHLine(args, 0.05, new Pen(Color.DarkRed, width: 2));
|
this.PaintHLine(args, 0.05, new Pen(color: IndicatorExtensions.Volatility, width: 2));
|
||||||
this.PaintSmoothCurve(args, CviSeries!, cvi!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
this.PaintSmoothCurve(args, CviSeries!, cvi!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class HistoricalIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures price fluctuations over time, indicating market volatility based on past price movements.";
|
Description = "Measures price fluctuations over time, indicating market volatility based on past price movements.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
|
|
||||||
HvSeries = new("HV", Color.Blue, 2, LineStyle.Solid);
|
HvSeries = new("HV", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
AddLineSeries(HvSeries);
|
AddLineSeries(HvSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ public class JbandsIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Upper and Lower Bands.";
|
Description = "Upper and Lower Bands.";
|
||||||
SeparateWindow = false;
|
SeparateWindow = false;
|
||||||
|
|
||||||
UbSeries = new("UB", Color.Blue, 2, LineStyle.Solid);
|
UbSeries = new("UB", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
LbSeries = new("LB", Color.Red, 2, LineStyle.Solid);
|
LbSeries = new("LB", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
AddLineSeries(UbSeries);
|
AddLineSeries(UbSeries);
|
||||||
AddLineSeries(LbSeries);
|
AddLineSeries(LbSeries);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class JvoltyIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures market volatility according to Mark Jurik.";
|
Description = "Measures market volatility according to Mark Jurik.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
|
|
||||||
JvoltySeries = new("JVOLTY", Color.Blue, 2, LineStyle.Solid);
|
JvoltySeries = new("JVOLTY", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
AddLineSeries(JvoltySeries);
|
AddLineSeries(JvoltySeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class RealizedIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures actual price volatility over a specific period, useful for risk assessment and forecasting.";
|
Description = "Measures actual price volatility over a specific period, useful for risk assessment and forecasting.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
|
|
||||||
RvSeries = new("RV", Color.Blue, 2, LineStyle.Solid);
|
RvSeries = new("RV", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
AddLineSeries(RvSeries);
|
AddLineSeries(RvSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class RviIndicator : Indicator, IWatchlistIndicator
|
|||||||
Description = "Measures the direction of volatility, helping to identify overbought or oversold conditions in price.";
|
Description = "Measures the direction of volatility, helping to identify overbought or oversold conditions in price.";
|
||||||
SeparateWindow = true;
|
SeparateWindow = true;
|
||||||
|
|
||||||
RviSeries = new("RVI", Color.Blue, 2, LineStyle.Solid);
|
RviSeries = new("RVI", color: IndicatorExtensions.Volatility, 2, LineStyle.Solid);
|
||||||
AddLineSeries(RviSeries);
|
AddLineSeries(RviSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using TradingPlatform.BusinessLayer;
|
||||||
|
|
||||||
|
namespace QuanTAlib;
|
||||||
|
|
||||||
|
public class ObvIndicator : Indicator, IWatchlistIndicator
|
||||||
|
{
|
||||||
|
[InputParameter("Show cold values", sortIndex: 21)]
|
||||||
|
public bool ShowColdValues { get; set; } = true;
|
||||||
|
|
||||||
|
private Obv? obv;
|
||||||
|
protected LineSeries? ObvSeries;
|
||||||
|
public int MinHistoryDepths => 5;
|
||||||
|
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
|
||||||
|
|
||||||
|
public ObvIndicator()
|
||||||
|
{
|
||||||
|
Name = "OBV - On-Balance Volume";
|
||||||
|
Description = "Measures buying and selling pressure by analyzing volume in relation to price changes.";
|
||||||
|
SeparateWindow = true;
|
||||||
|
|
||||||
|
ObvSeries = new("OBV", color: IndicatorExtensions.Volume, 2, LineStyle.Solid);
|
||||||
|
AddLineSeries(ObvSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
obv = new Obv();
|
||||||
|
base.OnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(UpdateArgs args)
|
||||||
|
{
|
||||||
|
TBar input = IndicatorExtensions.GetInputBar(this, args);
|
||||||
|
TValue result = obv!.Calc(input);
|
||||||
|
|
||||||
|
ObvSeries!.SetValue(result.Value);
|
||||||
|
ObvSeries!.SetMarker(0, Color.Transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416 // Validate platform compatibility
|
||||||
|
|
||||||
|
public override string ShortName => "OBV";
|
||||||
|
|
||||||
|
public override void OnPaintChart(PaintChartEventArgs args)
|
||||||
|
{
|
||||||
|
base.OnPaintChart(args);
|
||||||
|
this.PaintHLine(args, 0, new Pen(color: Color.DimGray, width: 1));
|
||||||
|
this.PaintSmoothCurve(args, ObvSeries!, obv!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user