Files
QuanTAlib/lib/oscillators/kdj/Kdj.md
T
Miha Kralj 92709ef2ed Add Stochastic Oscillator implementation and validation tests
- Implemented Stochastic Oscillator (%K and %D) in Stoch.cs with streaming and batch processing capabilities.
- Added validation tests for the Stochastic Oscillator in Stoch.Validation.Tests.cs, ensuring consistency with Skender.Stock.Indicators.
- Created documentation for the Stochastic Oscillator in Stoch.md, detailing its mathematical formula, architecture, parameters, and common pitfalls.
- Updated project file to include necessary numeric libraries for highest and lowest calculations.
2026-02-12 14:29:54 -08:00

107 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# KDJ: Enhanced Stochastic Oscillator
> "K leads, D confirms, J exaggerates — three perspectives on momentum."
KDJ is an enhanced Stochastic Oscillator popular in Asian markets. It extends the classic Stochastic by adding a J line that amplifies divergence between K and D, providing earlier reversal signals. Uses Wilder's RMA (Exponential Moving Average with `α = 1/signal`) instead of SMA for smoother K and D lines.
## Calculation
1. Compute highest high and lowest low over the lookback period using monotonic deques.
2. Calculate the Raw Stochastic Value (RSV).
3. Smooth RSV with RMA to get K; smooth K with RMA to get D.
4. Compute J as the amplified divergence.
Formula:
```
RSV = 100 × (Close - LowestLow) / (HighestHigh - LowestLow)
K = RMA(RSV, signal) // α = 1/signal
D = RMA(K, signal) // α = 1/signal
J = 3K - 2D
```
If the price range is zero, RSV defaults to `50.0` (neutral). K and D are clamped to `[0, 100]`. J is unbounded and can exceed 100 or go below 0.
Exponential warmup compensators ensure accurate K and D values from the first bar, avoiding the typical initialization bias of recursive filters.
## Interpretation
- **K > D** → bullish momentum (K crosses above D = buy signal)
- **K < D** → bearish momentum (K crosses below D = sell signal)
- **J > 100** → strongly overbought, potential reversal down
- **J < 0** → strongly oversold, potential reversal up
- **K > 80** → overbought zone
- **K < 20** → oversold zone
## Parameters
| Name | Type | Default | Range | Description |
| :--- | :--- | :------ | :---- | :---------- |
| `length` | `int` | `9` | `>0` | Lookback period for highest high / lowest low. |
| `signal` | `int` | `3` | `>0` | RMA smoothing period for K and D lines. |
## API
```mermaid
classDiagram
class Kdj {
+Name : string
+WarmupPeriod : int
+IsHot : bool
+K : TValue
+D : TValue
+Last : TValue (J line)
+Update(TBar input, bool isNew) TValue
+Update(TBarSeries source) (TSeries K, TSeries D, TSeries J)
+Prime(TBarSeries source) void
+Reset() void
+Batch(TBarSeries source, int length, int signal) (TSeries K, TSeries D, TSeries J)
+Batch(ReadOnlySpan~double~ high, low, close, Span~double~ kOut, dOut, jOut, int length, int signal) void
+Calculate(TBarSeries source, int length, int signal) ((TSeries K, TSeries D, TSeries J) Results, Kdj Indicator)
}
```
## Usage Example
```csharp
using QuanTAlib;
// Initialize
var kdj = new Kdj(length: 9, signal: 3);
foreach (var bar in bars)
{
kdj.Update(bar, isNew: true);
if (kdj.IsHot)
{
Console.WriteLine($"{bar.Time}: K={kdj.K.Value:F2} D={kdj.D.Value:F2} J={kdj.Last.Value:F2}");
}
}
```
## Performance Profile
| Metric | Score | Notes |
| :--- | :--- | :--- |
| **Throughput** | 9 | O(1) amortized via monotonic deques. |
| **Allocations** | 0 | Zero allocations in hot path. |
| **Complexity** | O(1) | Amortized constant time per update. |
| **Accuracy** | 10 | Exact match with PineScript reference. Exponential warmup compensators. |
| **Timeliness** | 8 | RMA smoothing provides faster response than SMA-based Stochastic. |
| **Overshoot** | 7 | J line intentionally unbounded for early signals. |
| **Smoothness** | 8 | Double RMA smoothing eliminates noise. |
## Validation
No direct TA-Lib/Tulip/Skender equivalent exists for KDJ with Wilder's RMA smoothing. Validation is performed against the PineScript reference and internal consistency checks:
- Streaming vs Batch vs Span cross-mode consistency
- Mathematical identity: J = 3K 2D
- K/D bounded in [0, 100]
- Parameter sensitivity across multiple configurations
## Sources
- Chinese securities analysis (KDJ is a standard indicator on Chinese exchanges)
- [PineScript reference](kdj.pine)