What it measures
Pivot points are price levels calculated from the previous period's high, low and close. The central pivot (P) is a kind of average of that period, and the resistance (R1, R2, R3) and support (S1, S2, S3) levels sit at distances derived from its range. Because everyone using the same formula gets the same levels, they are widely watched, especially by intraday traders.
They come from floor traders, who calculated the day's levels by hand before the open. Several formulas exist; classic, Fibonacci, Camarilla and Woodie are the most common.
The formula in words
Let H, L and C be the previous period's high, low and close, and range = H − L.
| Type | Pivot (P) | R1 and S1 | Further levels |
|---|---|---|---|
| Classic | (H + L + C) ÷ 3 | R1 = 2P − L, S1 = 2P − H | R2/S2 = P ± range; R3 = H + 2(P − L), S3 = L − 2(H − P) |
| Fibonacci | (H + L + C) ÷ 3 | P ± 0.382 × range | P ± 0.618 × range, P ± range |
| Camarilla | (H + L + C) ÷ 3 | C ± range × 1.1 ÷ 12 | C ± range × 1.1 ÷ 6, C ± range × 1.1 ÷ 4 |
| Woodie | (H + L + 2C) ÷ 4 | As classic | As classic |
Camarilla levels are centred on the close rather than the pivot, and sit much closer together. Some Woodie variants use the current period's open instead of the previous close. The pivot point calculator gives the same levels for any high, low and close.
How traders read it
- Bias. Price above P is read as a bullish session, below P as bearish. The first test of P after the open is often watched.
- Reaction levels. R1 and S1 are the levels reached most often on a typical day; R2/S2 and R3/S3 come into play on wider-range days. Traders look for rejections at a level or closes through it.
- Breakouts. A close above R1 (or below S1) early in the session is read as a strong day developing. The script has alerts for both.
- Camarilla. Camarilla users often fade moves to the third level and treat a break of the fourth level (C ± range × 1.1 ÷ 2) as a trend day. The script draws three levels on each side.
- Weekly and monthly. Swing traders use pivots from the previous week or month as slower reference levels.
Common settings
| Setting | Typical value | Notes |
|---|---|---|
| Period | Day for intraday charts | Week for hourly charts, month for daily charts. |
| Type | Classic | Camarilla for tighter intraday levels. |
| Levels shown | R1/S1 to R3/S3 | The outer levels are rarely reached on quiet days. |
For markets that trade around the clock, the "previous day" depends on where the data feed starts its session; for forex this is often 17:00 New York time. The market hours tool shows the main sessions in your time zone.
Pine Script v6 code
The complete, self-contained script is below. Copy it into a new indicator in TradingView's Pine Editor, or download the .pine file.
//@version=6
indicator("Pivot points: classic, Fibonacci, Camarilla, Woodie", shorttitle = "Pivots", overlay = true, max_labels_count = 50)
pType = input.string("Classic", "Type", options = ["Classic", "Fibonacci", "Camarilla", "Woodie"], group = "Pivots")
period = input.string("Day", "From the previous", options = ["Day", "Week", "Month"], group = "Pivots")
showR3 = input.bool(true, "Show R3 and S3", group = "Display")
showLbl = input.bool(true, "Label the levels on the last bar", group = "Display")
resCol = input.color(color.red, "Resistance", group = "Display")
supCol = input.color(color.teal, "Support", group = "Display")
pCol = input.color(color.orange, "Pivot", group = "Display")
tf = period == "Week" ? "W" : period == "Month" ? "M" : "D"
newPeriod = timeframe.change(tf)
// Track the current period's high and low; when a new period starts, freeze the finished period's high, low and close.
var float curHigh = na
var float curLow = na
var float prevHigh = na
var float prevLow = na
var float prevClose = na
var int periods = 0
if newPeriod
periods += 1
prevHigh := curHigh
prevLow := curLow
prevClose := close[1]
curHigh := high
curLow := low
else
curHigh := math.max(nz(curHigh, high), high)
curLow := math.min(nz(curLow, low), low)
// The first period on the chart is usually incomplete, so levels start after the second period change.
ready = periods >= 2
H = prevHigh
L = prevLow
C = prevClose
R = H - L
float pp = na
float r1 = na
float s1 = na
float r2 = na
float s2 = na
float r3 = na
float s3 = na
if pType == "Fibonacci"
pp := (H + L + C) / 3
r1 := pp + 0.382 * R
s1 := pp - 0.382 * R
r2 := pp + 0.618 * R
s2 := pp - 0.618 * R
r3 := pp + R
s3 := pp - R
else if pType == "Camarilla"
pp := (H + L + C) / 3
r1 := C + R * 1.1 / 12
s1 := C - R * 1.1 / 12
r2 := C + R * 1.1 / 6
s2 := C - R * 1.1 / 6
r3 := C + R * 1.1 / 4
s3 := C - R * 1.1 / 4
else
// Classic, or Woodie, which counts the previous close twice.
pp := pType == "Woodie" ? (H + L + 2 * C) / 4 : (H + L + C) / 3
r1 := 2 * pp - L
s1 := 2 * pp - H
r2 := pp + R
s2 := pp - R
r3 := H + 2 * (pp - L)
s3 := L - 2 * (H - pp)
// Hide the first bar of each period on intraday charts so the lines break instead of jumping.
gap = newPeriod and timeframe.in_seconds() < timeframe.in_seconds(tf)
show = ready and not gap
plot(show ? pp : na, "P", color = pCol, linewidth = 2, style = plot.style_linebr)
plot(show ? r1 : na, "R1", color = resCol, style = plot.style_linebr)
plot(show ? s1 : na, "S1", color = supCol, style = plot.style_linebr)
plot(show ? r2 : na, "R2", color = color.new(resCol, 30), style = plot.style_linebr)
plot(show ? s2 : na, "S2", color = color.new(supCol, 30), style = plot.style_linebr)
plot(show and showR3 ? r3 : na, "R3", color = color.new(resCol, 55), style = plot.style_linebr)
plot(show and showR3 ? s3 : na, "S3", color = color.new(supCol, 55), style = plot.style_linebr)
tag(float y, string txt, color col) =>
label.new(bar_index + 1, y, txt, style = label.style_label_left, color = color.new(col, 100), textcolor = col, size = size.small)
var array<label> tags = array.new<label>()
if barstate.islast
for t in tags
t.delete()
tags.clear()
if showLbl and ready
tags.push(tag(pp, "P", pCol))
tags.push(tag(r1, "R1", resCol))
tags.push(tag(s1, "S1", supCol))
tags.push(tag(r2, "R2", resCol))
tags.push(tag(s2, "S2", supCol))
if showR3
tags.push(tag(r3, "R3", resCol))
tags.push(tag(s3, "S3", supCol))
aboveR1 = ta.crossover(close, r1)
belowS1 = ta.crossunder(close, s1)
aboveP = ta.crossover(close, pp)
belowP = ta.crossunder(close, pp)
alertcondition(ready and aboveR1, "Close above R1", "{{ticker}} closed above R1 ({{interval}})")
alertcondition(ready and belowS1, "Close below S1", "{{ticker}} closed below S1 ({{interval}})")
alertcondition(ready and aboveP, "Close above the pivot", "{{ticker}} closed above the pivot point ({{interval}})")
alertcondition(ready and belowP, "Close below the pivot", "{{ticker}} closed below the pivot point ({{interval}})")The script tracks the high and low of the current period bar by bar and, when a new day, week or month starts, freezes the finished period's high, low and close. The levels are then fixed for the whole new period, so nothing is recalculated in hindsight and no higher-timeframe request is needed. Levels start after the first complete period on the chart, and labels mark them on the last bar.
Alert conditions fire on a close above R1, a close below S1, and closes across the pivot. The period's high and low come from the bars on your chart, so if your chart includes or excludes extended hours, the levels follow that setting.
Add it to your chart
- Open any chart on TradingView and open the Pine Editor.
- Create a new indicator, delete the template code and paste the script.
- Click Save, then Add to chart. Change lengths and levels from the indicator's settings.
Stuck on an error? See how to add a Pine Script indicator to TradingView.
Pitfalls
- Different data, different levels. Pivots from a chart with extended-hours bars differ from pivots built on regular-session bars only, and brokers' daily candles can start at different times.
- Treating levels as walls. Pivot levels are reference points, not guaranteed support or resistance. Price passes through them every day.
- Too many levels. With several formulas and periods on one chart, some level is always nearby. Pick one formula and one period.
- Daily pivots on daily bars. Each bar is its own period, so the levels change on every bar. Use an intraday chart, or weekly or monthly pivots.
Related reading
- Multi-timeframe Pine Script with request.security(), without repainting
- What AI chart analysis can (and can't) do for your trading
- Pivot Point Calculator (free tool)
- Forex Market Hours (free tool)
- Fibonacci Retracement Calculator (free tool)
The script is an educational example: test it on your own markets before relying on it. Indicators describe the past; they don't predict the future. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.