PSX glossary

Circuit breaker (PSX)

How the Pakistan Stock Exchange's per-symbol price limits work, and how to detect a locked stock in Python with pypsx.

pyPSX· 13 July 2026· 1 min read

A circuit breaker halts or caps trading in a security when its price moves too far in a session. It’s a volatility control, not a value judgment.

At PSX specifically

PSX applies a per-scrip price band measured from the previous day’s close. When a stock hits the upper or lower band it is said to be “locked” (locked at upper / locked at lower), bids or offers pile up at the limit but the price can’t move past it until the next session. This is different from a US-style market-wide halt: on PSX the limit is symbol-by-symbol, and index-wide halts are a separate, rarer mechanism. Settlement runs T+1 through NCCPL.

Because the band is anchored to the previous close, you can detect a locked day directly from OHLCV: on a lock, the day’s high (upper lock) or low (lower lock) sits right at the band and the close pins to it.

Detect it in Python

import pypsx

df = pypsx.download("OGDC", period="1y")

# Approx band (PSX commonly uses ~7.5%; treat as illustrative, not exact).
BAND = 0.075
prev_close = df["Close"].shift(1)
upper = prev_close * (1 + BAND)
lower = prev_close * (1 - BAND)

locked_up = df["Close"] >= upper - 1e-9
locked_down = df["Close"] <= lower + 1e-9

print("Days locked at upper:", int(locked_up.sum()))
print("Days locked at lower:", int(locked_down.sum()))

Use this to filter out days where a fill at the close would have been impossible - important when you backtest, because a signal on a locked-up day can’t actually be bought at that price.