Black-Scholes Pricing & Greeks¶
Option price, delta, gamma, theta, vega — ported from the site's pricer.
Part 06 of 37 in the ServLoci algo/options trading notebook series — full index in notebooks/README.md.
Setup¶
# Get your dedicated static IPv6 + SOCKS5 credentials free:
# https://comm.servloci.in/register (or /auth/google?free=1 for an instant trial)
# Your api_key / api_secret pair shows up in the portal after signup:
# https://comm.servloci.in/user
!pip install -q "requests[socks]"
!curl -sL https://comm.servloci.in/sdk/servloci.py -o servloci.py
import os
from servloci import ServLoci
SERVLOCI_API_KEY = os.environ.get("SERVLOCI_API_KEY", "dhan:1000000001") # broker:client_id
SERVLOCI_API_SECRET = os.environ.get("SERVLOCI_API_SECRET", "") # from the portal — leave blank to run this notebook in demo mode
sl = None
if SERVLOCI_API_SECRET:
sl = ServLoci(api_key=SERVLOCI_API_KEY, api_secret=SERVLOCI_API_SECRET)
print("ServLoci configured:", sl.host, sl.port)
else:
print("SERVLOCI_API_SECRET not set — running in demo mode (no live proxy calls).")
Why option pricing needs a model¶
A stock has one obvious "fair value" input: the price someone will pay for it right now. An option doesn't — its value depends on where the underlying might go before expiry, how much time is left, and how uncertain the market is about that path. Black-Scholes (1973) was the first widely-used formula to turn those inputs — spot, strike, time to expiry, volatility, and the risk-free rate — into a single price, and it's still the reference model every Indian index-options trader is quoted against, even when the market's own price has drifted from it.
Python port of shared/lib/blackScholes.js — the exact pricer behind /tools/strategy-builder, swapping the hand-rolled erf approximation for scipy.stats.norm.
from scipy.stats import norm
import math
def bs_price(opt_type, spot, strike, t_years, vol, rate=0.065):
if t_years <= 0 or vol <= 0:
return max(spot - strike, 0) if opt_type == "CE" else max(strike - spot, 0)
d1 = (math.log(spot / strike) + (rate + vol * vol / 2) * t_years) / (vol * math.sqrt(t_years))
d2 = d1 - vol * math.sqrt(t_years)
if opt_type == "CE":
return spot * norm.cdf(d1) - strike * math.exp(-rate * t_years) * norm.cdf(d2)
return strike * math.exp(-rate * t_years) * norm.cdf(-d2) - spot * norm.cdf(-d1)
def greeks(opt_type, spot, strike, t_years, vol, rate=0.065):
if t_years <= 0 or vol <= 0:
return {"delta": 0, "gamma": 0, "theta": 0, "vega": 0}
d1 = (math.log(spot / strike) + (rate + vol * vol / 2) * t_years) / (vol * math.sqrt(t_years))
d2 = d1 - vol * math.sqrt(t_years)
nd1 = norm.pdf(d1)
delta = norm.cdf(d1) if opt_type == "CE" else norm.cdf(d1) - 1
gamma = nd1 / (spot * vol * math.sqrt(t_years))
vega = (spot * nd1 * math.sqrt(t_years)) / 100 # per 1% vol move
term1 = -(spot * nd1 * vol) / (2 * math.sqrt(t_years))
if opt_type == "CE":
theta = (term1 - rate * strike * math.exp(-rate * t_years) * norm.cdf(d2)) / 365
else:
theta = (term1 + rate * strike * math.exp(-rate * t_years) * norm.cdf(-d2)) / 365
return {"delta": delta, "gamma": gamma, "theta": theta, "vega": vega}
spot, strike, t_years, vol = 24000, 24000, 7 / 365, 0.13
print("CE price:", round(bs_price("CE", spot, strike, t_years, vol), 2))
print("CE greeks:", {k: round(v, 4) for k, v in greeks("CE", spot, strike, t_years, vol).items()})
Reading the Greeks like a trader, not a mathematician¶
- Delta is the option's directional exposure — an ATM call near 0.5 delta behaves like half a share; a deep ITM call near 1.0 behaves like a full share. Traders use delta as a rough hedge ratio ("I'm short 3 lots at 0.4 delta, so I'm short the equivalent of ~1.2 lots of the underlying") and as a proxy for probability-of-finishing-ITM.
- Gamma measures how fast delta itself moves. Gamma is highest for ATM options in the final days before expiry — this is why weekly index-option sellers get nervous into expiry day: a small spot move near the strike can flip an option's delta (and the position's effective exposure) very quickly, which is the mechanism behind "gamma risk" blowups.
- Theta is time decay, quoted per day. It's the reason option selling is a business model on its own: every day that passes without the underlying moving, a short option collects theta as pure carry — as long as gamma doesn't overwhelm it first.
- Vega is exposure to implied volatility itself, independent of direction. Buying an option before an event (RBI policy, results, budget day) is often a bet on vega — IV expands going in — followed by the well-known "IV crush" once the event passes and uncertainty resolves.
Black-Scholes assumes continuous trading, a constant known volatility, and log-normal returns — none of which hold exactly for NSE index options. In practice: volatility is not constant across strikes (see notebook 12's IV skew), gaps happen overnight and around events (violating the "continuous price path" assumption), and the model has no view on liquidity or bid-ask spread. Traders use Black-Scholes as a common quoting language, not as ground truth — the market's own price, not the model's, is what you actually pay or receive.
« Previous: Broker Auth: Fyers
Next: Option Payoff & Breakeven Calculator »
Try the concepts above interactively: Options Strategy Builder · Docs · Get your static IP