mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-17 01:58:06 +00:00
- Implemented ChopIndicator for Quantower with configurable period and cold value display. - Created Chop class for calculating the Choppiness Index with detailed documentation. - Added comprehensive unit tests for Chop functionality, covering various market conditions and edge cases. - Developed markdown documentation for CHOP, detailing its historical context, mathematical foundation, and usage examples. - Established a remediation plan for channel indicators documentation, identifying gaps and prioritizing updates.
134 lines
4.9 KiB
Markdown
134 lines
4.9 KiB
Markdown
# APZ: Adaptive Price Zone
|
||
|
||
> "Volatility is not noise; it is the breathing rhythm of the market."
|
||
|
||
APZ (Adaptive Price Zone) is a volatility-based envelop composed of double-smoothed exponential moving averages. Unlike standard bands that often perform poorly in non-trending "choppy" markets, APZ uses a square-root weighted EMA to create a highly responsive zone that identifies reversal points in sideways action.
|
||
|
||
## Historical Context
|
||
|
||
Created by Lee Leibfarth and published in *Technical Analysis of Stocks & Commodities* (Sep 2006, "Trading With An Adaptive Price Zone"), APZ was specifically engineered for the "non-trending" phase of market cycles. Leibfarth recognized that most indicators fail in chop; trend followers get whipsawed, and oscillators saturate. APZ fills this gap by adapting its bandwidth dynamically to statistical noise, allowing traders to fade extremes in range-bound environments.
|
||
|
||
## Architecture & Physics
|
||
|
||
APZ relies on a "Double-Smoothed EMA" (DS-EMA) for both the centerline and the band width. The smoothing factor is aggressive, derived from the square root of the period, making it significantly faster than a standard EMA.
|
||
|
||
### Calculation Steps
|
||
|
||
1. **Smoothing Factor**:
|
||
$$\alpha = \frac{2}{\sqrt{Period} + 1}$$
|
||
|
||
2. **Center Line (DS-EMA of Price)**:
|
||
$$EMA1_{Price} = \text{Price}_t \times \alpha + EMA1_{Price, t-1} \times (1 - \alpha)$$
|
||
$$Center_t = EMA1_{Price} \times \alpha + Center_{t-1} \times (1 - \alpha)$$
|
||
|
||
3. **Adaptive Range (DS-EMA of Range)**:
|
||
$$Range_t = \text{High}_t - \text{Low}_t$$
|
||
$$EMA1_{Range} = Range_t \times \alpha + EMA1_{Range, t-1} \times (1 - \alpha)$$
|
||
$$SmoothRange_t = EMA1_{Range} \times \alpha + SmoothRange_{t-1} \times (1 - \alpha)$$
|
||
|
||
4. **Bands**:
|
||
$$BandWidth_t = SmoothRange_t \times Factor$$
|
||
$$Upper_t = Center_t + BandWidth_t$$
|
||
$$Lower_t = Center_t - BandWidth_t$$
|
||
|
||
Where $Period$ determines responsiveness and $Factor$ scales the zone width.
|
||
|
||
## Performance Profile
|
||
|
||
The implementation utilizes compounded warmup compensation to stabilize the nested EMAs derived from bar 1 (zero-lag start).
|
||
|
||
### Operation Count - Single value
|
||
|
||
| Operation | Count | Cost (cycles) | Subtotal |
|
||
| :--- | :---: | :---: | :---: |
|
||
| ADD/SUB | 6 | 1 | 6 |
|
||
| MUL | 10 | 3 | 30 |
|
||
| FMA | 4 | 4 | 16 |
|
||
| SQRT | 1 | 15 | 15 |
|
||
| **Total** | **21** | — | **~67 cycles** |
|
||
|
||
*Note: SQRT is computed once at initialization. The runtime complexity is dominated by the 4 FMA instructions for the double smoothing.*
|
||
|
||
### Operation Count - Batch processing
|
||
|
||
| Operation | Scalar Ops | SIMD Ops (AVX/SSE) | Acceleration |
|
||
| :--- | :---: | :---: | :---: |
|
||
| Double Smoothing | 4N | N/A | 1× |
|
||
|
||
*Note: Due to the nested recursive nature ($t$ depends on $t-1$), vectorization is limited to parallel processing of Price and Range chains.*
|
||
|
||
## Validation
|
||
|
||
| Library | Status | Notes |
|
||
| :--- | :--- | :--- |
|
||
| **TA-Lib** | N/A | Not implemented |
|
||
| **Skender** | N/A | Not implemented |
|
||
| **Internal** | ✅ | Validated against Leibfarth's formula |
|
||
| **TradingView** | ✅ | Matches standard scripts |
|
||
|
||
## Usage & Pitfalls
|
||
|
||
- **Market Regime**: APZ is a **Mean Reversion** tool. It works best when ADX < 30. In strong trends, price will "surf" the bands rather than reverse.
|
||
- **Whipsaw**: The bands are extremely responsive. A closing price outside the bands suggests an immediate reversal, not a breakout.
|
||
- **Period Selection**: Because of the square root, a period of 20 (sqrt≈4.47) behaves like an EMA of ~3.5. It is much faster than a standard 20 EMA.
|
||
|
||
## API
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class Apz {
|
||
+TValue Last
|
||
+TValue Upper
|
||
+TValue Lower
|
||
+bool IsHot
|
||
+Update(TBar bar) TValue
|
||
+Update(TBarSeries source) tuple
|
||
+Batch(...) void
|
||
}
|
||
```
|
||
|
||
### Class: `Apz`
|
||
|
||
| Parameter | Type | Default | Range | Description |
|
||
| :--- | :--- | :--- | :--- | :--- |
|
||
| `period` | `int` | — | `>0` | Lookback period (internally $\sqrt{P}$). |
|
||
| `multiplier` | `double` | `2.0` | `>0` | Band width factor. |
|
||
| `source` | `TBarSeries` | — | `any` | Initial input source (optional). |
|
||
|
||
### Properties
|
||
|
||
- `Last` (`TValue`): The current center line (DS-EMA Price).
|
||
- `Upper` (`TValue`): The current upper band.
|
||
- `Lower` (`TValue`): The current lower band.
|
||
- `IsHot` (`bool`): Returns `true` if valid data is available (warmup complete).
|
||
|
||
### Methods
|
||
|
||
- `Update(TBar input)`: Updates the indicator with a new bar.
|
||
- `Update(TBarSeries source)`: Processes a full series.
|
||
- `Batch(...)`: Static method for high-performance batch processing.
|
||
|
||
## C# Example
|
||
|
||
```csharp
|
||
using QuanTAlib;
|
||
|
||
// Initialize
|
||
var indicator = new Apz(period: 20, multiplier: 2.0);
|
||
|
||
// Update Loop
|
||
foreach (var bar in bars)
|
||
{
|
||
var center = indicator.Update(bar);
|
||
|
||
// Mean reversion logic
|
||
if (indicator.IsHot)
|
||
{
|
||
if (bar.Close > indicator.Upper.Value)
|
||
Console.WriteLine("Overshoot: Sell Signal");
|
||
if (bar.Close < indicator.Lower.Value)
|
||
Console.WriteLine("Undershoot: Buy Signal");
|
||
}
|
||
}
|
||
```
|