关于 digital-oracle
一种用市场交易数据回答市场、经济和资产问题的分析技能,面向需要结构化判断的用户。它要求至少三个独立信号交叉验证,并按信号表、矛盾分析和概率情景组织报告。
主要功能
- 01仅以交易数据作为依据
- 02跨至少三个维度验证信号
- 03按问题与时间范围筛选信号
- 04调用多种市场数据提供方
- 05输出结构化概率情景分析
适用场景
- 01评估衰退或行业周期风险
- 02分析股票、期权或资产价格
- 03依据市场信号评估地缘冲突风险
- 04分析中国 A 股的资金流向
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ komako-workshop/ digital-oracle --skill digital-oracle安装后在 Claude Code 中输入/digital-oracle确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
ITERATION_PLAN.md.gitignoreLICENSEREADME.en.mdREADME.mddigital_oracle/__init__.pycache.pyhttp.pyconcurrent.pyproxy_pool.pysnapshots.pydigital_oracle/providers/_coerce.py__init__.pybase.pycme_fedwatch.pybis.pyedgar.pyderibit.pycftc.pycoingecko.pypolymarket.pyeastmoney.pykalshi.pyfear_greed.pyprices.pyweb.pyworldbank.pystooq.pytreasury.pyyahoo.py详细介绍
digital-oracle
市场是有效的。价格包含所有公开信息。读懂价格 = 读懂市场共识。
方法论
仅使用市场交易数据回答问题,不以新闻、观点或统计报告作为因果证据。 如果某件事属实,某个市场早已将其反映在价格中。
五条铁律:
- 仅使用交易数据——价格、成交量、未平仓合约、价差、溢价。绝不引用分析师观点。
- 明确说明从价格到判断的推理过程——清楚解释“为什么这个价格能回答这个问题”。
- 使用多个信号交叉验证——绝不根据单一信号下结论。至少涵盖 3 个独立维度。
- 标注每个信号的时间范围——期权价格反映 3 个月,设备订单反映 3 年;不要把它们混在同一项判断中。
- 采用结构化输出——最终报告必须遵循第 5 步模板:分层信号表 → 矛盾分析 → 概率情景 → 信号一致性评估。不得用散文替代结构化报告。
工作流
第 1 步:理解问题
将用户的问题拆解为:
- 核心变量:是什么事件或趋势?
- 时间范围:用户问的是 3 个月、1 年还是 5 年?
- 可定价性:市场上是否有人真金白银地交易这一结果?
第 2 步:选择信号
根据问题类型,从以下信号菜单中选择。不要只使用一个类别——至少涵盖 3 个类别。
地缘政治冲突 / 战争风险
- Polymarket:搜索相关事件合约(停火、入侵、政权更迭、宣战)
- Kalshi:搜索相关二元合约
- 避险资产:黄金(GC=F)、白银(SI=F)、瑞士法郎(USDCHF=X)
- 冲突代理指标:原油(CL=F)、天然气(NG=F)、小麦(ZW=F)、国防 ETF(ITA)、国防类股票
- 风险比率:铜金比(风险规避指标)、金银比
- CFTC COT:原油 / 黄金 / 小麦的机构持仓变化(聪明资金押注的方向)
- BIS:相关国家的央行政策利率走势
- FearGreedProvider:CNN 恐惧与贪婪指数(由 7 个价格信号构成的综合指标)
- 网络搜索:VIX、MOVE 指数、主权 CDS、战争风险溢价、BDI 运费、高收益债 OAS
- 货币:相关国家的货币对(例如 USDRUB=X、USDCNY=X)
- 国家 ETF:相关国家的资产流动(例如 FXI、EWY)
经济衰退 / 宏观周期
- Treasury:收益率曲线形态(10Y-2Y 利差、10Y-3M 利差)、实际利率、盈亏平衡通胀率
- YahooPriceProvider:SPY、铜(HG=F)、原油(CL=F)的价格走势
- 风险比率:铜金比
- CFTC COT:铜 / 原油的投机性净持仓(管理资金看涨还是看跌)
- BIS:信贷与 GDP 缺口(信贷过热 = 周期后期)、政策利率方向
- World Bank:GDP 增长率的历史走势、跨国比较
- Deribit:BTC 期货基差(风险偏好代理指标)
- CoinGecko:加密货币总市值 + BTC 市占率(风险偏好代理指标)
- FearGreedProvider:CNN 恐惧与贪婪指数(由 7 个价格信号构成的综合指标 → 0-100)
- Kalshi
KXFED系列:FOMC 利率决策合约。(用它判断利率路径——CMEFedWatchProvider 目前在所有已测试主机上都被 CME 的机器人防护机制以 403 拒绝。) - Polymarket:衰退相关合约、央行利率路径
- 货币:DXY / 美元强弱、新兴市场货币
- 网络搜索:高收益债利差(HY OAS)、TED 利差、MOVE 指数、TTF 天然气、BDI 运费
行业周期 / 泡沫评估
- YahooPriceProvider:行业龙头股走势、行业 ETF
- 找出行业的“单一用途商品”(例如,GPU 租赁价格 → AI,螺纹钢 → 建筑业)
- 上游设备制造商的订单 / 股价(例如,ASML → 半导体)
- 龙头公司的估值折价(例如,TSMC 相较于同行 → 台湾海峡风险定价)
- EDGAR:行业龙头内部人士的交易节奏(Form 4)——集中卖出 = 看跌信号
- CFTC COT:相关大宗商品的机构持仓变化
- CoinGecko:对于加密行业,关注 BTC/ETH/山寨币的市值分布
- 网络搜索:VC 融资集中度、杠杆 ETF 集中度、保证金债务水平
- Deribit:相关加密资产的隐含波动率
资产定价 / 是否买入
- YahooPriceProvider:目标资产价格走势(日线 / 周线 / 月线)
- 相关资产的相对价格变化(两种大宗商品价格背离 = 结构性信号)
- Treasury:作为估值锚的无风险利率
- YFinance:期权链(IV、看跌 / 看涨比率、最大痛点、希腊值、隐含波动幅度)
- EDGAR:内部人士卖出节奏(大量 Form 4 卖出 = 内部人士看跌)
- CFTC COT:大宗商品资产投机者与商业交易者的净持仓背离
- CoinGecko:对于加密资产,查看市值、距 ATH/ATL 的幅度、24 小时波动率
- Deribit:加密期权链(隐含波动率 = 市场预期区间)
- Polymarket/Kalshi:相关事件的概率定价
- FearGreedProvider:CNN 恐惧与贪婪综合评分(动量、市场广度、VIX、看跌 / 看涨比率、垃圾债需求、波动率、避险资产)
- 网络搜索:VIX、公司债券发行量、分析师评级分布
股票 / 期权分析 / 暴跌概率
- YFinance:期权链 → 平值期权 IV(预期波动率)、IV 偏斜(上行 / 下行恐惧不对称性)、看跌 / 看涨比率(多空情绪)、最大痛点(做市商获利区间)、隐含波动幅度(预期价格区间)、希腊值(delta ≈ 价内概率)
- YahooPriceProvider:标的历史价格 → 已实现波动率(与隐含波动率比较,以判断期权溢价)
- Kalshi:SPY/NASDAQ 价格区间市场 → 直接进行概率定价
- CFTC COT:S&P 500/VIX 期货持仓 → 机构方向
- 防御性轮动:XLY(周期性)相较于 XLP(防御性)和 XLU(公用事业)的相对表现 → 市场防御性
- Treasury:收益率曲线形态 → 衰退信号
- FearGreedProvider:CNN 恐惧与贪婪指数
- 网络搜索:VIX 水平、保证金债务水平、杠杆 ETF 集中度
中国 A 股:个股 / ETF / 板块
A 股在境内交易所上市,以人民币报价,没有美国市场的价格,因此常见的 Polymarket/Kalshi/CFTC 数据层无法提供相关信息。请改用东方财富。
- 东方财富
get_quote:查询 6 位代码的实时行情 → 最新价、涨跌幅、换手率、市盈率(TTM)、市净率、市值。传入纯代码(600519、000977)即可,to_secid会解析交易所。 - 东方财富
get_fund_flow:**真正投入资金的信号。**按单笔委托规模拆分每日净流入:超大单 / 大单(合称「主力」,即机构)与中单 / 小单(散户)。机构买入而散户卖出,与情况相反时的盘面截然不同,单看价格无法看出这一点。 - 东方财富
list_sector_fund_flow:按机构净流入对行业或概念板块进行排名 → 资金正在轮动进入哪些板块。可直接回答「哪个板块有资金流入」。 - 东方财富
get_history:提供前复权(adjust="forward")的 OHLCV → 可用于分析实际波动率、趋势和成交量确认。 - YahooPriceProvider:通过
600519.SS/000977.SZ后缀查询相同股票 — 可用于交叉验证,也是将 A 股与美国可比标的放在同一维度比较的唯一方式。 - FXI / USDCNY=X:反映境外投资者对中国资产的风险偏好和资金流向 — 从离岸市场视角审视同一问题。
- 板块联动解读:对于半导体 / AI 硬件,可与美国可比标的(NVDA、AMD、SOXX)交叉验证,因为它们共用同一条供应链。
有两点需要注意。东方财富在收盘后发布资金流数据,因此盘中问题只能看到前一天的情况。另外,没有针对中国个股的预测市场价格 — 如果用户想要概率,就必须根据持仓和波动率进行推断,而不能直接查到。
**可用交易标的目录:**见 references/symbols.md **提供方 API 参考:**见 references/providers.md
第 3 步:信号路由
在获取数据之前,根据以下三项标准评估第 2 步中的每个候选信号:
- 相关性:该信号能否实际回答用户的具体问题?(例如,询问台湾 → 跳过 CoinGecko)
- 时间匹配:该信号的定价周期是否与问题的时间范围匹配?(例如,询问 3 个月后的情况 → 跳过滞后 1–2 年的世界银行 GDP 数据)
- 信息增量:该信号是否提供其他信号尚未涵盖的独立视角?避免重复,保留互补信号。
只保留通过全部三项检查的信号。这样可以减少噪声、节省数据获取时间,并让分析更清晰。
第 4 步:获取数据
使用 digital-oracle 的 Python 提供程序获取结构化数据,通过 gather() 并行调用所有来源(包括网络搜索):
from digital_oracle import (
PolymarketProvider, PolymarketEventQuery,
KalshiProvider, KalshiMarketQuery,
YahooPriceProvider, PriceHistoryQuery, # requires uv pip install yfinance
DeribitProvider, DeribitFuturesCurveQuery,
USTreasuryProvider, YieldCurveQuery,
WebSearchProvider,
CftcCotProvider, CftcCotQuery,
CoinGeckoProvider, CoinGeckoPriceQuery,
EdgarProvider, EdgarInsiderQuery,
BisProvider, BisRateQuery,
WorldBankProvider, WorldBankQuery,
YFinanceProvider, OptionsChainQuery, # requires uv pip install yfinance
FearGreedProvider,
EastmoneyProvider, EastmoneyQuoteQuery, EastmoneyKlineQuery,
EastmoneyFundFlowQuery, EastmoneySectorFlowQuery,
gather,
)
pm = PolymarketProvider()
kalshi = KalshiProvider()
yahoo = YahooPriceProvider() # requires uv pip install yfinance
deribit = DeribitProvider()
treasury = USTreasuryProvider()
web = WebSearchProvider()
cftc = CftcCotProvider()
coingecko = CoinGeckoProvider()
edgar = EdgarProvider() # set EDGAR_USER_EMAIL to identify yourself to SEC; a contact is required or it 403s
bis = BisProvider()
wb = WorldBankProvider()
yf = YFinanceProvider() # requires uv pip install yfinance
fear_greed = FearGreedProvider()
eastmoney = EastmoneyProvider() # China A-share: quotes, OHLCV, fund flow, sector rotation
result = gather({
"pm_events": lambda: pm.list_events(PolymarketEventQuery(slug_contains="...", limit=10)),
"yield_curve": lambda: treasury.latest_yield_curve(),
"gold": lambda: yahoo.get_history(PriceHistoryQuery(symbol="GC=F", limit=30)),
# Institutional positioning
"gold_cot": lambda: cftc.list_reports(CftcCotQuery(commodity_name="GOLD", limit=4)),
# Crypto market sentiment
"crypto": lambda: coingecko.get_prices(CoinGeckoPriceQuery(coin_ids=("bitcoin", "ethereum"))),
# Insider trades
"insider": lambda: edgar.get_insider_transactions(EdgarInsiderQuery(ticker="AAPL", limit=10)),
# Central bank policy rates
"rates": lambda: bis.get_policy_rates(BisRateQuery(countries=("US", "CN"), start_year=2023)),
# GDP data
"gdp": lambda: wb.get_indicator(WorldBankQuery(indicator="NY.GDP.MKTP.CD", countries=("US", "CN"))),
# BTC futures term structure (risk appetite proxy)
"btc_futures": lambda: deribit.get_futures_term_structure(DeribitFuturesCurveQuery(currency="BTC")),
# Kalshi event markets (use event_ticker or series_ticker, not keyword search)
"kalshi_fed": lambda: kalshi.list_markets(KalshiMarketQuery(series_ticker="KXFED", limit=10)),
# Options chain (with Greeks)
"spy_options": lambda: yf.get_chain(OptionsChainQuery(ticker="SPY", expiration="2026-04-17")),
# CNN Fear & Greed (composite of 7 price signals)
"fear_greed": lambda: fear_greed.get_index(),
# China A-share: institutional vs retail flow, and which sector money rotated into
"cn_stock": lambda: eastmoney.get_quote(EastmoneyQuoteQuery(symbol="002156")),
"cn_flow": lambda: eastmoney.get_fund_flow(EastmoneyFundFlowQuery(symbol="002156", limit=10)),
"cn_sectors": lambda: eastmoney.list_sector_fund_flow(EastmoneySectorFlowQuery(limit=15)),
# Web search runs in parallel with structured providers
"vix": lambda: web.search("VIX index current level"),
"hy_spread": lambda: web.search("US high yield bond spread OAS"),
})
# Partial failures don't affect other results
curve = result.get("yield_curve")
vix_info = result.get_or("vix", None) # WebSearchResult — use .text() to render
# Options data usage
chain = result.get_or("spy_options", None)
if chain:
print(f"ATM IV: {chain.atm_iv:.1%}, Implied move: {chain.implied_move():.1%}")
print(f"Put/Call OI ratio: {chain.put_call_oi_ratio:.2f}")
print(f"Max pain: {chain.max_pain()}")
全部 14 个提供程序:
| 提供程序 | 数据类型 | 用途 | 依赖项 |
|---|---|---|---|
| PolymarketProvider | 预测市场合约 | 事件概率定价 | stdlib |
| KalshiProvider | 二元合约 | 美国受监管的事件合约 | stdlib |
| YahooPriceProvider | 价格历史 | 股票/ETF/外汇/大宗商品 | yfinance |
| DeribitProvider | 加密货币衍生品 | 期货期限结构、期权 IV | stdlib |
| USTreasuryProvider | 美国国债收益率 | 收益率曲线、通胀预期 | stdlib |
| WebSearchProvider | 网络搜索 | VIX/MOVE/CDS/BDI 补充数据 | stdlib |
| CftcCotProvider | 期货持仓 | 机构方向(聪明资金) | stdlib |
| CoinGeckoProvider | 加密货币现货 | BTC/ETH 价格、市值、占比 | stdlib |
| EdgarProvider | SEC 文件 | 内幕交易 Form 4、文件搜索 | stdlib |
| BisProvider | 央行数据 | 政策利率、信贷与 GDP 缺口 | stdlib |
| WorldBankProvider | 发展指标 | GDP、人口、贸易、宏观数据 | stdlib |
| YFinanceProvider | 美国期权链 | IV、Greeks、看跌/看涨比率、最大痛点 | yfinance |
| FearGreedProvider | 市场情绪 | CNN 7 项信号综合 → 0–100 分 | stdlib |
| EastmoneyProvider | 中国 A 股 | 行情、OHLCV、按订单规模划分的资金流、板块轮动 | stdlib |
| CMEFedWatchProvider | 利率概率 | 目前被 CME 以 403 错误拦截 — 请使用 Kalshi KXFED | stdlib |
15 个提供程序中有 13 个无需外部依赖,也无需 API 密钥。YahooPriceProvider 和 YFinanceProvider 需要执行
pip install yfinance。
WebSearchProvider 用法:
web.search("query")→ 返回WebSearchResult(搜索摘要)— 使用.text()渲染web.fetch_page("url")→ 返回WebPageContent(页面正文提取内容)- 搜索引擎为 DuckDuckGo,无需 API 密钥
结构化提供程序无法获取的数据 — 请改用网络搜索: VIX、MOVE、CDS 利差、TTF 天然气、BDI 运费、战争风险溢价、高收益债 OAS — 这些数据需要从金融网页获取。它们仍属于交易数据,符合方法论。
步骤 5:数据分析
这是报告质量的关键。不要只总结数据,还要从数据中得出判断。
四个分析维度:
-
信号解读:每个数据点说明了什么?从价格中推断含义。不要只说“黄金上涨 3%”,而要说“市场正在计入尾部风险”。例如,铜金比下降 → 工业需求弱于避险需求 → 风险规避。
-
交叉验证:哪些信号指向同一方向(共振)?哪些信号相互矛盾(背离)?背离本身就是高价值信号。例如,黄金发出“灾难”信号,但股票市场表现“良好” → 两个市场对不同时间窗口进行了定价。
-
时间对齐:按定价期限对信号分组。不要把不同时间窗口的信号放在同一轮判断中。
- 短期(3-12 个月):预测市场合约、VIX/MOVE、价格反应模式、高管抛售
- 中期(1-3 年):行业领军企业收入一致预期、资本支出计划、风险投资集中度、杠杆集中度
- 长期(3-10 年):设备制造商订单、不可逆的资本配置、超长期基础设施投资
- 短期看跌 + 长期看涨 ≠ 矛盾,= S 曲线拐点
-
权重判断:并非所有信号都同样可靠。有真实资金支持的信号 > 调查结果。流动性高的市场 > 流动性低的市场。直接定价 > 间接代理指标。例如,Polymarket 高流动性合约 > CDS 报价(更新缓慢、流动性低)。
核心原则:不要按多数表决。 当信号出现分歧时:
- 首先检查时间维度——不同信号对不同的未来时间窗口进行定价
- 留意“两个趋势同时发生”——旧经济的日本化 + 新经济繁荣可以并存
- 考虑“方向正确,但时机不对”——长期看涨,但短期过热 → 等待回调
步骤 6:输出报告
必须遵循以下结构。 可以调整层级数量和措辞,但不能省略四个主要部分(数据摘要、分析、概率估计、结论),也不能将它们合并成文字段落:
# [Question Title]: Multi-Signal Synthesis
## Data Summary
### Layer 1: [Most direct signal source]
| Signal | Data | What it's saying |
|--------|------|-----------------|
(table, one signal per row, third column is reasoning from price to meaning)
### Layer 2: [Secondary signal source]
(same format)
### Layer N: ...
(as needed, typically 3-5 layers)
## Analysis
### Resonance signals
(which signals point in the same direction, and what judgment they form)
### Key divergences
(A says X, B says Y → explain why + who is more credible)
### Time stratification
(what do short-term / medium-term / long-term signals each point to)
## Probability Estimates
| Scenario | Probability | Basis |
|----------|-------------|-------|
### Most likely path: [one-sentence summary]
**Core logic chain:** (2-3 paragraphs, reasoning from data to conclusion)
## Conclusion
> [One-sentence summary, preferably including a specific probability estimate]
### Sub-conclusions
| Dimension | Judgment | Confidence |
|-----------|----------|------------|
| Short-term (6-12mo) | ... | High/Medium/Low |
| Medium-term (1-3yr) | ... | High/Medium/Low |
| Long-term (3-5yr) | ... | High/Medium/Low |
| Systemic risk | ... | High/Medium/Low |
(adjust dimensions to match the question — e.g., replace "systemic risk" with whatever dimension is most relevant)
### Risk factors
- **Upside risk:** what scenario would make things better than expected
- **Downside risk:** what scenario would make things worse than expected
### Signals to monitor
| Signal | Current value | Threshold | Meaning |
|--------|--------------|-----------|---------|
| ... | ... | if crosses X | then Y |
(3-5 concrete signals with specific trigger levels and what they would imply)
---
*Data sources: [list all structured and web data sources]*
*Fetched at: [date]*
说明
- Polymarket 的
slug_contains搜索为模糊搜索——获取结果后,再按标题关键词筛选 - YahooPriceProvider 使用 Yahoo Finance 的代码:期货代码以
=F为后缀(例如GC=F、CL=F、HG=F),外汇代码以=X为后缀(例如EURUSD=X),美股 / ETF 使用普通代码(例如SPY、LMT) - YahooPriceProvider 需要
yfinance——使用uv pip install --target .deps yfinance安装 - Yahoo Finance 上可以通过交易所后缀查询欧洲股票(例如,Rheinmetall 的代码是
RHM.DE,BAE Systems 的代码是BA.L) - 预测市场合约的流动性各不相同——成交量低于 100K USD 的合约应降低权重
- 不同信号的更新频率不同:预测市场为实时更新,Yahoo Finance 有每日延迟,Treasury 为每周更新
- CFTC COT 在周二更新,周五发布。commodity_name 使用大写形式("GOLD"、"CRUDE OIL"、"S&P 500")
- CoinGecko 免费 API 有速率限制(约 10–30 次请求 / 分钟)——在 gather 中不要安排过多 CoinGecko 调用
- EDGAR 需要
EdgarProvider(user_email="[email protected]")——SEC 要求 User-Agent 中包含电子邮件,否则会返回 403。首次调用会解析代码到 CIK 的映射,因此速度稍慢 - BIS 数据更新不频繁(每月 / 每季度)——适合观察长期趋势,不适合短线交易
- World Bank 的 GDP 数据通常滞后 1–2 年——最新年份可能返回
None - YFinance 需要
uv pip install yfinance(会自动安装 pandas)。盘后 IV 可能不准确(bid/ask = 0)——请在交易时段使用 - YFinance 的
get_chain()会自动计算 Black-Scholes Greeks(使用纯标准库math.erf,无需 scipy) - 看跌期权 delta 的绝对值 ≈ 到期时执行价处于价内的概率(粗略估计)
- Put/Call 比率 > 1.5 通常看跌,但作为反向指标,极端值(> 3)可能预示底部
- Max pain 是使做市商利润最大化的行权价——实际到期价格通常会向 max pain 靠拢
- Kalshi 不支持关键词搜索——使用
series_ticker或event_ticker筛选市场。可通过浏览 kalshi.com 查找代码,或先不加筛选条件列出市场。常见系列:KXFED(Fed 利率)、KXINX(S&P 500 区间)、KXGDP(GDP) - Deribit 的期货方法是
get_futures_term_structure(),不是get_futures_curve()。期权链方法是get_option_chain() - FearGreedProvider 无需 API 密钥。它返回一个综合分数(0–100),由 7 个市场价格信号综合得出:股票动能、市场广度、VIX、Put/Call 比率、垃圾债券需求、波动率、安全资产需求。分数 < 25 = 极度恐惧,> 75 = 极度贪婪
- CMEFedWatchProvider 目前无法使用:无论从住宅网络还是数据中心主机测试,CME 的机器人防护都会对所有 User-Agent 返回 403。不要在它上面浪费一次往返请求——直接使用 Kalshi
KXFED获取利率路径 - EdgarProvider 需要在 User-Agent 中提供联系人信息,否则 SEC 会返回 403。现在默认提供了联系人信息,但请设置
EDGAR_USER_EMAIL,以便根据 SEC 的公平访问政策正确标识自己 - BIS 的
get_credit_to_gdp()返回的是缺口(相对长期趋势的偏离值,例如美国约为 -12 个百分点),而不是信贷与 GDP 的原始比率(约为 140%)。如果需要比率水平,请传入series=CREDIT_GAP_SERIES["ratio"]。两位数的正缺口是经典的信贷泡沫预警信号 - EastmoneyProvider 接受不带前缀的 6 位 A 股代码;
to_secid()会解析交易所(6xxxxx/5xxxxx/9xxxxx→ 上海,其余 → 深圳)。资金流向金额以 CNY 计,并在收盘后发布。main_net=extra_large_net+large_net,即机构资金;medium/small为散户资金 - Eastmoney 会按源 IP 限流;行情 / 资金流向 / 板块数据会自动回退到其延迟主机。
get_history会优先从 Tencent 获取数据,仅在必要时回退到 Eastmoney,因为 Eastmoney 的历史数据主机受到的限流最严格——这意味着来自 Tencent 的 K 线中turnover_cny为None,但 OHLCV 数据完整 - 报告美元金额时,请使用
USD而不是$,以免 Markdown 渲染器将$...$解释为 LaTeX