ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于 Pathway 与 Databento 的期权 Greeks 实时计算指南

2026/9/8 23:39:32 拓冰建站 浏览量
基于 Pathway 与 Databento 的期权 Greeks 实时计算指南 基于 Pathway 与 Databento 的期权 Greeks 实时计算指南【免费下载链接】pathwayPython ETL framework for stream processing, real-time analytics, LLM pipelines, and RAG.项目地址: https://gitcode.com/GitHub_Trending/pa/pathway本篇技术指南围绕仓库中“使用 Pathway 与 Databento 计算期权 Greeks”的完整示例展开说明如何以金融衍生品数据为输入在 Pathway 流处理框架中完成合约过滤、盘口数据聚合、隐含波动率求解与 Delta/Gamma/Theta/Vega/Rho 五大风险指标计算并通过 Streamlit 仪表盘实时展示。读者学完后将掌握 Pathway 的 CSV 静态读取、Python 连接器回放replay、pw.udf数值计算、表连接/索引引用与 Web 查询querying接口的完整实战用法。项目要解决什么问题期权的 Greeks 是什么期权Options是赋予持有者权利而非义务、在规定期限内按约定价格买入或卖出标的资产的金融衍生品。仅仅知道期权价格是不够的——交易员与风险管理者还需要量化地回答“价格对哪些因素有多敏感”这组敏感性指标就是Option Greeks期权希腊字母用于衡量价格、标的资产价格、时间、波动率与利率等多种风险因子变动时期权价格的变化。本示例基于 Pathway 的计算流程计算并输出五个常用 Greeks指标含义代码中对应的计算函数DeltaΔ期权价格对标的资产价格变动的敏感度compute_deltaGammaΓDelta 对标的资产价格变动的敏感度Delta 的变化率compute_gammaThetaΘ期权价格对时间流逝的敏感度时间衰减compute_thetaVegaν期权价格对隐含波动率变动的敏感度compute_vegaRhoρ期权价格对无风险利率变动的敏感度compute_rho数据链路为Databento提供机构级行情数据的服务商负责行情与合约数据的获取Pathway负责持续计算Streamlit负责结果展示。本示例完整代码位于 examples/projects/option-greeksREADME 说明见 examples/projects/option-greeks/README.md。总体工作流整个流水线可归纳为读取合约定义与盘口数据 → 过滤出与目标期货ESM4相关的 Call/Put → 计算各期权盘中价midprice → 求得到期时间与远期价格 → 用 Black 模型反解隐含波动率 → 计算五种 Greeks → 通过 Web 接口对外暴露供 Streamlit 轮询展示。项目组织与文件职责原文档给出的工程目录如下相对项目根目录的实际路径见各注释examples/projects/option-greeks/ ├── data/ │ ├── definition.csv # 静态脚本使用的期权合约定义数据 │ └── options.csv # 静态脚本使用的盘口mbp-1行情数据 ├── .env # 存放 Databento API key 与 Web 服务端口等参数 ├── greeks-replay.py # 回放模式从 Databento Historical API 读取行情并计算 Greeks ├── greeks-static.py # 静态模式读取上述 CSV 文件并计算 Greeks ├── requirements.txt # 运行所需依赖清单 └── streamlit_ux.py # 基于 Streamlit 的结果展示界面补充说明data/中的数据规模当前仓库版本为definition.csv约 3253 行、options.csv约 18545 行。静态 CSV 中合约定义列包含ts_recv, raw_symbol, expiration, instrument_class, strike_price, underlying, instrument_id盘口数据列包含ts_recv, symbol, bid_px_00, ask_px_00, raw_symbol, bid_px, ask_px与代码中定义的两套 Schema 一一对应。querying.py不属于原文档树形图但被streamlit_ux.py依赖负责用 FastAPI 将 Pathway 表注册为可按别名查询的 HTTP 端点。.env在仓库中保存为模板API_KEY、PORT实际运行前需填入你自己的密钥。快速开始完整运行步骤1. 安装依赖在原文档与仓库中运行两个脚本所需的第三方库统一写在 requirements.txt 中包含databento、pandas、scipy、pathway、python-dotenv、fastapi、pydantic、streamlit、uvicorn。安装命令pip install -r requirements.txt2. 配置 Databento API Key先到 Databento 注册账号并获取 API key注册可获得免费额度。然后打开项目目录下的.env填入API_KEY 你的_databento_api_key PORT 16001其中API_KEY用于调用 Databento Historical APIPORT是后续 Web 查询服务监听的端口。两个脚本中都会通过load_dotenv()读取该文件脚本内部以os.environ.get(API_KEY)、os.environ.get(PORT)获取对应变量。注意若直接使用静态数据greeks-static.py不需要真实 API key但脚本仍会读取.env中的PORT。3. 启动 Streamlit UX无论最终跑静态还是回放脚本展示界面都以相同方式启动streamlit run streamlit_ux.pyStreamlit 服务默认运行在http://localhost:8501。启动后页面应显示 Option Greeks 标题与模式说明文字此时可能看到“等待数据”的错误提示这是正常现象——因为后端数据流尚未启动源码中该页面会请求http://localhost:{port}/get_table?aliastable_greeks见 streamlit_ux.py。4. 运行数据脚本需要拿到真实行情做回放时执行python greeks-replay.py等待数秒完成启动后数据即开始以流的方式注入。验证是否成功的两种方式与原文档一致刷新 Streamlit 页面看到类似下图的表格即表示成功。由于处于replay模式数据是带延迟地逐条回放反复刷新可以看到表格在实时增长直接查询 JSON 端点浏览器访问http://localhost:16001/get_table?aliastable_greeks若返回包含 Greeks 数值的 JSON说明后端计算链路工作正常。该接口由querying.py中的 FastAPI 端点实现别名不存在时返回 404见 querying.py。5. 运行静态脚本如果只想在不依赖 Databento API 的情况下复现整条计算链路可以运行使用仓库内置 CSV 的静态版本python greeks-static.py该脚本不调用行情服务直接读取 data/definition.csv 与 data/options.csv其余计算逻辑与回放脚本完全一致。源码级拆解从行情到 Greeks 的五步流水线两套脚本的计算主链基本相同这里以逻辑更完整的 greeks-replay.py 为主线并标注与静态版 greeks-static.py 的差异。3.1 定义关键参数与输入 Schema两类脚本使用同一批行情参数回放脚本见 greeks-replay.pydb_dataset GLBX.MDP3CME Globex 的 MDP 3.0 行情数据集示例中选取的是基于 E-mini SP 500ES的期货期权db_def_schema definition与db_price_schema mbp-1分别指合约定义静态属性与一档盘口行情db_def_symbols [ES.OPT]父级符号模式下筛选出所有根代码为ES的期权front_month_symbol ESM4近月主力期货合约代码用于定位期权标的interest_rate 0.043Black 模型中的无风险利率示例为常数 4.3%回放脚本额外需要start_time、data_duration获取合约定义的窗口与query_data_duration获取行情的时间窗示例为从 2024-04-04 17:00Us/Central起取 2 分钟mbp-1数据。两个输入都通过pw.Schema声明列类型class DefinitionInputSchema(pw.Schema): ts_recv: int # 收到数据的时间(ns) raw_symbol: str # 期权符号 expiration: int # 期权到期时间(ns) instrument_class: str # 期权类型 C/P/T 等 strike_price: float # 行权价 underlying: str # 第一标的资产符号 instrument_id: int # 期权唯一标识 class OptionInputSchema(pw.Schema): raw_symbol: str # 期权符号 bid_px: float # 买价 ask_px: float # 卖价3.2 读取数据静态 CSV vs 历史回放静态模式使用pw.io.csv.read(..., modestatic)一次性读入 CSVgreeks-static.py。回放模式使用pw.io.python.read()配一个ConnectorSubject子类在run()中调用 Databento 的client.timeseries.get_range(...)逐行取出数据再通过self.next(...)送入 Pathwaygreeks-replay.py。回放脚本中有两个值得注意的数据清洗点合约定义价格需/1e9归一化Databento 传输中使用 1e-9 为单位。mbp-1盘口数据中买/卖价为INT64_MAX附近的占位值代表“未知/无效价格”代码用levels[0].bid_px (1 63) - 10判断并跳过这些记录greeks-replay.py否则会把约 922 亿的错误价格带入计算。回放与静态的唯一本质差异是回放脚本在每条行情后调用time.sleep(time_between_updates)0.05 秒/条以模拟慢速实时流greeks-replay.py——这正是页面刷新时表格不断增长的原因。3.3 合约过滤、盘口聚合与表连接拿到两张“表”后先用连续filter收缩范围table_esm4 table_esm4.filter(pw.this.underlying front_month_symbol) # 只留 ES 近月标的 table_esm4 table_esm4.filter( (pw.this.instrument_class C) | (pw.this.instrument_class P) # 只留 Call/Put )回放脚本中还需要把过滤后的raw_symbol收集成列表reducepw.reducers.tuple作为下一步向 Databento 请求期权行情价格的符号集。接着用groupby(...).reduce(...)对同一期权在回放窗口内的买/卖价求平均得到盘口中价midpricetable_mbp1 table_mbp1.groupby(pw.this.raw_symbol).reduce( raw_symbolpw.this.raw_symbol, option_midprice(pw.reducers.avg(pw.this.bid_px) pw.reducers.avg(pw.this.ask_px)) / 2, )随后把“合约定义”与“行情价格”两张表以raw_symbol等值连接起来table_prices table_esm4.join( table_mbp1, pw.left.raw_symbol pw.right.raw_symbol ).select( *pw.left, # 带入合约定义的整行 option_midpricepw.right.option_midprice, )最后用ix_ref按 key 引用另一张表的列取出主力期货ESM4的 midprice 作为期权定价所需的远期价格 Ftable_prices table_prices.with_columns( future_pricetable_mbp1.ix_ref(front_month_symbol).option_midprice )3.4 到期时间与 Black 模型定价期权定价需要“距离到期还有多少年”。原始expiration是纳秒时间戳因此用一个pw.udf装饰的纯 Python 函数把纳秒差折算成年份pw.udf def compute_time_to_expiration(expiration_time: int) - float: return (expiration_time - int(start_time.timestamp() * 1e9)) / (1e9 * 86400 * 365)本项目针对的是期货期权因此使用适合以期货价格F为标的的Black 模型而非经典的 Black-Scholes 公式。定价函数返回基于正态分布累计分布函数norm.cdf的价格def compute_price(F, K, T, sigma, rinterest_rate, is_callTrue) - float: d1 (math.log(F / K) (sigma**2 / 2) * T) / (sigma * math.sqrt(T)) d2 d1 - sigma * math.sqrt(T) sign 2 * int(is_call) - 1 return math.exp(-r * T) * sign * (norm.cdf(sign * d1) * F - norm.cdf(sign * d2) * K)其中F为远期价格K为行权价T为以年计的到期时间sigma为波动率r为无风险利率。3.5 用 scipy 反解隐含波动率模型给定价需要波动率σ但行情并不直接提供它。工程上的做法是反解隐含波动率找到一个σ使 Black 模型价格等于市场 midprice即求方程BlackPrice(σ) − midprice 0的根。代码用scipy.optimize.root_scalar以x00.0001、x10.8为初值区间求解求解失败not result.converged时返回Nonepw.udf def compute_volatility(F, K, T, is_call, option_midprice) - float | None: result scipy.optimize.root_scalar( lambda sigma: option_midprice - compute_price(FF, KK, TT, sigmasigma, is_callis_call), x00.0001, x10.8, ) return result.root if result.converged else None由于 Pathway 是增量/持续计算引擎这里把scipy的求根逻辑封装为pw.udf后每条新到价的行会按需重新求根。产生None的行随后被filter(pw.this.volatility.is_not_none())剔除保证后续 Greeks 计算只作用于收敛成功的记录greeks-replay.py。3.6 计算五种 Greeks先由σ计算中间量d1、d2随后五个pw.udf依次完成指标计算。以代码为准其数学形式为DeltaCall 为e^{−rT}·Φ(d1)Put 为−e^{−rT}·Φ(−d1)Gammae^{−rT}·φ(d1) / (F·σ·√T)Call/Put 相同Theta含term −F·σ·φ(d1) / (2√T)的表达式Call/Put 分开计算并统一除以252把“年化时间衰减”折算为“每日”对应一年约 252 个交易日VegaF·φ(d1)·√T·e^{−rT} / 100除以 100 对应“波动率变动 1 个百分点”的价格变化RhoCall 为−T·e^{−rT}·(F·Φ(d1)−K·Φ(d2)) / 100Put 为对应负向组合再/100除以 100 对应利率变动 1 个百分点。φ为标准正态概率密度norm.pdfΦ为标准正态累计分布norm.cdf。五种指标函数都以pw.udf声明见 greeks-replay.py 与静态脚本中完全相同的实现最后用一个select把五个结果与instrument_id、ts_recv一起投影为最终输出表table_greekstable_greeks table_d1d2.select( ts_recvpw.this.ts_recv, instrument_idpw.this.instrument_id, deltacompute_delta(...), gammacompute_gamma(...), thetacompute_theta(...), vegacompute_vega(...), rhocompute_rho(...), )3.7 结果对外暴露Web 查询与 Streamlit最终结果表通过streamlit_ux.py的辅助函数暴露给外部streamlit_ux.send_table_to_web(port, table_greeks, table_greeks) pw.run()send_table_to_webstreamlit_ux.py实际做了两件事调用querying.register_table(table, alias)底层通过pw.io.subscribe(self, on_changeupdate)订阅表变更新增行写入字典、删除行移除把实时结果缓存在内存中querying.py以monitoring_levelpw.MonitoringLevel.NONE在独立线程中启动pw.run()同时用 Uvicorn 启动监听0.0.0.0:port的 FastAPI 服务注册GET /get_table?alias...端点将表内容序列化为 JSONquerying.py。Streamlit 界面streamlit_ux.py通过requests带重试适配器周期性拉取http://localhost:{PORT}/get_table?aliastable_greeks把 JSON 转为 DataFrame将纳秒级ts_recv转为时间并设置instrument_id为索引后用st.dataframe渲染表格请求失败则显示错误信息。图 Streamlit.png 即为运行成功后的真实界面表格以instrument_id为索引列出每个期权的delta/gamma/rho/theta/vega与数据接收时间ts_recv。小结把这个示例迁移到自己的行情源这个示例的价值在于它演示了一套与数据源解耦的持续计算范式只要把表数据送进 Pathway无论是pw.io.csv.read、pw.io.python.read的ConnectorSubject还是其他内置连接器后续的过滤、join、pw.udf数值计算、ix_ref引用与pw.io.subscribe输出都可以原样复用。将其用于自己的期权风控场景时通常只需修改四处.env中的API_KEY与PORT顶部参数区数据集、符号集、主力合约、利率与时间窗若标的不是期货期权需将compute_price及 Greeks 公式替换为对应的定价模型如标的为股票/指数的 Black-Scholes 或二叉树模型将 Streamlit 页面请求的别名与端口对齐querying.py中注册的表名。原文档与仓库中的完整可运行版本分别见 docs/2.developers/7.templates/ETL/_readmes/option-greeks.md 与 examples/projects/option-greeks。【免费下载链接】pathwayPython ETL framework for stream processing, real-time analytics, LLM pipelines, and RAG.项目地址: https://gitcode.com/GitHub_Trending/pa/pathway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考