mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-22 20:48:04 +00:00
Add Standard Deviation Channel (SDCHANNEL) implementation and documentation
- Implemented Sdchannel class for calculating standard deviation channels based on linear regression. - Added detailed documentation for SDCHANNEL, including overview, calculation methods, and interpretation. - Updated project files to include new numerics library components in Channels and Volatility projects.
This commit is contained in:
+132
-69
@@ -1,98 +1,161 @@
|
||||
# Moving Average Envelope
|
||||
# MAENV: Moving Average Envelope
|
||||
|
||||
Moving Average Envelope consists of three lines: a moving average in the middle and two lines plotted at a fixed percentage above and below it. The envelope provides a simple way to identify potential support and resistance levels based on a percentage deviation from the average price.
|
||||
> "The simplest channels are often the most useful - a percentage above and below tells you when price is stretched."
|
||||
|
||||
## Calculation
|
||||
The Moving Average Envelope (MAENV) creates a fixed percentage-based channel around a selectable moving average. Unlike volatility-adaptive channels like Keltner or Bollinger Bands, MAENV maintains constant proportional distance from the middle line, making it useful for mean-reversion strategies where you expect price to oscillate within predictable bounds.
|
||||
|
||||
```
|
||||
Middle = MA(Source, Length)
|
||||
Upper = Middle + (Middle × Percentage/100)
|
||||
Lower = Middle - (Middle × Percentage/100)
|
||||
```
|
||||
## Historical Context
|
||||
|
||||
Where:
|
||||
* MA = Moving Average (can be SMA, EMA, or WMA)
|
||||
* Source = Price series (typically close price)
|
||||
* Length = Lookback period for moving average
|
||||
* Percentage = Fixed percentage for band width
|
||||
Moving Average Envelopes are among the oldest channel indicators, predating volatility-based bands by decades. The concept is straightforward: if price tends to revert to a moving average, then defining zones at fixed percentages above and below that average provides natural support and resistance levels.
|
||||
|
||||
## Parameters
|
||||
The choice of moving average type affects responsiveness:
|
||||
|
||||
* Source (default: close) - Price series used for the moving average
|
||||
* Length (default: 20) - Period used for moving average calculation
|
||||
* Percentage (default: 1.0) - Fixed percentage distance from MA to bands
|
||||
* MA Type (default: 1) - Moving average type: 0:SMA, 1:EMA, or 2:WMA
|
||||
- **SMA**: Equal weighting creates stable, predictable bands but slower reaction to price changes
|
||||
- **EMA**: Exponential weighting responds faster to recent prices, making bands more dynamic
|
||||
- **WMA**: Linear weighting provides a middle ground, emphasizing recent data without the sharp responsiveness of EMA
|
||||
|
||||
## Interpretation
|
||||
This implementation offers all three options, letting traders choose the smoothing behavior that matches their strategy.
|
||||
|
||||
* The middle line shows the average price trend
|
||||
* Upper and lower bands create a channel based on fixed percentage
|
||||
* Price reaching the bands may indicate overbought/oversold conditions
|
||||
* Unlike volatility-based bands, envelope width changes proportionally with price
|
||||
* Band penetration may signal potential trend reversals
|
||||
* Works best in trending markets with consistent volatility
|
||||
## Architecture & Physics
|
||||
|
||||
## Implementation
|
||||
### 1. Moving Average Calculation
|
||||
|
||||
The implementation includes:
|
||||
* Choice of three moving average types (SMA, EMA, WMA)
|
||||
* Optimized calculations for each MA type
|
||||
* Circular buffer for efficient SMA calculation
|
||||
* Alpha smoothing for EMA
|
||||
* Linear weighting for WMA
|
||||
* Proper handling of NA values
|
||||
* Input validation
|
||||
* Percentage-based band width calculation
|
||||
The middle band is computed using the selected MA type:
|
||||
|
||||
**SMA (Simple Moving Average)** - O(1) streaming via ring buffer:
|
||||
|
||||
$$
|
||||
\text{SMA}_t = \frac{1}{n} \sum_{i=0}^{n-1} P_{t-i}
|
||||
$$
|
||||
|
||||
Implementation uses circular buffer to maintain running sum, achieving constant-time updates.
|
||||
|
||||
**EMA (Exponential Moving Average)** - O(1) with warmup compensation:
|
||||
|
||||
$$
|
||||
\alpha = \frac{2}{n+1}
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{sum}_t = \text{sum}_{t-1}(1-\alpha) + P_t \cdot \alpha
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{weight}_t = \text{weight}_{t-1}(1-\alpha) + \alpha
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{EMA}_t = \frac{\text{sum}_t}{\text{weight}_t}
|
||||
$$
|
||||
|
||||
Warmup compensation ensures accurate values from the first bar by tracking both weighted sum and weight.
|
||||
|
||||
**WMA (Weighted Moving Average)** - O(n):
|
||||
|
||||
$$
|
||||
\text{WMA}_t = \frac{\sum_{i=0}^{n-1} w_i \cdot P_{t-i}}{\sum_{i=0}^{n-1} w_i}
|
||||
$$
|
||||
|
||||
where $w_i = (n-i) \times n$ giving highest weight to most recent values.
|
||||
|
||||
### 2. Band Calculation
|
||||
|
||||
Bands are symmetric percentage-based offsets:
|
||||
|
||||
$$
|
||||
\text{dist}_t = \text{Middle}_t \times \frac{\text{percentage}}{100}
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{Upper}_t = \text{Middle}_t + \text{dist}_t
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{Lower}_t = \text{Middle}_t - \text{dist}_t
|
||||
$$
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
### Band Width Formula
|
||||
|
||||
Total band width scales linearly with both the middle value and percentage parameter:
|
||||
|
||||
$$
|
||||
\text{Width}_t = \text{Upper}_t - \text{Lower}_t = 2 \times \text{Middle}_t \times \frac{\text{percentage}}{100}
|
||||
$$
|
||||
|
||||
This creates proportional bands - a 2% envelope means bands are always 4% of the middle value apart.
|
||||
|
||||
### EMA Warmup Derivation
|
||||
|
||||
Traditional EMA initialization (`EMA_0 = P_0`) creates bias when the first value differs significantly from subsequent values. The warmup compensation tracks:
|
||||
|
||||
$$
|
||||
\text{theoretical\_weight} = \alpha \sum_{i=0}^{t} (1-\alpha)^i = 1 - (1-\alpha)^{t+1}
|
||||
$$
|
||||
|
||||
By dividing sum by actual accumulated weight, the EMA converges to the true value faster and without initialization bias.
|
||||
|
||||
## Performance Profile
|
||||
|
||||
### Operation Count (Streaming Mode, per Bar)
|
||||
### Operation Count (Streaming Mode)
|
||||
|
||||
| Operation | EMA Type | SMA Type | WMA Type | Cost |
|
||||
| :--- | :---: | :---: | :---: | :---: |
|
||||
| ADD/SUB | 2 | 2 | 1 | 1 cycle |
|
||||
| MUL | 4 | 2 | 2 | 3 cycles |
|
||||
| DIV | 0 | 1 | 1 | 15 cycles |
|
||||
| MA Type | Per-Bar Cost | Memory | Complexity |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| SMA | ~5 ops | O(n) buffer | O(1) |
|
||||
| EMA | ~8 ops | O(1) scalars | O(1) |
|
||||
| WMA | ~3n ops | O(n) buffer | O(n) |
|
||||
|
||||
**Per-bar totals:**
|
||||
- **EMA type**: 2×1 + 4×3 = ~14 cycles
|
||||
- **SMA type**: 2×1 + 2×3 + 1×15 = ~23 cycles (running sum)
|
||||
- **WMA type**: 1×1 + 2×3 + 1×15 = ~22 cycles (running sums)
|
||||
SMA and EMA achieve constant-time streaming updates. WMA requires linear time due to weighted sum recalculation.
|
||||
|
||||
### Complexity Analysis
|
||||
### Batch Mode Performance
|
||||
|
||||
| Mode | Complexity | Notes |
|
||||
| :--- | :---: | :--- |
|
||||
| Streaming (EMA) | O(1) | IIR recursion, constant time |
|
||||
| Streaming (SMA) | O(1) | Running sum with circular buffer |
|
||||
| Streaming (WMA) | O(1) | Incremental weight adjustment |
|
||||
| Batch | O(n) | Linear scan, n = series length |
|
||||
For batch processing of 1000 values:
|
||||
|
||||
**Memory**: Fixed ~64 bytes state regardless of period.
|
||||
| MA Type | Streaming | Batch (SIMD) | Speedup |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| SMA | ~5000 ops | ~5000 ops | 1× |
|
||||
| EMA | ~8000 ops | ~8000 ops | 1× |
|
||||
| WMA | ~3M ops | ~3M ops | 1× |
|
||||
|
||||
### SIMD Analysis
|
||||
|
||||
| Optimization | Applicable | Notes |
|
||||
| :--- | :---: | :--- |
|
||||
| AVX2 vectorization | ❌ | EMA/SMA recursion prevents parallelization |
|
||||
| FMA | ✅ | Band calculation: `Middle ± Middle × factor` |
|
||||
| Batch parallelism | Partial | Band calc vectorizable after MA computed |
|
||||
Limited SIMD benefit due to recursive nature of MA calculations.
|
||||
|
||||
### Quality Metrics
|
||||
|
||||
| Metric | Score | Notes |
|
||||
| :--- | :---: | :--- |
|
||||
| **Accuracy** | 10/10 | Exact computation |
|
||||
| **Timeliness** | 5/10 | MA lag inherited (period/2 for SMA) |
|
||||
| **Overshoot** | 2/10 | Fixed percentage, no volatility adaptation |
|
||||
| **Smoothness** | 7/10 | Follows MA smoothness |
|
||||
| **Accuracy** | 10/10 | Exact percentage-based calculation |
|
||||
| **Timeliness** | 7/10 | Depends on MA type (EMA fastest) |
|
||||
| **Stability** | 9/10 | No volatility-driven expansion |
|
||||
| **Predictability** | 10/10 | Constant proportional width |
|
||||
|
||||
## Validation
|
||||
|
||||
| Library | Status | Notes |
|
||||
| :--- | :---: | :--- |
|
||||
| **TA-Lib** | N/A | Not implemented |
|
||||
| **Skender** | N/A | Not implemented |
|
||||
| **Tulip** | N/A | Not implemented |
|
||||
| **Ooples** | N/A | Not implemented |
|
||||
| **Internal** | ✅ | Mode consistency verified |
|
||||
| **TA-Lib** | N/A | No direct equivalent |
|
||||
| **Skender** | N/A | No direct equivalent |
|
||||
| **Tulip** | N/A | No direct equivalent |
|
||||
| **Ooples** | N/A | No direct equivalent |
|
||||
| **PineScript** | ✅ | Reference implementation match |
|
||||
|
||||
Validation performed against internal manual calculations and PineScript reference. No external library provides identical multi-MA-type envelope implementation.
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **MA Type Selection**: SMA provides most stable bands but slowest response. EMA responds quickly but may whipsaw. WMA balances both but costs O(n) per update.
|
||||
|
||||
2. **Percentage Calibration**: Optimal percentage varies by instrument volatility. Highly volatile assets need wider envelopes (3-5%), stable assets work with narrow bands (0.5-1%).
|
||||
|
||||
3. **False Breakouts**: Fixed percentage bands don't adapt to volatility regime changes. Price may consistently breach bands during high-volatility periods.
|
||||
|
||||
4. **Warmup Period**: All MA types need `period` bars for full accuracy. EMA warmup compensation accelerates convergence but initial bars still have reduced effective lookback.
|
||||
|
||||
5. **Memory Footprint**: SMA and WMA require period-sized buffers (~8 bytes × period per instance). EMA uses only scalar state (~32 bytes total).
|
||||
|
||||
6. **Bar Correction (isNew=false)**: State restoration copies entire buffer for SMA/WMA. For large periods, this adds latency to tick-by-tick updates.
|
||||
|
||||
## References
|
||||
|
||||
- Murphy, J.J. (1999). *Technical Analysis of the Financial Markets*. New York Institute of Finance.
|
||||
- TradingView. "Moving Average Envelope." Pine Script Reference.
|
||||
|
||||
Reference in New Issue
Block a user