Indicator TutorialPine Script v5

How to Create Pivot Points on TradingView

Pull clean daily anchors into any timeframe and plot PP, support, and resistance levels.

Pivot points translate the previous session range into intraday reference levels. This guide explains the Standard formulas, popular variants, and a complete Pine Script v5 example that fetches daily OHLC with request.security so your pivots stay consistent on lower timeframes.

What Are Pivot Points?

Pivot points are intraday support and resistance levels derived from a prior period’s high, low, and close—usually the previous regular session on daily charts.

The Standard pivot set includes the central pivot (PP), three resistance levels (R1–R3), and three support levels (S1–S3). Traders use them for mean reversion, breakout confirmation, and risk placement.

Alternative families—Fibonacci, Woodie, and Camarilla—reuse the same inputs but apply different weightings to open, high, low, and close.

Why Traders Use This Indicator

  • Objective levels reset each session, reducing discretionary line drawing.
  • Widely watched levels can cluster order flow around PP and R1/S1.
  • Works across equities, futures, and FX when session boundaries are defined.
  • Complements trend tools by framing mean-reversion zones inside a range day.
  • Easy to automate in Pine Script once daily OHLC is sourced reliably.
ParameterDefaultDescription
Prior high / low / closeDailyClassic pivots use the previous completed session’s high, low, and close.
Standard PP(H + L + C) / 3Central pivot balancing the full prior range.
Standard R1 / S12*PP - L / 2*PP - HFirst ring of resistance and support around the pivot.
Timezone / sessionExchangeDaily bar definition must match your broker for pivots to align with the crowd.

How Pivot Math Maps to Price

Standard

  • PP = (High + Low + Close) / 3
  • R1 = 2×PP − Low, S1 = 2×PP − High
  • R2 = PP + (High − Low), S2 = PP − (High − Low)
  • R3 = High + 2×(PP − Low), S3 = Low − 2×(High − PP)

Fibonacci scales the prior range by 0.382, 0.618, and 1.000 from PP toward H/L.

Woodie emphasizes the open: PP = (H + L + 2×O) / 4 with adjusted R/S formulas.

Camarilla uses tighter coefficients (often 1.1/1.1, 1.1/1.2, etc.) on the range for intraday mean reversion.

Signal Interpretation

Range bias: Fade moves into R3/S3 only when broader context suggests balance; respect trend days when price holds beyond R2/S2.

Breakout bias: A decisive close beyond R1 or S1 with expanding range can target R2/S2 next.

PP as magnet: On neutral days, price often revisits PP; combine with volume to judge acceptance or rejection.

Combining with Other Indicators

Use pivots with VWAP for session context: agreement between daily PP and VWAP adds confluence.

Add ATR bands or Keltner channels to avoid trading every touch of a pivot in volatile markets.

The Hard Way: Writing Pine Script Manually

Challenges of Manual Coding

Choosing the correct daily symbol and session for request.security.

Preventing lookahead by using completed daily bars only ([1] on daily series).

Plotting levels as horizontal lines that update cleanly at the day rollover.

Supporting multiple pivot variants without duplicating large formula blocks.

Handling markets with different session cuts (crypto vs RTH equities).

Pine Script v5
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify — Standard Pivot Points with daily OHLC via request.security

//@version=5
indicator("Standard Pivot Points (Daily)", shorttitle="Pivots D1", overlay=true)

grp = "Data source"
sym = input.symbol("", "Symbol (blank = chart)", group=grp)
tf = input.timeframe("D", "Higher timeframe", group=grp)

// Prior completed daily bar OHLC on chosen symbol/timeframe
[dHigh, dLow, dClose, dOpen] = request.security(
     sym,
     tf,
     [high[1], low[1], close[1], open[1]],
     gaps=barmerge.gaps_off,
     lookahead=barmerge.lookahead_off)

pp = (dHigh + dLow + dClose) / 3.0
r1 = 2.0 * pp - dLow
s1 = 2.0 * pp - dHigh
r2 = pp + (dHigh - dLow)
s2 = pp - (dHigh - dLow)
r3 = dHigh + 2.0 * (pp - dLow)
s3 = dLow - 2.0 * (dHigh - pp)

showLabels = input.bool(true, "Show end labels")

plot(pp, color=color.new(color.yellow, 0), title="PP", linewidth=2)
plot(r1, color=color.new(color.red, 30), title="R1")
plot(r2, color=color.new(color.red, 10), title="R2")
plot(r3, color=color.new(color.red, 0), title="R3")
plot(s1, color=color.new(color.teal, 30), title="S1")
plot(s2, color=color.new(color.teal, 10), title="S2")
plot(s3, color=color.new(color.teal, 0), title="S3")

// Optional: show prior open for context
plot(dOpen, color=color.new(color.gray, 60), title="Prior D Open", linewidth=1, style=plot.style_circles)

// Midpoints between levels (optional intraday guides)
mR = (pp + r1) / 2.0
mS = (pp + s1) / 2.0
plot(mR, color=color.new(color.orange, 70), title="PP-R1 mid", linewidth=1)
plot(mS, color=color.new(color.blue, 70), title="PP-S1 mid", linewidth=1)

// Simple touch markers (educational)
touchPP = ta.crossunder(low, pp) or ta.crossover(high, pp)
plotshape(touchPP, title="PP touch", style=shape.circle, location=location.abovebar, size=size.tiny, color=color.new(color.yellow, 40))

// New day detection on chart timeframe
newDay = ta.change(time("D")) != 0
if newDay and showLabels
    label.new(bar_index, pp, "PP", style=label.style_label_left, color=color.new(color.yellow, 80), textcolor=color.black, size=size.small)

// Table: last bar snapshot
var table t = table.new(position.bottom_right, 2, 8, border_width=1)
if barstate.islast
    table.cell(t, 0, 0, "Prior H", text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 1, 0, str.tostring(dHigh, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 0, 1, "Prior L", text_color=color.white, bgcolor=color.new(color.gray, 75))
    table.cell(t, 1, 1, str.tostring(dLow, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 75))
    table.cell(t, 0, 2, "Prior C", text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 1, 2, str.tostring(dClose, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 0, 3, "PP", text_color=color.white, bgcolor=color.new(color.gray, 75))
    table.cell(t, 1, 3, str.tostring(pp, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 75))
    table.cell(t, 0, 4, "R1", text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 1, 4, str.tostring(r1, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 0, 5, "S1", text_color=color.white, bgcolor=color.new(color.gray, 75))
    table.cell(t, 1, 5, str.tostring(s1, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 75))
    table.cell(t, 0, 6, "R2", text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 1, 6, str.tostring(r2, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 65))
    table.cell(t, 0, 7, "S2", text_color=color.white, bgcolor=color.new(color.gray, 75))
    table.cell(t, 1, 7, str.tostring(s2, format.mintick), text_color=color.white, bgcolor=color.new(color.gray, 75))

alertcondition(ta.crossover(close, r1), title="Close crosses above R1", message="Price crossed above R1")
alertcondition(ta.crossunder(close, s1), title="Close crosses below S1", message="Price crossed below S1")

Maintenance Note: If your pivots disagree with a reference site, compare session (ETH vs RTH), timezone, and whether the reference uses the current developing daily bar versus the prior completed bar. Keep lookahead_off when sourcing higher timeframes.

The Easy Way: Build with Pineify Visual Editor

What if you could create the same indicator without writing a single line of code? Pineify is a visual editor designed for TradingView users who want professional-grade indicators through an intuitive interface.

FeatureManual Pine ScriptPineify Visual Editor
Daily data wiringrequest.security tuple + [1] indexing is easy to get subtly wrong.Higher-timeframe helpers reduce security() mistakes.
Multiple pivot typesEach variant duplicates formulas and inputs.Parameterized templates keep variants consistent.
Visual clutterSeven levels plus mids can overwhelm the chart.Toggle groups and styling presets simplify UX.
AlertsMust wire alertcondition per level and direction.Reusable alert patterns speed deployment.
PortabilityHard-coded symbol strings break on different feeds.Defaults follow chart symbol with optional override.

Faster pivot variants without copying long math blocks.

Cleaner organization of session and symbol inputs.

Consistent labeling for SEO-friendly published scripts.

Easier collaboration when non-coders adjust levels or colors.

Lower risk of lookahead when composing multi-timeframe logic.

Step-by-Step Tutorial

1

Define the anchor timeframe

Choose daily (or week) as the pivot source and document the session.

2

Pull prior OHLC with security

Use request.security with [1] on the HTF series and lookahead_off.

3

Compute Standard PP and R/S

Implement PP, R1–R3, S1–S3 from the classic textbook formulas.

4

Plot as continuous series

Plot functions will carry levels forward until the next anchor update.

5

Add optional variants

Layer Fibonacci, Woodie, or Camarilla as toggled calculations.

6

Validate against a benchmark

Compare to a trusted pivot table for one symbol on a known session.

7

Ship alerts

Expose alerts for breaks of PP, R1, and S1 matching your playbook.

Trading Strategies & Pro Tips

PP bounce

Fade shallow moves back toward PP when overnight trend is flat and volume declines at extremes.

Pro Tip: Require a rejection candle rather than touching the level alone.

R1/S1 breakout

Enter with the break of R1 or S1 when opening range supports a trend day.

Camarilla mean reversion

Use Camarilla H3/L3 style reactions for short-term reversions inside the day.

Confluence scalps

Trade only when PP aligns with VWAP and a visible swing level.

Common Mistakes to Avoid

  • Using the developing daily bar instead of the prior completed session.
  • Leaving lookahead_on when pulling higher timeframe data.
  • Mixing ETH pivots with RTH chart data without noticing.
  • Plotting too many variants simultaneously without opacity controls.
  • Forgetting extended hours prints change highs/lows vs cash session.

Frequently Asked Questions

Automate pivot logic with Pineify

  • Generate clean Standard, Woodie, and Camarilla blocks from one spec.
  • Reduce security() boilerplate when sourcing daily anchors.
  • Ship readable, maintainable scripts for clients and communities.

Disclaimer: Trading involves significant risk. The indicators, code, and strategies provided are for educational purposes only and do not constitute financial advice. Past performance is not indicative of future results.