options-payoff
生成一张带动态参数控制的交互式期权收益曲线图。每当用户分享期权持仓截图、描述期权策略,或询问如何可视化该期权交易如何盈利或亏损时,都要使用此技能。触发条件包括:任何提到蝶式价差(butterfly)、价差(vertical/calendar/diagonal/ratio)、跨式(straddle)、宽跨式(strangle)、铁鹰(condor)、备兑开仓(covered call)、保护性看跌(protective put)、铁鹰价差(iron condor),或任何多腿期权结构。只要用户粘贴执行价、权利金、到期日期,或说诸如“把收益展示给我”“绘制盈亏曲线”“这笔交易看起来是什么样的”,或上传来自券商的截图(IBKR、TastyTrade、Robinhood 等),也要触发。即使用户只提供了部分信息,也要始终使用此技能——尽可能提取现有信息,其余使用默认值。
分类
金融分析安装
下载并解压到你的 skills 目录
复制命令,发送给 OpenClaw 自动安装:
Options Payoff Curve Skill
Generates a fully interactive HTML widget (via visualize:show_widget) showing:
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_spreadStep 4: Render the Widget
Use visualize:read_me with modules ["chart", "interactive"] before building.
Required Controls (sliders)
Structure section:
Pricing variables section:
Spot price:
Required Stats Cards (live-updating)
Chart Specs
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:
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 normCDFRead the relevant reference file if you're unsure about payoff formula edge cases for a given strategy.