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
- 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) |
| **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) |