# 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.