mcpField
D
Deskpricer

Deskpricer

本地服务
github.com/JohnJohnJohnJohn金融数据03 周前更新

关于 Deskpricer

Deskpricer 是面向个人交易台使用的本地期权定价服务,可通过 HTTP 或 MCP 提供分析能力。它支持欧式和美式股票期权,并可与 Excel 公式配合使用。

主要功能

  1. 01计算期权价格与 Greeks
  2. 02反推隐含波动率
  3. 03分解期权损益归因
  4. 04聚合多腿投资组合 Greeks
  5. 05默认提供 XML,支持 JSON

适用场景

  1. 01在 Excel 工作表中获取期权价格与 Greeks
  2. 02根据市场价格求解隐含波动率
  3. 03分析持仓期间的损益构成
  4. 04汇总多腿期权组合风险

MCP 相关

MCP 服务提供 `price_option`、`implied_volatility`、`pnl_attribution` 和 `portfolio_greeks` 工具,使用与 HTTP API 相同的定价引擎。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

DeskPricer v3.5.0

用于欧式和美式普通股期权的本地 HTTP 定价微服务。专为与 Excel WEBSERVICE + FILTERXML 集成而设计——无需 VBA,服务内部也不会调用 Bloomberg 终端。

设计意图: DeskPricer 是一款仅限本地使用的工具,用于个人交易台定价和期权分析。不适合以公共服务或服务器服务的形式运行或提供服务。所有设计选择——绑定 localhost、无身份验证、无 TLS、无速率限制、默认使用 XML——都体现了这一点。


与 AI Agent 配合使用(MCP)

DeskPricer 可作为 MCP 服务使用。将其添加到 Cursor、Claude Desktop 或任何兼容 MCP 的 Agent 中:

pip install deskpricer

已发布到 PyPI:https://pypi.org/project/deskpricer/

Cursor — 添加到 ~/.cursor/mcp.json:

{
  "mcpServers": {
    "deskpricer": {
      "command": "deskpricer-mcp",
      "args": []
    }
  }
}

Claude Desktop — 添加到 claude_desktop_config.json:

{
  "mcpServers": {
    "deskpricer": {
      "command": "deskpricer-mcp"
    }
  }
}

如果 deskpricer-mcp 不在 PATH 中,请使用虚拟环境中该可执行文件的完整路径。

工具:price_option、implied_volatility、pnl_attribution、portfolio_greeks ——使用与 HTTP API 相同的定价引擎。

完整的设置说明、约定和提示词示例,请参阅 docs/mcp_quickstart.md。


快速入门

从干净克隆到成功调用定价接口,不到 5 分钟:

# 1. Install
python -m venv .venv
.venv\Scripts\activate
pip install -e ".[dev]"

# 2. Run
python -m deskpricer.main

# 3. Test with curl
curl "http://127.0.0.1:8765/v1/greeks?s=100&k=105&t=0.25&r=0.05&q=0.02&b=0.0&v=0.20&type=call&style=european"

# 4. Test with Excel (copy into a cell)
# =FILTERXML(WEBSERVICE("http://127.0.0.1:8765/v1/greeks?s=100&k=105&t=0.25&r=0.05&q=0.02&b=0.0&v=0.20&type=call&style=european"),"//outputs/price")

curl 调用的预期输出(XML):

<?xml version="1.0" encoding="UTF-8"?>
<greeks>
  <meta>
    <service_version>3.5.0</service_version>
    <quantlib_version>1.42.1</quantlib_version>
    <engine>analytic</engine>
    <valuation_date>2026-06-10</valuation_date>
  </meta>
  <inputs>
    <s>100.0</s>
    <k>105.0</k>
    <t>0.25</t>
    <r>0.05</r>
    <q>0.02</q>
    <b>0.0</b>
    <v>0.2</v>
    <type>call</type>
    <style>european</style>
  </inputs>
  <outputs>
    <price>2.288743</price>
    <delta>0.356244</delta>
    <gamma>0.037206</gamma>
    <vega>0.185519</vega>
    <theta>-0.033315</theta>
    <rho>0.083111</rho>
    <charm>-0.001241</charm>
  </outputs>
</greeks>

如需 JSON,请发送 Accept: application/json,或附加 ?format=json。


试用演示工作簿

打开 sample/DeskPricer_Bitcoin_Demo.xlsx,查看一个开箱即用的示例。该工作簿包含 3 个工作表:

工作表内容
Greeks比特币欧式看涨期权——现货价 $75K、行权价 $100K、到期时间 3M、波动率 50%
ImpliedVol根据 $3,398.71 的市场价格反推出约 68.3% 的隐含波动率
PnL Attribution分解现货价从 $75K 涨至 $80K、波动率从 50% 扩大至 55% 时的 PnL

每个工作表都已预先填入实际的 WEBSERVICE 和 FILTERXML 公式。只需启动 DeskPricer,单元格就会自动填充。


功能

  • 定价 + Greeks:支持单个期权或多腿投资组合
  • 隐含波动率求解器(通过 QuantLib 使用 Brent 方法)
  • PnL 归因——将期权 PnL 分解为 delta、gamma、vega、theta、rho、vanna、volga 和残差
  • 默认使用 XML——Excel WEBSERVICE + FILTERXML 开箱即用;也可通过 Accept: application/json 使用 JSON
  • 仅限 localhost——绑定到 127.0.0.1;不暴露到网络

约定

Greek单位 / 约定
delta绝对值(∂V/∂S)
gamma绝对值(∂²V/∂S²)
vega每 1% 波动率点
theta每 日历日(ACT/365)。典型的期权多头为负值(时间衰减)。其符号与 Bloomberg DM 相反,后者将 theta 报告为正的衰减值。
rho每 1% 利率点(仅无风险利率;不包含股息收益率或借券成本的 rho)
charm每 日历日(∂delta/∂t)

借券成本(b):可选的年化股票借券成本(十进制)。有效持有成本为 r − q − b。省略该参数或设为 0.0,均与 3.4.0 之前的行为一致。

距到期时间(t):以 ACT/365 下的年数提供。内部会将其转换为日历日(round(t * 365)),并设置最小值为 1 天,然后根据所选日历(默认 hong_kong)顺延至下一个工作日。Theta 和 charm 按日历日而非工作日计算。

PnL 归因:calendar_days 表示实际经过的持仓日历天数。theta_pnl = theta × calendar_days_elapsed。如果未提供估值日期,calendar_days 默认为 1。多日持仓时,请提供明确日期以确保准确性。


安装选项

独立可执行文件(推荐)

从 Releases 页面下载 DeskPricer_v3.exe 并运行:

.\DeskPricer_v3.exe

服务将在端口 8765 上启动。如需使用其他端口:

.\DeskPricer_v3.exe --port 9000
从源代码安装
python -m venv .venv
.venv\Scripts\activate
pip install -e ".[dev]"
python -m deskpricer.main

Excel 用户指南

服务状态

拉取价格前,请检查服务是否正在运行:

单元格公式
状态=IFERROR(FILTERXML(WEBSERVICE("http://127.0.0.1:8765/v1/health"),"//status"),"DOWN")

预期输出: UP


示例 1:为单个期权定价并计算 Greeks

假设工作表中有:

列标签示例值
C现货价格100
K执行价105
T到期时间(年)0.25
R无风险利率0.05
Q股息率0.02
B借贷成本(可选,默认值为 0.0)0.0
V波动率0.20
TYPE期权类型call
STYLE风格european

步骤 1 — 在辅助单元格中构建 URL(例如 H2):

="http://127.0.0.1:8765/v1/greeks?s="&C2&"&k="&K2&"&t="&T2&"&r="&R2&"&q="&Q2&"&b="&B2&"&v="&V2&"&type="&TYPE2&"&style="&STYLE2

步骤 2 — 获取原始 XML(例如 I2):

=WEBSERVICE(H2)

步骤 3 — 将值提取到各个单元格中:

输出公式
价格=VALUE(FILTERXML(I2,"//outputs/price"))
Delta=VALUE(FILTERXML(I2,"//outputs/delta"))
Gamma=VALUE(FILTERXML(I2,"//outputs/gamma"))
Vega=VALUE(FILTERXML(I2,"//outputs/vega"))
Theta=VALUE(FILTERXML(I2,"//outputs/theta"))
Rho=VALUE(FILTERXML(I2,"//outputs/rho"))
Charm=VALUE(FILTERXML(I2,"//outputs/charm"))

上述示例的预期输出:

Greek值
价格2.288743
Delta0.356244
Gamma0.037206
Vega0.185519
Theta-0.033315
Rho0.083111
Charm-0.001241

提示: 将每个 FILTERXML 包装在 IFERROR(...,"ERR") 中,避免某一行出错导致整个工作表无法使用。


示例 2:根据市场价格反推隐含波动率

你观察到同一期权的市场中间价为 6.50,并希望求出隐含波动率。

步骤 1 — 构建 URL(例如 H2):

="http://127.0.0.1:8765/v1/impliedvol?s="&C2&"&k="&K2&"&t="&T2&"&r="&R2&"&q="&Q2&"&b="&B2&"&price=6.50&type="&TYPE2&"&style="&STYLE2

步骤 2 — 提取隐含波动率:

=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/implied_vol"))

预期输出: 0.417484(≈ 41.7 % 波动率)


示例 3:PnL 归因

你昨天(t-1)持有一个头寸,并希望解释今天的 PnL。

假设:

字段t-1 值t 值
现货价格100102
时间0.250.2466
波动率0.200.22
利率0.050.05
股息0.020.02
借贷成本0.00.0
数量10—

步骤 1 — 构建 URL:

="http://127.0.0.1:8765/v1/pnl_attribution?s_t_minus_1=100&s_t=102&k=105&t_t_minus_1=0.25&t_t=0.2466&r_t_minus_1=0.05&r_t=0.05&q_t_minus_1=0.02&q_t=0.02&b_t_minus_1=0.0&b_t=0.0&v_t_minus_1=0.2&v_t=0.22&type=call&style=european&qty=10&cross_greeks=true"

步骤 2 — 提取归因分类:

分类公式
实际 PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/actual_pnl"))
Delta PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/delta_pnl"))
Gamma PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/gamma_pnl"))
Vega PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/vega_pnl"))
Theta PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/theta_pnl"))
Rho PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/rho_pnl"))
Vanna PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/vanna_pnl"))
Volga PnL=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/volga_pnl"))
残差=VALUE(FILTERXML(WEBSERVICE(H2),"//outputs/residual_pnl"))

预期输出:

分类值
price_t_minus_12.288743
price_t3.448862
实际 PnL11.601
Delta PnL7.125
Gamma PnL0.744
Vega PnL3.710
Theta PnL-0.333
Rho PnL0.0
Vanna PnL0.343
Volga PnL0.031
已解释 PnL11.621
残差-0.020

residual_pnl 用于捕捉 t-1 与 t 之间的高阶效应和模型差异。启用 cross_greeks=true 可纳入 vanna 和 volga 的贡献。


示例 4:投资组合 / 批量 Greeks

对于组合层面的汇总,可通过 Power Query 或小型 VBA 辅助工具使用 POST /v1/portfolio/greeks 端点。该端点接受包含多条腿的 JSON 请求体,并返回各腿及汇总 Greeks。

完整的请求/响应架构请参阅 docs/api.md。


希腊字母约定

希腊字母单位说明
Delta绝对值每 1 美元现货价格变动
Gamma绝对值每 1 美元现货价格变动
Vega每 1 个波动率点即小数形式的波动率 × 100
Theta每 日历日经过一个日历日后的远期盈亏(1 个日历日后的重估值 − 今日价格)。对于衰减中的多头期权,该值为负。
Rho每 1 个利率百分点即小数形式的利率 × 100
Charm每 日历日∂delta/∂t(t − 1/365 时的 delta − 今日 delta)。对于看涨期权多头,该值为负 — delta 会随着到期日临近而衰减

日志位置与结构化日志记录

  • 日志路径:DESKPRICER_LOG_DIR 环境变量会覆盖默认路径(Windows 上为 C:\ProgramData\DeskPricer\logs,其他系统上为 ~/.local/share/deskpricer/logs)。
  • 格式:使用 Python 标准库的 logging 模块,搭配自定义 JSON 格式化器和 RotatingFileHandler(每 10 MB 轮换,保留 5 个备份)。这取代了早期手动编写的 open() 方案。
  • 更改路径:
    $env:DESKPRICER_LOG_DIR = "C:\MyLogs"
    python -m deskpricer.main
    

故障排除

QuantLib 安装失败

如果 pip install 在安装 QuantLib 时失败,请确保已安装 C++ 编译器和 CMake,或使用预构建的 wheel。详细步骤请参阅 docs/operator_guide.md。

零日期到期带来的意外情况

t=0 会被设为至少 1 个日历日,以防止 QuantLib 崩溃。你会得到少量时间价值溢价,而不是纯粹的内在价值。这是有意为之。

引擎与行权风格不匹配
  • style=european → 仅支持 engine=analytic
  • style=american → 仅支持 engine=binomial_crr 或 binomial_jr
XML 与 JSON

Excel 默认接收 XML。如需 JSON,请发送 Accept: application/json 或使用 ?format=json。

错误代码
代码含义
INVALID_INPUT业务规则或架构验证失败
UNSUPPORTED_COMBINATION引擎与行权风格不匹配
PRICING_FAILURE意外的内部错误(不会泄露回溯信息)

限制

  • 没有 FD 引擎 — 欧式期权和经济上等价的美式期权使用 BSM 闭式解;其他美式期权使用二叉树 CRR/JR。
  • 通过进程池并发运行 QuantLib — 默认使用 min(4, cpu_count()) 个工作进程(DESKPRICER_WORKERS)。每个请求中的投资组合腿会在单次工作进程调用中批量处理。
  • 有限的扰动范围 — bump_spot_rel ≤ 0.1、bump_vol_abs ≤ 0.01、bump_rate_abs ≤ 0.01。
  • 没有数据库或持久化 — 所有状态均为每个请求独立的内存状态。
  • 没有身份验证、TLS 或速率限制 — 按设计仅供本地使用。

运行测试

pytest tests -v

设计决策

按设计仅供本地使用

DeskPricer 是一款个人桌面工具,而非公共 API。这解释了所有有意省略的功能:

  • 没有身份验证 / 授权 — 只有 127.0.0.1 能访问该服务。
  • 没有 TLS / HTTPS — 按设计,本地环回流量未加密。
  • 没有速率限制 — 不进行节流;并发请求由进程池处理,而不是在单一 QuantLib 全局状态上串行处理。
  • 没有 Swagger / Redoc — 生产版本会隐藏 OpenAPI 文档,以缩小攻击面。
  • 默认使用 XML — Excel 的 WEBSERVICE 函数不会发送 Accept: application/json。

如果你需要这些功能,DeskPricer 并不适合你。请使用正规的 API 网关或功能齐全的定价平台。

QuantLib 为什么在进程池中运行

QuantLib 的 Python 绑定依赖单个进程全局的 Settings.instance() 对象。DeskPricer 不会使用 asyncio.Lock 将所有请求串行化,而是通过 ProcessPoolExecutor 分派 QuantLib 工作。每个工作进程都有独立隔离的设置,因此并发的 Agent 或 Excel 调用可以并行定价,而不会破坏评估日期。进程池大小默认为 min(4, cpu_count()),可通过 DESKPRICER_WORKERS 配置。

欧式期权和经济上等价的美式期权完全绕过 QuantLib,改用纯 Python 的 BSM 实现(bsm_fast),并通过 QuantLib 验证,精度达到小数点后六位。

为什么 PnL 归因使用带有许多查询参数的 GET

Excel 的 WEBSERVICE 函数仅支持 HTTP GET。由于此服务的主要用户是 Excel,因此 GET /v1/pnl_attribution 端点专门针对与 WEBSERVICE 的兼容性进行设计。需要更简洁 JSON 请求正文的编程客户端目前可以使用 POST /v1/portfolio/greeks;未来版本可能会添加用于 PnL 归因的 POST 替代方案。


项目结构

DeskPricer/
├── pyproject.toml
├── README.md
├── src/deskpricer/          # FastAPI app + pricing core
│   ├── app.py               # Thin composition root
│   ├── routers/             # APIRouter modules
│   ├── services/            # Pricing orchestration + QL lock
│   ├── pricing/             # QuantLib pricing engines
│   ├── schemas.py           # Pydantic models
│   ├── responses.py         # XML/JSON serializers
│   ├── errors.py            # Custom exceptions
│   ├── logging_config.py    # Structured JSON logging
│   └── main.py              # Uvicorn entrypoint
├── tests/                   # pytest + hypothesis
├── tests/fixtures/          # Regression baseline JSONs
├── scripts/                 # Build + fixture generation
├── sample/                  # Demo Excel workbook
└── docs/                    # API ref + operator guide

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。