Black-Scholes Pricing & Greeks¶
Option price, delta, gamma, theta, vega — ported from the site's pricer.
Part 06 of 20 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).")
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()})
« Previous: Broker Auth: Fyers
Next: Option Payoff & Breakeven Calculator »
Try the concepts above interactively: Options Strategy Builder · Docs · Get your static IP