尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Python API for European option pricing, Greeks, implied volatility and market risk, validated against references and invariants
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Python backend for European option pricing, Greeks, implied volatility, and market-risk analytics.
Open the live demo → (synthetic inputs, no live market data)
DeltaCore provides deterministic pricing and risk components for vanilla derivatives workflows. Pure pricing kernels sit behind typed API boundaries, with explicit model conventions and numerical checks against known references and invariants.
Problem: make European-option pricing and risk calculations inspectable through pure Python kernels and typed HTTP boundaries.
uv sync --extra dev && uv run pytest; run
uv run uvicorn derivatives_risk_engine.api.main:app --reload for the API/demo.| Area | Current status |
|---|---|
| Pricing | European call/put options under Black-Scholes and Bachelier |
| API | FastAPI endpoints for pricing, Greeks, implied volatility, scenario PnL, and VaR/ES |
| Demo | Browser demo at /demo, backed by live API calls; live at deltacore.lucaslebihan.dev |
| Greeks | Analytic Black-Scholes delta, gamma, vega, theta, rho |
| Implied volatility | Black-Scholes implied volatility with convergence diagnostics |
| Monte Carlo | Black-Scholes European pricing with standard error and confidence interval |
| Risk | Deterministic scenario PnL, historical VaR, and Expected Shortfall |
| Validation | Closed-form fixtures, put-call parity, finite-difference Greeks |
| Quality | Ruff formatting/linting, strict mypy, pytest |
| Roadmap | Monte Carlo API endpoint and richer demo views |
The distribution name is deltacore; the Python import namespace remains
derivatives_risk_engine to keep the domain model explicit.
Pricing services need model behavior that remains inspectable when numerical logic is exposed through an API. DeltaCore separates pure quantitative kernels from transport and orchestration so pricing, implied-volatility, and risk calculations can be validated independently and reused consistently.
The implementation emphasizes:
F = S exp((r - q)T), risk-free discounting, and annualized normal volatility
in price units.-dV/dT.shocked_price - base_price.-PnL; VaR is the conservative empirical loss quantile, and ES is the mean of
losses at or beyond that quantile.uv sync --extra dev
uv run pytest
Run the full local quality gate:
uv run ruff format --check .
uv run ruff check .
uv run mypy src tests
uv run pytest
The Black-Scholes implementation assumes lognormal spot dynamics, continuous risk-free and dividend rates, annualized volatility, and time to expiry expressed as a year fraction. Inputs are deterministic and use no live market data.
from derivatives_risk_engine.core.instruments import EuropeanOption
from derivatives_risk_engine.core.market import BlackScholesMarket
from derivatives_risk_engine.models.black_scholes import black_scholes_price
option = EuropeanOption(option_type="call", strike=100.0, time_to_expiry=1.0)
market = BlackScholesMarket(
spot=100.0,
risk_free_rate=0.05,
dividend_yield=0.0,
volatility=0.20,
)
price = black_scholes_price(option, market)
print(price) # 10.450583572185565
Use the Bachelier normal model:
from derivatives_risk_engine.core.instruments import EuropeanOption
from derivatives_risk_engine.core.market import BachelierMarket
from derivatives_risk_engine.models.bachelier import bachelier_price
option = EuropeanOption(option_type="call", strike=100.0, time_to_expiry=1.0)
market = BachelierMarket(
spot=100.0,
risk_free_rate=0.05,
dividend_yield=0.0,
normal_volatility=15.0,
)
price = bachelier_price(option, market)
print(price) # 8.460134478825838
Compute Black-Scholes Greeks:
from derivatives_risk_engine.core.instruments import EuropeanOption
from derivatives_risk_engine.core.market import BlackScholesMarket
from derivatives_risk_engine.risk.greeks import black_scholes_greeks
option = EuropeanOption(option_type="call", strike=100.0, time_to_expiry=1.0)
market = BlackScholesMarket(
spot=100.0,
risk_free_rate=0.05,
dividend_yield=0.0,
volatility=0.20,
)
greeks = black_scholes_greeks(option, market)
print(greeks.delta, greeks.vega)
Solve Black-Scholes implied volatility:
from derivatives_risk_engine.calibration.implied_vol import (
solve_black_scholes_implied_volatility,
)
from derivatives_risk_engine.core.instruments import EuropeanOption
option = EuropeanOption(option_type="call", strike=100.0, time_to_expiry=1.0)
result = solve_black_scholes_implied_volatility(
option=option,
spot=100.0,
risk_free_rate=0.05,
dividend_yield=0.0,
target_price=10.450583572185565,
)
print(result.implied_volatility) # 0.20
print(result.diagnostics.converged)
Run deterministic Monte Carlo pricing:
from derivatives_risk_engine.core.instruments import EuropeanOption
from derivatives_risk_engine.core.market import BlackScholesMarket
from derivatives_risk_engine.numerics.monte_carlo import monte_carlo_black_scholes_price
option = EuropeanOption(option_type="call", strike=100.0, time_to_expiry=1.0)
market = BlackScholesMarket(
spot=100.0,
risk_free_rate=0.05,
dividend_yield=0.0,
volatility=0.20,
)
result = monte_carlo_black_scholes_price(
option=option,
market=market,
num_paths=50_000,
seed=7,
)
print(result.price, result.standard_error)
print(result.confidence_interval_low, result.confidence_interval_high)
Run deterministic stress scenarios:
from derivatives_risk_engine.core.instruments import EuropeanOption
from derivatives_risk_engine.core.market import BlackScholesMarket
from derivatives_risk_engine.risk.scenario import (
MarketShock,
run_black_scholes_scenarios,
)
option = EuropeanOption(option_type="call", strike=100.0, time_to_expiry=1.0)
market = BlackScholesMarket(
spot=100.0,
risk_free_rate=0.05,
dividend_yield=0.0,
volatility=0.20,
)
results = run_black_scholes_scenarios(
option,
market,
(
MarketShock(name="spot_down_5", spot_shift=-5.0),
MarketShock(name="vol_up_5_points", volatility_shift=0.05),
),
)
for result in results:
print(result.scenario_name, result.pnl)
Estimate historical VaR and Expected Shortfall:
from derivatives_risk_engine.risk.var import historical_var_expected_shortfall
pnls = (12.0, 7.0, 5.0, 2.0, 0.0, -1.0, -3.0, -8.0, -10.0, -20.0)
result = historical_var_expected_shortfall(pnls, confidence_level=0.80)
print(result.value_at_risk) # 8.0
print(result.expected_shortfall) # 12.666666666666666
Run the service:
uv run uvicorn derivatives_risk_engine.api.main:app --reload
Open the browser demo:
http://127.0.0.1:8000/demo
The demo offers keyboard-accessible spot and volatility sliders, automatic updates, and a nine-point option-price sensitivity curve from the existing scenario API. Expand Inspect curve values to see its numerical values. Rates and dividend yields are annual decimals, expiry is in years, and prices use the same currency units as spot/strike. The curve is another view of the same Black-Scholes model, not independent numerical validation or market data. Invalid inputs clear old results rather than leaving stale prices visible.
For optional desktop/mobile browser checks against a running API (Playwright must be available):
DELTACORE_DEMO_URL=http://127.0.0.1:8000 node tests/browser/demo.cjs
Current endpoints:
GET /health
GET /demo
POST /price/european
POST /greeks/european
POST /implied-volatility
POST /risk/scenario-pnl
POST /risk/historical-var
curl -X POST http://127.0.0.1:8000/price/european \
-H 'content-type: application/json' \
-d '{
"option_type": "call",
"spot": 100.0,
"strike": 100.0,
"time_to_expiry": 1.0,
"risk_free_rate": 0.05,
"dividend_yield": 0.0,
"volatility": 0.20
}'
{
"model": "black_scholes",
"option_type": "call",
"price": 10.450583572185565,
"convention": "continuous_rates_annualized_volatility"
}
flowchart LR
API["FastAPI API"] --> Services["Service layer"]
Services --> Core["Core instruments and market data"]
Services --> Models["Pricing models"]
Models --> Numerics["Numerical methods"]
Services --> Risk["Risk analytics"]
Dependency direction is intentionally simple:
api -> services -> core/models/numerics/risk
Domain code does not depend on FastAPI. Pricing kernels stay pure and deterministic so they can be tested independently from transport concerns.
| Check | What it protects |
|---|---|
| Closed-form call fixture | Black-Scholes call value under continuous rates |
| Closed-form put fixture | Put sign convention and discounting |
| Bachelier fixtures | Normal-model prices under forward-discounted convention |
| Put-call parity with dividends | Internal consistency across calls and puts in both models |
| Analytic Greeks vs finite difference | Delta, gamma, vega, theta, and rho conventions |
| Implied volatility inversion | Recovers known vol and reports impossible prices |
| Monte Carlo confidence interval | Fixed-seed simulation contains closed-form price |
| Scenario PnL repricing | Shocked price equals direct Black-Scholes repricing |
| Historical VaR/ES | Conservative loss quantile and tail-loss mean |
| Expiry intrinsic value | Correct zero-time limiting behavior |
| API integration smoke test | Pricing, Greeks, implied vol, risk endpoints, and demo page wiring |
DeltaCore is not a live trading system and does not ingest market data. The
current implementation is a validated backend slice for vanilla European option
pricing, Black-Scholes Greeks, Black-Scholes implied-volatility inversion, and
Monte Carlo pricing with confidence intervals, plus deterministic scenario PnL
and historical VaR/Expected Shortfall. A lightweight browser demo is available
at /demo and calls the same FastAPI endpoints exposed to external clients.
Exotic products, calibration surfaces, Monte Carlo API exposure, and broader
market-risk workflows are planned milestones and will be documented with
explicit assumptions as they are implemented.
The prepared homelab manifest runs this API behind Caddy with
sudo homelab project deploy deltacore (homelab is the author's private server
tooling, not part of this repository). It checks formatting, lint, typing and
tests before activating an immutable release. Uvicorn is a runtime dependency,
so a production-only uv sync --frozen --no-extra dev --no-editable retains the
server. The backend binds loopback; /health is the readiness endpoint and
the public root redirects to the existing /demo. The service is stateless.
The demo is published at https://deltacore.lucaslebihan.dev/demo.
/demo preserves a base European option and applies bounded spot, volatility
and calendar-time shocks. /risk/scenario-attribution returns full repricing,
base-state delta/gamma/vega/theta contributions and their signed residual for one
option unit. Five volatility points mean an absolute 0.05 change; elapsed days
use a 365-day year and reduce remaining expiry. The approximation omits cross
and higher-order terms; it can deteriorate for large shocks and near expiry.
The evidence drawer separates reference fixtures, numerical derivative checks and same-model curve/IV consistency. Downloaded JSON retains exact inputs and outputs. The historical P&L sample is independent of the option and has its own errors. A zero-expiry option can be priced, but base Greeks/attribution are undefined. IV inversion reports solver bounds and failure reasons.
Set DEMO_BUILD_REVISION to the actual build SHA to identify a packaged release;
otherwise the page honestly displays unknown. Static assets ship in the wheel.
Browser journey checks: node tests/browser/demo.cjs with Playwright available
and DELTACORE_DEMO_URL pointing at a local server.