
Options Payoff
- 1.9k installs
- 3.1k repo stars
- Updated July 21, 2026
- himself65/finance-skills
options-payoff is an agent skill for plot options payoff diagrams and breakeven analysis for calls and puts.
About
The options-payoff skill is designed for plot options payoff diagrams and breakeven analysis for calls and puts. Current SPX reference price: --- Step 2: Identify Strategy Type Match to one of the supported strategies below, then read the corresponding section in references/strategies.md. Iron Condor Payoff (expiry) --- Step 4: Render the Widget Use visualize:read_me with modules ["chart", "interactive"] before building. Invoke when the user plots options payoff, breakeven, or call/put strategy diagrams.
- Expiry payoff curve (dashed gray line) — intrinsic value at expiration.
- Theoretical value curve (solid colored line) — Black-Scholes price at current DTE/IV.
- Dynamic sliders for all key parameters.
- Real-time stats: max profit, max loss, breakevens, current P&L at spot.
- All strike prices (K1, K2, K3... as needed by strategy).
Options Payoff by the numbers
- 1,889 all-time installs (skills.sh)
- +135 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #76 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
options-payoff capabilities & compatibility
- Capabilities
- expiry payoff curve (dashed gray line) — intrins · theoretical value curve (solid colored line) — b · dynamic sliders for all key parameters · real time stats: max profit, max loss, breakeven
What options-payoff says it does
Generate an interactive options payoff curve chart with dynamic parameter controls. Use this skill whenever the user shares an options position screenshot, describes an options str
Generate an interactive options payoff curve chart with dynamic parameter controls. Use this skill whenever the user shares an options position screenshot, desc
npx skills add https://github.com/himself65/finance-skills --skill options-payoffAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.9k |
|---|---|
| repo stars | ★ 3.1k |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 21, 2026 |
| Repository | himself65/finance-skills ↗ |
How do I plot options payoff diagrams and breakeven analysis for calls and puts?
Plot options payoff diagrams and breakeven analysis for calls and puts.
Who is it for?
Options traders visualizing payoff curves and strategy P/L at expiration.
Skip if: Skip for equity fundamental analysis without options payoff scope.
When should I use this skill?
User plots options payoff, breakeven, or call/put strategy diagrams.
What you get
Completed options-payoff workflow with documented commands, files, and expected deliverables.
- interactive HTML payoff widget
- expiry and theoretical payoff curves
- breakeven and P&L statistics
By the numbers
- Supports 3 options strategies: Butterfly, Vertical spread, and Calendar spread
- Exposes 5 adjustable parameters: strikes, premium, IV, DTE, and spot price
Files
Options Payoff Curve Skill
Generates a fully interactive HTML widget (via visualize:show_widget) showing:
- Expiry payoff curve (dashed gray line) — intrinsic value at expiration
- Theoretical value curve (solid colored line) — Black-Scholes price at current DTE/IV
- Dynamic sliders for all key parameters
- Real-time stats: max profit, max loss, breakevens, current P&L at spot
---
Step 1: Extract Strategy From User Input
When the user provides a screenshot or text, extract:
| Field | Where to find it | Default if missing |
|---|---|---|
| Strategy type | Title bar / leg description | "custom" |
| Underlying | Ticker symbol | SPX |
| Strike(s) | K1, K2, K3... in title or leg table | nearest round number |
| Premium paid/received | Filled price or avg price | 5.00 |
| Quantity | Position size | 1 |
| Multiplier | 100 for equity options, 100 for SPX | 100 |
| Expiry | Date in title | 30 DTE |
| Spot price | Current underlying price (NOT strike) | middle strike |
| IV | Shown in greeks panel, or estimate from vega | 20% |
| Risk-free rate | — | 4.3% |
Critical for screenshots: The spot price is the CURRENT price of the underlying index/stock, NOT the strikes. Never default spot to a strike price value.
Current SPX reference price:
!`python3 -c "import yfinance as yf; print(f'SPX ≈ {yf.Ticker(\"^GSPC\").fast_info[\"lastPrice\"]:.0f}')" 2>/dev/null || echo "SPX price unavailable — check market data"`---
Step 2: Identify Strategy Type
Match to one of the supported strategies below, then read the corresponding section in references/strategies.md.
| Strategy | Legs | Key Identifiers |
|---|---|---|
| butterfly | Buy K1, Sell 2×K2, Buy K3 | 3 strikes, "Butterfly" in title |
| vertical_spread | Buy K1, Sell K2 (same expiry) | 2 strikes, debit or credit |
| calendar_spread | Buy far-expiry K, Sell near-expiry K | Same strike, 2 expiries |
| iron_condor | Sell K2/K3, Buy K1/K4 wings | 4 strikes, 2 spreads |
| straddle | Buy Call K + Buy Put K | Same strike, both types |
| strangle | Buy OTM Call + Buy OTM Put | 2 strikes, both OTM |
| covered_call | Long 100 shares + Sell Call K | Stock + short call |
| naked_put | Sell Put K | Single leg |
| ratio_spread | Buy 1×K1, Sell N×K2 | Unequal quantities |
For strategies not listed, use custom mode: decompose into individual legs and sum their P&Ls.
---
Step 3: Compute Payoffs
Black-Scholes Put Price
d1 = (ln(S/K) + (r + σ²/2)·T) / (σ·√T)
d2 = d1 - σ·√T
put = K·e^(-rT)·N(-d2) - S·N(-d1)Black-Scholes Call Price (via put-call parity)
call = put + S - K·e^(-rT)Butterfly Put Payoff (expiry)
if S >= K3: 0
if S >= K2: K3 - S
if S >= K1: S - K1
else: 0Net P&L per share = payoff − premium_paid
Vertical Spread (call debit) Payoff (expiry)
long_call = max(S - K1, 0)
short_call = max(S - K2, 0)
payoff = long_call - short_call - net_debitCalendar Spread Theoretical Value
Calendar cannot be expressed as a simple expiry function — always use BS pricing for both legs:
value = BS(S, K, T_far, r, IV_far) - BS(S, K, T_near, r, IV_near)For expiry curve of calendar: near leg expires worthless, far leg = BS with remaining T.
Iron Condor Payoff (expiry)
put_spread = max(K2-S, 0) - max(K1-S, 0) // short put spread
call_spread = max(S-K3, 0) - max(S-K4, 0) // short call spread
payoff = credit_received - put_spread - call_spread---
Step 4: Render the Widget
Use visualize:read_me with modules ["chart", "interactive"] before building.
Required Controls (sliders)
Structure section:
- All strike prices (K1, K2, K3... as needed by strategy)
- Premium paid/received
- Quantity
- Multiplier (100 default, show for clarity)
Pricing variables section:
- IV % (5–80%, step 0.5)
- DTE — days to expiry (0–90)
- Risk-free rate % (0–8%)
Spot price:
- Full-width slider, range = [min_strike - 20%, max_strike + 20%], defaulting to ACTUAL current spot
Required Stats Cards (live-updating)
- Max profit (expiry)
- Max loss (expiry)
- Breakeven(s) — show both for two-sided strategies
- Current theoretical P&L at spot
Chart Specs
- X-axis: SPX/underlying price
- Y-axis: Total USD P&L (not per-share)
- Blue solid line = theoretical value at current DTE/IV
- Gray dashed line = expiry payoff
- Green dashed vertical = strike prices (K2 center strike brighter)
- Amber dashed vertical = current spot price
- Fill above zero = green 10% opacity; below zero = red 10% opacity
- Tooltip: show both curves on hover
Code template
Use this JS structure inside the widget, adapting pnlExpiry() and bfTheory() per strategy:
// Black-Scholes helpers (always include)
function normCDF(x) { /* Horner approximation */ }
function bsCall(S,K,T,r,sig) { /* standard BS call */ }
function bsPut(S,K,T,r,sig) { /* standard BS put */ }
// Strategy-specific expiry payoff (returns per-share value BEFORE premium)
function expiryValue(S, ...strikes) { ... }
// Strategy-specific theoretical value using BS
function theoreticalValue(S, ...strikes, T, r, iv) { ... }
// Main update() reads all sliders, computes arrays, destroys+recreates Chart.js instance
function update() { ... }
// Attach listeners
['k1','k2',...,'iv','dte','rate','spot'].forEach(id => {
document.getElementById(id).addEventListener('input', update);
});
update();---
Step 5: Respond to User
After rendering the widget, briefly explain: 1. What strategy was detected and how legs were mapped 2. Max profit / max loss at current settings 3. One key insight (e.g., "spot is currently 950 pts below the profit zone, expiring tomorrow")
Keep it concise — the chart speaks for itself.
---
Reference Files
references/strategies.md— Detailed payoff formulas and edge cases for each strategy typereferences/bs_code.md— Copy-paste ready Black-Scholes JS implementation with normCDF
Read the relevant reference file if you're unsure about payoff formula edge cases for a given strategy.
options-payoff
Generate interactive options payoff curve charts with dynamic parameter controls.
What it does
This skill renders a fully interactive HTML widget showing:
- Expiry payoff curve (dashed gray line) — intrinsic value at expiration
- Theoretical value curve (solid colored line) — Black-Scholes price at current DTE/IV
- Dynamic sliders for all key parameters (strikes, premium, IV, DTE, spot price)
- Real-time stats: max profit, max loss, breakevens, current P&L at spot
Supported strategies
| Strategy | Legs |
|---|---|
| Butterfly | Buy K1, Sell 2×K2, Buy K3 |
| Vertical spread | Buy K1, Sell K2 (same expiry) |
| Calendar spread | Buy far-expiry K, Sell near-expiry K |
| Iron condor | Sell K2/K3, Buy K1/K4 wings |
| Straddle | Buy Call K + Buy Put K |
| Strangle | Buy OTM Call + Buy OTM Put |
| Covered call | Long 100 shares + Sell Call K |
| Naked put | Sell Put K |
| Ratio spread | Buy 1×K1, Sell N×K2 |
For unlisted strategies, the skill uses custom mode — decomposing into individual legs and summing their P&Ls.
Triggers
- Describing an options strategy (e.g., "show me a bull call spread")
- Uploading a screenshot from a broker (IBKR, TastyTrade, Robinhood, etc.)
- Mentioning strike prices, premiums, or expiry dates
- Asking to "show me the payoff", "draw the P&L curve", or "what does this trade look like"
Platform
Works on Claude.ai (via the built-in show_widget tool) or with the generative-ui skill on Claude Code.
Setup
# As a plugin (recommended — installs all skills)
npx plugins add himself65/finance-skills --plugin finance-market-analysis
# Or install just this skill
npx skills add himself65/finance-skills --skill options-payoffSee the main README for more installation options.
Reference files
references/strategies.md— Detailed payoff formulas and edge cases for each strategy typereferences/bs_code.md— Copy-paste ready Black-Scholes JS implementation with normCDF
Black-Scholes JavaScript Implementation
Copy-paste ready. Include at the top of every widget's <script> block.
// Normal CDF via Horner's method (accurate to 7 decimal places)
function normCDF(x) {
const a1=0.254829592, a2=-0.284496736, a3=1.421413741,
a4=-1.453152027, a5=1.061405429, p=0.3275911;
const sign = x < 0 ? -1 : 1;
x = Math.abs(x);
const t = 1 / (1 + p * x);
const y = 1 - (((((a5*t + a4)*t + a3)*t + a2)*t + a1)*t) * Math.exp(-x*x/2);
return 0.5 * (1 + sign * y);
}
// Black-Scholes Put price
// S=spot, K=strike, T=years to expiry, r=rate (decimal), sigma=IV (decimal)
function bsPut(S, K, T, r, sigma) {
if (T <= 0) return Math.max(K - S, 0);
if (sigma <= 0) return Math.max(K - S, 0);
const d1 = (Math.log(S/K) + (r + sigma*sigma/2)*T) / (sigma*Math.sqrt(T));
const d2 = d1 - sigma * Math.sqrt(T);
return K * Math.exp(-r*T) * normCDF(-d2) - S * normCDF(-d1);
}
// Black-Scholes Call price
function bsCall(S, K, T, r, sigma) {
if (T <= 0) return Math.max(S - K, 0);
if (sigma <= 0) return Math.max(S - K, 0);
const d1 = (Math.log(S/K) + (r + sigma*sigma/2)*T) / (sigma*Math.sqrt(T));
const d2 = d1 - sigma * Math.sqrt(T);
return S * normCDF(d1) - K * Math.exp(-r*T) * normCDF(d2);
}Typical Parameter Conversions
const T = dte / 365; // DTE slider value → years
const r = rate / 100; // rate slider % → decimal
const sigma = iv / 100; // IV slider % → decimalComputing Greeks (for display)
function bsDelta(S, K, T, r, sigma, isCall) {
if (T <= 0) return isCall ? (S>K?1:0) : (S<K?-1:0);
const d1 = (Math.log(S/K) + (r + sigma*sigma/2)*T) / (sigma*Math.sqrt(T));
return isCall ? normCDF(d1) : normCDF(d1) - 1;
}
function bsTheta(S, K, T, r, sigma, isCall) {
if (T <= 0) return 0;
const d1 = (Math.log(S/K) + (r + sigma*sigma/2)*T) / (sigma*Math.sqrt(T));
const d2 = d1 - sigma * Math.sqrt(T);
const term1 = -S * Math.exp(-0.5*d1*d1) / Math.sqrt(2*Math.PI) * sigma / (2*Math.sqrt(T));
if (isCall) return (term1 - r * K * Math.exp(-r*T) * normCDF(d2)) / 365;
return (term1 + r * K * Math.exp(-r*T) * normCDF(-d2)) / 365;
}Options Strategy Payoff Formulas
Butterfly (Put or Call)
Structure: Buy K1, Sell 2×K2, Buy K3 (K1 < K2 < K3, wings equal: K2-K1 = K3-K2) Cost: Net debit (long butterfly) Max profit: wing_width - premium, at K2 Max loss: premium paid, outside K1 or K3
function expiryValue(S, k1, k2, k3) {
if (S >= k3) return 0;
if (S >= k2) return k3 - S;
if (S >= k1) return S - k1;
return 0;
}
function theoreticalValue(S, k1, k2, k3, T, r, iv) {
const s = iv/100;
return bsPut(S,k1,T,r,s) - 2*bsPut(S,k2,T,r,s) + bsPut(S,k3,T,r,s);
}Broken wing butterfly: K3-K2 ≠ K2-K1 → one side has residual directional exposure. Adjust formula accordingly.
---
Vertical Spread
Call Debit Spread (bullish)
Buy K1 call, Sell K2 call (K1 < K2)
function expiryValue(S, k1, k2) {
return Math.max(S-k1, 0) - Math.max(S-k2, 0);
}
function theoreticalValue(S, k1, k2, T, r, iv) {
return bsCall(S,k1,T,r,iv/100) - bsCall(S,k2,T,r,iv/100);
}Max profit: K2-K1-debit | Max loss: debit paid
Put Debit Spread (bearish)
Buy K2 put, Sell K1 put (K1 < K2)
function expiryValue(S, k1, k2) {
return Math.max(k2-S, 0) - Math.max(k1-S, 0);
}Max profit: K2-K1-debit | Max loss: debit paid
Credit Spread
Sell the near strike, buy the far strike for protection. Net credit received. Expiry payoff = -(debit_spread expiry). Max profit = credit, Max loss = width - credit.
---
Calendar Spread (Time Spread)
Structure: Buy far-DTE option at K, Sell near-DTE option at K (same strike) Key: Cannot show a simple expiry curve — instead show value as DTE_near approaches 0.
// T_near = DTE_near/365, T_far = DTE_far/365
function theoreticalValue(S, K, T_near, T_far, r, iv_near, iv_far, isCall) {
if (isCall) return bsCall(S,K,T_far,r,iv_far/100) - bsCall(S,K,T_near,r,iv_near/100);
return bsPut(S,K,T_far,r,iv_far/100) - bsPut(S,K,T_near,r,iv_near/100);
}
// At near expiry (T_near=0): near leg expires, far leg retains time value
function atNearExpiry(S, K, T_far, r, iv_far, isCall) {
if (isCall) return bsCall(S,K,T_far,r,iv_far/100);
return bsPut(S,K,T_far,r,iv_far/100);
}UI note for calendar: Show TWO sliders for DTE (near and far). "Expiry" curve = at-near-expiry value minus premium paid. Max profit: When spot = K at near expiry (maximum time value difference) Max loss: Premium paid (if spot moves far from K in either direction)
---
Iron Condor
Structure: Sell K2 put, Buy K1 put (put spread) + Sell K3 call, Buy K4 call (call spread) K1 < K2 < K3 < K4. Net credit received.
function expiryValue(S, k1, k2, k3, k4) {
const putSpread = Math.max(k2-S,0) - Math.max(k1-S,0); // loss on short put spread
const callSpread = Math.max(S-k3,0) - Math.max(S-k4,0); // loss on short call spread
return -(putSpread + callSpread); // net payoff from short spreads
}
// credit = premium_received. P&L = credit + expiryValue
function theoreticalValue(S, k1, k2, k3, k4, T, r, iv) {
const s=iv/100;
return -(bsPut(S,k2,T,r,s)-bsPut(S,k1,T,r,s)) - (bsCall(S,k3,T,r,s)-bsCall(S,k4,T,r,s));
}Max profit: credit received | Max loss: max(K2-K1, K4-K3) - credit
---
Straddle
Structure: Buy call at K + Buy put at K (same strike, same expiry)
function expiryValue(S, k) {
return Math.abs(S - k); // = max(S-K,0) + max(K-S,0)
}
function theoreticalValue(S, k, T, r, iv) {
return bsCall(S,k,T,r,iv/100) + bsPut(S,k,T,r,iv/100);
}Breakevens: K ± premium. Max loss: premium paid (if S=K at expiry).
---
Strangle
Structure: Buy OTM put at K1 + Buy OTM call at K2 (K1 < K2)
function expiryValue(S, k1, k2) {
return Math.max(k1-S, 0) + Math.max(S-k2, 0);
}
function theoreticalValue(S, k1, k2, T, r, iv) {
return bsPut(S,k1,T,r,iv/100) + bsCall(S,k2,T,r,iv/100);
}Breakevens: K1 - premium, K2 + premium. Max loss: premium if K1 ≤ S ≤ K2.
---
Covered Call
Structure: Long 100 shares at cost_basis + Sell call at K
function expiryValue(S, K, costBasis) {
const stockPnl = S - costBasis;
const shortCallPnl = -Math.max(S-K, 0) + premium; // premium = call premium received
return stockPnl + shortCallPnl;
}Max profit: K - costBasis + premium | Max loss: costBasis - premium (stock goes to 0)
---
Naked / Cash-Secured Put
Structure: Sell put at K, receive premium
function expiryValue(S, K, premium) {
return premium - Math.max(K-S, 0);
}Max profit: premium | Max loss: K - premium (stock goes to 0)
---
Edge Cases
- DTE = 0: skip BS entirely, use intrinsic value only
- IV = 0: BS undefined (σ=0), use max(intrinsic, 0)
- K1 > K2: warn user, auto-sort strikes ascending
- Negative theoretical value: clip to 0 for display (arbitrage-free floor)
- Calendar with IV skew: use separate IV sliders for near vs far leg
Related skills
How it compares
Pick options-payoff over static chart libraries when you need self-contained HTML widgets with live Black-Scholes curves and strategy-specific leg modeling.
FAQ
What does options-payoff do?
Plot options payoff diagrams and breakeven analysis for calls and puts.
When should I use options-payoff?
User plots options payoff, breakeven, or call/put strategy diagrams.
Is options-payoff safe to install?
Review the Security Audits panel on this page before installing in production.