mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-07 13:37:44 +00:00
272 lines
11 KiB
Markdown
272 lines
11 KiB
Markdown
# TWAP: Time Weighted Average Price
|
||
|
||
> *Equal time, equal weight—the simplest benchmark refuses to let any single moment dominate the conversation.*
|
||
|
||
| Property | Value |
|
||
| ---------------- | -------------------------------- |
|
||
| **Category** | Volume |
|
||
| **Inputs** | OHLCV bar (TBar) |
|
||
| **Parameters** | `period` (default DefaultPeriod) |
|
||
| **Outputs** | Single series (TWAP) |
|
||
| **Output range** | Unbounded |
|
||
| **Warmup** | `> 1` bars |
|
||
| **PineScript** | [twap.pine](twap.pine) |
|
||
|
||
- Time Weighted Average Price (TWAP) calculates the average price over a period by giving equal weight to each price point, regardless of volume.
|
||
- **Similar:** [VWAP](../vwap/Vwap.md) | **Complementary:** Volume | **Trading note:** Time-Weighted Average Price; equal time weighting vs volume weighting. Algorithmic execution benchmark.
|
||
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
|
||
|
||
Time Weighted Average Price (TWAP) calculates the average price over a period by giving equal weight to each price point, regardless of volume. Unlike VWAP which emphasizes high-volume periods, TWAP treats every moment as equally important. This makes it a pure temporal benchmark—ideal for evaluating execution quality when volume patterns could bias the analysis.
|
||
|
||
The elegance of TWAP lies in its simplicity: accumulate prices, count observations, divide. No volume weighting, no complex adjustments. Just a running average that answers the question: "What was the typical price during this period?"
|
||
|
||
## Historical Context
|
||
|
||
TWAP emerged from the world of algorithmic trading in the 1990s alongside its volume-weighted sibling, VWAP. While VWAP became the dominant benchmark for evaluating trade execution, TWAP filled a crucial niche:
|
||
|
||
- Markets with unreliable or absent volume data (forex, some futures)
|
||
- Situations where volume manipulation could skew benchmarks
|
||
- Academic studies requiring volume-agnostic price measurements
|
||
- Low-liquidity instruments where volume spikes create VWAP distortions
|
||
|
||
The indicator gained renewed interest with the rise of cryptocurrency trading, where volume data quality varies dramatically across exchanges. A TWAP benchmark remains consistent regardless of reported volume, making it valuable for cross-exchange comparisons.
|
||
|
||
TWAP also serves as the basis for TWAP execution algorithms—strategies that break large orders into equal slices executed at regular intervals, aiming to achieve the time-weighted average price while minimizing market impact.
|
||
|
||
## Architecture & Physics
|
||
|
||
TWAP operates as a simple accumulator with optional periodic resets. The state tracks a running sum of prices and a count of observations.
|
||
|
||
### Component Breakdown
|
||
|
||
1. **Price Accumulation**: Sum of all prices in the current session
|
||
2. **Count Tracking**: Number of observations accumulated
|
||
3. **Period Management**: Optional reset at specified intervals
|
||
4. **Average Calculation**: Sum divided by count
|
||
|
||
### State Requirements
|
||
|
||
| Component | Type | Purpose |
|
||
| :--- | :--- | :--- |
|
||
| SumPrices | double | Running sum of prices in session |
|
||
| Count | int | Number of prices accumulated |
|
||
| Index | int | Bar counter for period resets |
|
||
| LastValid | double | Fallback for NaN/Infinity handling |
|
||
| Twap | double | Current TWAP value |
|
||
|
||
### Session Reset Behavior
|
||
|
||
The period parameter controls session boundaries:
|
||
|
||
- **Period = 0**: Never reset; continuous average from start
|
||
- **Period > 0**: Reset sum and count every N bars
|
||
|
||
Session resets are critical for intraday benchmarking where you want fresh TWAP calculations for each trading session rather than a cumulative average across days.
|
||
|
||
## Mathematical Foundation
|
||
|
||
### Running Average Formula
|
||
|
||
$$
|
||
TWAP_t = \frac{\sum_{i=1}^{n} P_i}{n}
|
||
$$
|
||
|
||
where:
|
||
|
||
- $P_i$ = Price at observation $i$
|
||
- $n$ = Number of observations
|
||
|
||
### Incremental Update (Streaming)
|
||
|
||
$$
|
||
Sum_t = Sum_{t-1} + P_t
|
||
$$
|
||
|
||
$$
|
||
Count_t = Count_{t-1} + 1
|
||
$$
|
||
|
||
$$
|
||
TWAP_t = \frac{Sum_t}{Count_t}
|
||
$$
|
||
|
||
### With Period Reset
|
||
|
||
At bar $t$ where $t \mod period = 1$ (first bar of new session):
|
||
|
||
$$
|
||
Sum_t = P_t
|
||
$$
|
||
|
||
$$
|
||
Count_t = 1
|
||
$$
|
||
|
||
$$
|
||
TWAP_t = P_t
|
||
$$
|
||
|
||
### Price Source
|
||
|
||
For TBar input, the typical price (HLC3) is used:
|
||
|
||
$$
|
||
P_t = \frac{High_t + Low_t + Close_t}{3}
|
||
$$
|
||
|
||
This provides a better representation of average trading price than using close alone.
|
||
|
||
## TWAP vs VWAP Comparison
|
||
|
||
| Aspect | TWAP | VWAP |
|
||
| :--- | :--- | :--- |
|
||
| Weighting | Equal per observation | Volume-proportional |
|
||
| Volume data required | No | Yes |
|
||
| Sensitivity to spikes | Time-based only | Volume and price |
|
||
| Manipulation resistance | Higher | Lower (volume can be faked) |
|
||
| Formula | $\frac{\sum P}{n}$ | $\frac{\sum (P \times V)}{\sum V}$ |
|
||
| Use case | Time-based benchmarks | Volume-based benchmarks |
|
||
|
||
### When TWAP > VWAP
|
||
|
||
High volume concentrated at lower prices during the session. Interpretation: early buying pressure (accumulation) occurred at cheaper levels.
|
||
|
||
### When TWAP < VWAP
|
||
|
||
High volume concentrated at higher prices during the session. Interpretation: buying pressure came at elevated prices (late to the move).
|
||
|
||
## Performance Profile
|
||
|
||
### Operation Count (Streaming Mode)
|
||
|
||
| Operation | Count | Notes |
|
||
| :--- | :---: | :--- |
|
||
| ADD | 3 | HLC3 calculation + sum update |
|
||
| DIV | 2 | HLC3 calculation + TWAP |
|
||
| CMP | 1 | Period boundary check |
|
||
| INC | 2 | Count and index increments |
|
||
| **Total** | 8 | Per bar, O(1) |
|
||
|
||
TWAP is one of the simplest indicators computationally—no lookback buffer, no complex mathematics.
|
||
|
||
### Batch Mode (SIMD)
|
||
|
||
| Operation | Vectorizable | Notes |
|
||
| :--- | :---: | :--- |
|
||
| HLC3 calculation | ✅ | Fully parallel |
|
||
| Price accumulation | ❌ | Sequential dependency (running sum) |
|
||
| Count tracking | ❌ | Sequential increment |
|
||
| Division | ❌ | Depends on running count |
|
||
|
||
The running sum dependency limits SIMD optimization. However, the HLC3 preprocessing step can be vectorized when processing bar data.
|
||
|
||
### Memory Footprint
|
||
|
||
| Scope | Size |
|
||
| :--- | :--- |
|
||
| Per instance | 56 bytes (State record struct × 2) |
|
||
| Buffer requirements | None (O(1) state) |
|
||
|
||
### Quality Metrics
|
||
|
||
| Metric | Score | Notes |
|
||
| :--- | :---: | :--- |
|
||
| **Accuracy** | 10/10 | Exact arithmetic computation |
|
||
| **Timeliness** | 8/10 | First bar valid; no warmup |
|
||
| **Smoothness** | 9/10 | Inherently smoothed by averaging |
|
||
| **Noise Filtering** | 6/10 | Moderate; better with more observations |
|
||
| **Memory** | 10/10 | O(1) constant regardless of history |
|
||
|
||
## Validation
|
||
|
||
| Library | Status | Notes |
|
||
| :--- | :---: | :--- |
|
||
| **TA-Lib** | N/A | Not implemented (VWAP variants only) |
|
||
| **Skender** | N/A | Not implemented |
|
||
| **Tulip** | N/A | Not implemented |
|
||
| **Ooples** | N/A | Not implemented |
|
||
| **PineScript** | ✅ | Reference implementation available |
|
||
|
||
TWAP is straightforward enough that validation focuses on internal consistency between streaming, batch, and span modes (verified with 1e-9 tolerance) and formula correctness against manual calculations.
|
||
|
||
## Common Pitfalls
|
||
|
||
1. **Period Selection**: For intraday trading, set period to match your session length (e.g., 390 for regular US equity session in 1-minute bars). Period = 0 creates a cumulative average that becomes increasingly stable—useful for long-term benchmarks but less responsive for intraday analysis.
|
||
|
||
2. **HLC3 vs Close**: TWAP uses typical price (HLC3), not close. This better represents the average traded price within each bar but may differ from close-only implementations in other platforms.
|
||
|
||
3. **Initial Value**: The first bar's TWAP equals that bar's typical price. Unlike moving averages, there's no "warmup" period where values are unreliable.
|
||
|
||
4. **Comparing Across Sessions**: TWAP values are only meaningful within their session context. Comparing TWAP from yesterday to TWAP from today without considering the reset boundary leads to incorrect conclusions.
|
||
|
||
5. **TValue Limitations**: When using `Update(TValue)`, you're providing a single price rather than OHLC data. The implementation uses this price directly. For proper TWAP from bar data, use `Update(TBar)`.
|
||
|
||
6. **Cumulative Nature**: With period = 0, TWAP becomes increasingly stable as more observations accumulate. After 1000 bars, a new bar changes TWAP by only ~0.1%. Consider whether you need this stability or session-based freshness.
|
||
|
||
7. **Reset Timing**: Period resets occur when the bar count exceeds the period. With period = 5, the 6th bar starts a new session. The reset is on boundary crossing, not modular arithmetic.
|
||
|
||
8. **isNew Parameter**: Bar correction (isNew = false) properly restores state including accumulated sum and count. Incorrect implementation causes cumulative drift in TWAP values.
|
||
|
||
## Interpretation Guide
|
||
|
||
### Execution Quality Analysis
|
||
|
||
| Execution Price vs TWAP | Interpretation |
|
||
| :--- | :--- |
|
||
| Buy below TWAP | Good execution (bought cheaper than average) |
|
||
| Buy above TWAP | Poor execution (paid premium) |
|
||
| Sell above TWAP | Good execution (sold higher than average) |
|
||
| Sell below TWAP | Poor execution (sold at discount) |
|
||
|
||
### Trend Analysis
|
||
|
||
| Price Position | Market State |
|
||
| :--- | :--- |
|
||
| Price consistently above TWAP | Bullish session; buyers dominating |
|
||
| Price consistently below TWAP | Bearish session; sellers dominating |
|
||
| Price oscillating around TWAP | Range-bound; equilibrium |
|
||
| Price diverging from TWAP | Trend acceleration |
|
||
|
||
### TWAP as Support/Resistance
|
||
|
||
In intraday trading, TWAP often acts as dynamic support/resistance:
|
||
|
||
- Uptrend: TWAP provides support; pullbacks to TWAP are buying opportunities
|
||
- Downtrend: TWAP provides resistance; rallies to TWAP are selling opportunities
|
||
- Range: Price reverts to TWAP; fade moves away from it
|
||
|
||
### Algorithmic Execution Benchmark
|
||
|
||
For TWAP execution algorithms:
|
||
|
||
- **Slippage** = Actual Avg Price - TWAP
|
||
- **Positive slippage** (for buys): Paid more than benchmark
|
||
- **Negative slippage** (for buys): Paid less than benchmark
|
||
|
||
Target: Minimize absolute slippage to achieve the unbiased average price.
|
||
|
||
## Parameter Selection Guide
|
||
|
||
| Use Case | Period Setting | Rationale |
|
||
| :--- | :--- | :--- |
|
||
| Intraday benchmarking | Session length | Fresh TWAP each session |
|
||
| Multi-day analysis | 0 (continuous) | Cumulative average |
|
||
| Hourly benchmarks | 60 (for 1-min bars) | Reset every hour |
|
||
| Weekly analysis | Bars per week | Weekly TWAP cycles |
|
||
| Custom intervals | As needed | Match your trading horizon |
|
||
|
||
### Session Length Examples
|
||
|
||
| Market | Bars per Session (1-min) |
|
||
| :--- | :--- |
|
||
| US Equities (Regular) | 390 |
|
||
| US Futures (23-hour) | 1380 |
|
||
| Forex (24-hour) | 1440 |
|
||
| Crypto (24-hour) | 1440 |
|
||
|
||
## References
|
||
|
||
- Almgren, R., & Chriss, N. (2001). "Optimal Execution of Portfolio Transactions." *Journal of Risk*.
|
||
- Berkowitz, S., Logue, D., & Noser, E. (1988). "The Total Cost of Transactions on the NYSE." *Journal of Finance*.
|
||
- Kissell, R., & Glantz, M. (2003). *Optimal Trading Strategies*. AMACOM.
|
||
- TradingView. "PineScript TWAP Implementation." Community Scripts. |