我早期接美股数据时,以为拿到 AAPL 的实时价格和日线 K 线就够了。REST 调通,K 线能画,看起来一切正常。 后来才发现,盘前盘后的 5.5 小时可交易窗口我完全没覆盖,财报日历是手动维护的,字段名和文档对不上——写代码要反复试错,AI Agent 也调不通数据,因为只有 REST 没有 MCP。 这些坑不是因为接口调不通,而是因为一开始就没看清美股数据到底有几层。 美股数据不是接口问题,是分层问题。 这篇文章要做两件事:第一,把美股数据的五层结构摊开,让你在写第一行接入代码前就能画出数据架构图;第二,以一套统一 API 服务为具体参考,把每一层的实际字段、参数、边界条件讲清楚。读完你就能判断自己的项目需要接哪几层、在哪一层停。 美股数据能力全景图 先看整体结构。从行情到 AI 接入,是一条五层的链路: ┌─────────────────────────────────────────────────────────────┐ │ Layer 5:AI-native 接入(怎么用) │ │ REST │ WebSocket │ MCP │ CLI │ Skill │ └──────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────▼──────────────────────────────────┐ │ Layer 4:基本面(公司值多少) │ │ 财务三表 │ 估值 │ 行业 │ 股东 │ 公司档案 │ └──────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────▼──────────────────────────────────┐ │ Layer 3:公司行动(除权除息、拆股) │ │ 分红 │ 回购 │ 公司行动 │ 除权日 │ └──────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────▼──────────────────────────────────┐ │ Layer 2:事件驱动(什么时候发生什么) │ │ 财报日历 │ 预估/实际 EPS │ 营收预估/实际 │ └──────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────▼──────────────────────────────────┐ │ Layer 1:行情(市场发生了什么) │ │ 快照 │ K线 │ 盘前盘后 │ 盘口 │ 逐笔 │ 交易时段 │ └─────────────────────────────────────────────────────────────┘ Layer 1 是地基,Layer 2–4 是纵深,Layer 5 是出口。五层缺一层,你的数据管道就会在某个节点断掉。 下面的内容以 TickDB 为参考实现,它的美股能力覆盖了这五层。先建立结构,再看细节。 五层能力速查 层级 解决什么问题 你什么时候需要它 核心接口/字段 谁用它 Layer 1 实时价格 + 盘前盘后 盘中信号、盘前 gap get_ticker、pre_market_quote、post_market_quote 盘中策略、看板、Agent Layer 2 事件驱动(财报日历) 财报季前后事件响应 calendar?market=US&category=report、value_type 事件策略、风控 Layer 3 公司行动(股息/除权) 回测处理除权跳空 dividends、corp-actions、ex_date 红利策略、回测 Layer 4 基本面季报 基本面选股、估值过滤 financials/latest、OperatingRevenue、NetProfit、EPS 多因子、估值 Layer 5 AI-native 接入 LLM 工作流取数 REST、WebSocket、MCP、CLI、Skill AI 应用、Agent 这张表的正确读法:不是让你五层全接,而是让你先确认自己的项目在哪一层停。停在 Layer 1 可以,但要知道 Layer 2 的缺口会在财报季暴露。 你是哪类读者 你 → 打开文章 │ ├── 个人量化开发者 │ └─→ Layer 1 + 2 + 最小可用组合 │ ├── 小团队数据工程师 │ └─→ Layer 1–4 + 数据架构建议 │ ├── AI 工具使用者 │ └─→ Layer 5 + Agent 取数工作流 │ └── 金融应用团队 └─→ Layer 5 + 边界 + POC 验收清单 Layer 1:行情——美股从 4AM ET 就开始交易,A 股 9:30 才有第一笔 这是第一层。你接了吗? A 股 9:30 开盘,9:15 集合竞价,盘前没有连续交易。美股不一样:东部时间 4:00 开始盘前交易,9:30 正式开盘,16:00 收盘,16:00–20:00 盘后交易。 一天 16 个小时有价格。如果你只接 last_price,盘前盘后的价格你完全拿不到,策略漏掉每天 5.5 小时的可交易窗口。 盘前盘后行情数据怎么用 API 接入,和 A 股有什么区别? 这个问题就在这里展开。 实时快照 我实测了 get_ticker,返回里盘前、盘中、盘后是三个独立嵌套对象: import requests API_KEY = "your_api_key" BASE_URL = "https://api.tickdb.ai/v1" HEADERS = {"X-API-Key": API_KEY} resp = requests.get( f"{BASE_URL}/market/ticker", params={"symbols": "AAPL.US"}, headers=HEADERS, ) data = resp.json()["data"][0] # 三个时段的报价对象 pre = data.get("pre_market_quote", {}) post = data.get("post_market_quote", {}) overnight = data.get("overnight_quote", {}) print("盘前 last_done:", pre.get("last_done")) print("盘后 last_done:", post.get("last_done")) print("夜盘 last_done:", overnight.get("last_done")) print("时间戳:", data.get("timestamp")) 运行后你应该看到:pre_market_quote、post_market_quote、overnight_quote 三个对象,每个包含 last_done、timestamp、volume、quote_volume、high、low、prev_close。时间戳是整数 Unix 毫秒,例如 1789588801000。 注意我用 .get() 处理缺失。盘前盘后对象在非交易时段可能为空,不要假设每个标的、每个时刻都返回相同对象。 交易时段 我调用 GET /v1/market/trading-sessions?market=US,返回 data[0].trading_sessions[],三段数值区间: begin_time–end_time 额外字段 400–930 trade_session: 1 930–1600 无trade_session 字段 1600–2000 trade_session: 2 响应没有返回 pre_market、regular、post_market 的文本枚举。你需要在代码里自己做数值映射: sessions = requests.get( f"{BASE_URL}/market/trading-sessions", params={"market": "US"}, headers=HEADERS, ).json()["data"][0]["trading_sessions"] SESSION_MAP = {1: "pre_market", 2: "post_market", None: "regular"} for s in sessions: name = SESSION_MAP.get(s.get("trade_session")) print(f"{name}: {s['begin_time']} - {s['end_time']}") K 线与历史行情 get_kline 可以取 AAPL 日线,返回 data.klines。复权支持 none、forward、backward。前复权适合实时信号,后复权适合历史比较分析,混用会产生系统性误差。 klines = requests.get( f"{BASE_URL}/market/kline", params={"symbols": "AAPL.US", "interval": "1d", "adjust": "forward", "limit": 20}, headers=HEADERS, ).json()["data"]["klines"] for k in klines[-3:]: print(k["timestamp"], k["open"], k["close"], k["volume"]) 运行后你应该看到:最近 20 根日线,每根含 timestamp、open、high、low、close、volume。 盘口与逐笔 get_order_book 返回多档买卖盘,get_trades 返回逐笔成交。盘口对时延极度敏感,用之前必须验证目标市场的实际可用性,不能从接口存在推断全市场覆盖。本次实测为 L1 盘口,非 Level 2 深度。 Layer 1 的关键认知 如果你只接了 last_price,盘前盘后的 5.5 小时可交易窗口你完全没覆盖。 本层实测边界:以上字段基于 2026-09-17 对 AAPL.US 的单次调用。盘前报价是否从 4:00 ET 起持续可取、每只美股是否返回相同对象,待补测。 自建成本:如果你只需要日线,免费方案可以覆盖。但盘前盘后字段的完整性、trade_session 数值映射、WebSocket 断线重连,自建需要持续维护。到这里停,成本是几小时;要继续到 Layer 2,成本开始按周计算。 Layer 2:事件驱动——财报日历,全市场事件流才是正确打开方式 这是第二层。第一层加第二层,事件驱动策略的基础设施就有了。 我一开始以为财报日历是传入 AAPL 就返回 AAPL 的财报日期。实测发现不是。 TickDB 的 calendar 端点返回的是全市场 report 事件流。我调用: GET /v1/fundamentals/calendar?market=US&category=report&from=2026-09-17&to=2026-12-31 返回结构是 data.events[]。每个事件包含 category、event_datetime、symbol、event_type、date_type、content、market、counter_name、currency、star,以及 data[]。后者通过 value_type 区分 estimate_eps、estimate_revenue、actual_eps、actual_revenue,数值在 value_raw / value_text。 这反而更强。 按标的查,只能做单标的的事件响应;全市场事件流,可以一次拉全市场,为自己的股票池做批量事件过滤。这才是量化团队真正需要的数据管道设计。 resp = requests.get( f"{BASE_URL}/fundamentals/calendar", params={ "market": "US", "category": "report", "from": "2026-09-17", "to": "2026-12-31", }, headers=HEADERS, ) events = resp.json()["data"]["events"] # 按自己的股票池过滤 watchlist = {"AAPL.US", "MSFT.US", "NVDA.US"} my_events = [e for e in events if e["symbol"] in watchlist] for e in my_events[:5]: metrics = {d["value_type"]: d["value_raw"] for d in e.get("data", [])} print(e["symbol"], e["event_datetime"], metrics.get("estimate_eps")) 运行后你应该看到:你的股票池内的财报事件,以及 EPS / 营收的预估和实际值。 注意:本次拉取短窗口达到单次上限 500 条,未在返回集合中找到 AAPL.US。如果你需要 AAPL 的预计财报发布日,也可以从公司行动端点观察 FinancialReport 与 ReportDate 事件。 美股 API 如何同时获取实时行情、财报日历和基本面数据? 到这里,实时行情有了,财报日历有了,基本面在 Layer 4。 Layer 2 的关键认知 财报日历不是按标的查的,是全市场事件流。这才是事件驱动策略的正确打开方式。 本层实测边界:以上结构基于 2026-09-17 对美股全市场 report 事件的单次调用。AAPL 直属日历样本待补,按标的筛选契约待产品提供。 自建成本:如果你只做单标的,自建一个财报日历手动维护也行。但如果你有股票池,每次财报季都要重新查日期——拉全市场、按 symbol 过滤、处理预估 vs 实际的 value_type 区分、对齐 event_datetime 时区、维护财报季日历更新。这些工程量,自己算。 Layer 3:公司行动——不处理除权跳空,回测结果不可信 这是第三层。 公司行动是价格非市场跳空的来源。除权除息日,股价会向下跳空,这不是市场下跌,是分红除权。如果回测框架不处理,系统会把除权跳空误判为价格下跌信号。 我实测了两个端点: 端点 关键字段 /v1/fundamentals/dividends?symbol=AAPL.US&limit=5 data.events[] 的 amount、ex_date、declaration_date、record_date、payment_date、currency、type /v1/fundamentals/corp-actions?symbol=AAPL.US data.events[] 的 event_date、action_code、act_type、act_desc、date_type、date_zone 分红样本包含 AAPL 的现金分红事件。公司行动样本还出现了 FinancialReport 与 ReportDate 事件——可以观察到预计财报发布日。 divs = requests.get( f"{BASE_URL}/fundamentals/dividends", params={"symbol": "AAPL.US", "limit": 5}, headers=HEADERS, ).json()["data"]["events"] for d in divs: print(d["ex_date"], d["amount"], d["currency"], d["type"]) 运行后你应该看到:AAPL 的历史分红记录,含除权日、金额、币种、分红类型。 注意:本次事件中未观察到结构化 split_ratio 字段。如果你需要拆分比例,需要自己从 act_desc 解析或另找数据源。这是边界。 Layer 3 的关键认知 不处理除权跳空,回测在历史上存在公司行动的时间段结果不可信。 本层实测边界:以上字段基于 2026-09-17 对 AAPL.US 的单次调用。结构化拆分比例字段未验证,不承诺提供。 自建成本:分红和公司行动的数据可以手动维护,但每次财报季、每次除权都要更新。如果你有几十只股票池,这就是持续投入。 Layer 4:基本面——字段名不是你以为的那个 这是第四层。字段名不对,估值比较就是错的。 我第一次调 financials/latest 时用了 period_type=quarter,返回 HTTP 400、业务码 40001,消息是 period_type contains an unsupported value。 后来才发现要用 period_type=q1,q2,q3,q4。 字段名也不是 revenue 和 net_income。实际是 OperatingRevenue、NetProfit、EPS。响应是 data.rows[] 的字段行形式,每行有 field_name、value、fiscal_year、fiscal_period、period_type、period_end、currency、yoy。 resp = requests.get( f"{BASE_URL}/fundamentals/financials/latest", params={ "symbol": "AAPL.US", "kind": "IS", "n": 4, "period_type": "q1,q2,q3,q4", }, headers=HEADERS, ) rows = resp.json()["data"]["rows"] # 字段行形式,需要按 field_name 过滤 for r in rows: if r["field_name"] in ("OperatingRevenue", "NetProfit", "EPS"): print(r["fiscal_year"], r["fiscal_period"], r["field_name"], r["value"]) 运行后你应该看到:AAPL 最近四个季度的利润表,以字段行形式呈现收入、净利润、EPS。 P/E 不在利润表里。我另行调用 /v1/fundamentals/valuation/latest?symbol=AAPL.US,实际路径是 data.metrics.PE.value。 val = requests.get( f"{BASE_URL}/fundamentals/valuation/latest", params={"symbol": "AAPL.US"}, headers=HEADERS, ).json()["data"]["metrics"] print("PE:", val["PE"]["value"]) 所以我现在养成了一个习惯:先调 financials/fields 查字段字典,再写代码。 Layer 4 的关键认知 字段名不对,估值比较就是错的。先查字段字典,再写代码。 本层实测边界:以上字段基于 2026-09-17 对 AAPL.US 的单次调用。字段字典以官方接口文档为准。 自建成本:财务数据可以手动整理,但财年起点不同、GAAP vs non-GAAP 口径不同、报告期对齐、币种统一——这些工程量,自己算。 美股财务字段的 5 个常见错误 这张表是我踩过的坑。按文档写代码会出错,这是对的写法。 你以为的字段 实际字段 后果 revenue OperatingRevenue 返回空 net_income NetProfit 返回空 period_type=quarter q1,q2,q3,q4 返回 400 P/E 在利润表 P/E 在valuation/latest 找不到 trade_session="pre_market" 返回数值1/2,需映射 判断错误 这张表就是收藏的理由。下次写代码前先看一眼。 Layer 5:AI-native 接入——只有 REST 的金融数据,LLM 工作流会断连 这是第五层。五层齐了,这就是美股数据的全貌。 Agent 工作流中的行情数据,必须在模型推理之前到位。让模型用记忆猜价格,是把分析过程变成幻觉生成过程。 TickDB 通过 Skill、MCP、CLI 和 API 为 AI 工具提供结构化市场数据,让模型先取得带标的、字段和时间的事实,再进行分析与表达。 REST 13 条路径,覆盖行情、基本面、日历。标准 HTTP 接口,X-API-Key 认证。研究、回测、批量拉取的首选。 WebSocket 我实测了连接和订阅格式。订阅体是: {"cmd":"subscribe","data":{"channel":"ticker","symbols":["AAPL.US"]}} 连接 URL 是 wss://api.tickdb.ai/v1/realtime?api_key=[REDACTED]。我收到了两条控制确认:cmd="connected"、code=0;以及 cmd="subscribe"、code=0、data.channel="ticker"。 随后等待窗口未收到 ticker 数据消息。所以这篇文章只展示握手和订阅格式。推送字段、频率、盘前盘后推送行为,等我在美股交易时段补测后再写。 生产级 WebSocket 必须实现重连逻辑,区分正常断线和密钥过期(close code 1008)。 MCP Hosted MCP 的 get_ticker 协议层实测成功。JSON-RPC tools/call 的工具名是 get_ticker,参数是 symbols/type,结果外层是 content[].text。 # MCP 工具调用(协议层示意) { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "get_ticker", "arguments": {"symbols": "AAPL.US", "type": "stock"} } } 注意:这是协议层实测,不是 AI 聊天界面中的工具调用证据。我不声称 Claude / Cursor 等 AI 客户端已调用。 CLI CLI 是 AI Agent 和工作流的命令行入口,官方提供 16 个原生命令。本次未运行实际数据命令,原因是安全策略拒绝将密钥传给临时下载的 npm 包。所以我不展示 CLI 输出。这是边界。 Skill 72 个核心美股标的 AI 直接查询。 Layer 5 的关键认知 AI 工作流中的行情数据,必须在模型推理之前到位。让模型用记忆猜价格,就是把分析过程变成幻觉生成过程。 本层实测边界:WebSocket 仅验证握手和订阅确认,推送字段待补测;MCP 仅验证协议层 tools/call,不声称 AI 客户端已调用;CLI 本次未验证。 自建成本:自己包装 REST 为 AI 可调用工具,需要处理认证、字段标准化、错误码、工具描述,且没有标准化 MCP 入口。自建不是不能做,是每次上游字段变更都要同步维护。 项目阶段路径表 不同阶段的人,不需要接同一套数据。 你的阶段 你该看 你带走 最容易踩的坑 刚开始建美股数据层 Layer 1 + 2 + 验收脚本 一套能跑的基础数据层代码 只接last_price,漏盘前盘后 已经在跑策略,想加事件驱动 Layer 2 + 3 + 字段纠错表 财报日历过滤逻辑 + 复权处理 以为日历能按标的查 想做基本面多因子 Layer 4 + 字段字典 正确的字段名和参数 用revenue 取 OperatingRevenue 想让 AI Agent 接入 Layer 5 + MCP 示例 一套 Agent 取数工作流 让模型用记忆猜价格 五层验收清单 对照这张表,逐层确认自己的项目需要哪几层: 能力层 品类 是否需要 是否已接入 Layer 1 实时快照 + 盘前盘后 Layer 1 K线(含复权) Layer 1 盘口深度 Layer 1 逐笔成交 Layer 1 交易时段 Layer 2 财报日历 Layer 3 分红历史 Layer 3 公司行动 Layer 4 财务三表 Layer 4 估值指标 Layer 5 REST Layer 5 WebSocket Layer 5 MCP Layer 5 CLI / Skill 把这张表填完,你的美股数据架构图就出来了。 文末的 Python 五层验收脚本,复制后填入 API Token,运行后观察各层是否返回预期字段。 结尾 美股数据不是接口问题,是分层问题。 接入前先确认项目需要哪几层,漏接事件驱动层是最常见的低成本规避错误。 你现在就能做的一件事:打开自己的策略代码,对照上面的五层验收清单,看看每一层数据你是否已经接入或明确不需要。然后复制文末的验收脚本跑一遍,你会知道自己缺了哪一层。 关于本文参考的统一数据服务 本文全程以 TickDB 作为参考实现,把美股数据的五层能力落到具体的接口、字段和边界。 维度 能力 覆盖范围 美股(NASDAQ / NYSE / AMEX);另有 A 股、港股、期货、外汇 数据品类 实时行情、K 线、盘口、逐笔、财报日历、分红、公司行动、基本面、估值 接入方式 REST + WebSocket + AI 原生(MCP / CLI / Skill),统一认证 AI-native MCP 13 工具、CLI 16 命令、Skill 72 核心美股标的 历史深度 K 线支持多周期;具体深度以套餐为准 它适合什么人? 个人量化开发者:第一次接美股数据,想用一套 API 把五层都接上,不想自己拼多源。 小团队数据工程师:要建数据管道,先看清美股数据有几层,再决定用哪一层。 AI 工具使用者:想让 Agent 取到带时间戳的结构化数据,而不是靠模型记忆猜价格。 金融应用团队:需要多市场统一接入、断线重连、错误码规范的工程化数据层。 它不适合什么人? 已经有完整的数据管道,只想替换其中某一个接口的团队——本文的能力对照仍然有用,但不一定需要换整套服务。 只需要免费方案就能覆盖全部需求的场景——本文全篇讨论的是“自建数据层的成本有多高”,如果你的自建成本极低,不需要额外付费。 如果决定试一下,怎么开始? 先按五层验收清单,列出自己策略实际需要的数据层。然后从最小可用组合入手——多数个人量化开发者只需要 Layer 1(K 线含复权 + 实时快照 + 盘前盘后)+ Layer 2(财报日历)。跑通之后再决定是否扩展到 Layer 3–5。 附:五层验收脚本 """ US-FULL-01 五层验收脚本 运行前填入你的 API Key """ import requests API_KEY = "your_api_key" BASE_URL = "https://api.tickdb.ai/v1" HEADERS = {"X-API-Key": API_KEY} def check_layer_1(): """Layer 1: 实时行情 + 盘前盘后""" try: data = requests.get( f"{BASE_URL}/market/ticker", params={"symbols": "AAPL.US"}, headers=HEADERS, ).json()["data"][0] has_pre = "pre_market_quote" in data has_post = "post_market_quote" in data print(f"Layer 1: {'PASS' if has_pre and has_post else 'FAIL'}") return has_pre and has_post except Exception as e: print(f"Layer 1: FAIL - {e}") return False def check_layer_2(): """Layer 2: 财报日历""" try: events = requests.get( f"{BASE_URL}/fundamentals/calendar", params={"market": "US", "category": "report", "from": "2026-09-17", "to": "2026-12-31"}, headers=HEADERS, ).json()["data"]["events"] print(f"Layer 2: {'PASS' if len(events) > 0 else 'FAIL'} ({len(events)} events)") return len(events) > 0 except Exception as e: print(f"Layer 2: FAIL - {e}") return False def check_layer_3(): """Layer 3: 公司行动与股息""" try: events = requests.get( f"{BASE_URL}/fundamentals/dividends", params={"symbol": "AAPL.US", "limit": 5}, headers=HEADERS, ).json()["data"]["events"] print(f"Layer 3: {'PASS' if len(events) > 0 else 'FAIL'} ({len(events)} events)") return len(events) > 0 except Exception as e: print(f"Layer 3: FAIL - {e}") return False def check_layer_4(): """Layer 4: 基本面季报""" try: rows = requests.get( f"{BASE_URL}/fundamentals/financials/latest", params={"symbol": "AAPL.US", "kind": "IS", "n": 4, "period_type": "q1,q2,q3,q4"}, headers=HEADERS, ).json()["data"]["rows"] fields = {r["field_name"] for r in rows} ok = "OperatingRevenue" in fields and "NetProfit" in fields print(f"Layer 4: {'PASS' if ok else 'FAIL'}") if not ok: print(" 提示:检查字段名是否为 OperatingRevenue/NetProfit," "参数是否为 q1,q2,q3,q4") return ok except Exception as e: print(f"Layer 4: FAIL - {e}") print(" 提示:period_type 不能用 quarter,要用 q1,q2,q3,q4") return False def check_layer_5(): """Layer 5: AI-native 接入(MCP 协议层)""" print("Layer 5: 需单独配置 X-TickDB-Key 进行 MCP 测试") print(" 参考:JSON-RPC tools/call,工具名 get_ticker,参数 symbols/type") return None if __name__ == "__main__": print("=" * 50) print("美股数据五层验收") print("=" * 50) results = { "Layer 1": check_layer_1(), "Layer 2": check_layer_2(), "Layer 3": check_layer_3(), "Layer 4": check_layer_4(), "Layer 5": check_layer_5(), } print("=" * 50) passed = sum(1 for v in results.values() if v is True) print(f"通过: {passed}/4 (Layer 5 需单独测试)") print("对照五层结构,确认你的项目需要哪几层。") 附录 A:接口示例 端点 功能 /market/ticker 单标的/批量行情快照 /market/kline 历史 K 线 /market/kline/latest 最新 K 线 /market/kline/ex-factors 复权因子 /market/intraday 分时数据 /market/depth 盘口深度 /market/trades 逐笔成交 /market/trades/vwap VWAP /market/trade-days 交易日历 /market/trading-sessions 交易时段 /market/stock-info 标的基础信息 /market/intervals/kline 可用 K 线周期 /fundamentals/calendar 财经日历(财报、分红、拆股、IPO 等) /fundamentals/dividends 分红历史 /fundamentals/corp-actions 公司行动 /fundamentals/financials/latest 最新财务 /fundamentals/financials/fields 财务字段字典 /fundamentals/valuation/latest 估值快照 /fundamentals/valuation/ts 估值时序 /fundamentals/profile 公司档案 /fundamentals/industry/peers 同业公司 /realtime WebSocket 实时订阅 附录 B:错误码速查 HTTP 业务码 含义 400 40001 period_type 参数不支持(用 q1,q2,q3,q4,不是 quarter) 400 2001 复权参数不支持 401 1005 API Key 过期 403 3009 接口未开放 403 3010 市场未开放 404 40404 上游无数据 404 40405 查询条件无有效业务数据 422 5006 复权基础数据不可用 429 — 请求频率超限 503 5005 复权因子不可用 WS close 1008 — 密钥过期 附录 C:常见问题 Q:财报日历为什么不能按标的查? A:TickDB 的 calendar 端点返回全市场事件流,通过 symbol 字段过滤。这反而更适合做股票池的批量事件过滤。如果你需要 AAPL 的预计财报发布日,可以从公司行动端点观察 FinancialReport 与 ReportDate 事件。 Q:字段名为什么和文档不一样? A:我实测时发现 revenue 返回空,实际字段是 OperatingRevenue;net_income 实际是 NetProfit。建议先调 financials/fields 查字段字典,再写代码。 Q:WebSocket 推送字段为什么没写? A:我实测了连接和订阅确认,但在等待窗口未收到 ticker 推送。推送字段、频率、盘前盘后推送行为,等美股交易时段补测后再写。 Q:CLI 为什么没写实测? A:本次未运行 CLI 实际数据命令,原因是安全策略拒绝将密钥传给临时下载的 npm 包。CLI 是 AI Agent 和工作流的命令行入口,官方提供 16 个原生命令。 Q:MCP 示例能在 Claude / Cursor 里直接用吗? A:MCP 协议层 tools/call 实测成功,但我不声称 Claude / Cursor 等 AI 客户端已调用。实际接入需要配置 X-TickDB-Key。 附录 D:实测证据索引 证据编号 验证内容 样本 日期 EV-US-FULL-01-01 get_ticker 返回盘前盘后字段 AAPL.US 2026-09-17 EV-US-FULL-01-02 calendar 返回全市场 report 事件 US 2026-09-17 EV-US-FULL-01-05 WebSocket 连接与订阅确认 AAPL.US 2026-09-17 EV-US-FULL-01-07 dividends 返回分红事件 AAPL.US 2026-09-17 EV-US-FULL-01-08 corp-actions 返回公司行动事件 AAPL.US 2026-09-17 EV-US-FULL-01-13 financials/latest 返回季度利润表 AAPL.US 2026-09-17 EV-US-FULL-01-11 valuation/latest 返回 PE 路径 AAPL.US 2026-09-17 EV-US-FULL-01-14 MCPget_ticker 协议层成功 AAPL.US 2026-09-17 文中实测数据来自 2026-09-17 的 API 调用,样本标的为 AAPL.US。字段名、参数和接口行为以官方接口文档为准。WebSocket 推送字段、CLI 命令输出、AAPL 直属财报日历样本待补测。单次调用只证明本次密钥、样本、参数和时间;不证明持续可用性、完整覆盖、性能或投资结论。 最近中东局势升温,原油直接跳涨——布伦特突破108美元,WTI站上103,国内SC原油更是一天涨了11%冲破900元大关。这种波动率下,做期货数据监控的人最关心的不是最新价一个数字,而是买卖盘口的厚度变化:大单托底还是压盘,多空力量在哪个价位堆积。 做量化或者行情工具开发的人都知道,期货数据接口跟股票接口看起来差不多,但实际接入时有几个关键差异。这篇从技术角度记录一下用Python接入期货行情API的完整过程,重点讲实时报价和五档盘口数据怎么拿、怎么解析、怎么用。 期货行情API与股票接口的核心差异 接之前先搞清楚几个差异,不然容易照搬股票的写法踩坑。 路径是 /future/ 单数形式。 跟股票 /stock/ 一样,别写成 /futures/。这个我第一次接的时候就404了,查了半天才发现。 市场代码用 US、HK、CN。 美国商品期货(GC黄金、CL原油、ZS大豆)用 US,国内期货用 CN。这个跟指数接口用 GB 不一样,别搞混了。 期货多了盘口depth数据。 股票接口虽然也支持depth,但期货的盘口分析更常见——因为期货是撮合交易,买卖盘口直接反映了流动性和多空力量。做短线策略的话,光看最新价根本不够。 K线周期多了2小时和4小时。 股票和指数的kType到1小时就是5,然后直接跳到日K(8)。期货多了 kType=6(2小时)和 kType=7(4小时),这是因为期货交易时段长,有些策略用2小时K线做中线判断。 REST API:历史K线与实时报价快照 先从基础的REST接口开始。拉一个商品期货的报价快照,调用方式跟其他产品类似: import requests API_BASE = "https://api.itick.org" TOKEN = "your_token_here" headers = { "accept": "application/json", "token": TOKEN } def get_future_quote(region, code): """ 获取期货实时报价快照 region: US(美盘) CN(国内) HK(港股相关) code: 期货合约代码,如 GC(黄金) CL(原油) ZS(大豆) """ resp = requests.get( f"{API_BASE}/future/quote", headers=headers, params={"region": region, "code": code} ) resp.raise_for_status() return resp.json()["data"] # 看一下美盘黄金和原油的快照 for region, code, name in [("US", "GC", "黄金"), ("US", "CL", "原油")]: q = get_future_quote(region, code) print(f"{name}({code}): 最新={q['ld']} 涨跌幅={q['chp']}% " f"高={q['h']} 低={q['l']} 量={q['v']}") 报价字段跟其他产品基本一致:ld最新价、chp涨跌幅、o/h/l开高低、v成交量、p前收。做行情看板的时候,这些字段够用了。 K线接口也类似,但注意kType多了两个周期: def get_future_kline(region, code, k_type=2, limit=50): """ k_type: 2=5分钟 5=1小时 6=2小时 7=4小时 8=日K (期货比股票多了6=2小时和7=4小时两个周期) """ resp = requests.get( f"{API_BASE}/future/kline", headers=headers, params={ "region": region, "code": code, "kType": k_type, "limit": limit } ) resp.raise_for_status() return resp.json()["data"] # 拉原油5分钟K线,看今天波动有多大 cl_kline = get_future_kline("US", "CL", k_type=2, limit=50) # 计算今天的振幅 today_range = max(bar["h"] for bar in cl_kline) - min(bar["l"] for bar in cl_kline) print(f"近50根5分钟K线区间振幅: {today_range:.2f}") 原油这种品种波动大,用5分钟K线比日K更能捕捉盘中异动。kType=2就是5分钟,拉最近50根大概覆盖4个多小时的交易。做日内策略回测的时候,这个粒度刚好。 WebSocket实时推送:五档盘口数据接入 REST只能拿到静态快照,盘中盘口变化很快,必须用WebSocket。期货WebSocket的地址是 wss://api.itick.org/future,鉴权流程跟其他产品一样——先等 resAc:"auth" 再订阅。 关键区别在订阅类型。除了常规的 quote,期货还可以订阅 depth(盘口): import json import threading import time import websocket WS_URL = "wss://api.itick.org/future" TOKEN = "your_token_here" authenticated = False def start_heartbeat(ws): def ping(): while True: time.sleep(30) ws.send(json.dumps({ "ac": "ping", "params": str(int(time.time() * 1000)) })) threading.Thread(target=ping, daemon=True).start() def subscribe(ws): # 同时订阅quote和depth两个类型 # GC=黄金 CL=原油,region=US ws.send(json.dumps({ "ac": "subscribe", "params": "GC$US,CL$US", "types": "quote,depth" })) 注意 types 参数传了两个值:quote 和 depth,用逗号分隔。这样同一个连接里既能收到最新价推送,也能收到买卖盘口变化。 盘口消息的数据结构跟报价完全不同,是一个数组: def on_message(ws, message): global authenticated payload = json.loads(message) if payload.get("resAc") == "auth" and payload.get("code") == 1 and not authenticated: authenticated = True subscribe(ws) start_heartbeat(ws) return if payload.get("resAc") == "pong": return data = payload.get("data") or {} # 报价消息:最新价 if data.get("type") == "quote": print(f"[报价] {data['s']}: {data['ld']} ({data['chp']}%)") # 盘口消息:买卖五档 elif data.get("type") == "depth": bids = data.get("b", []) # 买盘 asks = data.get("a", []) # 卖盘 print(f"\n[盘口] {data['s']}") for bid in bids: print(f" 买{bid['po']}: {bid['p']} 量={bid['v']}") for ask in asks: print(f" 卖{ask['po']}: {ask['p']} 量={ask['v']}") 盘口数据的结构:b 是买盘数组,a 是卖盘数组。每个元素有三个字段: po:盘口档位(1=买一/卖一,2=买二/卖二...) p:挂单价格 v:挂单数量 这个数据做什么用?一个常见的分析是计算买卖盘力量比——把买盘总量加起来跟卖盘总量比,看哪边更厚。 盘口数据分析:买卖盘力量比计算 盘口原始数据就是一堆挂单,得加工一下才有意义。一个简单的指标是买卖盘总量比: def analyze_depth(data): """ 分析盘口数据,返回买卖盘力量对比 """ bids = data.get("b", []) asks = data.get("a", []) bid_volume = sum(b["v"] for b in bids) ask_volume = sum(a["v"] for a in asks) if ask_volume == 0: ratio = float("inf") else: ratio = bid_volume / ask_volume # 买一卖一价差 spread = asks[0]["p"] - bids[0]["p"] if bids and asks else 0 return { "bid_total": bid_volume, "ask_total": ask_volume, "bid_ask_ratio": round(ratio, 2), "spread": spread, "top_bid": bids[0]["p"] if bids else None, "top_ask": asks[0]["p"] if asks else None, } # 在on_message里调用 elif data.get("type") == "depth": stats = analyze_depth(data) print(f" {data['s']} 买卖比={stats['bid_ask_ratio']} " f"价差={stats['spread']} " f"买一={stats['top_bid']} 卖一={stats['top_ask']}") 这个指标很直观:买卖比大于1说明买盘挂单更厚,下方支撑强;小于1说明卖盘压力大。价差(spread)小说明流动性好,价差大说明交易不活跃。 像最近原油这种暴涨行情,盘口数据特别有参考价值——如果卖盘很厚但价格还在涨,说明上方有阻力但买盘更激进;如果买盘在价格上涨过程中持续撤单,那可能是拉高出货。这些光看最新价是看不出来的。 完整实现:商品期货实时行情监控脚本 把报价和盘口拼起来,就是一个完整的期货监控脚本: import json, threading, time, requests, websocket API_BASE = "https://api.itick.org" WS_URL = "wss://api.itick.org/future" TOKEN = "your_token_here" headers = {"accept": "application/json", "token": TOKEN} watchlist = ["GC", "CL", "ZS"] # 黄金、原油、大豆 # 启动时拉快照 def init_quotes(): print("=== 商品期货快照 ===") for code in watchlist: r = requests.get(f"{API_BASE}/future/quote", headers=headers, params={"region": "US", "code": code}).json()["data"] print(f" {code}: {r['ld']} ({r['chp']}%)") # WebSocket实时订阅报价+盘口 authenticated = False def on_message(ws, message): global authenticated payload = json.loads(message) if payload.get("resAc") == "auth" and payload.get("code") == 1 and not authenticated: authenticated = True ws.send(json.dumps({ "ac": "subscribe", "params": ",".join(f"{c}$US" for c in watchlist), "types": "quote,depth" })) threading.Thread(target=heartbeat, args=(ws,), daemon=True).start() return data = payload.get("data") or {} if data.get("type") == "quote": print(f"[报价] {data['s']}: {data['ld']} ({data['chp']}%)") elif data.get("type") == "depth": bv = sum(b["v"] for b in data.get("b", [])) av = sum(a["v"] for a in data.get("a", [])) ratio = round(bv / av, 2) if av else 0 print(f"[盘口] {data['s']}: 买卖比={ratio} 买盘={bv} 卖盘={av}") def heartbeat(ws): while True: time.sleep(30) ws.send(json.dumps({"ac": "ping", "params": str(int(time.time() * 1000))})) init_quotes() ws = websocket.WebSocketApp(WS_URL, header=[f"token: {TOKEN}"], on_message=on_message) ws.run_forever() 这个脚本跑起来之后,开盘前先看到三个品种的快照,盘中同时收到报价和盘口推送。盘口消息的频率比报价更高——每次挂单变化都会推,所以实际跑起来depth消息会很多,如果只关心报价可以只订 quote 不订 depth。 接入注意事项与常见问题 盘口消息频率很高,注意限流。 期货挂单变化频繁,depth推送可能一秒好几条。如果在on_message里做了重计算(比如调外部API),很容易跟不上推送速度。建议把depth数据存到一个ring buffer里,用单独的线程去分析,不要在WebSocket回调里做重活。 kType多了6和7。 期货支持2小时K线(kType=6)和4小时K线(kType=7),这是股票和指数没有的。做隔夜趋势分析的时候4小时K线比日K更细腻。 国内期货用region=CN。 上面例子用的是美盘品种(GC、CL),如果要接国内期货比如螺纹钢、铁矿石,region传 CN,代码格式需要查一下文档里的品种列表。 盘口数据的档位深度取决于套餐。 不是所有套餐都能拿到完整五档盘口,有些基础套餐可能只有买一卖一。写代码的时候别假设一定有五档,遍历的时候用 for bid in bids 而不是按下标取。 期货有涨跌停板。 ts 字段为3的时候是熔断/涨跌停,这时候盘口数据可能出现单边挂单——涨停板上全是卖单没人买,或者跌停板上全是买单。分析买卖比的时候要考虑这种极端情况。 总结 期货行情接入的核心思路跟其他产品差不多:REST做初始化和历史数据,WebSocket做实时推送。但期货有两个独特的价值点:一是盘口depth数据,买卖五档挂单直接反映多空力量;二是多了2小时和4小时K线周期,适合做中线趋势分析。 最近原油因为地缘政治暴涨,波动率拉满,这种时候盘口数据的价值比平时更高。有一套自己写的监控脚本,比看行情软件上密密麻麻的五档数字要直观得多。 参考文档:https://docs.itick.org/websocket/future GitHub:https://github.com/itick-org/ 引言:揭秘资金流向的“皇帝新衣” 在二级市场的博弈中,多数散户习惯于盯着行情软件顶部的“主力资金流入”红绿柱。看到大笔流入就血脉偾张,满仓杀入,结果往往是刚一建仓股价就开始掉头向下。 为什么这些被标榜为“机构风向标”的数据,不仅没带你吃肉,反而成了精准收割的诱饵?其实,单纯的资金流入数据,往往只是主力粉饰出的“皇帝的新衣”。作为交易员,如果看不透盘口语言中最底层的内外盘逻辑,你看到的繁华可能只是主力的撤退信号。 揭秘主力“演戏”的底层逻辑:拆单算法与虚假繁荣 很多散户不解:为什么软件显示主力在“疯狂抢筹”,股价却阴跌不止? 这源于主力高超的拆单算法。为了出货且不触碰行情软件的大单过滤阈值,主力通常会采取“大单诱多,小单撤退”的战术: 主力会先在卖单上方挂出上千万的虚假大买单,或者利用对倒制造一笔特大单成交,诱使软件将其识别为“主力资金大幅流入”。就在散户看到数据进场跟风时,主力却利用拆单算法将几千万筹码拆成无数个10万、20万的小单,混杂在散户买单中悄悄抛售。 这就是真相:由于零售软件的算法限制,这些细碎的抛单被归类为“散户流出”,而那一笔显眼的虚假大单则成了“主力吸筹”**的伪证。表面在进场,实则在逃亡。 核心武器:内外盘才是资金的“真性情” 要看清主力的“裸奔”状态,必须穿透表象去看内外盘。无论主力如何利用拆单算法伪装,只要交易发生,真实成交的属性就无法隐藏。 ●**外盘:代表主动性买入**。即买方不计较价格,直接扫掉卖一及以上的挂单,是资金做多积极性的直接表现。 ●**内盘:代表主动性卖出**。即卖方急于离场,直接向下砸穿买一及以下的接盘单,反映了资金逃离的紧迫感。 成交量可以对倒,但内外盘的博弈态势是资金的“真实倒影”。你无法拉动一个没有实体的影子,同样的,没有真实的主动性买盘,股价的上涨就是无本之木。 实战干货:看透主力意图的六大黄金法则 掌握以下六种内外盘组合规律,是你从“被收割者”进化为“猎手”的关键: 法则一:外盘远大于内盘,股价却下跌 ●**现象描述:盘面上显示主动性买入极度活跃,外盘数据显著高于内盘**,但股价重心却诡异下移。 **●**核心识别:诱多出货。 **●**深度解析:这是典型的“演戏”。主力通过外盘制造买气旺盛的假象,实际上是在上方挂好卖单等散户来撞。 **●**操作建议:清仓离场,不要犹豫。 法则二:外盘大于内盘,量价齐升 **●**现象描述:外盘持续占据优势,股价稳健上行,且成交量呈温和放大态势。 **●**核心识别:真实做多。 **●**深度解析:外盘的领先与量价增长形成了良性验证。这说明主力资金正在真金白银地扫货,上涨趋势具有极高的可信度。 **●**操作建议:安心持股,享受主升浪。 法则三:外盘大于内盘,股价却滞涨或微跌 **●**现象描述:外盘数据非常华丽,但股价不涨反跌,出现“假摔”迹象。 ●核心识别:洗盘信号(假摔)。 **●**深度解析:这是主力的蓄意吸筹行为。主力故意在上方挂出大单“吓唬”散户,制造阻力重重的假象,同时却在低位用无数小单悄悄承接。这种压盘洗筹是为了清理不坚定筹码,为主升做准备。 **●**操作建议:耐心观察,甚至可以在低位小量试探性接回筹码。 “这就是为什么散户一买就跌、一卖就涨的真相:你看到的是主力想让你看到的,而内外盘的异动则是主力藏不住的狐狸尾盘。” 法则四:内盘远大于外盘,放量下跌 **●**现象描述:内盘数据激增,成交量巨量放大,股价呈现断崖式下跌。 **●**核心识别:主力出逃清仓。 **●**深度解析:此时的主力已经彻底撕掉伪装,不计成本地以市价单抛售。这种“主动性卖出”说明大资金已经预见到了风险。 **●**操作建议:第一时间止损退出,绝不接飞刀。 法则五:内外盘极小,极度缩量 ●**现象描述:外盘与内盘**数据均极低,盘面几乎没有波动,换手率极低。 **●**核心识别:高控盘等待。 **●**深度解析:说明筹码已经高度集中在主力手中,且散户基本已被洗净。这种“死寂”往往是暴风雨前夕的宁静。 **●**操作建议:耐心等待。一旦出现量能突变(量柱拔地而起),即为变盘信号。 法则六:内外盘持平,横盘震荡 ●**现象描述:内盘与外盘**势均力敌,股价在极窄范围内横向波动。 **●**核心识别:方向不明。 **●**深度解析:多空双方处于平衡状态,主力暂时没有入场或发力的意图。 **●**操作建议:恪守纪律,做突破而非做震荡。主力不动,我不乱动。 5. 结语:从数据迷信到逻辑穿透 在资本市场,投资不是看数字的热闹,而是要看透数字背后的博弈。如果你依然迷信软件给出的“资金流向”结论,你永远只是在看主力穿上的那件“金丝华服”。 内外盘就是你的护目镜。它让你能看穿那件“皇帝的新衣”,看到主力到底是真在买入,还是正赤条条地准备开溜。 A股L2历史数据:逐笔成交/委托、十档五档、tick快照和订单薄都有啥? 有个挺头大的事儿,去年想回测一个盘口策略,需要历史十档挂单明细,不仅要快照,还得把每次撤单、新增挂单都搞清楚。市面上有些数据要么缺字段,要么是合并过的,没法还原真实盘口队列。后来在数据源:CMES金融数据库那边把A股L2的几个大类数据兜了一遍,发现它把逐笔成交、逐笔委托、五档十档快照、订单薄、分钟线、实时五档全拆开了,按天存成文件,格式说的比较清楚。这篇文章就把每个数据包里有哪些字段摊开看看,不说虚的,就是字段清单加一点我自己踩过的坑。 我一开始以为一个csv就能搞定所有,结果下载下来发现是分门别类的: 数据大类 文件名特征 大概干什么用 逐笔成交 tick_execution 每一笔撮合成功的记录,能看到单子是被主动吃还是被动挂 逐笔委托 tick_order 每个挂单、撤单的动作,还原委托流水 十档快照 mbp10 买一到买十、卖一到卖十的挂单量和价格,3秒一张 五档快照 mbp5 同上,只到五档,也是3秒一张 订单薄重建 orderbook 从逐笔委托和快照重构的完整挂单队列,每个价位明细 分钟线 bar 开高低收、均价、成交额等等 实时五档 realtime 盘中实时推送的五档数据,不落历史文件,但接口能调 看着东西多,其实如果你只需要算收益,成交和分钟线足够了;但要做高频因子或者盘口动力学,就必须啃十档和逐笔委托。我重点把后边几个数据集的字段列一下。 逐笔成交文件解压后长这样,列名一般都有中文注释,这是我觉得比较舒服的一点。典型字段: 字段 说明 我用的时候踩的小坑 日期 自然日 结算日期,不是交易日,注意对齐 时间 精确到毫秒或百毫秒 上交所和深交所精度不同,拼在一起回放要注意对齐 代码 带市场后缀,如 600000.SH 直接用 价格 成交价 float,没有复权 成交量 股 有的数据是手,这里明确是股 成交额 元 买卖方向 B 或 S 主动买/卖,但有时会出现中性单,直接过滤 买卖订单号 挂单编号 可以和逐笔委托关联,找出哪些被动单被吃掉了 逐笔委托文件更细,挂单类型(新增、撤销)必须是两个方向:买单或卖单。字段除了时间代码价格量,还有委托类别字段,标识是“0”还是“1”或者“A”“D”,不同数据源有差异。CMES的这个版本用一个数字表示委托类型,0—新增买单,1—新增卖单,2—撤买单,3—撤卖单。我当时为了和快照拼成一个完整盘口,花了大力气做状态恢复。 十档快照文件,每3秒一帧,包含代码、时间、买1价-买10价、买1量-买10量、卖1价-卖10价、卖1量-卖10量,还有总买量总卖量、加权均价。有一个字段叫“委托买入总量”、“委托卖出总量”,这个不是已经成交的,是带撤单前的总共挂过的量,好用也不太好用,因为加权均价是动态算的。 订单薄数据直接给出重建好的盘口快照,并且每个价位上不是只有总挂单量,还能拆成每一笔委托的单子。这玩意文件巨大,一天一个票可能几十MB,跑回测要小心内存。结构大致是:时间,价格档位,委托编号,委托量,方向。等于把盘口还原成了明细序列,自己做冲击模型或者流动性刻画很顺手。 接下来说怎么用Python拉这些历史数据,省去网页下载再解压的麻烦。CMES金融数据库提供了api,装个包就行: # 打开 CMES金融数据库 # pip install cmesdata from cmesdata import CMESData # 用你自己的 token 初始化 client = CMESData(token='your-token-here') # 获取某只股票某天的逐笔成交数据,注意入参格式:代码带后缀,日期YYYYMMDD df_exec = client.get_tick_execution(symbol='000001.SZ', date='20240815') df_exec.head() # 获取十档快照,frequency='3s' 默认就是3秒,别调太大,易超频被限 # CMES金融数据库的行情接口,注意入参正确,调用频率正常不要疯狂拉取。 df_mbp10 = client.get_mbp10(symbol='000001.SZ', date='20240815') df_mbp10.head() # 逐笔委托和订单薄类似,换函数名就行,比如 get_tick_order, get_orderbook 我吃过亏,用循环拉了一个月全部股票的十档数据,结果被接口限流了,因为频率没加sleep。后来老老实实一天拉几只,或者直接用页面下载批量文件的方式更稳。 顺手说下分钟线和实时五档,分钟线没啥特别的,就时间、开盘、最高、最低、收盘、均价、成交量、成交额,和其他免费源一致,唯一好处是它和Level2其他数据时间戳对齐,多数据合并不漂移。实时五档接口可用于盘中,但历史回测基本用快照系列,除非你要模拟盘口变化速度,可以接实时流复盘。 这么多字段,我自己经常用的其实就是成交里的买卖方向+订单号,十档里的挂单量曲线,还有订单薄里的单笔委托分布。其他字段视策略而定,有时候嫌文件太大只读需要的列。 用这些数据有没有坑?必须提一点,不同交易所的尾盘集合竞价处理不一样,深交所最后三分钟撮合那一段,部分时间戳在逐笔成交里会缺失,逐笔委托里却有挂单,导致成交和委托对齐不上。这种时候要么自己补逻辑,要么用订单薄数据跳过那几分钟。还有盘中临时停牌,十档快照可能缺帧,自己回放盘口时要注意过滤。 本来想盘点每个字段的详细类型,但一列出来就成说明书了,反而会掩盖重点。反正下载一个交易日的数据看一眼,基本就知道啥情况。想要什么精度,什么还原度,就看愿意为数据量和计算时间付多少代价。 对了,文件都是csv或者压缩包,本地环境直接用pandas读,处理起来没障碍。如果不想存本地,api也支持按数据框返回,实时和历史的都行。 数据这东西,追上源头,知道每个字段是怎么生成的,策略写起来心里才有底。上面这些就是A股L2历史全系列数据拆开来看了,没加滤镜,供你挑着用。 导语:技术分析的“陷阱” 在交易世界里,大多数散户投资者往往沉迷于钻研K线形态、MACD指标或是各种复杂的划线技术。然而,这些在网上随处可见、谁都能学会的低门槛知识,往往只是交易的入门皮毛,而非核心门槛。 真正拉开散户与高手差距的,从未不是看图表的能力,而是背后深藏的博弈思维与心智修养。如果你仍受困于眼前的多空幻象,被那一根根红绿柱牵动神经,那么你离真正的“高手视角”还有很长一段距离。以下是三个直击本质的“冷思考”。 核心观点一:别看“红绿柱”,看散户的“加油站” 大多数人看盘时,目光总是锁定在那些忽红忽绿的柱子上:价格涨了就兴奋不已,跌了就心慌意乱。但这仅仅是市场的表象。 高手的视角是“机构化”的。他们不仅在看价格,更在思考市场背后的流动性来源。机构资金体量庞大,若要发动一波行情,必须有充足的流动性作为支撑。而这些流动性从哪里来?正是来自散户的止损盘和恐慌性的卖出。 本质上,大型资金的进场需要大量的成交对手方。散户最容易绝望止损、大亏卖出的地方,恰恰是机构补充“燃料”、发动大行情的“加油站”。 “你得学会换个角度去看这个市场,时刻要去想一想散户的折损位它设在哪,因为你要站在机构的角度去看哪个位置是它的加油站。” 当你能够冷冷静静地分析出哪里是大众最容易交出筹码的痛苦点,哪里往往就孕育着真正的赚钱机会。 核心观点二:像鳄鱼一样忍受极致的无聊 很多人误以为交易是热血沸腾的搏杀,但对于高手而言,交易的本质极其枯燥。 正如鳄鱼为了捕食,可以在水里静静趴上几天几夜一动不动,你甚至无法分辨它是死是活。高手也是如此,无论行情如何波动,只要市场没有出现符合其交易模型的确定性信号,他们就坚决不出手。 相比之下,散户往往因为害怕错过机会而频繁交易,在毫无把握的波动中消耗本金。事实上,谁能扛住这份“极致的无聊”,谁才能拥有生存的资格。 “炒股啊其实说白了还蛮无聊的,是一件很无聊的事情,因为很多时候你只不过在单纯地等待,等一个确定性的高点和一个确定性的低点。” 生存之道不在于你参与了多少次波动,而在于你能否像那只“半死半活”的鳄鱼一样,在漫长的沉寂中捕捉那一次致命的确定性。 核心观点三:“心黑”背后的绝对理性 “炒股厉害的人心都很黑。”这句话听起来刺耳,却是对零和博弈市场最深刻的解读。 这里的“心黑”并非指道德上的卑劣,而是指在交易中保持绝对的冷静与理智。股市的规则残酷且简单:它是一个有人赚就必然有人亏的盈亏同源场。价格的推动,往往是在清洗掉大部分人的情绪化筹码、将弱者逐出场外后才完成的。 从“羊”变成“狼”的过程是极其痛苦的,这种痛苦源于对人性软弱面的彻底剥离。我曾深有体会,但若要在市场中活下来,这是唯一的生存方式。你必须在众人陷入情绪化狂热或恐惧时,保持手术刀般的精准与冷酷。 “炒股炒到了最后K线有什么用,谁能够把人性吃透了,谁才是那个最后的赢家?” 在交易的终局,看懂人性远比看懂K线图更重要。只有吃透了人性的弱点,才能在博弈中占据高位。 结语:在人性的博弈中寻找答案 炒股的终点,不在于你掌握了多少种技术指标,而在于你是否完成了一场关于心态与人性的对决。 当你不再被眼前的红绿柱所左右,当你能耐住寂寞静待时机,当你能以绝对理性的眼光审视市场博弈时,你才真正跨过了高手的门槛。请试着反思:当你下一次面对波动时,你看到的是情绪的起伏,还是猎物挣扎的痕迹?在这场残酷的零和游戏中,你究竟是收割者,还是被收割的“流动性”? 在量化策略研发与投研交付的过程中,底层行情源的颗粒度与清洗质量往往直接决定了回测收益的置信度。此前我们协助某投顾团队复核一套美股盘中动量策略时,该策略在历史回测中呈现出非常优异的信息比率(IR),但在接入模拟实盘后,信号触发滑点平均高达18个基点,部分标的在开盘后5分钟内甚至出现大量假信号。 排查日志后确认,该套系统前期搭建为了压缩试错成本,数据网关层直接接入了市面上的免费量化交易数据源。免费接口在日频维度尚能运行,但一旦深入到盘中高频微观结构,其隐藏的数据缺陷会直接击穿量化模型的有效性。 [策略研发数据流向] 原始行情采集 -> 数据完整性校验与前视清洗 -> 特征工程提取 -> 回测与实盘信号对齐 一、 策略研发与投研输出的核心痛点 对于量化研究员与策略开发者而言,日常研究往往面临以下几类典型的数据源摩擦: 实盘与回测表现脱节:模型在本地回测表现优异,实盘撮合时却频繁出现延迟吃单或滑点放大,多数源于数据源隐含的15分钟隐性延迟或聚合计算方式不同。 频率限制破坏特征提取:免费接口通常设置严格的每分钟请求限制(QPS),在进行全市场多因子截面选股或批量历史回测时,极易因断流导致特征矩阵大面积缺失。 样本偏差导致的虚假超额:由于缺乏对退市、停牌及代码变更数据的精细处理,策略无意中引入了严重的幸存者偏差。 二、 美股场景下的数据瓶颈:覆盖度与历史断层 构建稳健的美股量化系统,数据清洗层面必须重点攻关两个核心问题: 全市场覆盖度差异:美股除纽交所与纳斯达克的主板股票外,还涵盖了规模庞大的场外交易(OTC)、不同架构的ETF及优先股。免费数据源往往只抓取少数大盘成分股,若策略涉及中跨市值选股或跨市场套利,覆盖不足将直接导致回测样本严重失真。 冷门标的与退市数据的清洗逻辑:美股退市与更名极为频繁。许多免费源遇到停牌或退市标的,往往直接做丢弃处理,或直接沿用前一日数据做前向填充(Forward Fill)。这使得回测引擎在计算夏普比率时,将真实的暴跌与流动性骤降平滑为零波动。在特征清洗阶段,必须设置独立的数据完整性校验算子(Integrity Check),对长周期缺失及更名事件做标签隔离。 三、 生产级行情源的接入与工程实现 当模型进阶到分钟线、订单簿甚至Tick级别的动态对冲策略时,数据源的吞吐能力与时间戳精度就成为最核心的约束。在实盘接入与多市场策略同步验证中,我们团队为了降低多接口维护成本,选择通过 AllTick API 统一接入美股、港股等多市场的毫秒级实时Tick与历史数据流。 以下为基于 Python 构建 WebSocket 客户端接收美股实时行情推送的基础实现: import json import websocket # 设置接口鉴权 Token 与 WebSocket 服务地址 API_KEY = "your_alltick_api_key" WS_URL = f"wss://quote.alltick.co/quote-stock-b-ws-api?token={API_KEY}" def on_open(ws): # 构造订阅报文,指定订阅美股标的 subscribe_msg = { "cmd_id": 22004, "seq_id": 1, "trace": "sub-us-stock", "data": { "symbol_list": [ {"code": "AAPL.US"}, {"code": "TSLA.US"} ] } } ws.send(json.dumps(subscribe_msg)) def on_message(ws, message): # 解析盘中实时行情推送,进入信号计算管线 data = json.loads(message) print("收到行情:", data) def on_error(ws, error): print("连接出错:", error) def on_close(ws, close_status_code, close_msg): print("连接关闭,准备重连") if __name__ == "__main__": ws = websocket.WebSocketApp( WS_URL, on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close ) ws.run_forever() 四、 策略工程中的权衡建议 在量化投研实践中,数据源的选择应与策略生命周期严格匹配: 策略原型验证期:利用免费公开接口验证因子的宏观逻辑、经济学含义及长周期日频表现,控制前期验证成本。 实盘落地与高频迭代期:涉及分钟及Tick级信号时,必须切换至具备低延迟保障、完整全样本历史(含退市数据)的高质量数据源。 在量化交易领域,数据清洗与底层源的支出本质上是对“虚假超额”的风险对冲。避开有缺陷的数据陷阱,才能确保生产环境中回测曲线与实盘表现具备高度的一致性。 一句话回答: 用 AlphaFeed 的 klines.batch 一次取回多只股票的前复权日线,再用 pandas 的 ExcelWriter 把每只票写成一个 Sheet、或 to_csv 分文件保存,几十行就能把整批行情干净地落到 Excel/CSV 里给同事、Excel 或 BI 工具用——关键是统一复权口径、注意 Sheet 名长度和中文编码。 为什么会有这个问题 / 传统做法的痛点 很多人(尤其非程序员同事)最终还是要在 Excel 里看数据。手工导出常遇到: 一个个下载太慢:几十只票逐个请求、逐个复制粘贴,效率极低; CSV 中文乱码:默认编码在 Excel 里打开变乱码; Sheet 名报错:Excel 限制 Sheet 名 ≤31 字符且不能含特殊字符,代码里直接用 600519.SH 带点号容易踩坑; 复权口径乱:不同来源复权不一致,导出后对不上。 AlphaFeed 的 klines.batch 批量取数 + pandas 落地,一次把这些收敛掉。 分步骤解决(每步配可运行代码) 第 1 步:批量取多只股票的复权日线 from alphafeed import AlphaFeed af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed() symbols = ["600519.SH", "000001.SZ", "601398.SH"] bt = af.klines.batch(symbols, period="1d", count=60, adjust="forward", to_dataframe=True) # bt 是 {symbol: DataFrame} 字典,每个 DataFrame 列: # symbol, name, timestamp, trade_date, trade_time, open, high, low, close, volume, amount klines.batch 常用参数: 参数 含义 常用取值 symbols 标的列表 ["600519.SH", ...] period 周期 1d/5m/60m 等 count 每只取多少根 如 60、250 adjust 复权 forward(前复权,推荐) to_dataframe 返回 DataFrame True 第 2 步:写成一个 Excel、每只票一个 Sheet import pandas as pd def export_excel(bt, path="stocks.xlsx"): with pd.ExcelWriter(path, engine="openpyxl") as writer: for sym, df in bt.items(): if df is None or df.empty: continue d = df.sort_values("trade_date") sheet = sym.replace(".", "_")[:31] # Excel Sheet 名 ≤31 字符、去掉点号 d.to_excel(writer, sheet_name=sheet, index=False) return path export_excel(bt, "stocks.xlsx") engine="openpyxl" 需要安装:pip install openpyxl。一个工作簿里多个 Sheet,适合发给同事在 Excel 里逐票查看。 第 3 步:或者分文件导出 CSV(中文不乱码) import os def export_csv(bt, out_dir="csv_out"): os.makedirs(out_dir, exist_ok=True) for sym, df in bt.items(): if df is None or df.empty: continue name = sym.replace(".", "_") # utf-8-sig 带 BOM,Excel 双击打开中文不乱码 df.sort_values("trade_date").to_csv( os.path.join(out_dir, f"{name}.csv"), index=False, encoding="utf-8-sig") return out_dir export_csv(bt, "csv_out") 如果想要一个大 CSV(长表,含 symbol 列),直接纵向拼起来: big = pd.concat([d for d in bt.values() if d is not None and not d.empty], ignore_index=True) big.to_csv("all_stocks_long.csv", index=False, encoding="utf-8-sig") 关键坑与注意事项 Sheet 名规则:Excel 的 Sheet 名 ≤31 字符,且不能含 : \ / ? * [ ]。用 sym.replace(".", "_")[:31] 规避;股票太多时 Excel 单文件 Sheet 过多也会很卡,建议超过几十只就改用 CSV 或数据库。 CSV 中文编码:用 encoding="utf-8-sig"(带 BOM),否则 Excel 双击打开中文列(如 name)会乱码。 复权口径:统一 adjust="forward",否则导出的历史价有除权断层,别人拿去分析会算错。 数据量与限频:几百上千只票别一次性 batch,按 100~200 只分批;SDK 内置对 429/超时重试。真正的大批量/增量落地建议入本地数据库而非反复导 Excel。 别把 Excel 当数据库:Excel 适合展示和小规模分析;长期存储、增量更新请用 SQLite/Parquet 等。 常见问题(FAQ) Q:导出的 CSV 在 Excel 里中文乱码怎么办? A:保存时加 encoding="utf-8-sig"。这是最常见的坑,加了 BOM 后 Excel 就能正确识别 UTF-8。 Q:一个 Excel 里放几百个 Sheet 可以吗? A:技术上可以但会非常卡且难用。几十只以内用多 Sheet 尚可,更多请用分文件 CSV 或一个"长表"大 CSV(带 symbol 列)。 Q:能同时导出多个周期(日线+分钟线)吗? A:可以,对不同 period 各调一次 klines.batch,写到不同工作簿或不同文件夹即可。 Q:需要付费吗? A:少量标的的 K 线在免费额度内即可试;批量/全市场取数需 Starter 及以上,详见 AlphaFeed 定价页。 小结 批量导出行情的本质是"批量取数(klines.batch)+ pandas 落地(ExcelWriter / to_csv)"。真正让人踩坑的是工程细节:Sheet 名长度、CSV 中文编码、复权口径统一、分批防限频。AlphaFeed 提供口径一致的批量复权 K 线,配合本文的模板,你几十行就能把整批数据干净地交给 Excel 或下游工具。 参考 AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart 亲测最好用的AI编写量化策略工具,可以让 AI 直接写各个平台的策略代码,直接生成可运行的策略代码,代码质量远高于直接使用 DeepSeek、Trae 等平台。大家可以直接用描述策略,然后一键生成可运行的完整策略代码,也可以把它当做一个API 查询工具。 最新消息,已经支持SuperMind等主流量化平台啦,并且实盘亲测过了,很适合小白用户,上线之后获得了非常多朋友的好评。 🚀️Supermind AI量化助手:https://easyquant.ai 一句话回答: 已实现波动率(Realized Volatility, RV)是"用高频(如分钟)收益的平方和来估计波动",比只用日收盘价的历史波动率更贴近真实日内波动。用 AlphaFeed 取 5 分钟 K 线,把每根的对数收益平方求和得到已实现方差,再按每日 bar 数和交易日折算年化,几行代码就能算出更精细的波动率。 为什么会有这个问题 / 传统做法的痛点 大多数人算波动率是"日收盘收益的标准差 × √252"。这没错,但它只用了每天一个价格,丢掉了日内所有波动信息: 一只票日内剧烈震荡但收盘刚好回到昨收,日收益≈0,日频波动率会严重低估它的真实波动; 事件驱动、盘中冲高回落这类结构,日线完全看不到。 已实现波动率的思路是:波动会累积在日内每一小段,用分钟收益的平方和把它们加起来,估计更稳、更贴近现实。难点是拿到干净的分钟数据——这正是 AlphaFeed 的强项。 分步骤解决(每步配可运行代码) 第 1 步:取分钟 K 线 from alphafeed import AlphaFeed import numpy as np af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed() df = af.klines.get("600519.SH", period="5m", count=240, adjust="forward", to_dataframe=True) df = df.sort_values(["trade_date", "trade_time"]).reset_index(drop=True) print(df[["trade_date", "trade_time", "close"]].tail()) 分钟 K 线关键列: 列名 含义 备注 trade_date 交易日 按日+时间排序 trade_time 分钟时间 5m 表示每 5 分钟一根 close 收盘价 算分钟收益用 period 周期参数 5m/15m/30m/60m 等 A 股每个交易日约 4 小时,5 分钟线约 48 根/日(bars_per_day=48);换成 15m 就是 16 根/日,采样频率越高 bar 数越多。 第 2 步:用分钟收益平方和算已实现波动率 def realized_vol(symbol, count=240, bars_per_day=48, trading_days=252): df = af.klines.get(symbol, period="5m", count=count, adjust="forward", to_dataframe=True) df = df.sort_values(["trade_date", "trade_time"]).reset_index(drop=True) r = np.log(df["close"] / df["close"].shift(1)).dropna() # 分钟对数收益 rv_var = float((r ** 2).sum()) # 样本区间已实现方差 = Σ r² n_days = max(len(r) / bars_per_day, 1e-9) daily_var = rv_var / n_days # 日均已实现方差 ann_vol = float(np.sqrt(daily_var * trading_days)) # 年化波动率 return {"bars": len(df), "approx_days": round(n_days, 2), "annualized_vol": round(ann_vol, 4)} print(realized_vol("600519.SH", count=240)) # 例如:{'bars': 240, 'approx_days': 4.98, 'annualized_vol': 0.1423} 上例约 5 个交易日的 5 分钟数据估出茅台年化已实现波动率约 14.2%。核心公式就三步:Σ(分钟对数收益²) → 除以天数得日方差 → ×交易日数再开方得年化。 第 3 步:日频历史波动率对比(看差异) d = af.klines.get("600519.SH", period="1d", count=60, adjust="forward", to_dataframe=True).sort_values("trade_date") dr = np.log(d["close"] / d["close"].shift(1)).dropna() hist_vol = float(dr.std() * np.sqrt(252)) # 传统日频历史波动率 print(round(hist_vol, 4)) 两者度量的是同一个"波动",但已实现波动率利用了日内信息,在震荡剧烈时更灵敏;日频历史波动率更平滑、样本要求低。实务里常两者并看。 关键坑与注意事项 隔夜跳空:跨交易日的第一根分钟收益包含"隔夜跳空",会放大 RV。严谨做法是按日分组、去掉每日第一根的跨夜收益,只累加日内收益,再把隔夜方差单独处理。本文最简版未剔除,长期严谨分析需注意。 采样频率权衡:频率越高(如 1m)理论越精确,但微观结构噪声(买卖价跳动)会污染估计;5m/15m 是常见折中。 年化假设:trading_days=252、bars_per_day 要和你的实际数据匹配;A 股 5m≈48 根/日,改周期务必同步改 bars_per_day。 复权:用 adjust="forward",避免除权跳空混进收益。 样本长度:几天的分钟数据只是短期估计;要稳定的年化值应取更长窗口(如 20 个交易日滚动)。 常见问题(FAQ) Q:已实现波动率和历史波动率、隐含波动率什么区别? A:历史波动率=日收益标准差年化;已实现波动率=高频收益平方和年化(用了日内信息);隐含波动率来自期权价格反推(前瞻)。本文讲前两者。 Q:为什么我的 RV 特别大? A:多半是把隔夜跳空也算进去了,或采样频率太高引入噪声。先按日剔除跨夜收益、把频率降到 5m/15m 再看。 Q:能算滚动的日度 RV 序列吗? A:可以,按 trade_date 分组,每天 Σ日内收益² 得当日已实现方差,开方即当日 RV,再拼成时间序列做波动率预测的输入。 Q:需要付费吗? A:单只标的的分钟线在免费额度内即可试算;批量/长历史分钟数据需 Starter 及以上,详见 AlphaFeed 定价页。 小结 已实现波动率的精髓是"用日内高频收益的平方和,把日线丢掉的波动信息捡回来"。公式简单,真正的门槛是干净、连续、复权正确的分钟数据。AlphaFeed 提供分钟级复权 K 线,让你几行就能算出比日频更贴近现实的波动率——只要记得处理隔夜跳空和采样频率这两个坑。 参考 AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart 一个令散户心碎的讽刺现象 在股市博弈的修罗场里,有一个极其讽刺且扎心的现象:散户每天挑灯夜战,深挖财报、毛利、市盈率,试图以此寻找财富密码;而主力每天却在冷冷地盯着屏幕,研究散户的心理底线。 你是否经历过这样的绝望:好不容易研究透了一家公司,认定它业绩大增、估值偏低,结果满怀信心买入后,股价不仅纹丝不动,甚至精准地在你入场后开启阴跌。你百思不得其解,甚至愤怒于主力是不是“瞎了眼”,竟然看不见这么好的基本面? 真相远比你想象的残酷:你研究的是公司,而主力研究的是你。 核心误区:你和主力研究的根本不是同一个东西 主力之所以能赚走你的钱,并不是因为他们比你更懂财务模型,而是因为从交易的第一秒起,你们的出发点就南辕北辙。 散户痴迷于利润增长、PE倍数;而主力关注的是:你什么时候会忍不住追涨?跌到什么位置你会彻底慌乱?涨到什么价格你才愿意过来接盘? 你研究的是股票,他研究的是怎么把股票卖给你。 对于主力资金来说,他们根本不关心这家公司明年到底赚几个亿,也不屑于和你讨论估值应该是37块还是42块。他们是来求财的,不是来搞学术研究的。他们对“如何点燃情绪、如何通过洗盘把你踢出局”了如指掌。 残酷逻辑:逻辑是上涨的理由,资金才是上涨的动力 很多人执着于“好公司就该涨”,这在本质上是混淆了“理由”与“动力”。 在A股的题材行情中,当一个风口启动,你会看到一种荒诞的“鸡犬升天”:龙头涨完二线涨,最后连产业链上做“螺丝帽”的小透明都能连拉涨停。难道这些螺丝帽厂的基本面在一夜之间发生了翻天覆地的变化?显然没有。唯一的解释是:钱来了。 逻辑是上涨的理由,而资金才是上涨的动力。 逻辑决定了这个故事是否正宗,决定了谁能走得更远;但短期内到底涨不涨,优先取决于有没有资金愿意进场。有逻辑没资金,股价只能趴着装死;而资金一旦进场,哪怕逻辑不够完美,股价照样能被真金白银怼上天。 心理陷阱:你是在做“价值投资”,还是在找“不卖的借口”? 最扎心的交易行为莫过于:买入时冲着短线,套牢后才开始研究基本面。 大多数散户的堕落链条是极其相似的: **1.**轻率买入: 冲着短期爆发进去,告诉自己“破位就走”。 **2.**拒绝止损: 真的破位了,手却不听使唤。 **3.**疯狂找补: 为了缓解焦虑,开始翻研报,“这公司有深度合作啊,产业趋势没变啊”。 **4.**强行转型: 既然亏了,那我就改做“长期价值投资”吧。 **5.**信仰幻灭: 陷入漫长的等待,直到某天解套了,曾经研究的“星辰大海”瞬间不重要了,你只想抓紧跑路。 我想提醒你:不要上午还是个短线客,下午一看跌了,就突然变成**“巴菲特”**了。 这不是投资,这是在为自己失控的交易寻找一个不肯认输的借口。 被忽略的成本:时间也是交易成本 即便你选的是好公司,如果资金不进场,你面临的是巨大的时间成本。 一轮行情结束后,距离下一轮主升浪可能隔着半年甚至一年的调整期。基本面告诉你的是这公司以后“可能有故事”,但资金痕迹告诉你的才是“故事何时开始”。 如果你忽略了资金的态度,哪怕你研究得再认真,市场也不会因为你“态度端正”就多给你涨一个点。 实战教学:如何像专业人士一样观察“资金痕迹”? 别把观察资金想得太神秘。真正的交易高手,通常只盯着这四个核心维度: ●位置与赔率: 同样一个题材,涨了80%的位置和刚突破平台的初始阶段,赔率天差地别。题材要正宗,但位置比逻辑更重要。 ●成交量结构: 别光听故事,要看钱。观察突破前是否有连续性的放量和阳线。如果逻辑吹得天花乱坠,成交量却纹丝不动,那你必须问一句:钱在哪儿? ●上涨的连续性与回调的克制: 真正的强势股上涨干脆利落,阳线具有连续性;而回调时极其克制,回踩支撑有力。这反映了主力资金锁仓的决心。 ●拒绝脑补,尊重市场投票: 哪怕你觉得逻辑值100亿也没用,只有市场用真金白银投出来的票才有用。如果整个趋势结构已经完全破坏掉,你再拿十份研报过来安慰自己也没用。 结构坏了,该认错就得认错。 总结与反思:从“好公司”到“好交易” 市场从来不只是财务报表的比赛,它更是资金、筹码、情绪与人性的博弈。 请记住这个本质的区别: ●你研究业绩,别人研究预期差; ●你研究好坏,别人研究谁来接盘; ●你研究公司值多少钱,别人研究现在还有多少人愿意买。 我从不反对研究基本面,但我反对的是只研究股票,却不研究“交易股票的人”。 基本面告诉你的是这个股票**“值不值得买”,而资金运动告诉你的才是“现在有没有人真的在买”****。** 优秀的交易者,永远在寻找好公司被资金看见、被情绪点燃的那个瞬间。 在下一次买入前,你准备好问自己那句最关键的话了吗——“现在是谁在买?”