第 7 章 · 03 polygon_api 真相澄清


文档摘要

第 7 章 · 03 polygonapi 真相澄清 本节摘要:本节直面 AutoHedge 一个尴尬的真相—— 文件名叫 polygon,但代码里实际指向的却是 ,而且路径用的还是 polygon 风格的( 、 )。这种「名实不符」是项目未完成的典型缩影:作者大概率起手想用 polygon.io(知名股票数据 API),写了一半换了数据源(massive.com),却没改文件名、没改路径风格、也没改错误日志里的「Polygon API」。

第 7 章 · 03 polygon_api 真相澄清

本节摘要:本节直面 AutoHedge 一个尴尬的真相——autohedge/tools/polygon_api.py 文件名叫 polygon,但代码里实际指向的却是 api.massive.com,而且路径用的还是 polygon 风格的(/v3/reference/tickers/.../v1/open-close/...)。这种「名实不符」是项目未完成的典型缩影:作者大概率起手想用 polygon.io(知名股票数据 API),写了一半换了数据源(massive.com),却没改文件名、没改路径风格、也没改错误日志里的「Polygon API」。本节逐段读这个文件,讲清三个对外函数(get_ticker_overview/get_balance_sheets/get_daily_ticker_summary)各自做什么,并把它和 yahoo_api 对照,说明为什么这个工具实际上没被任何 Agent 用上、为什么是「半成品占位」。读完本节,你会更清醒地看待项目的成熟度。

内容来源:原项目源码 autohedge/tools/polygon_api.py,逐行精读并套用体系化模板。

⚠️ 现实澄清:这个文件是「名实不符」的活样本。文件名 polygon、域名 massive.com、路径 polygon 风格、日志写 Polygon——四处不一致。它没被任何 Agent 绑定,在项目里实际不起作用。本节的价值在「识别半成品」,不在「学怎么用」。

学习目标

阅读完本节,你应当能够:

  1. 逐行读懂 polygon_api.py 的三个对外函数。
  2. 指出文件名、域名、路径、日志四处名实不符的具体位置。
  3. 推断这个文件的演化轨迹(polygon 起手 → 换 massive → 没收尾)。
  4. 解释为什么这个工具没被任何 Agent 用上(不在 get_tools、不在 workers.py)。
  5. 从这个样本学会识别半成品占位,避免被文件名误导。

一、文件开头就露馅:名实不符

先看文件最顶部的模块 docstring 和常量(第 1-14 行):

""" Stocks API client for ticker overview, balance sheets, and daily OHLC. Uses Massive API (https://massive.com/docs). Set MASSIVE_API_KEY and optionally POLYGON_BASE_URL in .env. """ import json import os from typing import Any, Optional import httpx from loguru import logger DEFAULT_BASE_URL = "https://api.massive.com"

逐行细看,矛盾立刻浮现:

  • docstring 第 2 行:自称 Stocks API client(股票 API 客户端)——但文件名是 polygon_api,polygon.io 确实是股票数据商,这点对得上。
  • docstring 第 3 行:「Uses Massive API (https://massive.com/docs)」——突然变成了 massive.com。
  • docstring 第 4 行:「Set MASSIVE_API_KEY and optionally POLYGON_BASE_URL in .env」——同时提到 massive 和 polygon 两个名字,env 变量名也是混的。
  • 第 14 行:DEFAULT_BASE_URL = "https://api.massive.com"——实际请求走的是 massive.com。

这就是第一处名实不符:文件叫 polygon,实际打 massive.com。而且 docstring 自己还残留着「POLYGON_BASE_URL」这个根本没在代码里用到的环境变量名——这是个没清理干净的痕迹。

二、鉴权:又冒出一个 MASSIVE_API_KEY

_get_headers(第 17-22 行):

def _get_headers() -> dict[str, str]: headers: dict[str, str] = {} key = os.getenv("MASSIVE_API_KEY") if key: headers["Authorization"] = f"Bearer {key}" return headers

观察:

  • 读的是 MASSIVE_API_KEY(又一个项目里没在 .env.example 出现的 key,和 EXA_API_KEY 一样是「代码读、配置漏写」)。
  • 鉴权用 Authorization: Bearer <key>——这是 massive.com 的鉴权风格;polygon.io 用的是 apiKey 查询参数或 header。又一个「实指向 massive」的证据。
  • .env.example既没有 MASSIVE_API_KEY,也没有 POLYGON_API_KEY,只有 JUPITER/OPENAI/WALLET 三个。所以这个工具即便被调用,也永远拿不到 key,header 永远是空 dict。

三、错误日志:第三处名实不符

看内部 _get 函数(第 25-42 行):

def _get(path: str, *, params: Optional[dict[str, Any]] = None) -> str: url = f"{DEFAULT_BASE_URL.rstrip('/')}{path}" try: with httpx.Client(timeout=15) as client: resp = client.get( url, params=params, headers=_get_headers() or None, ) resp.raise_for_status() return json.dumps(resp.json()) except httpx.HTTPError as e: logger.error(f"Polygon API request failed: {e}") # ← 日志写 Polygon! raise

注意第 41 行的错误日志:"Polygon API request failed"——但实际请求的是 massive.com。这是第三处名实不符:日志里的名字还是 polygon,会误导排查问题的人。

💡 半成品的指纹:这种「日志名/变量名/文件名和实际行为不一致」,是代码改了一半没改完的典型指纹。生产代码 review 时,看到这种不一致就该追问:「这个文件到底想用哪个服务?为什么没收尾?」

四、三个对外函数:路径全是 polygon 风格

虽然 BASE 是 massive.com,但路径风格还是 polygon.io 的。逐个看。

get_ticker_overview(第 45-72 行)

def get_ticker_overview(ticker: str, date: Optional[str] = None) -> str: ... path = f"/v3/reference/tickers/{ticker.strip()}" params: dict[str, Any] = {} if date: params["date"] = date return _get(path, params=params if params else None)
  • 路径 /v3/reference/tickers/{ticker}polygon.io 的标准路径(polygon 的 ticker reference 端点)。
  • 把这个路径拼到 api.massive.com 后面,大概率 massive.com 根本没有这个端点——请求会 404。
  • 入参支持 date(point-in-time,按某日查),这也是 polygon 的特性。

get_balance_sheets(第 75-149 行)

这是文件里最长的函数,但逻辑很简单——把一堆可选筛选条件塞进 params:

def get_balance_sheets( *, cik: Optional[str] = None, tickers: Optional[str] = None, tickers_any_of: Optional[str] = None, period_end: Optional[str] = None, period_end_gte: Optional[str] = None, period_end_lte: Optional[str] = None, filing_date: Optional[str] = None, fiscal_year: Optional[float] = None, fiscal_quarter: Optional[float] = None, timeframe: Optional[str] = None, limit: Optional[int] = None, sort: Optional[str] = None, ) -> str: params: dict[str, Any] = {} if cik is not None: params["cik"] = cik ... return _get("/stocks/financials/v1/balance-sheets", params=params or None)
  • 11 个全关键字可选参数,每个都是「非 None 才塞进 params」的模式——典型的 polygon 风格筛选 API。
  • tickers_any_of 映射成查询参数 tickers.any_of(带点号),这是 polygon 的命名约定。
  • 路径 /stocks/financials/v1/balance-sheets ——注意这个路径和上面的 /v3/reference/ 风格又不一样,像是 massive.com 的路径风格。所以同一个文件里路径风格都可能是混的。

get_daily_ticker_summary(第 152-189 行)

def get_daily_ticker_summary( stocks_ticker: str, date: str, adjusted: Optional[bool] = None, ) -> str: ... path = f"/v1/open-close/{stocks_ticker.strip()}/{date.strip()}" params: dict[str, Any] = {} if adjusted is not None: params["adjusted"] = "true" if adjusted else "false" return _get(path, params=params if params else None)
  • 路径 /v1/open-close/{ticker}/{date}polygon.io 的日开高低收端点(Daily Open/Close API)。
  • 参数 adjusted(复权)也是 polygon 的标准参数。

五、四处名实不符汇总

把上面看到的矛盾集中成一张表:

位置 内容 指向
文件名 polygon_api.py polygon
docstring Uses Massive API massive
docstring env POLYGON_BASE_URL(代码未用) polygon(残留)
docstring env MASSIVE_API_KEY massive
常量 DEFAULT_BASE_URL = "https://api.massive.com" massive
鉴权 MASSIVE_API_KEY + Bearer massive
错误日志 Polygon API request failed polygon(残留)
路径 /v3/reference/tickers/ polygon 风格 polygon
路径 /v1/open-close/ polygon 风格 polygon
路径 /stocks/financials/v1/balance-sheets massive 风格 massive

四处名字打架:文件名、docstring、域名、日志各说各话。这是项目「写到一半换方向、没回头清理」的铁证。

六、推断演化轨迹

从这些蛛丝马迹,可以合理推断这个文件的演化轨迹:

  1. 起手:作者最初打算用 polygon.io(Solana 之外,股票端最知名的付费数据 API),写好了路径风格、参数风格,文件命名 polygon_api。
  2. 换方向:开发到一半,可能因为 polygon 要付费/审核,改用了 massive.com(一个较新的数据服务),把 BASE_URL 和 docstring 改成 massive。
  3. 没收尾:文件名没改、路径没改、日志没改、.env.example 没加 MASSIVE_API_KEY,甚至连 docstring 里的 POLYGON_BASE_URL 都没删。换完核心逻辑就去做别的了,留下一个半成品。
  4. 未接入:更重要的是,这个文件从未被任何 Agent 用上——workers.py 四个专家没一个 import 它,get_tools() 也没收它。它纯粹躺在 tools 目录里。

七、和 yahoo_api 的对比:为什么 yahoo 留下了,polygon 没接

同样是股票数据工具,为什么 yahoo_api 写得那么认真(限流容错、部分返回),polygon_api 却是个半成品?

维度 yahoo_api polygon_api
数据源 yfinance(免费、非官方) 起手 polygon、实际 massive(付费)
完成度 完整可用,容错细致 半成品,名实不符
是否被 Agent 用 (workers.py 里也没显式绑) 完全没接
教学价值 限流容错典范 半成品识别样本

合理推断:作者发现免费数据源(yfinance)够用之后,就放弃了付费数据源(polygon/massive)的接入,yahoo_api 留下打磨,polygon_api 扔在那。这符合「最小成本跑通 demo」的常见心态。

八、教学价值:学会识别半成品

本节最大的价值,不是「学怎么用 polygon_api」(它根本没被用),而是学会从代码痕迹识别半成品。归纳几个指纹:

  1. 名实不符:文件名、docstring、域名、日志指向不同服务。
  2. 残留变量:docstring 提到代码里根本没用的 env(POLYGON_BASE_URL)。
  3. 风格混杂:同文件内路径风格不统一(有的 /v3/reference/、有的 /stocks/...)。
  4. 配置缺失:代码读的 env(MASSIVE_API_KEY)在 .env.example 里没列。
  5. 无人调用:全项目搜不到对它的 import / 调用(除了可能的旧入口)。
  6. 错误信息陈旧:日志还写着旧服务的名字。

⚠️ 现实澄清:看到这种文件,别被「文件名叫 polygon」骗去配 polygon API key——配了也没用,代码根本不打 polygon。也别花时间想「怎么把它接给 Agent」,作者自己都没接。它的正确处理方式是:要么补完(确定用哪个服务,改对名字,接入 Agent),要么删掉(承认这是 abandoned code)。现状是「既没补完也没删」,纯粹占地方。

本节要点回顾

  1. 名实不符:文件名 polygon、docstring 提 massive、BASE 是 api.massive.com、日志写 Polygon——四处打架。
  2. 演化推断:起手 polygon.io → 中途换 massive.com → 没清理文件名/路径/日志/env → 留下半成品。
  3. 三个函数:get_ticker_overview(/v3/reference/tickers/)、get_balance_sheets(11 个筛选参数)、get_daily_ticker_summary(/v1/open-close/)——路径都是 polygon 风格,拼到 massive 域名下大概率 404。
  4. 鉴权用 MASSIVE_API_KEY + Bearer:和 polygon 的 apiKey 鉴权不同;且这个 key 在 .env.example 里根本没列。
  5. 从未被接入:workers.py 四个专家没一个用它,get_tools() 也没收它——纯占位。
  6. 半成品指纹:名实不符、残留变量、风格混杂、配置缺失、无人调用、日志陈旧——看到这些就该警惕。
  7. 与 yahoo 对比:同样股票数据工具,yahoo 完整打磨、polygon 半成品——合理推断作者弃用付费源、留用免费源。

至此第 7 章结束,你看清了 AutoHedge 的数据工具层:yahoo 限流容错认真做、Jupiter 官方 API 对称设计、polygon 名实不符的占位。下一章我们进入全教程技术密度最高的部分——Solana 链上交易实战,从账户与密钥模型开始。


发布者: 作者: 灏天文库 转发
评论区 (0)
U