Pivot Points

Haiyue
13min

Pivot Points

Indicator Overview
  • Category: Trend — Overlay Indicator
  • Default Parameters: None (uses the previous trading period’s OHLC data)
  • Output: Pivot point P and three sets of support/resistance levels (S1-S3, R1-R3)
  • Applicable Markets: Stocks, Futures, Forex (especially suited for intraday trading)

I. What are Pivot Points

Pivot Points are one of the oldest and most classic support/resistance calculation methods in financial markets, originating from the daily practices of floor traders. Before electronic trading became widespread, floor traders at the Chicago Mercantile Exchange would manually calculate the day’s key price levels before the open using the previous day’s high, low, and close.

This method can be traced back to the mid-20th century in the U.S. futures markets. Because it requires no subjective parameter settings and is simple to compute, pivot points remain widely used by traders worldwide. They are especially common as reference price levels in forex and futures intraday trading.

Core Philosophy

The pivot point system is based on a straightforward statistical observation: the previous trading day’s price range has significant reference value for current-day price behavior. The central pivot point P represents the previous day’s “fair price,” and the support/resistance levels derived from it mark key zones where buying and selling forces are likely to exchange.

Different Types of Pivot Points

Besides the standard (Classic) pivot points, there are Fibonacci, Woodie, Camarilla, and DeMark pivot point variants. This article focuses on the most commonly used Standard Pivot Points.

II. Mathematical Principles and Calculation

Standard Pivot Point Formulas

Let the previous trading period’s high be HH, low be LL, and close be CC.

Central Pivot Point:

P=H+L+C3P = \frac{H + L + C}{3}

First Support/Resistance Level:

R1=2PLR_1 = 2P - L

S1=2PHS_1 = 2P - H

Second Support/Resistance Level:

R2=P+(HL)R_2 = P + (H - L)

S2=P(HL)S_2 = P - (H - L)

Third Support/Resistance Level:

R3=H+2(PL)R_3 = H + 2(P - L)

S3=L2(HP)S_3 = L - 2(H - P)

Formula Derivation Logic

R1R_1 and S1S_1 derivation: Using PP as the axis, the distance from PP to the previous day’s extreme is mirrored to the other side.

  • R1=2PL=P+(PL)R_1 = 2P - L = P + (P - L), i.e., P plus the distance from P to the low
  • S1=2PH=P(HP)S_1 = 2P - H = P - (H - P), i.e., P minus the distance from the high to P

R2R_2 and S2S_2 introduce the previous day’s full range (HL)(H - L):

  • R2=P+(HL)R_2 = P + (H - L), the pivot point plus one full range
  • S2=P(HL)S_2 = P - (H - L), the pivot point minus one full range

R3R_3 and S3S_3 extend further, representing support/resistance for extreme scenarios.

Spacing Relationship Between Levels

R1P=PS1=PL+HP=asymmetricR_1 - P = P - S_1 = P - L + H - P = \text{asymmetric}

Note

Pivot point support and resistance levels are not necessarily symmetrically distributed. When the previous day’s close is biased toward the high or low end, P will deviate from the midpoint, causing unequal spacing between support/resistance levels. This is precisely why pivot points can reflect the market’s bullish/bearish bias.

Calculation Steps

  1. Obtain the previous trading period’s (typically previous trading day’s) High, Low, and Close
  2. Calculate the central pivot point PP
  3. Sequentially calculate R1/S1, R2/S2, and R3/S3
  4. Plot these 7 price levels as horizontal reference lines for the current day

III. Python Implementation

import numpy as np
import pandas as pd

def pivot_points(df: pd.DataFrame) -> pd.DataFrame:
    """
    Calculate standard pivot points (using previous trading day's OHLC).

    Parameters
    ----------
    df : DataFrame, must contain 'high', 'low', 'close' columns,
         with a date index where each row represents one trading day.

    Returns
    ----------
    DataFrame with P, R1, S1, R2, S2, R3, S3 columns.
    Each row's pivot points are based on that row's (previous day's) data,
    applicable to the next trading day.
    """
    high = df['high']
    low = df['low']
    close = df['close']

    # Central pivot point
    p = (high + low + close) / 3

    # First support/resistance level
    r1 = 2 * p - low
    s1 = 2 * p - high

    # Second support/resistance level
    r2 = p + (high - low)
    s2 = p - (high - low)

    # Third support/resistance level
    r3 = high + 2 * (p - low)
    s3 = low - 2 * (high - p)

    result = pd.DataFrame({
        'P': p,
        'R1': r1, 'S1': s1,
        'R2': r2, 'S2': s2,
        'R3': r3, 'S3': s3
    }, index=df.index)

    # Shift forward by one period: today's pivot points are based on yesterday's data
    result = result.shift(1)

    return result


def pivot_points_intraday(daily_df: pd.DataFrame,
                          intraday_df: pd.DataFrame) -> pd.DataFrame:
    """
    Map daily pivot points onto intraday minute data.

    Parameters
    ----------
    daily_df : Daily DataFrame, must contain 'high', 'low', 'close' columns
    intraday_df : Intraday DataFrame with DatetimeIndex

    Returns
    ----------
    Intraday DataFrame with pivot point columns appended
    """
    pivots = pivot_points(daily_df)

    # Merge daily pivot points into intraday data by date
    intraday_df = intraday_df.copy()
    intraday_df['date'] = intraday_df.index.date

    pivots_reset = pivots.copy()
    pivots_reset['date'] = pivots_reset.index.date

    merged = intraday_df.merge(pivots_reset, on='date', how='left', suffixes=('', '_pivot'))
    merged.index = intraday_df.index
    merged.drop(columns=['date'], inplace=True)

    return merged


# ========== Usage Example ==========
if __name__ == "__main__":
    np.random.seed(42)
    n = 60
    dates = pd.date_range('2024-01-01', periods=n, freq='B')

    # Simulate daily OHLCV data
    price = 100 + np.cumsum(np.random.randn(n) * 1.0)
    high_arr = price + np.abs(np.random.randn(n)) * 2.0
    low_arr = price - np.abs(np.random.randn(n)) * 2.0

    df = pd.DataFrame({
        'open':  price + np.random.uniform(-0.5, 0.5, n),
        'high':  high_arr,
        'low':   low_arr,
        'close': price + np.random.uniform(-0.5, 0.5, n),
        'volume': np.random.randint(1000, 5000, n)
    }, index=dates)

    # Calculate pivot points
    pivots = pivot_points(df)
    merged = df.join(pivots)

    print("Pivot points for the last 10 trading days:")
    print(merged[['close', 'P', 'R1', 'S1', 'R2', 'S2', 'R3', 'S3']].tail(10).to_string())

    # Determine closing price position relative to pivot point
    merged['position'] = 'neutral'
    merged.loc[merged['close'] > merged['R1'], 'position'] = 'above_R1'
    merged.loc[merged['close'] < merged['S1'], 'position'] = 'below_S1'
    merged.loc[merged['close'] > merged['R2'], 'position'] = 'above_R2'
    merged.loc[merged['close'] < merged['S2'], 'position'] = 'below_S2'

    print("\nPrice position distribution relative to pivot points:")
    print(merged['position'].value_counts())

    # Evaluate pivot point prediction accuracy: did intraday H/L touch R1/S1
    touched_r1 = (merged['high'] >= merged['R1']).sum()
    touched_s1 = (merged['low'] <= merged['S1']).sum()
    valid = merged['P'].notna().sum()
    print(f"\nPercentage of days touching R1 intraday: {touched_r1/valid:.1%}")
    print(f"Percentage of days touching S1 intraday: {touched_s1/valid:.1%}")

IV. Problems the Indicator Solves

1. Intraday Key Price Level Reference

Pivot points provide intraday traders with support/resistance levels that are determinable before the market opens, without waiting for intraday data to accumulate.

2. Market Bias Assessment

Price PositionMarket Bias
Open > PBullish, watch R1 and R2 as targets
Open < PBearish, watch S1 and S2 as targets
Hovering near PDirection unclear, wait for a breakout

3. Entry and Exit Reference

  • Breakout trading: After price breaks above R1 and pulls back to confirm, go long with R1 as stop-loss, targeting R2
  • Reversal trading: After price touches S2 and a reversal candlestick appears, go long with S2 as stop-loss, targeting P or S1
  • Profit targets: Each support/resistance level naturally serves as a take-profit level

4. Volatility Expectation

R2S2=2(HL)R_2 - S_2 = 2(H-L), which is twice the previous day’s range. If price frequently touches R2/S2, it indicates the current day’s volatility is significantly higher than the previous day.

Classic Floor Trader Rules
  • When price trades above P, lean toward buying
  • When price trades below P, lean toward selling
  • S1 and R1 are the most frequently touched support/resistance levels
  • S3 and R3 are rarely reached; when they are, it typically indicates extreme market conditions

V. Advantages, Disadvantages, and Use Cases

Advantages

  1. Zero parameters: Entirely based on objective prior-period price data, no subjective parameter settings needed
  2. Universal applicability: Works for any market and any timeframe
  3. Pre-computed: Key price levels for the entire day can be determined before the open
  4. Self-fulfilling: Since a large number of traders monitor pivot point levels, these levels themselves become effective support/resistance
  5. Simple calculation: Only basic arithmetic is required

Disadvantages

  1. Static nature: Does not adjust during the day as price changes, unable to adapt to breaking events
  2. No directional signal: Provides only price levels, not trend direction
  3. May fail in strong trends: Strong trend days may blow through all support/resistance levels
  4. Depends on data quality: Abnormal trading days (half-day sessions, gap opens) can distort pivot point calculations
  5. Timezone differences: In the 24-hour forex market, different timezones define “previous day” differently, potentially causing inconsistent pivot point calculations

Use Cases

ScenarioSuitabilityNotes
Futures intraday tradingHighThe classic application for pivot points
Forex intraday tradingHighRequires a unified timezone definition (typically New York close)
Stock intraday tradingMedium-HighClear open/close times make calculation straightforward
Weekly/Monthly analysisMediumWeekly/monthly pivot points can serve as medium-term references
Crypto (24/7)MediumRequires a custom definition of “day” start/end time
Long-term investingLowDaily pivot points hold little significance for long-term positions

Comparison with Similar Indicators

DimensionPivot PointsBollinger BandsIchimoku CloudFixed S/R Levels
Parameter RequirementsNone24Subjective judgment
Dynamic NatureUpdated dailyReal-timeReal-timeManual adjustment
Known in AdvanceBefore openDuring sessionDuring sessionPre-determined
Suitable TimeframePrimarily intradayAnyDaily and aboveAny
Self-Fulfilling NatureStrongMediumMediumDepends on attention

Common Variant Formulas

VariantP CalculationCharacteristics
Classic(H+L+C)/3(H+L+C)/3Most universal
Woodie(H+L+2C)/4(H+L+2C)/4Places more weight on the close
Camarilla(H+L+C)/3(H+L+C)/3 (different R/S formulas)Tighter levels, suited for short-term trading
Fibonacci(H+L+C)/3(H+L+C)/3 (expanded using Fib ratios)Incorporates 38.2%/61.8% ratios
Usage Notes
  • Pivot points work best when combined with other tools (candlestick patterns, volume analysis); do not blindly enter a trade simply because price touches a support/resistance level
  • On major economic data release days or during unexpected events, pivot points lose much of their reference value
  • Forex traders should ensure they use the same daily cutoff time as major brokers (typically 17
    New York time)