Option Payoff & Breakeven Calculator¶
Multi-leg payoff curves, breakevens, and max profit/loss at expiry.
Part 07 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/strategyMath.js — payoff is computed at expiry (intrinsic value only), same as the payoff chart on /tools/strategy-builder.
def leg_payoff_at_expiry(leg, underlying_price):
iv = max(underlying_price - leg["strike"], 0) if leg["type"] == "CE" else max(leg["strike"] - underlying_price, 0)
sign = 1 if leg["side"] == "buy" else -1
return sign * (iv - leg["premium"]) * leg["qty"]
def strategy_payoff_at_expiry(legs, underlying_price):
return sum(leg_payoff_at_expiry(leg, underlying_price) for leg in legs)
def net_premium(legs):
return sum((-1 if leg["side"] == "buy" else 1) * leg["premium"] * leg["qty"] for leg in legs)
def payoff_curve(legs, spot, rng=0.15, steps=120):
lo, hi = spot * (1 - rng), spot * (1 + rng)
pts = []
for i in range(steps + 1):
p = lo + (hi - lo) * i / steps
pts.append({"price": p, "pnl": strategy_payoff_at_expiry(legs, p)})
return pts
def breakevens(points):
crossings = []
for a, b in zip(points, points[1:]):
if (a["pnl"] < 0 <= b["pnl"]) or (a["pnl"] > 0 >= b["pnl"]):
t = 0 if a["pnl"] == b["pnl"] else -a["pnl"] / (b["pnl"] - a["pnl"])
crossings.append(a["price"] + t * (b["price"] - a["price"]))
return crossings
def max_profit_loss(points):
pnls = [p["pnl"] for p in points]
return {"maxProfit": max(pnls), "maxLoss": min(pnls)}
legs = [
{"side": "buy", "type": "CE", "strike": 24000, "premium": 180, "qty": 75},
{"side": "sell", "type": "CE", "strike": 24200, "premium": 90, "qty": 75},
]
points = payoff_curve(legs, spot=24000)
print("Net premium:", net_premium(legs))
print("Breakevens:", breakevens(points))
print("Max P/L:", max_profit_loss(points))
import matplotlib.pyplot as plt
def plot_payoff(points, title):
xs = [p["price"] for p in points]
ys = [p["pnl"] for p in points]
plt.axhline(0, color="grey", linewidth=0.8)
plt.plot(xs, ys)
plt.title(title)
plt.xlabel("Underlying spot")
plt.ylabel("P&L (INR)")
plt.show()
plot_payoff(points, "Bull call spread payoff at expiry")
« Previous: Black-Scholes Pricing & Greeks
Next: Strategy: Straddle & Strangle »
Try the concepts above interactively: Options Strategy Builder · Docs · Get your static IP