做跨境量化或者港股通策略的开发者,接港股数据是绕不开的。港股跟A股有个很特别的联动关系——同一家公司在A股和港股两地上市,价格经常不一样,这就是所谓的AH股溢价。这个价差不仅是金融从业者关心的套利机会,也是技术开发者做跨市场数据监控的典型场景。 这篇从AH股溢价监控这个实际场景出发,讲一下怎么用Python接港股实时行情数据,以及怎么同时拉A股和港股的价格做价差计算。 为什么要接港股数据 一开始我做A股量化的时候,数据都是国内的接口,用得挺顺手。后来想做AH股套利策略,才发现需要同时拿A股和港股两边的实时价格。这时候问题就来了——用两个不同的接口拿两边的数据,时间戳对不上,延迟也不一样,算出来的价差不准。 后来找了一圈,试了几个不同的金融数据接口,最后留下来一直在用的是那种同时覆盖A股和港股的统一数据源——不用维护两套代码,两边的数据时间戳一致性也靠谱很多。现在做跨市场监控,一个key打通多个市场的接口选择其实挺关键的。 港股市场的基本情况 先理一下港股的基本情况,这样看返回数据的时候才知道每个字段是什么意思。 交易时间:上午9:30-12:00,下午13:00-16:00。比A股多半小时,中午也有1小时休市。 代码格式:港股代码是5位数字,比如00700是腾讯、09988是阿里、03690是美团。跟A股的6位数字不一样,传参数的时候要注意位数。 交易货币:港币(HKD)。算AH股溢价的时候要注意汇率换算。 region代码:港股市场region传 HK,A股传 CN。 REST拉取港股报价 先从REST开始,确认数据格式。 import requests API_BASE = "https://api.itick.org" TOKEN = "your_token_here" headers = {"accept": "application/json", "token": TOKEN} # 拉港股实时报价 def get_hk_stock_quote(code): resp = requests.get( f"{API_BASE}/stock/quote", headers=headers, params={ "region": "HK", "code": code } ) return resp.json()["data"] # 拉几只港股大盘股 stocks = ["00700", "09988", "03690"] for code in stocks: q = get_hk_stock_quote(code) sign = "+" if q["chp"] >= 0 else "" print(f"{code}: {q['ld']} ({sign}{q['chp']}%)") 返回字段跟其他市场基本一致:ld最新价、chp涨跌幅、o/h/l开高低、v成交量。做行情看板这些字段够用了。 注意:港股代码是5位数字,传参数的时候要传字符串形式("00700"),不要传数字。一开始我传了"700",结果返回空数据——港股代码必须带前导零,5位数字。 WebSocket订阅港股 做实时监控的时候,轮询REST接口效率太低,这时候就得用WebSocket实时推送了。 import json import threading import time import websocket WS_URL = "wss://api.itick.org/stock" TOKEN = "your_token_here" 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": "00700$HK,09988$HK", "types": "quote" })) return if payload.get("resAc") == "pong": return data = payload.get("data") or {} if data.get("type") == "quote": sign = "+" if data["chp"] >= 0 else "" print(f"{data['s']}: {data['ld']} ({sign}{data['chp']}%)") 港股订阅是两个参数(00700$HK),跟美股、A股一样,不是印度那种三个参数。 AH股溢价监控实战 这是港股数据最有技术含量的应用场景——同一家公司在A股和港股两地上市,价格经常不一样。 比如招商银行,A股代码是600036,港股代码是03968。两边的价格理论上应该差不多,但实际上经常有5%-30%的溢价差。这个价差就是量化交易者关心的套利机会。 # AH股溢价监控 # 招商银行:A股 600036,港股 03968 # 中国平安:A股 601318,港股 02318 def get_ah_premium(a_code, h_code, hkd_cny_rate=0.92): """ 计算AH股溢价率 a_code: A股代码 h_code: 港股代码 hkd_cny_rate: 港币兑人民币汇率 """ # 拉A股价格 a_resp = requests.get( f"{API_BASE}/stock/quote", headers=headers, params={"region": "CN", "code": a_code} ).json()["data"] # 拉港股价格 h_resp = requests.get( f"{API_BASE}/stock/quote", headers=headers, params={"region": "HK", "code": h_code} ).json()["data"] # 港股价格换算成人民币 h_price_cny = h_resp["ld"] * hkd_cny_rate # 计算溢价率 premium = (a_resp["ld"] - h_price_cny) / h_price_cny * 100 return { "a_code": a_code, "a_price": a_resp["ld"], "h_code": h_code, "h_price_hkd": h_resp["ld"], "h_price_cny": round(h_price_cny, 2), "premium_pct": round(premium, 2) } # 监控几只AH股 ah_pairs = [ ("600036", "03968"), # 招商银行 ("601318", "02318"), # 中国平安 ("600900", "00900"), # 长江电力 ] for a_code, h_code in ah_pairs: result = get_ah_premium(a_code, h_code) print(f"{result['a_code']} / {result['h_code']}: " f"A股{result['a_price']}元, 港股{result['h_price_hkd']}港币 " f"(≈{result['h_price_cny']}元), " f"溢价{result['premium_pct']}%") 这个脚本跑起来之后,就能看到每只AH股的溢价率了。溢价率过高或者过低的时候,就是套利的机会。 注意:汇率是动态变化的,做实时监控的时候要定期更新汇率,不能写死。 K线数据获取 K线接口跟其他市场一样,只是region传 HK。 def get_hk_kline(code, k_type=8, limit=100): """ k_type: 1=1分钟 2=5分钟 5=1小时 8=日K 9=周K 10=月K """ resp = requests.get( f"{API_BASE}/stock/kline", headers=headers, params={ "region": "HK", "code": code, "kType": k_type, "limit": limit } ) return resp.json()["data"] # 拉腾讯近100根日K daily = get_hk_kline("00700", k_type=8, limit=100) closes = [bar["c"] for bar in daily] # 算20日均线 ma20 = sum(closes[-20:]) / 20 print(f"00700最新收盘: {closes[-1]}, 20日均线: {ma20:.2f}") K线返回标准OHLCV:t时间戳、o/h/l/c开高低收、v成交量。做技术分析直接用这些字段。 港股特有的注意事项 代码是5位数字,带前导零。 港股代码是5位数字(00700、09988),跟A股的6位数字(600519)不一样。一开始我传了"700",结果返回空数据——港股代码必须是5位,前面补零。 交易时间比A股长半小时。 港股上午9:30-12:00,下午13:00-16:00。比A股多半小时,做跨市场监控的时候要注意两边的交易时间窗口。 交易货币是港币。 港股价格单位是港币(HKD),做AH股溢价计算的时候要换算成人民币。汇率是动态的,不能写死。 港股通标的有限。 不是所有港股都能通过港股通买,做策略的时候要注意标的范围。 时间戳是毫秒。 所有返回的时间戳都是毫秒,直接当秒数处理会得到一个很远的未来时间,记得除以1000。 完整脚本:港股+AH股溢价监控 把前面几块拼起来,最终的完整脚本: import json, time, threading, requests, websocket API_BASE = "https://api.itick.org" WS_URL = "wss://api.itick.org/stock" TOKEN = "your_token_here" headers = {"accept": "application/json", "token": TOKEN} # 港股监控列表 watchlist = ["00700", "09988", "03690"] # 启动时拉快照 print("=== 港股快照 ===") for code in watchlist: r = requests.get(f"{API_BASE}/stock/quote", headers=headers, params={"region": "HK", "code": code}).json()["data"] sign = "+" if r["chp"] >= 0 else "" print(f" {code}: {r['ld']} ({sign}{r['chp']}%)") # AH股溢价快照 print("\n=== AH股溢价 ===") ah_pairs = [("600036", "03968"), ("601318", "02318")] for a_code, h_code in ah_pairs: a = requests.get(f"{API_BASE}/stock/quote", headers=headers, params={"region": "CN", "code": a_code}).json()["data"] h = requests.get(f"{API_BASE}/stock/quote", headers=headers, params={"region": "HK", "code": h_code}).json()["data"] h_cny = h["ld"] * 0.92 premium = (a["ld"] - h_cny) / h_cny * 100 print(f" {a_code}/{h_code}: A股{a['ld']}元, 港股{h['ld']}港币 " f"(≈{h_cny:.2f}元), 溢价{premium:.1f}%") # 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 params = ",".join(f"{c}$HK" for c in watchlist) ws.send(json.dumps({ "ac": "subscribe", "params": params, "types": "quote" })) threading.Thread(target=heartbeat, args=(ws,), daemon=True).start() return if payload.get("resAc") == "pong": return data = payload.get("data") or {} if data.get("type") == "quote": sign = "+" if data["chp"] >= 0 else "" print(f"[实时] {data['s']}: {data['ld']} ({sign}{data['chp']}%)") def heartbeat(ws): while True: time.sleep(30) ws.send(json.dumps({"ac": "ping", "params": str(int(time.time() * 1000))})) ws = websocket.WebSocketApp(WS_URL, header=[f"token: {TOKEN}"], on_message=on_message) ws.run_forever() 这个脚本跑起来之后,开盘前先看到一组港股的快照和AH股溢价率,盘中实时更新港股价格。 小结 接港股数据的技术框架跟A股、美股差不多——REST做快照和历史数据,WebSocket做实时推送。主要区别在代码格式(5位数字带前导零)、交易货币(港币)和交易时间(比A股长半小时)。最有技术含量的应用场景是AH股溢价监控——同时拉A股和港股两边的价格,算跨市场价差。 做港股量化策略或者AH股套利的话,这套流程可以直接套。具体的参数细节和返回字段说明,我一般都是边写代码边翻官方文档对照,比自己猜参数靠谱多了。 GitHub:https://github.com/itick-org/ 做跨市场行情App,最容易被用户截图投诉的,是价格旁边那个红绿百分比。同一刻、同一个金价,涨跌可以是−0.69%,也可以是+0.24%。本文拆解涨幅榜、价格提醒、持仓页、首页详情页4个最容易出错的场景,附一张跨市场分母清单。 做跨市场行情App,最容易被用户截图投诉的,往往是价格旁边那个红绿百分比。 2026年10月13日周二,北京时间10:56,黄金4,175.15美元。同一个价格,我按5种常见算法各算了一遍涨跌幅: 跟谁比 基准价(美元) 涨跌 24小时前(约) 4,204.35 −0.69% 我实测的接口给的“前收” 4,190.27 −0.36% 纽约17:00 4,171.38 +0.09% UTC 0点(日K收盘) 4,170.54 +0.11% 北京时间0点 4,164.95 +0.24% 单次快照。基准价都取自同一数据源的K线,涨跌幅按同一个公式重算,可以自己验算。 换成钱:持有100盎司黄金,按“24小时前”算,账面一天亏约2,920美元;按“北京时间0点”算,赚约1,020美元,相差3,940美元。两个App给出相反的颜色,都没算错。 黄金只是一个品种。把A股、港股、美股、外汇、加密放进同一个App,这种事会成倍出现:寒武纪除权那天,日K线上“暴跌36.7%”,实际只跌5.6%;同一只苹果,首页显示+1.29%,详情页显示+0.47%;比特币的“今日涨跌”,其实是过去24小时。 跨市场行情应用里,涨跌幅不是一个现成的字段,而是一道除法:分子是现价,各家一样;分母是“跟谁比”,每个市场都不一样。分母不统一就上屏,涨幅榜、价格提醒、持仓页、首页推送,四个地方都会出错。 这篇写给做行情产品的人——产品、运营和技术同事,也写给每天看行情App的投资者。读完你能带走: 4个最容易出错的产品场景:用户看到什么、错在哪、代价多大、怎么修 一张跨市场“分母清单”:每个市场的涨跌幅该跟谁比,界面上该写什么 上线前问数据供应商的5个问题 一段代码(给技术同事):按统一基准重算涨跌,自动识别A股除权除息日 先记住一句话:看涨跌,先问“跟谁比”。 一、一分钟看懂:涨跌幅为什么会对不上 涨跌幅 =(现价 − 基准价)÷ 基准价。现价各家一样,分歧全在基准价。 系列上一篇《行情看板Demo三天、上线三个月:拆解7个返工点》提出过一个检查框架:界面上的每个数字,都要能说清自己的品种、时段、算法、时间、状态。涨跌幅是“算法”这一格里最常见、也最容易出错的数字。 拆开看,基准价由3个问题决定: 跟哪个价比?昨天的收盘价、某个整点的价格,还是除权后的参考价。 跟几点的价比?“今天”从北京时间0点算、UTC 0点算、纽约17:00算,还是干脆用“过去24小时”。 中间发生过什么?除权除息、跨时段(盘后、夜盘)、休市。 连“收盘价”本身都是规则算出来的。上交所从2018年8月20日起,股票收盘价由14:57–15:00的收盘集合竞价产生,这三分钟可以报单、不能撤单;纳斯达克16:00的收盘撮合产生官方收盘价;黄金干脆没有官方收盘价。每个市场规则不同,默认分母也不同: 市场 涨跌幅通常跟谁比 最容易出错的地方 A股 上一交易日收盘价 除权除息日要改用参考价 港股 上一交易日收市价(由收市竞价时段决定) 跨市场排序时和美股、加密的窗口不同 美股 上一常规交易日收盘价 盘前、盘后、夜盘另有基准 黄金、外汇 没有官方收盘:纽约17:00、UTC 0点、北京0点都有人用 周日开盘会切出一根“迷你日K” 加密资产 没有收盘:滚动24小时,或用户自选0点 窗口每时每刻都在挪 指数 上一交易日收盘价 休市时段,各家显示不同 一个App里只放一个市场,问题不大;放进六个市场,这六套规则就会在同一块屏幕上撞车。下面是撞车最多的4个地方。 二、4个出错场景:钱和信任在哪里流失 每个场景都是同一个毛病:不同分母的涨跌幅,被当成同一种数放在了一起。 场景① 涨幅榜和自选列表:跨市场一排序,名次就失真 用户看到的:自选列表按涨跌幅排序,苹果+1.29%排第一,比特币−1.07%排最后。 错在哪:这5个涨跌幅,量的是5段不同的时间。 苹果、标普500:北京时间上午美股休市,显示的是上周五收盘到周一收盘的涨跌; 寒武纪:昨天收盘到现在; 黄金:看你选几点切日,图里按UTC 0点; 比特币:过去24小时,而且这个窗口一直在滑动。我实测它的“前收”,10月12日11:08是83,049.15,同日14:01是83,074.01,10月13日10:56是83,866.01,同一天里查两次,分母就变了。币安官方API文档把24小时行情定义为滚动窗口;Gate 则让用户在“过去24小时”“UTC+8 0点”“UTC 0点”三种起止时间里自己选。 指数还有一种情况:我实测标普500在10月12日北京白天显示0.00%(前收和最新价都是7,811.54),10月13日早上显示−0.06%(周一的涨跌)。同样是美股休市的北京白天,一天显示0,一天显示上一交易日的涨跌。 代价:榜单名次没有可比性。用户按“今日最强”去追,追的可能是两天前的涨幅;运营做跨市场涨幅榜活动,排第一的未必真涨得最多;指数休市显示0.00%,用户以为平盘。 怎么修:跨市场排序前,用K线按同一个窗口(比如“北京时间今天0点至今”)把所有品种重算一遍再排;休市的品种标“休市”,不和交易中的品种混排。 先问供应商:涨跌幅的基准时刻是几点、哪个时区?休市时显示什么? 场景② 价格提醒:同一个阈值,一个响一个不响 用户看到的:用户设了“黄金跌0.5%提醒我”。同一时刻,A平台推送了提醒,B平台没有。 错在哪:按“24小时前”算是−0.69%,提醒响;按“北京时间0点”算是+0.24%,提醒不响。两个平台都没算错,只是分母不同。 根子在于黄金没有官方收盘价。伦敦 LBMA 黄金价格每天定两次(伦敦时间10:30、15:00),上海金每天两次(北京时间10:15、14:15),COMEX 期货结算价按收盘前一段时间的成交量加权平均价算。现货平台不受这些约束,各自选时刻切“日”。CME 在2026年9月29日的文章里写,纽约时间17:00之后的一小时,是全球外汇日的“行政分界”——按这个时刻切日很常见,但不是唯一的选择。 切日时刻还会切出意外。按UTC 0点切日K线的数据源,周日晚上开盘那几个小时会单独成一根“日K”:我实测黄金10月11日(周日)这根K线成交量只有8,813,前后几个交易日都在15万以上。我实测的接口给出的“前收”4,190.27,正好就是这根周日K线的收盘,算出来是−0.36%,既不是纽约17:00的价格,也不是周一的收盘。 代价:误触发,用户可能据此卖出或加仓;漏触发,该提醒的没提醒。客服还解释不清“为什么别家提醒了你们没提醒”。 怎么修:提醒规则里写明基准,比如“较纽约17:00跌0.5%”,用户设置时就能看到;周日开盘那几个小时单独处理,不当成一个交易日。 两个边界:用小时K线取的“纽约17:00价格”,和别家的纽约收盘可能差零点几美元;“24小时前”只能取到最近的整点,是近似值。 先问供应商:黄金、外汇按几点切日?周日开盘那几个小时怎么算? 场景③ 持仓和资产页:除权那天“一夜亏三成” 用户看到的:持有寒武纪的用户,5月8日早上打开App,持仓市值少了三成;跌幅榜第一名是寒武纪,−36.70%。 错在哪:这天是寒武纪的除权除息日。2025年度分配方案是每股派现1.50元、每股转增0.49股,股权登记日5月7日。交易所规定,除权除息日的涨跌幅不跟昨天收盘比,而是跟除权(息)参考价比: 参考价 =(前收盘价 − 现金红利)÷(1 + 流通股份变动比例)=(1,868.00 − 1.50)÷ 1.49 = 1,252.68元 5月8日实际开盘1,217.03元、收盘1,182.53元: 按昨收1,868.00算:低开34.85%,收跌36.70% 按参考价1,252.68算:低开2.85%,收跌5.60% 我实测的复权因子也对得上:这次除权的前复权因子是0.6706,1,868.00 × 0.6706 = 1,252.68。 还有一个反证。寒武纪是科创板股票,涨跌幅限制20%。按参考价算,当天涨跌停区间是1,002.14–1,503.22元;如果错按昨收算,跌停价应是1,494.40元,而寒武纪全天都在1,158.01–1,220.00元之间成交——那就等于全天都在“跌停价以下”成交,这不可能。交易所自己用的分母,就是参考价。 代价:从持仓看,转增后股数变成1.49倍,每股还拿了1.50元现金,市值并没有少三成,但用户看到的是“亏了三成”,第一反应是截图投诉。跌幅榜挂错,运营要出面解释。做量化的拿不复权日K回测,除权日是一根假的大阴线,止损会在这天被误触发。 这不是一年碰上一次的事。10月正赶上中期分红集中除权,我实测的分红日历里,10月12日、13日两天的A股除权除息记录就超过20条。 怎么修:快照的前收和昨日收盘差得多,先标“除权除息”,涨跌按参考价算,持仓按新股数显示;回测用复权数据。 先问供应商:除权除息日的前收,是不是参考价? 场景④ 首页和详情页:同一只苹果,两个涨幅 用户看到的:首页上苹果+1.29%,点进详情页+0.47%。用户的第一反应:数据坏了。 错在哪:10月13日北京时间10:56,美股正在夜盘时段。我实测同一时刻的苹果有4个涨跌: 主快照340.97美元(周一常规盘收盘),较上周五收盘336.64,+1.29% 盘后341.36,较周一收盘,+0.11% 夜盘342.57,较周一收盘,+0.47% 夜盘较上周五收盘,+1.76%(自己算) 规则是:常规盘的涨跌,跟上一个常规交易日的收盘比;盘后、夜盘的涨跌,跟当天常规盘的收盘比。数据里写得很清楚:盘后、夜盘的前收是340.97(周一收盘),主快照的前收是336.64(上周五收盘)。四个数都对,只是分母不同。 代价:用户真正想知道的,往往是“从上周五到现在涨了多少”,答案是+1.76%,首页和详情页给他的哪个都不是。两个数并排、又不写分母,用户只会得出一个结论:这个App的数据不靠谱。到了财报季,盘后动辄跳空几个百分点,首页和详情页的差距会更大(本周五的文章专门讲)。 怎么修:同一屏上的每个涨跌幅,旁边写上时段和基准,比如“夜盘 较周一收盘 +0.47%”。 先问供应商:盘前、盘后、夜盘的涨跌,按哪个收盘算? 4个场景收在一张表里: 场景 用户看到的 错在哪 代价 怎么修 涨幅榜 苹果第一、比特币最后 5个涨跌幅量的是5段时间 名次失真,用户追错 按同一窗口重算再排 价格提醒 一家响、一家不响 黄金切日时刻不同 误触发、漏触发 规则里写明基准 持仓页 一夜“亏三成” 除权日没用参考价 恐慌、投诉、回测失真 识别除权日,按参考价算 首页/详情页 +1.29%和+0.47% 常规盘和夜盘分母不同 用户不再信任数据 每个涨跌幅标时段和基准 这4件事看起来是技术细节,其实是产品问题。卡尼曼和特沃斯基1979年提出的前景理论有一个结论:人判断得失,看的是相对某个参照点的变化,而不是绝对水平。行情App上的涨跌幅,就是替用户选好的参照点。同样4,175.15美元的金价,参照点选在24小时前,用户觉得亏了;选在北京时间0点,用户觉得赚了。谁定分母,谁就定了用户今天的情绪,所以分母应该写在界面上。 三、怎么修:跨市场统一分母,分3步 先给每个涨跌幅贴上分母标签,再按同一个窗口重算,最后单独处理除权。 1. 一张跨市场分母清单 市场 建议的分母 界面上要写的字 A股 上一交易日收盘;除权除息日用参考价 “较前收(除权调整)” 港股 上一交易日收市价 “较前收” 美股常规盘 上一常规交易日收盘 “较上一交易日收盘” 美股盘前/盘后/夜盘 当天常规盘收盘 “夜盘 较今日收盘” 黄金、外汇 选定一个切日时刻(如纽约17:00)并写出来 “较纽约17:00” 加密 滚动24小时,或指定时区0点 “24h”或“较UTC 0点” 指数(休市时段) 上一交易日涨跌并标日期,或标“休市” “10/12 收盘” 照着这张表,每个涨跌幅旁边都能写出它在跟谁比。A股参考价按交易所规则执行,其余是建议做法。 2. 三步落地 第一步,贴标签。每个涨跌幅带上基准价和基准时刻。不贴,用户拿两个App一比颜色不一样就来问;解释一次,下一个用户还会问。 第二步,统一窗口。跨市场比较(涨幅榜、资产总览、跨市场提醒)时,不比现成的百分比,用K线按同一个窗口自己重算。不重算,名次取决于谁的分母更旧。 第三步,单独处理除权。A股先判断是不是除权除息日:快照的前收和昨日收盘差得多,就按参考价或复权数据处理。 3. 为什么跨市场更难:6类资产,6套规则 只做A股,记住“前收、除权”两件事就够了。做跨市场,要同时管6套规则:A股的除权、港股的收市竞价、美股的四个时段、黄金外汇的切日时刻、加密的滚动窗口、指数的休市显示。 如果每个市场各接一家数据源,同样叫“前收”的字段,名字、时间戳格式、切日时刻都可能不一样。统一分母之前,得先写一层“翻译”;市场越多,翻译层越厚。规则还在变:美国夏令时11月1日结束,纽约17:00对应的北京时间要从早上5点变成6点,每一家数据源的处理都得重新核对一遍。 所以做跨市场行情应用,省事的做法是:一套接口拿到所有市场的快照、K线和复权数据,分母标签层只写一次。 4. 我用 TickDB 把6类资产跑了一遍 TickDB 为开发者和 AI 应用提供统一的全球行情数据接口,让团队通过一套接入获取多市场实时与历史数据,更快构建行情、分析和监控产品。 本文寒武纪、苹果、黄金、比特币、标普500的数字,都是我用同一套接口取的: 能做到 要你自己处理 6类资产(A股、港股、美股、外汇贵金属、指数、加密)的快照,用同一组字段返回现价、前收和时间戳 接口给的涨跌幅是一个现成的数,不带“分母说明”,标签要自己加 同一套K线接口覆盖各市场,可以按任意基准时刻(纽约17:00、北京0点、UTC 0点)自己重算 黄金、外汇这类没有官方收盘的品种,建议按自己选定、并写在界面上的基准重算 美股快照同时带盘后、夜盘各自的价格和前收;复权因子能还原寒武纪的除权参考价 复权数据会随新的公司行为更新,回测要记下查询时间和复权方式 左边是一套接口能直接支撑的,右边是任何数据源都替代不了的产品判断。(作者实测,2026年10月12–13日。) 5. 给技术同事:一段代码 不写代码的读者可以跳过这一节。下面这段代码做两件事:用小时K线按4种基准时刻重算黄金涨跌;自动识别A股除权除息日。 # 测试环境:Python 3.11 # 接口端点与字段名已于 2026-10-13 通过实际调用核对 import os import sys from datetime import datetime, timedelta, timezone from decimal import Decimal from zoneinfo import ZoneInfo import requests API_KEY = os.getenv("TICKDB_API_KEY") # 从环境变量读取,不要写进前端 BASE_URL = "https://api.tickdb.ai/v1/market" UTC, BJ, NY = timezone.utc, ZoneInfo("Asia/Shanghai"), ZoneInfo("America/New_York") HOUR_MS = 3_600_000 def get(path, **params): """调用接口,同时检查 HTTP 状态和业务返回码。""" try: resp = requests.get(f"{BASE_URL}/{path}", params=params, headers={"X-API-Key": API_KEY}, timeout=10) body = resp.json() except (requests.RequestException, ValueError) as e: raise RuntimeError(f"{path} 请求失败: {e}") from e if resp.status_code != 200 or body.get("code") != 0: raise RuntimeError(f"{path}: HTTP {resp.status_code}, code={body.get('code')}, {body.get('message')}") return body["data"] def pct(last, base): """涨跌幅(%)=(现价 − 基准价)÷ 基准价 × 100。""" last, base = Decimal(str(last)), Decimal(str(base)) return (last - base) / base * 100 def price_at(hourly, moment): """取某一时刻的价格:用“结束于该时刻”的那根小时K线的收盘价(K线时间戳为该小时的开始)。""" target = int(moment.timestamp() * 1000) - HOUR_MS for bar in hourly: if bar["time"] == target: return bar["close"] return None def last_moment(now, tz, hour): """now 之前最近一次 tz 时区的 hour 点(自动处理夏令时)。""" local = now.astimezone(tz) m = local.replace(hour=hour, minute=0, second=0, microsecond=0) if m > local: m -= timedelta(days=1) return m def gold_changes(symbol="XAUUSD"): """同一个现价,按4种自选基准价分别算涨跌。""" q = get("ticker", symbols=symbol, type="forex")[0] hourly = get("kline", symbol=symbol, interval="1h", type="forex", limit=48)["klines"] now = datetime.fromtimestamp(q["timestamp"] / 1000, UTC) day_ago = (now - timedelta(hours=24) + timedelta(minutes=30)).replace(minute=0, second=0, microsecond=0) # 24小时前,取最近的整点 bases = { "24小时前(近似)": price_at(hourly, day_ago), "纽约17:00收盘": price_at(hourly, last_moment(now, NY, 17)), "UTC 0点": price_at(hourly, last_moment(now, UTC, 0)), "北京时间0点": price_at(hourly, last_moment(now, BJ, 0)), } print(f"{symbol} 现价 {q['last_price']}({now.astimezone(BJ):%m-%d %H:%M} 北京时间)") for name, base in bases.items(): print(f" 较{name:<10} 基准 {base} 涨跌 {pct(q['last_price'], base):+.2f}%" if base else f" 较{name}:缺数据") def is_ex_rights_day(prev_close, last_daily_close, tol=Decimal("0.005")): """快照的前收和上一根日K收盘相差超过0.5%,大概率是除权除息日,要用参考价/复权数据核对。""" p, c = Decimal(str(prev_close)), Decimal(str(last_daily_close)) return abs(p / c - 1) > tol def check_ex_rights(symbol="688256.SH"): q = get("ticker", symbols=symbol, type="stock")[0] daily = get("kline", symbol=symbol, interval="1d", type="stock", limit=2)["klines"] yesterday_close = daily[-2]["close"] # 最后一根是今天(可能未结束),取倒数第二根 flag = is_ex_rights_day(q["prev_close"], yesterday_close) print(f"{symbol} 快照前收 {q['prev_close']} / 昨日K线收盘 {yesterday_close} → {'疑似除权除息日' if flag else '正常'}") if __name__ == "__main__": if not API_KEY: sys.exit("请先设置环境变量 TICKDB_API_KEY") gold_changes() check_ex_rights() # 历史核对:寒武纪 2026-05-08 除权除息日,参考价 1252.68,前一日收盘 1868.00 print("2026-05-08 寒武纪:", "疑似除权除息日" if is_ex_rights_day("1252.68", "1868.00") else "正常") 用10月13日10:56的实测数据跑出来的结果: XAUUSD 现价 4175.15(10-13 10:56 北京时间) 较24小时前(近似) 基准 4204.35 涨跌 -0.69% 较纽约17:00收盘 基准 4171.38 涨跌 +0.09% 较UTC 0点 基准 4170.54 涨跌 +0.11% 较北京时间0点 基准 4164.95 涨跌 +0.24% 688256.SH 快照前收 971.88 / 昨日K线收盘 971.88 → 正常 2026-05-08 寒武纪: 疑似除权除息日 三点说明: 基准价都取自小时K线。K线时间戳是该小时的开始,所以代码取的是“结束于某时刻”的那根K线的收盘价。 纽约17:00用时区库换算,夏令时自动处理,11月1日之后不用改代码。 0.5%的阈值是经验值,只负责标记;标记出来以后,要再用参考价或复权因子核对。 6. 上线前问供应商的5个问题 涨跌幅的基准价是哪个价?昨收、某个时刻的价格,还是除权后的参考价。 基准时刻是几点、哪个时区?周日开盘那几个小时怎么算?决定黄金、外汇、加密的涨跌能不能和股票放在一起。 除权除息日用不用参考价?不用,持仓页就会出现“一夜亏三成”。 盘前、盘后、夜盘的涨跌按哪个收盘算?不说清,首页和详情页就会对不上。 休市时显示上一交易日涨跌,还是0?显示0,用户会以为平盘。 常见问题 行情App的涨跌幅,为什么和别家不一样? 因为分母不同。涨跌幅=(现价−基准价)÷基准价,现价各家一样,基准价各家可以不同:A股除权日用参考价还是昨收,黄金按纽约17:00还是UTC 0点切日,加密用滚动24小时还是0点,美股夜盘跟周一收盘比还是跟上周五比。两个App的涨跌幅不一样,多半不是谁算错,而是分母不同。 跨市场涨幅榜怎么排才可比? 不要直接拿各市场现成的涨跌幅排序。先选定一个统一窗口,比如“北京时间今天0点至今”或“过去24小时”,用K线把每个品种按这个窗口重算一遍再排;休市的品种单独标出,不和交易中的品种混排。 黄金的收盘价是几点的价格? 黄金现货没有交易所规定的官方收盘价。伦敦 LBMA 黄金价格每天定两次,伦敦时间10:30和15:00;上海金每天两次,北京时间10:15和14:15;COMEX 黄金期货结算价按收盘前一段时间的成交量加权平均价确定。现货平台各自选时刻切“日”,常见的有纽约17:00、UTC 0点、北京时间0点。 为什么除权那天股价“暴跌”,涨跌幅却不大? 除权除息日的涨跌幅,基准不是昨天的收盘价,而是除权(息)参考价。寒武纪2026年5月8日前收1,868.00元,每股派现1.50元、转增0.49股,参考价1,252.68元;收盘1,182.53元,看着跌了36.7%,按参考价只跌5.6%。价格降下去的部分,换成了多出来的股份和到账的现金。 美股盘后、夜盘的涨跌是跟谁比? 跟当天常规盘的收盘比;常规盘的涨跌,跟上一个常规交易日的收盘比。2026年10月13日北京时间10:56,苹果主快照较上周五收盘涨1.29%,夜盘较周一收盘涨0.47%。首页显示主快照、详情页显示夜盘,就会出现两个不同的涨幅。 最后一个问题 你们App上的涨跌幅,分母写在哪? 今天就能做的一件事:打开自己App的涨幅榜,逐行写出每个涨跌幅跟谁比、从几点算起。写不出来的那一行,就是下一个客诉工单。 如果你只是用行情App的投资者,也可以试一次:同一时刻打开三个App,记下同一个品种的涨跌幅。不一样,多半不是谁错了,只是三个参照点。 看涨跌,先问“跟谁比”。 参考资料 LBMA,LBMA Gold Price CME Group,When FX Futures Pause: Understanding spread risk around the daily close,2026-09-29 上海证券交易所,收盘集合竞价相关说明,2018-08-06 Nasdaq,Opening and Closing Cross FAQ 香港交易所,Trading Mechanism of CAS in the Securities Market 上海黄金交易所,Shanghai Gold Benchmark Price Launching Ceremony,2016-04 CME Group,Gold 结算方法说明 寒武纪,2025年年度权益分派实施公告(公告编号2026-011) 上海证券交易所,《上海证券交易所科创板股票交易特别规定》 Spot API 文档:24hr Ticker Price Change Statistics Gate 帮助中心,如何切换涨跌幅起止时间 Kahneman, D. & Tversky, A. (1979). Prospect Theory: An Analysis of Decision under Risk. Econometrica, 47(2), 263–291 做跨市场行情App,最容易被用户截图投诉的,是价格旁边那个红绿百分比。同一刻、同一个金价,涨跌可以是−0.69%,也可以是+0.24%。本文拆解涨幅榜、价格提醒、持仓页、首页详情页4个最容易出错的场景,附一张跨市场分母清单。 做跨市场行情App,最容易被用户截图投诉的,往往是价格旁边那个红绿百分比。 2026年10月13日周二,北京时间10:56,黄金4,175.15美元。同一个价格,我按5种常见算法各算了一遍涨跌幅: 跟谁比 基准价(美元) 涨跌 24小时前(约) 4,204.35 −0.69% 我实测的接口给的“前收” 4,190.27 −0.36% 纽约17:00 4,171.38 +0.09% UTC 0点(日K收盘) 4,170.54 +0.11% 北京时间0点 4,164.95 +0.24% 单次快照。基准价都取自同一数据源的K线,涨跌幅按同一个公式重算,可以自己验算。 换成钱:持有100盎司黄金,按“24小时前”算,账面一天亏约2,920美元;按“北京时间0点”算,赚约1,020美元,相差3,940美元。两个App给出相反的颜色,都没算错。 黄金只是一个品种。把A股、港股、美股、外汇、加密放进同一个App,这种事会成倍出现:寒武纪除权那天,日K线上“暴跌36.7%”,实际只跌5.6%;同一只苹果,首页显示+1.29%,详情页显示+0.47%;比特币的“今日涨跌”,其实是过去24小时。 跨市场行情应用里,涨跌幅不是一个现成的字段,而是一道除法:分子是现价,各家一样;分母是“跟谁比”,每个市场都不一样。分母不统一就上屏,涨幅榜、价格提醒、持仓页、首页推送,四个地方都会出错。 这篇写给做行情产品的人——产品、运营和技术同事,也写给每天看行情App的投资者。读完你能带走: 4个最容易出错的产品场景:用户看到什么、错在哪、代价多大、怎么修 一张跨市场“分母清单”:每个市场的涨跌幅该跟谁比,界面上该写什么 上线前问数据供应商的5个问题 一段代码(给技术同事):按统一基准重算涨跌,自动识别A股除权除息日 先记住一句话:看涨跌,先问“跟谁比”。 一、一分钟看懂:涨跌幅为什么会对不上 涨跌幅 =(现价 − 基准价)÷ 基准价。现价各家一样,分歧全在基准价。 系列上一篇《行情看板Demo三天、上线三个月:拆解7个返工点》提出过一个检查框架:界面上的每个数字,都要能说清自己的品种、时段、算法、时间、状态。涨跌幅是“算法”这一格里最常见、也最容易出错的数字。 拆开看,基准价由3个问题决定: 跟哪个价比?昨天的收盘价、某个整点的价格,还是除权后的参考价。 跟几点的价比?“今天”从北京时间0点算、UTC 0点算、纽约17:00算,还是干脆用“过去24小时”。 中间发生过什么?除权除息、跨时段(盘后、夜盘)、休市。 连“收盘价”本身都是规则算出来的。上交所从2018年8月20日起,股票收盘价由14:57–15:00的收盘集合竞价产生,这三分钟可以报单、不能撤单;纳斯达克16:00的收盘撮合产生官方收盘价;黄金干脆没有官方收盘价。每个市场规则不同,默认分母也不同: 市场 涨跌幅通常跟谁比 最容易出错的地方 A股 上一交易日收盘价 除权除息日要改用参考价 港股 上一交易日收市价(由收市竞价时段决定) 跨市场排序时和美股、加密的窗口不同 美股 上一常规交易日收盘价 盘前、盘后、夜盘另有基准 黄金、外汇 没有官方收盘:纽约17:00、UTC 0点、北京0点都有人用 周日开盘会切出一根“迷你日K” 加密资产 没有收盘:滚动24小时,或用户自选0点 窗口每时每刻都在挪 指数 上一交易日收盘价 休市时段,各家显示不同 一个App里只放一个市场,问题不大;放进六个市场,这六套规则就会在同一块屏幕上撞车。下面是撞车最多的4个地方。 二、4个出错场景:钱和信任在哪里流失 每个场景都是同一个毛病:不同分母的涨跌幅,被当成同一种数放在了一起。 场景① 涨幅榜和自选列表:跨市场一排序,名次就失真 用户看到的:自选列表按涨跌幅排序,苹果+1.29%排第一,比特币−1.07%排最后。 错在哪:这5个涨跌幅,量的是5段不同的时间。 苹果、标普500:北京时间上午美股休市,显示的是上周五收盘到周一收盘的涨跌; 寒武纪:昨天收盘到现在; 黄金:看你选几点切日,图里按UTC 0点; 比特币:过去24小时,而且这个窗口一直在滑动。我实测它的“前收”,10月12日11:08是83,049.15,同日14:01是83,074.01,10月13日10:56是83,866.01,同一天里查两次,分母就变了。币安官方API文档把24小时行情定义为滚动窗口;Gate 则让用户在“过去24小时”“UTC+8 0点”“UTC 0点”三种起止时间里自己选。 指数还有一种情况:我实测标普500在10月12日北京白天显示0.00%(前收和最新价都是7,811.54),10月13日早上显示−0.06%(周一的涨跌)。同样是美股休市的北京白天,一天显示0,一天显示上一交易日的涨跌。 代价:榜单名次没有可比性。用户按“今日最强”去追,追的可能是两天前的涨幅;运营做跨市场涨幅榜活动,排第一的未必真涨得最多;指数休市显示0.00%,用户以为平盘。 怎么修:跨市场排序前,用K线按同一个窗口(比如“北京时间今天0点至今”)把所有品种重算一遍再排;休市的品种标“休市”,不和交易中的品种混排。 先问供应商:涨跌幅的基准时刻是几点、哪个时区?休市时显示什么? 场景② 价格提醒:同一个阈值,一个响一个不响 用户看到的:用户设了“黄金跌0.5%提醒我”。同一时刻,A平台推送了提醒,B平台没有。 错在哪:按“24小时前”算是−0.69%,提醒响;按“北京时间0点”算是+0.24%,提醒不响。两个平台都没算错,只是分母不同。 根子在于黄金没有官方收盘价。伦敦 LBMA 黄金价格每天定两次(伦敦时间10:30、15:00),上海金每天两次(北京时间10:15、14:15),COMEX 期货结算价按收盘前一段时间的成交量加权平均价算。现货平台不受这些约束,各自选时刻切“日”。CME 在2026年9月29日的文章里写,纽约时间17:00之后的一小时,是全球外汇日的“行政分界”——按这个时刻切日很常见,但不是唯一的选择。 切日时刻还会切出意外。按UTC 0点切日K线的数据源,周日晚上开盘那几个小时会单独成一根“日K”:我实测黄金10月11日(周日)这根K线成交量只有8,813,前后几个交易日都在15万以上。我实测的接口给出的“前收”4,190.27,正好就是这根周日K线的收盘,算出来是−0.36%,既不是纽约17:00的价格,也不是周一的收盘。 代价:误触发,用户可能据此卖出或加仓;漏触发,该提醒的没提醒。客服还解释不清“为什么别家提醒了你们没提醒”。 怎么修:提醒规则里写明基准,比如“较纽约17:00跌0.5%”,用户设置时就能看到;周日开盘那几个小时单独处理,不当成一个交易日。 两个边界:用小时K线取的“纽约17:00价格”,和别家的纽约收盘可能差零点几美元;“24小时前”只能取到最近的整点,是近似值。 先问供应商:黄金、外汇按几点切日?周日开盘那几个小时怎么算? 场景③ 持仓和资产页:除权那天“一夜亏三成” 用户看到的:持有寒武纪的用户,5月8日早上打开App,持仓市值少了三成;跌幅榜第一名是寒武纪,−36.70%。 错在哪:这天是寒武纪的除权除息日。2025年度分配方案是每股派现1.50元、每股转增0.49股,股权登记日5月7日。交易所规定,除权除息日的涨跌幅不跟昨天收盘比,而是跟除权(息)参考价比: 参考价 =(前收盘价 − 现金红利)÷(1 + 流通股份变动比例)=(1,868.00 − 1.50)÷ 1.49 = 1,252.68元 5月8日实际开盘1,217.03元、收盘1,182.53元: 按昨收1,868.00算:低开34.85%,收跌36.70% 按参考价1,252.68算:低开2.85%,收跌5.60% 我实测的复权因子也对得上:这次除权的前复权因子是0.6706,1,868.00 × 0.6706 = 1,252.68。 还有一个反证。寒武纪是科创板股票,涨跌幅限制20%。按参考价算,当天涨跌停区间是1,002.14–1,503.22元;如果错按昨收算,跌停价应是1,494.40元,而寒武纪全天都在1,158.01–1,220.00元之间成交——那就等于全天都在“跌停价以下”成交,这不可能。交易所自己用的分母,就是参考价。 代价:从持仓看,转增后股数变成1.49倍,每股还拿了1.50元现金,市值并没有少三成,但用户看到的是“亏了三成”,第一反应是截图投诉。跌幅榜挂错,运营要出面解释。做量化的拿不复权日K回测,除权日是一根假的大阴线,止损会在这天被误触发。 这不是一年碰上一次的事。10月正赶上中期分红集中除权,我实测的分红日历里,10月12日、13日两天的A股除权除息记录就超过20条。 怎么修:快照的前收和昨日收盘差得多,先标“除权除息”,涨跌按参考价算,持仓按新股数显示;回测用复权数据。 先问供应商:除权除息日的前收,是不是参考价? 场景④ 首页和详情页:同一只苹果,两个涨幅 用户看到的:首页上苹果+1.29%,点进详情页+0.47%。用户的第一反应:数据坏了。 错在哪:10月13日北京时间10:56,美股正在夜盘时段。我实测同一时刻的苹果有4个涨跌: 主快照340.97美元(周一常规盘收盘),较上周五收盘336.64,+1.29% 盘后341.36,较周一收盘,+0.11% 夜盘342.57,较周一收盘,+0.47% 夜盘较上周五收盘,+1.76%(自己算) 规则是:常规盘的涨跌,跟上一个常规交易日的收盘比;盘后、夜盘的涨跌,跟当天常规盘的收盘比。数据里写得很清楚:盘后、夜盘的前收是340.97(周一收盘),主快照的前收是336.64(上周五收盘)。四个数都对,只是分母不同。 代价:用户真正想知道的,往往是“从上周五到现在涨了多少”,答案是+1.76%,首页和详情页给他的哪个都不是。两个数并排、又不写分母,用户只会得出一个结论:这个App的数据不靠谱。到了财报季,盘后动辄跳空几个百分点,首页和详情页的差距会更大(本周五的文章专门讲)。 怎么修:同一屏上的每个涨跌幅,旁边写上时段和基准,比如“夜盘 较周一收盘 +0.47%”。 先问供应商:盘前、盘后、夜盘的涨跌,按哪个收盘算? 4个场景收在一张表里: 场景 用户看到的 错在哪 代价 怎么修 涨幅榜 苹果第一、比特币最后 5个涨跌幅量的是5段时间 名次失真,用户追错 按同一窗口重算再排 价格提醒 一家响、一家不响 黄金切日时刻不同 误触发、漏触发 规则里写明基准 持仓页 一夜“亏三成” 除权日没用参考价 恐慌、投诉、回测失真 识别除权日,按参考价算 首页/详情页 +1.29%和+0.47% 常规盘和夜盘分母不同 用户不再信任数据 每个涨跌幅标时段和基准 这4件事看起来是技术细节,其实是产品问题。卡尼曼和特沃斯基1979年提出的前景理论有一个结论:人判断得失,看的是相对某个参照点的变化,而不是绝对水平。行情App上的涨跌幅,就是替用户选好的参照点。同样4,175.15美元的金价,参照点选在24小时前,用户觉得亏了;选在北京时间0点,用户觉得赚了。谁定分母,谁就定了用户今天的情绪,所以分母应该写在界面上。 三、怎么修:跨市场统一分母,分3步 先给每个涨跌幅贴上分母标签,再按同一个窗口重算,最后单独处理除权。 1. 一张跨市场分母清单 市场 建议的分母 界面上要写的字 A股 上一交易日收盘;除权除息日用参考价 “较前收(除权调整)” 港股 上一交易日收市价 “较前收” 美股常规盘 上一常规交易日收盘 “较上一交易日收盘” 美股盘前/盘后/夜盘 当天常规盘收盘 “夜盘 较今日收盘” 黄金、外汇 选定一个切日时刻(如纽约17:00)并写出来 “较纽约17:00” 加密 滚动24小时,或指定时区0点 “24h”或“较UTC 0点” 指数(休市时段) 上一交易日涨跌并标日期,或标“休市” “10/12 收盘” 照着这张表,每个涨跌幅旁边都能写出它在跟谁比。A股参考价按交易所规则执行,其余是建议做法。 2. 三步落地 第一步,贴标签。每个涨跌幅带上基准价和基准时刻。不贴,用户拿两个App一比颜色不一样就来问;解释一次,下一个用户还会问。 第二步,统一窗口。跨市场比较(涨幅榜、资产总览、跨市场提醒)时,不比现成的百分比,用K线按同一个窗口自己重算。不重算,名次取决于谁的分母更旧。 第三步,单独处理除权。A股先判断是不是除权除息日:快照的前收和昨日收盘差得多,就按参考价或复权数据处理。 3. 为什么跨市场更难:6类资产,6套规则 只做A股,记住“前收、除权”两件事就够了。做跨市场,要同时管6套规则:A股的除权、港股的收市竞价、美股的四个时段、黄金外汇的切日时刻、加密的滚动窗口、指数的休市显示。 如果每个市场各接一家数据源,同样叫“前收”的字段,名字、时间戳格式、切日时刻都可能不一样。统一分母之前,得先写一层“翻译”;市场越多,翻译层越厚。规则还在变:美国夏令时11月1日结束,纽约17:00对应的北京时间要从早上5点变成6点,每一家数据源的处理都得重新核对一遍。 所以做跨市场行情应用,省事的做法是:一套接口拿到所有市场的快照、K线和复权数据,分母标签层只写一次。 4. 我用 TickDB 把6类资产跑了一遍 TickDB 为开发者和 AI 应用提供统一的全球行情数据接口,让团队通过一套接入获取多市场实时与历史数据,更快构建行情、分析和监控产品。 本文寒武纪、苹果、黄金、比特币、标普500的数字,都是我用同一套接口取的: 能做到 要你自己处理 6类资产(A股、港股、美股、外汇贵金属、指数、加密)的快照,用同一组字段返回现价、前收和时间戳 接口给的涨跌幅是一个现成的数,不带“分母说明”,标签要自己加 同一套K线接口覆盖各市场,可以按任意基准时刻(纽约17:00、北京0点、UTC 0点)自己重算 黄金、外汇这类没有官方收盘的品种,建议按自己选定、并写在界面上的基准重算 美股快照同时带盘后、夜盘各自的价格和前收;复权因子能还原寒武纪的除权参考价 复权数据会随新的公司行为更新,回测要记下查询时间和复权方式 左边是一套接口能直接支撑的,右边是任何数据源都替代不了的产品判断。(作者实测,2026年10月12–13日。) 5. 给技术同事:一段代码 不写代码的读者可以跳过这一节。下面这段代码做两件事:用小时K线按4种基准时刻重算黄金涨跌;自动识别A股除权除息日。 # 测试环境:Python 3.11 # 接口端点与字段名已于 2026-10-13 通过实际调用核对 import os import sys from datetime import datetime, timedelta, timezone from decimal import Decimal from zoneinfo import ZoneInfo import requests API_KEY = os.getenv("TICKDB_API_KEY") # 从环境变量读取,不要写进前端 BASE_URL = "https://api.tickdb.ai/v1/market" UTC, BJ, NY = timezone.utc, ZoneInfo("Asia/Shanghai"), ZoneInfo("America/New_York") HOUR_MS = 3_600_000 def get(path, **params): """调用接口,同时检查 HTTP 状态和业务返回码。""" try: resp = requests.get(f"{BASE_URL}/{path}", params=params, headers={"X-API-Key": API_KEY}, timeout=10) body = resp.json() except (requests.RequestException, ValueError) as e: raise RuntimeError(f"{path} 请求失败: {e}") from e if resp.status_code != 200 or body.get("code") != 0: raise RuntimeError(f"{path}: HTTP {resp.status_code}, code={body.get('code')}, {body.get('message')}") return body["data"] def pct(last, base): """涨跌幅(%)=(现价 − 基准价)÷ 基准价 × 100。""" last, base = Decimal(str(last)), Decimal(str(base)) return (last - base) / base * 100 def price_at(hourly, moment): """取某一时刻的价格:用“结束于该时刻”的那根小时K线的收盘价(K线时间戳为该小时的开始)。""" target = int(moment.timestamp() * 1000) - HOUR_MS for bar in hourly: if bar["time"] == target: return bar["close"] return None def last_moment(now, tz, hour): """now 之前最近一次 tz 时区的 hour 点(自动处理夏令时)。""" local = now.astimezone(tz) m = local.replace(hour=hour, minute=0, second=0, microsecond=0) if m > local: m -= timedelta(days=1) return m def gold_changes(symbol="XAUUSD"): """同一个现价,按4种自选基准价分别算涨跌。""" q = get("ticker", symbols=symbol, type="forex")[0] hourly = get("kline", symbol=symbol, interval="1h", type="forex", limit=48)["klines"] now = datetime.fromtimestamp(q["timestamp"] / 1000, UTC) day_ago = (now - timedelta(hours=24) + timedelta(minutes=30)).replace(minute=0, second=0, microsecond=0) # 24小时前,取最近的整点 bases = { "24小时前(近似)": price_at(hourly, day_ago), "纽约17:00收盘": price_at(hourly, last_moment(now, NY, 17)), "UTC 0点": price_at(hourly, last_moment(now, UTC, 0)), "北京时间0点": price_at(hourly, last_moment(now, BJ, 0)), } print(f"{symbol} 现价 {q['last_price']}({now.astimezone(BJ):%m-%d %H:%M} 北京时间)") for name, base in bases.items(): print(f" 较{name:<10} 基准 {base} 涨跌 {pct(q['last_price'], base):+.2f}%" if base else f" 较{name}:缺数据") def is_ex_rights_day(prev_close, last_daily_close, tol=Decimal("0.005")): """快照的前收和上一根日K收盘相差超过0.5%,大概率是除权除息日,要用参考价/复权数据核对。""" p, c = Decimal(str(prev_close)), Decimal(str(last_daily_close)) return abs(p / c - 1) > tol def check_ex_rights(symbol="688256.SH"): q = get("ticker", symbols=symbol, type="stock")[0] daily = get("kline", symbol=symbol, interval="1d", type="stock", limit=2)["klines"] yesterday_close = daily[-2]["close"] # 最后一根是今天(可能未结束),取倒数第二根 flag = is_ex_rights_day(q["prev_close"], yesterday_close) print(f"{symbol} 快照前收 {q['prev_close']} / 昨日K线收盘 {yesterday_close} → {'疑似除权除息日' if flag else '正常'}") if __name__ == "__main__": if not API_KEY: sys.exit("请先设置环境变量 TICKDB_API_KEY") gold_changes() check_ex_rights() # 历史核对:寒武纪 2026-05-08 除权除息日,参考价 1252.68,前一日收盘 1868.00 print("2026-05-08 寒武纪:", "疑似除权除息日" if is_ex_rights_day("1252.68", "1868.00") else "正常") 用10月13日10:56的实测数据跑出来的结果: XAUUSD 现价 4175.15(10-13 10:56 北京时间) 较24小时前(近似) 基准 4204.35 涨跌 -0.69% 较纽约17:00收盘 基准 4171.38 涨跌 +0.09% 较UTC 0点 基准 4170.54 涨跌 +0.11% 较北京时间0点 基准 4164.95 涨跌 +0.24% 688256.SH 快照前收 971.88 / 昨日K线收盘 971.88 → 正常 2026-05-08 寒武纪: 疑似除权除息日 三点说明: 基准价都取自小时K线。K线时间戳是该小时的开始,所以代码取的是“结束于某时刻”的那根K线的收盘价。 纽约17:00用时区库换算,夏令时自动处理,11月1日之后不用改代码。 0.5%的阈值是经验值,只负责标记;标记出来以后,要再用参考价或复权因子核对。 6. 上线前问供应商的5个问题 涨跌幅的基准价是哪个价?昨收、某个时刻的价格,还是除权后的参考价。 基准时刻是几点、哪个时区?周日开盘那几个小时怎么算?决定黄金、外汇、加密的涨跌能不能和股票放在一起。 除权除息日用不用参考价?不用,持仓页就会出现“一夜亏三成”。 盘前、盘后、夜盘的涨跌按哪个收盘算?不说清,首页和详情页就会对不上。 休市时显示上一交易日涨跌,还是0?显示0,用户会以为平盘。 常见问题 行情App的涨跌幅,为什么和别家不一样? 因为分母不同。涨跌幅=(现价−基准价)÷基准价,现价各家一样,基准价各家可以不同:A股除权日用参考价还是昨收,黄金按纽约17:00还是UTC 0点切日,加密用滚动24小时还是0点,美股夜盘跟周一收盘比还是跟上周五比。两个App的涨跌幅不一样,多半不是谁算错,而是分母不同。 跨市场涨幅榜怎么排才可比? 不要直接拿各市场现成的涨跌幅排序。先选定一个统一窗口,比如“北京时间今天0点至今”或“过去24小时”,用K线把每个品种按这个窗口重算一遍再排;休市的品种单独标出,不和交易中的品种混排。 黄金的收盘价是几点的价格? 黄金现货没有交易所规定的官方收盘价。伦敦 LBMA 黄金价格每天定两次,伦敦时间10:30和15:00;上海金每天两次,北京时间10:15和14:15;COMEX 黄金期货结算价按收盘前一段时间的成交量加权平均价确定。现货平台各自选时刻切“日”,常见的有纽约17:00、UTC 0点、北京时间0点。 为什么除权那天股价“暴跌”,涨跌幅却不大? 除权除息日的涨跌幅,基准不是昨天的收盘价,而是除权(息)参考价。寒武纪2026年5月8日前收1,868.00元,每股派现1.50元、转增0.49股,参考价1,252.68元;收盘1,182.53元,看着跌了36.7%,按参考价只跌5.6%。价格降下去的部分,换成了多出来的股份和到账的现金。 美股盘后、夜盘的涨跌是跟谁比? 跟当天常规盘的收盘比;常规盘的涨跌,跟上一个常规交易日的收盘比。2026年10月13日北京时间10:56,苹果主快照较上周五收盘涨1.29%,夜盘较周一收盘涨0.47%。首页显示主快照、详情页显示夜盘,就会出现两个不同的涨幅。 最后一个问题 你们App上的涨跌幅,分母写在哪? 今天就能做的一件事:打开自己App的涨幅榜,逐行写出每个涨跌幅跟谁比、从几点算起。写不出来的那一行,就是下一个客诉工单。 如果你只是用行情App的投资者,也可以试一次:同一时刻打开三个App,记下同一个品种的涨跌幅。不一样,多半不是谁错了,只是三个参照点。 看涨跌,先问“跟谁比”。 参考资料 LBMA,LBMA Gold Price CME Group,When FX Futures Pause: Understanding spread risk around the daily close,2026-09-29 上海证券交易所,收盘集合竞价相关说明,2018-08-06 Nasdaq,Opening and Closing Cross FAQ 香港交易所,Trading Mechanism of CAS in the Securities Market 上海黄金交易所,Shanghai Gold Benchmark Price Launching Ceremony,2016-04 CME Group,Gold 结算方法说明 寒武纪,2025年年度权益分派实施公告(公告编号2026-011) 上海证券交易所,《上海证券交易所科创板股票交易特别规定》 Spot API 文档:24hr Ticker Price Change Statistics Gate 帮助中心,如何切换涨跌幅起止时间 Kahneman, D. & Tversky, A. (1979). Prospect Theory: An Analysis of Decision under Risk. Econometrica, 47(2), 263–291 很多做短线量化的人卡在集合竞价阶段。 普通行情接口只能拿到开盘价,看不到竞价阶段真实撮合变化。 依靠滞后数据写出来的竞价策略,回测好看,实盘持续翻车。 集合竞价核心原理 A 股集合竞价分为两个阶段:9:15-9:20 可撤单,9:20-9:25 不可撤单。 9:25 一次性产生开盘成交价。 竞价阶段的虚假挂单,大多集中在 9:20 前。 集合竞价接口的字段怎么用 接口地址:http://api.xtick.top/doc/bid/time?type=1&code=all&token=你的token 返回的核心字段包括: 字段 含义 策略价值 price 当前匹配价格 观察竞价过程中价格是否被逐步推高 jjzf 竞价涨幅 相对昨收的偏离度 jjl 竞价量 当前累计撮合量 jje 竞价金额 量×价,反映资金参与深度 nol 未匹配量 买卖失衡的绝对值 noe 未匹配金额 未匹配量的金额口径 trend 未匹配方向 1偏向买方,-1偏向卖方 最关键的组合是jjzf + noe + trend。 竞价涨幅适中、未匹配金额大、且方向偏买方——这三个条件同时成立时,说明有资金在9:20后持续用真实挂单推价,撤单概率极低。 三个可直接落地的竞价筛选条件 条件一:竞价涨幅的“黄金窗口” 涨幅区间 含义 处理方式 < 2% 无主力介入 跳过 2%-4% 温和抢筹 重点观察 4%-6% 强高开,需放量验证 配合量能判断 > 6% 高开过多,追高风险大 除非有明确逻辑,否则放弃 竞价涨幅不是越高越好。2%到4%的温和高开,抛压消化充分,后续回踩不破均价线的概率最大。 条件二:未匹配金额的“方向确认” noe(未匹配金额)配合trend(方向)使用。 当noe > 500万且trend = 1时,说明买方挂单量显著大于卖方,且差额集中在买一侧。这种状态下,9:25撮合出来的开盘价会被“买方力量”顶在高位。 反过来,noe很大但trend = -1,说明卖方压力更大,高开可能是诱多。 条件三:竞价金额与流通市值的比值 竞价金额jje除以流通市值,得到一个“竞价参与度”指标。 竞价参与度 信号 < 0.05% 冷门,无资金关注 0.05%-0.15% 正常水平 0.15%-0.3% 活跃,值得跟踪 > 0.3% 极活跃,需警惕对倒 参与度超过0.3%时,必须结合trend判断方向。 如果是买方方向且价格稳步上推,是真实抢筹;如果价格在高位横盘但参与度极高,要防范对倒出货。 竞价信号到交易决策 集合竞价不是寻找“必涨信号”,而是把有限的盘前信息变成可检验的候选条件,再用开盘成交验证,并用纪律管理失败。**数据能提高观察质量,不能消除市场风险。 编辑 为什么90%的人会在竞价阶段亏钱? 因为他们在用眼睛交易,而不是用数据交易。 我统计了近三年的竞价数据,发现三个致命误区: 误区 具体表现 真实情况 看挂单量做决策 买一量巨大=强势 9:20前可撤单,大单随时消失 追涨停竞价 涨停价挂单=主力看好 可能是诱多,9:20后撤单跑路 忽视量比 只看价格不看成交量 无量高开=假突破,大概率回落 记住一句话:没有成交量支撑的竞价走势,都是耍流氓。 很多竞价策略回测时直接用9:25的开盘价数据,这忽略了一个事实:9:25之前你无法知道最终撮合结果。 如果用9:25数据做信号、9:25价格成交,等于用了未来数据。正确的回测方式是用9:23或9:24的快照生成信号,以9:25开盘价成交——这中间存在一个“信号到执行”的时间差,滑点必须计入。 参考Github开源项目:https://github.com/xticktop/skills 摆脱低效提问,解锁AI选股的正确姿势 在AI赋能金融投资的今天,许多投资者在尝试使用AI辅助选股时,往往第一句话就问:“今天推荐买哪只股票?”这种模糊且缺乏量化约束的提问,不仅容易引发AI的模型幻觉,更无法给出具备实操价值的研报级结果。 “用豆包选股90%的人第一句话就问错了,真正有用的是这五条指令……” 要想让豆包AI真正成为高效、可靠的A股智能筛选引擎,关键在于将复杂的选股逻辑拆解为结构化、多维度的提示词(Prompt)链条。通过分步递进与风控前置,把AI从“随机猜股票的黑盒”转化为“严格执行策略的量化助手”。 核心拆解:高效AI选股指令全景指南 专家提示(Expert Tip): 豆包AI依靠实时联网插件获取市场行情。在执行以下指令时,建议明确要求AI“检索最新的实时行情与财报数据”,以确保财务数据与资金流向的时效性。 指令一:基础指标初筛(成交量、市盈率与风险过滤) 选股的第一步在于建立兼具流动性与安全边际的初始股票池。通过量化门槛,快速剔除交投清淡或估值偏离度过高的标的。 【AI指令示范】 “请检索最新实时行情,帮我筛选近30天成交量温和放大、市盈率低于行业平均、且无退市风险的A股标的。” 该指令涵盖了三项核心初筛指标: **●**成交量: 要求“近30天成交量温和放大”。从金融技术面来看,相比爆发式的“放量巨阳”(往往伴随机构出货或追高陷阱),“温和放大”代表资金在底部吸筹或稳步建仓,能有效筛选出具备真实交易活跃度与流动性的标的。 **●**市盈率: 设定为“低于行业平均”,从估值安全垫出发,避免买入高估值泡沫标的,兼顾安全性与性价比。 **●**退市风险: 明确要求“无退市风险”,直接过滤ST、*ST以及存在被实施退市风险警示的股票,防范源头风险。 指令二:排雷深度核查(近三年净利润与业绩防雷) 在初步建立股票池后,第二步必须对企业基本面进行深度“防雷”核查。保障投资本金安全的前提,就是坚决剔除业绩下滑与存在财务隐患的公司。 【AI指令示范】 “针对上述初步筛选出的股票,请进一步核查其近三年净利润数据,坚决排除业绩下滑、存在商誉大幅减值风险或财报异常‘有雷’的公司。” 在实际操作中,近三年净利润是衡量企业核心造血能力的关键指标。通过该指令让AI深入审查财务报表,能够有效排除业绩下滑、非经常性损益虚增利润或审计意见异常等潜伏雷区,确保标的具备扎实的基本面支撑。 指令三:资金动向追踪(主力与北向资金持续加仓) 资金的真实流向是锁定市场合力、确认价格上涨动能的关键信号。第三步需要紧密追踪市场上两股最具风向标意义的资金力量。 【AI指令示范】 “请分析上述标的近期的资金流向,重点查看主力资金与北向资金的动态,仅保留主力与北向资金持续加仓、形成买入共振的标的。” 主力与北向资金联合筛选标准: ●**资金追踪维度: 联合监测本土公募/私募等主力资金与被称为“聪明钱(Smart Money)”的北向资金**(外资)。 **●**判定与保留标准: 设定“持续加仓”门槛,拒绝单日偶发性净流入,只保留资金持续加仓的标的。当内外资机构形成共振加仓时,往往预示着中长期趋势的确立。 指令四:赛道与风控综合评估(行业景气度、政策利好与估值回撤) 第四步需要自上而下结合行业宏观大环境与自下而上的个股回撤风险进行综合评估。既要顺应景气度挑选“成长赛道”,又要严控“估值与回撤风险”。 【AI指令示范】 “请分析上述标的所在行业的景气度和近期政策利好,优先挑选高成长赛道;同时评估标的的估值风险与历史最大回撤风险,最终给出安全可操作的个股清单。” **●筛选维度(行业/政策/风险):**筛选目标(成长赛道/安全可操作清单) ●行业景气度 & 政策利好:匹配产业政策倾斜与行业复合增长率,优先挑选具备高成长潜力的成长赛道 ●估值风险 & 回撤风险:测算分位数估值偏离度与阶段性最大回撤,全面评估风险并输出安全可操作的个股清单 指令五:全维度终极合成指令(一键复核与组合输出) 为了满足需要一次性高效输出的实战场景,我们可以将前四步的单项逻辑融合成一条“一键复核”的Master Prompt(母指令),实现全流程自动化复核。 【AI指令示范】 “请将上述选股逻辑合并执行:基于近30天成交量温和放大、市盈率低于行业均值且无退市风险(初筛),查验并剔除近三年净利润下滑及存在财务雷区标的(防雷),锁定主力与北向资金持续加仓标的(资金),结合行业景气度与政策利好评估回撤风险,最终输出一份包含核心逻辑与风险提示的A股安全可操作清单。” 通过终极合成指令,豆包AI能够在一个会话中完成“量价初筛 \rightarrow 业绩防雷 \rightarrow 资金验真 \rightarrow 赛道与风控复核”的全闭环拆解,显著提升选股效率与准确度。 让AI成为理性的投资助手 通过这套结构化的5条核心指令组合,投资者能够将模糊、无序的提问转化为严格的量化风控筛选流程,让AI真正成为专业、理性的投资决策辅助引擎。 在AI工具日益普及的今天,你准备好用精准指令升级你的投资策略了吗? 面对复杂市场的破局之道 进入下半年,全球宏观经济运行的脉络愈发交错复杂的信号。美联储利率路径的再修正、全球通胀拐点的隐现、美元指数的震荡以及地缘局势的剧烈扰动,共同交织成一个高波动、快轮动的市场环境。面对频繁切换的资产主线与纷繁复杂的盘面信息,许多投资者难免陷入交易节奏脱节的焦虑与迷茫:如何在纷繁嘈杂的宏观噪音中准确辨识资产定价的核心脉络?又该如何构建具备抗冲击能力与超额收益空间的资产组合? 事实上,资本市场的短期价格波动看似无序,其底层逻辑始终由资金流动、利率贴现与风险溢价等宏观因子深度驱动。理清这些底层传导机制,是投资者在下半年迷局中保持战略定力、实现穿透式建仓的破局之道。本文深入拆解下半年必须看懂的八大市场运行逻辑,帮助大家穿透盘面迷雾,梳理资产配置与交易的硬核规律。 核心拆解:下半年八大市场运行逻辑 逻辑一:利率政策与股市总基调(加息 vs 降息) 中央银行的货币政策周期是决定权益市场整体资金水位与风险偏好的“总开关”。在加息周期中,基准利率抬升直接导致实体经济与金融体系的借贷成本增加,全球金融条件(Financial Conditions)同步紧缩,流动性溢价受压制,导致股市整体估值承压;而在降息周期开启后,无风险利率下行与借贷成本下降不仅能够改善企业财务费用,更能边际释放充沛的市场流动性,进而提升风险偏好,为权益市场提供强劲的估值扩张支撑。 美加息股市弱,美降息股市强 【分析师点评】:利率政策是宏观资产定价的“第一性原理”。在构建股票多头仓位时,务必将央行货币政策的边际拐点作为判断大盘趋势与确定仓位上限的首要基准。 逻辑二:货币强弱与避险资产(美元 vs 黄金) 美元作为全球金融体系的核心结算与计价货币,与兼具黄金属性、货币属性及零息债券属性的金价之间存在显著的负相关关系。当美元指数走强时,以美元计价的黄金对非美货币持有者而言购入成本增加;同时,高企的美元利率大幅抬升了持有无息黄金的机会成本,对金价形成双重挤压。反之,美元走弱往往伴随着美债真实收益率(Real Yields)的回落,黄金的抗通胀与避险价值便会迎来重新定价的窗口期。 美元强黄金弱 【分析师点评】:黄金与美元是跨资产对冲交易中的经典负相关标的。密切跟踪美元指数及美债真实收益率的变化,是精准把握黄金长波段建仓时机的关键所在。 逻辑三:地缘政治与大宗商品(局势 vs 资源) 当关键地缘政治区域陷入紧张或冲突状态时,全球供应链的稳定性与大宗商品的供给弹性会受到严重冲击。无论是原油、天然气等能源品,还是铜、铝以及农业资源,市场对供给端中断的隐忧均会在短期内迅速转化为“地缘风险溢价”(Geopolitical Risk Premium)。资金倾向于迅速流入具备天然稀缺性的大宗商品,驱动资源类资产走出一轮独立行情。 地缘乱资源涨 【分析师点评】:地缘政治事件是典型的非对称供给侧冲击。在宏观黑天鹅频发的阶段,适度配置具备抗通胀与防冲击属性的资源品,是提高资产组合下行防御力的重要手段。 逻辑四:通胀放缓与成长板块(通胀回落 vs 科技) 通胀压力的缓解是决定成长股估值重塑的核心催化剂。当CPI或PCE等通胀指标持续回落时,市场对终端利率上限的预期开始松动,带动无风险利率与名义债券收益率下滑。从DCF(现金流折现)模型来看,科技股等成长性资产的现金流往往集中于远期,贴现率(Discount Rate)的分母端下降会产生巨大的估值弹升效应,进而拉动以科技为代表的高久期资产领涨市场。 通胀降科技涨 【分析师点评】:本逻辑侧重于内生无风险利率下降对科技股“DCF分母端”的估值修复。通胀回落直接解封了成长资产的定价天花板,是科技板块开启估值重估的关键信号。 逻辑五:通胀上升与价值板块(通胀升温 vs 银行) 相反,当通胀水平阶段性重新抬头或超预期升温时,市场对央行维持高利率(Higher-for-Longer)甚至加息的预期将迅速强化。在这种宏观背景下,以银行为代表的高股息、低估值金融板块往往展现出极强防御与相对收益属性。基准利率的高企以及收益率曲线的陡峭化预示着银行净息差(NIM)的扩大与盈利能力的改善,吸引避险资金向价值板块集中。 通胀升银行涨 【分析师点评】:通胀指标的变化直接决定了成长与价值风格的轮动方向。在通胀上升或维持高位的阶段,银行等具备净息差扩张红利与高股息安全边际的板块是资金的避风港。 逻辑六:汇率贬值对科技资产的驱动(美元走弱 vs 科技) 当美元汇率趋势性走弱(美元贬值)时,全球金融条件(FCI)呈现显著宽松态势,资金开始从单一美元存款或无风险资产中溢出,在全球范围内寻找高Beta、高资本回报率的风险资产。科技巨头通常具备极高的盈利质量、强劲的自由现金流与全球化的业务布局,在美元走弱带来的全球宏观流动性溢出效应(Overflow Effect)推动下,能够吸引大量跨国资本配置,展现出强劲的超越大盘表现。 美元贬科技强 【分析师点评】:不同于逻辑四的“贴现率逻辑”,逻辑六强调的是“外生跨国流动性溢出效应”。美元弱势松绑了全球金融条件,为跨国资本配置全球科技龙头创造了极为充沛的流动性土壤。 逻辑七:和平预期与能源价格波动(局势缓和 vs 能源) 地缘冲突的爆发固然会导致能源资产飙升,但随着停火协议、政治谈判的推进或战事趋于平息,此前盘踞在原油与天然气价格中的“地缘风险溢价”将被快速挤出。当供给端中断的恐慌情绪消退,资产定价逻辑将迅速重新锚定至实体经济的真实供需基本面。在缺乏额外需求拉动的情况下,溢价挤出效应通常会导致原油等能源资产价格出现均值回归式的回落。 战事停能源落 【分析师点评】:地缘风险溢价具有“风险事件演变快、溢价挤出速度更快”的特征。战事平息意味着短期风险溢价的出清,投资者需警惕情绪退潮后能源资产的回归挤压风险。 逻辑八:宏观主线下的综合资产轮动 上述七大逻辑并非彼此孤立的单向链条,而是交织构成下半年整体宏观图景的因子矩阵。在实际市场演变中,我们极少看到单一因子独立起作用,更多是多个因子共振带来的跨资产轮动场景。 例如: 场景一(金发女孩情景扩张):当“通胀回落 + 美联储降息 + 美元走弱”三者共振叠加时,市场将触发极其强烈的“科技(贴现率下降+流动性溢出)+ 黄金(真实利率下行)”双轮驱动主线。 场景二(滞胀或地缘冲击再现):当“地缘局势紧张 + 通胀升温 + 美联储鹰派”组合出现时,市场主线则会迅速切换至“资源(供给侧溢价)+ 银行(净息差防御)”的防御性配置。 宏观交织,因时而变 【分析师点评】:单因子口诀是基础,多因子共振才是策略全貌。掌握下半年资产配置的精髓,在于根据“通胀-利率-汇率-地缘”四维矩阵的动态变化,灵活调整组合中“攻击性前锋”(科技/黄金)与“防御性后卫”(银行/资源)的配比。3. 总结与展望:从逻辑到行动 宏观交易的迷人之处在于盘面瞬息万变,但驱动资产价格演变的核心定价逻辑始终有迹可循。从利率与通胀对权益估值的锚定,到汇率与地缘对大宗商品与避险资产的传导,这八大逻辑共同构成了下半年应对市场波动的坐标系。 站在当前的时间节点,对于投资者而言,“背诵口诀”仅是第一步,更重要的在于将这些逻辑转化为机构级的交易纪律——“顺应逻辑与趋势”,远比“盲目预测市场点位”更具胜率。唯有深刻理解宏观因子与各资产板块之间的传导机制,并在不同象限演变中建立相适应的建仓与风控机制,才能在下半年的市场大浪中保持定力,实现资产的稳健增值。 面对下半年的宏观演变,你的资产组合是否已经为这些关键逻辑做好了准备? 亲测最好用的AI编写量化策略工具,可以让 AI 直接生成同花顺Supermind上可运行的策略代码,代码质量远高于直接使用 DeepSeek、GPT等平台。 😃Supermind AI工具入口:https://easyquant.ai/ 大家可以直接向AI描述策略,然后一键生成可运行的完整策略代码,也可以把它当做一个API 查询工具。 同一张行情表,寒武纪的成交额自己算是5,414万元,接口给的是54.20亿元,差了100倍,原因只是一个单位。行情看板三天就能接通,上线后的返工,几乎都来自界面上说不清“自己是什么”的数字。 本文依据上交所、港交所的一手文件,加上10月12日盘中对7类资产的实测,给你四样东西: 一张“价格身份证”:每个数字上线前要答的5个问题 7个返工点逐条拆:钱在哪里算错、为什么会错 一份可以直接发给数据供应商的7问清单 2段可运行的 Python 代码 做行情看板,最便宜的一步恰恰是接接口。 10月12日周一上午,我把寒武纪和腾讯放进同一张行情表,拿“成交量×价格”自己算了一遍成交额: 寒武纪:成交量 54,605,最新价 991.44 元。自己算是约 5,414 万元,接口给的成交额是约 54.20 亿元,差了100倍。 腾讯:成交量 6,542,389,最新价 427.20 港元。自己算是约 27.95 亿港元,接口给的是 27.97 亿港元,对得上。 没有哪个数是错的。寒武纪的“成交量”按手计,1手是100股;腾讯的按股计。字段名都叫成交量,单位差了100倍。 (寒武纪快照为北京时间2026年10月12日11:29:56,腾讯为11:07:51。) 单位还只是一处。今年下半年,这类“同一个数、换了规则”的事正在变多:7月6日起,A股每天15:05到15:30多了一段盘后固定价格交易,据证券导报报道,首日约1,900家主板公司参与;11月16日起,港股开始统一每手股数,约650家公司可能要改。 行情接口几行代码就能接通。行情应用能不能上线,取决于界面上的每个数字能不能出示它的“身份证”:品种、时段、算法、时间、状态。答不出来的数字,迟早会以客户投诉、错误决策或返工账单的形式找上门。 下文分三部分:一块面板 → 7个返工点逐个拆 → 自建还是外采怎么算账。不写代码的读者,每节读到“先问供应商”就够了,技术细节可以直接转给技术同事。 第一部分|三天能做出来的面板,每个数字还要多答5个问题 我按一份技术底稿搭了一块跨资产行情面板:React 前端加 Python 后端,API Key 只放在服务端。7类资产各放一个品种:寒武纪(A股)、腾讯(港股)、苹果(美股)、欧元/美元(外汇)、黄金(贵金属)、标普500(指数)、BTC/USDT(加密资产)。 从第一次调用接口到页面上出现数字,比写这段话还快。 (真实数据静态快照,取证时刻见图;面板按底稿自建,不是官方产品界面。) 接通快,不等于做完了。和一个“三天Demo”比,这块面板多的是每个数字旁边那行小字:涨跌按什么窗口算,成交量按手还是按股,这个价是几点的。 这行小字,就是“价格身份证”的5格: 格 它回答什么 面板里的例子 品种 这个数属于谁 000001 是平安银行还是上证指数 时段 这个数产生在哪个交易时段 苹果的报价是周五收盘,盘口是今天的夜盘 算法 这个数按什么规则算、单位是什么 涨跌幅按当日还是滚动24小时;成交量按手还是按股 时间 这个数对应哪一刻 K线时间戳标的是这根的开始还是结束 状态 这个数现在有没有、还会不会变 指数的“买价0”其实是没有;最后一根K线还在变 读法:每一格都是上线前要答的一个问题,答不出来的那格,就是以后某个工单的位置。(例子均来自2026年10月12日实测。) Demo 回答“能不能显示”,产品要回答“显示的是什么”。 第二部分|7个返工点:钱在哪里算错 (以下实测均为北京时间2026年10月12日的单次调用。) ① 品种|同一个代码,可能是两个品种 能报错的接口,比替你猜的接口安全。 场景:用户在自选里输入“000001”,点了添加。他要的是平安银行,还是上证指数? 实测:我不带资产类型去查“000001”,接口直接返回 400 错误 AMBIGUOUS_SYMBOL,并列出两个候选:上证指数、平安银行。带上后缀再查,000001.SZ 是平安银行,11.77元;000001.SH 是上证指数,3,808.54点。 钱怎么算错:如果系统替用户猜成了指数,自选里写着“平安银行”的那一行就显示 3,808 元。1万股持仓,估值从约11.8万元变成约3,808万元。 为什么:同一串数字,在沪深两个交易所之间、股票和指数之间都可能重复。还有一层容易混:请求时用的类型、页面上的分类、数字的单位,是三件事。黄金请求时属于外汇类,页面上应该放在“贵金属”,单位是美元/盎司;指数的单位是“点”,不能加货币符号。 先问供应商:“代码冲突时,你们是报错、默认选一个,还是静默返回其中一个?” 给技术同事:品种目录从产品查询接口分页建立,存好代码、类型、市场、币种;不按代码后缀猜币种;后端只接受目录里有的代码。 ② 算法|“成交量”的单位,换一个市场就变 字段名一样,不等于单位一样。新加一个市场,先核单位。 场景:先做港股看板,上线顺利。老板说“加上A股”,半天接完,成交额、换手率、大单筛选全错了。 实测:开篇那组数,用成交额除以成交量:寒武纪约 99,255 元,是股价的100倍,1个单位是100股;腾讯约 427.45,和股价差不多,1个单位是1股。逐笔成交、盘口数量也一样:寒武纪下午14:00的买一是“976.01元、8手”。(单位由返回结果反推,接入前以文档为准。) 钱怎么算错:成交额差100倍只是第一层。第二层在大单筛选:寒武纪最近成交里有一笔数量“51”,当股算约5.06万元,按手算约505.6万元。阈值设成“单笔≥50万元算大单”,这一笔就漏了。 为什么:A股行情习惯按手报量,港股按股,加密资产按币;外汇不在集中交易所成交,“成交量”又是另一回事。 而且单位表不是写一次就完的。港交所现在有44种每手股数,从10股到10万股;6月30日宣布统一为8种,第二阶段从11月16日开始,约650家公司可能要改。A股这边,科创板200股以上可以按1股递增,“1手=100股”在交易规则里也不总是整齐的。 先问供应商:“每个市场的成交量、盘口数量、逐笔数量,单位分别是什么?写在文档哪里?” 给技术同事:单位按市场配置,不按字段名猜。每天用“成交额÷成交量÷价格”自检一次,比值在1或100附近都正常,突然跳变就报警。代码在第三部分。 ③ 时段|同一屏的两个价,可能来自两个时段 报价区和盘口区各有自己的时段。不标出来,用户只会觉得“你们的价格对不上”。 场景:周一上午,用户打开苹果的详情页。报价区写着 336.64,盘口买一是 337.14。他截图发给客服:“哪个是真的?” 实测:上午11:08,同一分钟里: 报价区的 336.64,是周五常规盘的收盘价,时间停在北京时间10月10日04:00,已经过去约55小时; 同一份快照里还有夜盘价 337.16,时间是11:07; 盘口买一 337.14、卖一 337.17,各只有1档,属于正在进行的夜盘; 最近成交每一笔都标着 overnight(夜盘)。 下午两点再查,报价区还是 336.64,夜盘价已经变成 337.03。美股常规盘开盘之前,这个主快照不会动。 钱怎么算错:按报价算盈亏、按盘口挂单,两个价差0.50美元,1万股就是5,000美元。更常见的代价是客服时间:两个数都对,只是没人告诉用户各自属于哪个时段。 为什么:快照的主价格停在最后一个常规盘,扩展时段放在单独的对象里,各带各的时间;盘口和成交走另外的接口,返回的是此刻正在交易的时段。美股夜盘的细节,上一篇《拆解美股夜盘数据5个口径》已经拆过。 A股也不再是“15:00收盘”那么简单。上交所修订后的《交易规则》7月6日起施行,盘后固定价格交易从科创板扩展到全部A股和ETF:每天15:05到15:30,按当天收盘价成交。据证券导报报道,首日这段时间全市场成交约10.7亿元。可我实测的交易时段接口,A股只返回到14:57,收盘集合竞价和这段盘后交易都不在里面。 时段表要自己核,不能只看接口给的清单。 先问供应商:“快照、盘口、成交分别对应哪个时段?15:05以后的盘后成交,算不算进当天成交量?” 给技术同事:行情状态按“类型+代码+时段”分开存,夜盘数据不覆盖主快照;页面上每块区域显示自己的时段和时间。 ④ 算法|涨跌幅不是一个字段,是三种窗口 窗口不同的涨跌幅放进一个排行榜,排出来的顺序本身就是错的。 场景:产品想在首页做一个“全市场涨幅榜”,股票、外汇、加密资产混在一起排。 实测: 寒武纪 −1.01%:相对昨收 985.99 元。这个昨收从早到晚没变过。 BTC/USDT +1.08%:下午两点查,它的“前收”是 83,074.01;上午11点查,同一个字段是 83,049.15。同一天,“前收”自己变了。 标普500 0.00%:前收 7,811.54,和最新价一模一样。美股还没开盘,这个0.00不代表“今天平盘”。 钱怎么算错:比特币的24小时涨幅和A股的当日涨幅比大小,没有意义;按涨跌幅触发的提醒,要么误报,要么该报的时候不报。 为什么:加密资产全天交易,没有“收盘”,涨跌按滚动24小时算,窗口起点每分钟都在往后挪。币安的官方接口文档写得很直白:24小时行情就是“24小时滚动窗口”的统计。股票按交易日算;指数在休市时前收怎么滚,各家做法不一样。 先问供应商:“每类资产的涨跌幅,基准价是什么、窗口多长?休市时前收怎么变?” 给技术同事:每条涨跌幅带上窗口标签,不做跨资产混排;真要统一,就用K线按同一个窗口自己重算。这个字段下一篇专门讲。 ⑤ 状态|“0”和“没有”,不是同一个数 不适用的字段显示“—”,不显示“0”。 场景:面板上,标普500那一行写着“买价0.00、卖价0.00、成交量0”。用户问:“标普今天没人交易?” 实测:我实测的接口,对标普500返回的买价、卖价都是 0.00000,成交量 0.00,上午、下午两次一样。指数本来就没有买卖盘和成交量,这里的0意思是“没有”。 外汇和黄金又是另一种情况:它们有买卖价,也返回了一个“成交量”(欧元/美元 38,426.00,黄金 45,598.00)。外汇不在集中交易所成交,这个数代表什么,文档没写,我的面板干脆不显示。 钱怎么算错:中间价按 (0+0)÷2 算出来是0,指数估值直接归零;用买卖价差做流动性风控,价差变成0,要么天天误报,要么永远不报。这两种错在测试环境里都看不出来。 为什么:指数是算出来的数,不能交易,没有买卖盘。可在接口里,“没有”和“0”长得一模一样,前端只看“有没有值”,就会把“没有”当成0画出来。 先问供应商:“不适用的字段,你们是返回空、不返回,还是返回0?” 给技术同事:按资产类型维护字段白名单,指数不读买卖价和成交量;格式化函数分清“不存在、为空、为零”三种情况,写成公共函数,别每个页面各写一遍。 ⑥ 时间|K线时间戳:有的标开始,有的标结束 时间戳不说是开始还是结束,就等于没说是哪一刻。 场景:你要做一张A股和港股的叠加对比图,或者一个跨市场的分钟级回测。 实测: 下午两点,同一次调用取“最新一根”5分钟K线:寒武纪标 14:05,腾讯标 14:00,说的是同一段5分钟。1分钟K线也一样:寒武纪标 14:01,腾讯标 14:00。 再看全天的5分钟K线:寒武纪第一根标 09:35,上午最后一根标 11:30,下午第一根标 13:05;腾讯第一根标 09:30,上周五还有一根标 16:00,那是港股16:00到16:10的收市竞价。 从这些时间看,A股用每根的结束时刻标注,港股用开始时刻。(这是推断,接入前以文档为准。) 最后一根还在变:寒武纪标14:05的那根,20秒内我查了3次,收盘价是 976.62、976.01、976.02,成交量从155涨到289。 钱怎么算错:叠加图上,两只票错开一整根。回测更贵:直接按时间戳对齐,总有一个市场的信号会提前用到5分钟后才有的数据,回测收益虚高,上线就对不上。日K线也一样:寒武纪午间返回的“今日收盘”是 991.44,到下午两点最新价已经是 976.01。盘中导出的CSV如果把最后一根当成收盘,报表里就是一个还没发生的收盘价。 为什么:这不是某一家接口的毛病。数据分析库 pandas 在把1分钟数据合成3分钟时,标签就有“取开头”和“取结尾”两种选法,同一组数据,时间戳能差一个周期。量化平台 QuantConnect 干脆给每根K线存两个时间:开始和结束,而且等这一根结束后才交给策略,就是为了防止回测提前看到未来。 量化研究机构 Concretum 做过一次对比:同一个开盘突破策略,代码、参数、日期都一样,只换数据商,最终资金从约22.6万美元到约72.6万美元,相差3倍多。他们的结论是:分歧不在策略,在数据。 先问供应商:“K线时间戳是开始还是结束?各市场一样吗?最后一根什么时候算结束?” 给技术同事:每根K线存成“开始—结束”的区间再对齐;导出CSV时给最后一行打上“可能未结束”的标记;不要拿最新报价拼一根“收盘K线”。 ⑦ 状态|盘口档位由市场决定,不支持的要说“不支持” 返回几档就画几档。不支持的市场,写“不支持”,不留空白。 场景:前端按A股写死了5档盘口,后来要加港股、美股、加密资产。 实测:同一个盘口接口,寒武纪返回5档,腾讯10档,苹果(夜盘)1档,BTC/USDT 每边1,000档。不支持盘口的品种,回应也不一样:标普500返回“成功”,但买卖两边都是空的;黄金、欧元/美元直接返回错误。 钱怎么算错:写死5档,港股丢掉一半深度;美股只有1档,前端要么画出4行空白,要么“补”出不存在的买二到买五,等于造了一份假深度,用户照着下单,这是最贵的一种错。外汇盘口显示空白,用户第一反应是“断线了”,工单又来了。 为什么:档位是市场本身决定的。A股5档、港股10档、美股夜盘可能只有1档、加密资产上千档,指数根本没有盘口。前端规定不了这件事。 先问供应商:“每个市场返回几档?不支持的市场返回什么?” 给技术同事:档位以接口返回为准,页面上写明“实际返回N档”;能力按市场配置;“没数据”“不支持”“请求失败”三种情况分开显示。盘口和成交的区别,第七篇再拆。 7个返工点,一张表收齐 返工点 身份证 这次实测 先问供应商 ① 同一个代码两个品种 品种 000001 不带类型,返回歧义错误和两个候选 代码冲突怎么处理? ② 成交量单位 算法 寒武纪按手、腾讯按股,差100倍 各市场数量单位是什么? ③ 两个时段 时段 苹果报价是周五收盘,盘口是今天夜盘 各接口对应哪个时段? ④ 涨跌窗口 算法 BTC 的前收一天里变了,A股不变 基准价和窗口是什么? ⑤ 0和没有 状态 指数买卖价返回0 不适用字段返回什么? ⑥ K线时间戳 时间 同一段5分钟,寒武纪标14:05,腾讯标14:00 时间戳是开始还是结束? ⑦ 盘口档位 状态 5档、10档、1档、1,000档;不支持的有的返回空、有的报错 各市场几档?不支持返回什么? 读法:最后一列就是可以直接发给供应商的7个问题。(实测均为2026年10月12日北京时间。) 第三部分|怎么办:自建还是外采,按这7点算账 1. 规则还在变:自建的成本在维护,不在接通 接通一个行情接口,确实只要几行代码。上面7个点没有一个是写代码的难题,难的是每一点都要有人知道规则,而且规则一直在变。只看今年下半年: 7月2日:港交所每手股数新框架第一阶段生效。 7月6日:A股盘后固定价格交易扩展到全部A股和ETF,每天15:05到15:30按收盘价成交。 11月1日:美国结束夏令时,美股各时段对应的北京时间整体后移1小时。 11月16日:港股无纸化市场上线,每手股数统一进入第二阶段。 四个日期里,两个改的是“单位”,两个改的是“时段”和“时间”,正好落在返工点②和③上。 数据层如果是自己接的,每一次都得有人跟:谁去看港交所公告,谁确认A股盘后成交算不算当天成交量,谁在夏令时切换那天检查一遍时间显示。 这不是写一次就完的代码。规则每变一次,5格身份证就要有人重核一次。 2. 一张算账表:自建要维护什么,外采要验收什么 返工点 自建要一直维护的 外采要验收的 谁拍板 ①② 品种和单位 品种目录、上市退市、代码变更、各市场单位表 目录能不能拿全;单位有没有写进文档 产品 ③ 时段 交易时段、交易日历、A股盘后、美股夏令时和夜盘 每个接口返回哪个时段,怎么标 产品、量化 ④⑤ 窗口和缺失 每类资产的涨跌窗口,每个字段适不适用 窗口和“不适用”有没有写清 产品、风控 ⑥ 时间 K线时间约定、最后一根怎么处理、时区 时间戳是开始还是结束、最后一根何时结束 量化、研发 ⑦ 能力 各市场档位、各套餐权限、错误分类 档位、权限、错误码有没有写清 商务、研发 读法:自建,就是把中间两列都变成自己的活;外采,是把维护交出去,把“问清楚”留给自己。 外采不是把这7个问题外包出去。供应商答不清的每一项,最后都会变回你自己的维护项。 行情数据本身是一门很大的生意:据 Burton-Taylor 的研究,2025年全球金融市场数据与分析支出增长6.5%,达到492亿美元。这也说明,“接一个免费接口”和“买一份能答清这5格的数据”,是两种不同的成本,不是同一个东西的免费版和付费版。 落到人身上,各签一行: 老板:“再加一个市场”不是半天的活,排期里要留出核对单位、时段、窗口和档位的时间;规则变了,谁来跟。 产品经理:每个数字旁边,标不标窗口、单位、时间?没标的那一个,就是你下一个要回答客户的问题。 商务和采购:拿下面7个问题去问供应商。不要求每项都答“支持”,但要求每项都答得清楚;答不清的,不进生产环境。 3. 上线前发给供应商的7个问题 可以直接复制: 代码冲突时,你们是报错、默认选一个,还是静默返回其中一个? 每个市场的成交量、盘口数量、逐笔数量,单位分别是什么? 快照、盘口、成交分别对应哪个时段?A股15:05以后的盘后成交,算不算进当天成交量? 每类资产的涨跌幅,基准价和窗口是什么?休市时前收怎么变? 不适用的字段(比如指数的买卖价、成交量),返回空、不返回,还是返回0? K线时间戳是开始还是结束?各市场一样吗?最后一根什么时候算结束? 每个市场返回几档盘口?不支持的市场返回什么? 4. 两段代码:给每个数字补上身份证 以下内容建议转给技术同事。 TickDB 为开发者和 AI 应用提供统一的全球行情数据接口,让团队通过一套接入获取多市场实时与历史数据,更快构建行情、分析和监控产品。 前面这些检查,我用 TickDB 的行情快照接口跑了一遍。下面两段代码是那块面板自选列表的取数核心:按资产类型分批请求,检查返回码,再给每个数字补上窗口、单位和时间。 代码1:按资产类型分批取快照,并给每个数字补上“身份证” import os import requests API_KEY = os.environ["TICKDB_API_KEY"] # 只放在服务端,不写进前端代码 BASE = "https://api.tickdb.ai/v1/market/ticker" # 身份证信息逐项配置,不从代码后缀推断 WATCHLIST = { "stock": {"688256.SH": {"unit": "手", "window": "当日"}, "700.HK": {"unit": "股", "window": "当日"}, "AAPL.US": {"unit": "股", "window": "常规盘"}}, "forex": {"EURUSD": {"unit": None, "window": "当日"}, "XAUUSD": {"unit": None, "window": "当日"}}, "indices": {"SPX": {"unit": None, "window": None}}, # 指数不读买卖价和成交量 "crypto": {"BTCUSDT": {"unit": "BTC", "window": "滚动24小时"}}, } def fetch(type_, symbols): resp = requests.get(BASE, params={"symbols": ",".join(symbols), "type": type_}, headers={"X-API-Key": API_KEY}, timeout=10) # 单次最多50个 body = resp.json() if resp.status_code != 200 or body.get("code") != 0: # 例如不带 type 查 "000001",会返回歧义错误和候选列表 raise RuntimeError(f"{type_}: {resp.status_code} {body.get('code')} {body.get('message')}") return body["data"] rows = [] for type_, items in WATCHLIST.items(): for q in fetch(type_, list(items)): meta = items[q["symbol"]] rows.append({ "symbol": q["symbol"], "type": type_, "price": q.get("last_price"), # 保留字符串,显示时再格式化 "time_ms": q.get("timestamp"), # 每个数字带自己的时间 "change_pct": q.get("price_change_percent_24h") if meta["window"] else None, "window": meta["window"], "volume": q.get("volume_24h") if meta["unit"] else None, "turnover": q.get("quote_volume_24h"), "unit": meta["unit"], "overnight": q.get("overnight_quote"), # 美股夜盘单独存,不覆盖主快照 }) 代码2:用“成交额 ÷ 成交量 ÷ 价格”自检成交量单位 from decimal import Decimal, InvalidOperation def unit_ratio(row): """返回 成交额/成交量/价格:约等于1是按股计,约等于100是按手计;缺任何一项返回 None。""" try: price, vol, turnover = (Decimal(str(row[k])) for k in ("price", "volume", "turnover")) except (InvalidOperation, TypeError, KeyError): return None if price <= 0 or vol <= 0: return None return round(turnover / vol / price, 1) for r in rows: if r["unit"] in ("手", "股"): ratio = unit_ratio(r) expected = 100 if r["unit"] == "手" else 1 flag = "OK" if ratio is not None and abs(ratio - expected) / expected < 0.05 else "CHECK" print(r["symbol"], r["unit"], ratio, flag) 用10月12日的实测数算一遍:寒武纪约100,腾讯约1,苹果约0.99。哪天比值突然跳到别处,就该去查单位是不是变了。 能做到的 / 边界 怎么验证 一个快照接口覆盖股票、外汇、贵金属、指数、加密资产,按类型分批请求 本文自选列表的7个品种 代码有歧义时返回错误并列出候选,不替你猜 不带类型查“000001” 美股盘前、盘后、夜盘分开存放,各带时间;美股成交记录标明属于哪个时段 查苹果的快照和最近成交 边界:各市场的数量单位、K线时间戳含义,本文由返回结果推断 接入前对照文档确认 边界:外汇、贵金属、指数不提供盘口和逐笔;交易时段接口没有列出A股收盘集合竞价和盘后交易时段 见返工点③⑦ 读法:前三行是这次实测能证明的,后两行是边界。以上只说明这次调用的情况,不代表全市场、全时段。(2026年10月12日实测。) 做和不做的差别:不做,成交额差100倍进了报表,客服天天解释“哪个价是真的”,回测因为时间戳错位虚高;做了,代码2自动判单位,每个数字带着窗口和时间,7个问题让每家供应商按同一套标准回答。 一个场景:一位做港股看板的产品经理,要加A股之前先跑了一遍代码2,看到寒武纪比值约100、腾讯约1,于是在A股成交量旁标上“手”,并把“单笔≥50万元”的大单阈值按手换算,免得上线后漏单。(场景按10月12日的实测数推演。) 以上代码只检查接入层行为,结果只说明本次调用的情况;比值在开盘初期、集合竞价前后可能小幅偏离,阈值按自己的品种调。 常见问题 1. A股和港股的成交量单位一样吗? 不一样。本文实测的接口里,A股按手(100股),港股按股。用“成交额÷成交量÷价格”可以自己核:寒武纪约100,腾讯约1。接入前以供应商文档为准。 2. A股现在几点收盘?15:05以后还有成交吗? 连续竞价到14:57,14:57到15:00是收盘集合竞价。2026年7月6日起,全部A股和ETF在15:05到15:30还有一段盘后固定价格交易,按当天收盘价成交。 3. K线的时间戳代表开始还是结束? 不同市场、不同数据商可能不一样。本文实测,同一段14:00到14:05的5分钟K线,寒武纪标14:05,腾讯标14:00。接入前要向供应商确认,并按“开始—结束”区间对齐。 4. 不同资产的涨跌幅能放在一起排行吗? 不建议。股票按当日算,加密资产按滚动24小时算,窗口不同,比大小没有意义。真要统一,就用K线按同一个窗口自己重算。 最后一个问题 你们面板上最显眼的那个数字,能说出它的5格身份证吗? 今天就能做的一件事:给自己的看板截一张图,在每个数字旁边写上它的单位、窗口和时间。写不出来的那一个,就是你的第一个返工点。 参考资料 访问日期均为2026年10月12日。 上海证券交易所,《上海证券交易所交易规则》(2026年修订,7月6日施行);光明网2026年7月6日相关报道 证券导报,2026年7月7日关于盘后固定价格交易首日的报道 港交所,每手股数框架咨询文件(2025年12月)及推进公告(2026年6月30日);SCMP 2026年3月9日相关报道 港交所,《Trading Mechanism of CAS in the Securities Market》(2026年4月10日版) 澎湃新闻,2023年8月11日关于科创板申报规则的报道 pandas 官方文档,resample 的 label 与 closed 参数 QuantConnect 文档,数据交付时间与 bar 的 Time / EndTime Concretum Group,《Can You Trust Your Intraday Database?》及配套文章 币安官方API文档,24小时行情接口定义 Burton-Taylor International Consulting 研究(FOW 2026年4月8日报道) TickDB,行情接口文档及作者实测记录 系列上一篇:《拆解美股夜盘数据5个口径》 做国内量化或者行情工具的开发者,A股数据肯定是绕不开的。但接A股数据的时候有个问题:A股的交易规则跟美股、港股都不一样——涨跌停、T+1、集合竞价、午休,这些规则在API数据里是怎么体现的? 这篇从A股交易规则出发,讲一下怎么用Python接A股实时行情,以及这些特殊规则在返回数据里怎么对应。如果你在找一个稳定的股票数据接口或者实时行情API,这篇应该能帮你省掉不少踩坑的时间。 为什么需要专业的A股数据接口 做量化策略或者行情面板的时候,数据是最基础的。一开始我试过爬财经网站的页面,但稳定性太差了——页面结构一改就挂,而且延迟很高,做实时监控根本没法用。后来才转用专业的金融数据API,至少数据格式稳定、接口响应快,不用每天盯着爬虫脚本挂没挂。 选接口的时候主要看几点:一是数据覆盖全不全,沪深两市的股票能不能都拿到;二是实时性够不够,做日内策略延迟太高就没意义了;三是历史K线数据够不够全,回测需要长时间的历史数据。最后找了一圈试了几个接口,留下来一直在用的是itick,主要是接口设计比较干净,文档也写得清楚。 A股交易规则与数据字段的对应 先把A股的交易规则理清楚,这样看返回数据的时候才知道每个字段是什么意思。 交易时间:上午9:30-11:30,下午13:00-15:00。中午有1.5小时休市。 涨跌停:主板股票±10%,创业板/科创板±20%,ST股票±5%。涨停的时候买盘挂单很多,卖盘很少;跌停反过来。 T+1:当天买的股票第二天才能卖,但API返回的成交量和成交额是实时的。 集合竞价:开盘前9:15-9:25是集合竞价时间,这时候也有成交数据。 这些规则在API返回数据里怎么体现呢?看几个关键字段: ts:交易状态,0=正常交易,1=停牌,2=退市,3=熔断。停牌的时候没有成交。 ld:最新价。涨停的时候这个价就是涨停价。 chp:涨跌幅百分比。±10%就是涨停/跌停了。 v:当日累计成交量。 tu:当日累计成交额。 REST拉取A股报价 先从REST开始,确认数据格式。做行情面板或者批量拉快照的时候,REST接口最方便。 import requests API_BASE = "https://api.itick.org" TOKEN = "your_token_here" headers = {"accept": "application/json", "token": TOKEN} # 拉A股实时报价 def get_a_share_quote(code): resp = requests.get( f"{API_BASE}/stock/quote", headers=headers, params={ "region": "CN", "code": code } ) return resp.json()["data"] # 拉几只A股大盘股 stocks = ["600519", "000001", "300750"] for code in stocks: q = get_a_share_quote(code) sign = "+" if q["chp"] >= 0 else "" print(f"{code}: {q['ld']} ({sign}{q['chp']}%)") 返回字段跟其他市场基本一致:ld最新价、chp涨跌幅、o/h/l开高低、v成交量。做技术分析或者行情看板这些字段够用了。 注意:A股代码是6位数字,传参数的时候要传字符串形式("600519"),不要传数字。一开始我传了数字类型,结果接口返回参数错误,折腾了半天才反应过来。 WebSocket订阅A股 做实时监控或者盘中告警的时候,轮询REST接口效率太低,这时候就得用WebSocket实时推送了。 WebSocket订阅格式跟美股一样,是两个参数:代码$市场。 import json import threading import time import websocket WS_URL = "wss://api.itick.org/stock" TOKEN = "your_token_here" 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 # A股订阅格式:代码$市场 ws.send(json.dumps({ "ac": "subscribe", "params": "600519$CN,000001$CN", "types": "quote" })) return if payload.get("resAc") == "pong": return data = payload.get("data") or {} if data.get("type") == "quote": sign = "+" if data["chp"] >= 0 else "" print(f"{data['s']}: {data['ld']} ({sign}{data['chp']}%)") A股订阅是两个参数(600519$CN),跟美股一样,不是印度那种三个参数。做实时行情推送的时候,WebSocket比轮询REST效率高很多——不需要每秒发一次请求,服务端有数据就主动推过来。 K线数据获取 做技术分析或者策略回测的时候,需要历史K线数据。K线接口跟其他市场一样,只是region传 CN。 def get_a_share_kline(code, k_type=8, limit=100): """ k_type: 1=1分钟 2=5分钟 5=1小时 8=日K 9=周K 10=月K """ resp = requests.get( f"{API_BASE}/stock/kline", headers=headers, params={ "region": "CN", "code": code, "kType": k_type, "limit": limit } ) return resp.json()["data"] # 拉贵州茅台近100根日K daily = get_a_share_kline("600519", k_type=8, limit=100) closes = [bar["c"] for bar in daily] # 算20日均线 ma20 = sum(closes[-20:]) / 20 print(f"600519最新收盘: {closes[-1]}, 20日均线: {ma20:.2f}") K线返回标准OHLCV:t时间戳、o/h/l/c开高低收、v成交量。做技术分析直接用这些字段就行,不用自己再清洗数据。 A股特有的注意事项 交易时间有午休。 A股中午休市1.5小时(11:30-13:00),这个时间段没有成交数据。做实时监控的时候要注意,别把午休时间当成流动性枯竭——我一开始做告警的时候,午休期间一直没数据还以为接口挂了,后来才反应过来是休市了。 涨跌停判断。 主板股票涨跌幅超过±10%就是涨停/跌停,创业板/科创板是±20%。做策略的时候要判断当前是否涨停,涨停的时候买不进去。可以通过chp字段判断,如果涨跌幅接近10%或者20%就要小心了。 代码是6位数字。 A股代码是6位数字(600519、000001),跟港股的5位数字(00700)、日本的4位数字(7203)都不一样。一开始我传了"700",结果返回空数据——那是港股腾讯的代码,A股没有700这个代码。 region是CN。 A股市场region传 CN,不是 SH 或 SZ。 集合竞价时间。 开盘前9:15-9:25是集合竞价,这时候也有成交数据,但价格波动很大。做策略的时候要注意区分集合竞价和连续竞价,别把集合竞价的成交量当成正常交易的量。 完整脚本:A股行情监控 把前面几块拼起来,最终的完整脚本: import json, time, threading, requests, websocket API_BASE = "https://api.itick.org" WS_URL = "wss://api.itick.org/stock" TOKEN = "your_token_here" headers = {"accept": "application/json", "token": TOKEN} # A股监控列表 watchlist = ["600519", "000001", "300750"] # 启动时拉快照 print("=== A股快照 ===") for code in watchlist: r = requests.get(f"{API_BASE}/stock/quote", headers=headers, params={"region": "CN", "code": code}).json()["data"] sign = "+" if r["chp"] >= 0 else "" print(f" {code}: {r['ld']} ({sign}{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 params = ",".join(f"{c}$CN" for c in watchlist) ws.send(json.dumps({ "ac": "subscribe", "params": params, "types": "quote" })) threading.Thread(target=heartbeat, args=(ws,), daemon=True).start() return if payload.get("resAc") == "pong": return data = payload.get("data") or {} if data.get("type") == "quote": sign = "+" if data["chp"] >= 0 else "" print(f"[实时] {data['s']}: {data['ld']} ({sign}{data['chp']}%)") def heartbeat(ws): while True: time.sleep(30) ws.send(json.dumps({"ac": "ping", "params": str(int(time.time() * 1000))})) ws = websocket.WebSocketApp(WS_URL, header=[f"token: {TOKEN}"], on_message=on_message) ws.run_forever() 这个脚本跑起来之后,开盘前先看到一组A股的快照,盘中实时更新价格和涨跌幅。做行情面板或者盘中告警的话,这个基础上再扩展就行。 小结 接A股数据的技术框架跟美股差不多——REST做快照和历史数据,WebSocket做实时推送。主要区别在交易规则(涨跌停、T+1、午休)和代码格式(6位数字)。这些细节不踩一遍坑很容易忽略。 参考文档:https://docs.itick.org/websocket/stocks GitHub:https://github.com/itick-org/ 散户交易的痛点与“大道至简”的交易哲学 许多散户在做短线交易时,往往陷入对复杂指标的盲目迷信——MACD、KDJ、RSI看了一大堆,各种交叉与背离记了满脑子,但在实际实操中却依然频繁亏损。究其原因,并非这些指标本身毫无价值,而是你看得越多,越容易在潜意识里进行“自我欺骗”。当股价跌破关键支撑位时,你总能从某个指标里找到不离场的托词,结果便是眼睁睁看着账户滑向万丈深渊。 短线交易要想真正实现盈利,靠的绝不是学遍所有指标,而是找到一套适合自己的规则并重复执行。看懂越多的指标越容易动摇心志,做短线真正需要的是极简的纪律和一套自洽的规则。用一套极简的纪律去约束情绪的波动,才是穿透牛熊周期、在残酷市场中死里逃生的关键。 “再简单的纪律也好过没有纪律。” 看清市场的资金本质,用规则取代情绪化决策,这正是散户短线交易走向成熟的第一步。 核心干货:5日均线短线交易的5大黄金法则 法则一:无放量大阳,坚决不碰(筛选标的) 短线交易的核心在于紧跟主力资金的步调。从筹码博弈的角度来看,放量大阳线是主力资金“建仓或拉升”最明确的筹码语言。如果一只股票在很长一段时间内,连一根有力度的放量大阳线都没有出现过,这表明根本没有主力资金在其中深度发力。 缺乏资金共振的标的,筹码完全处于无序的散户博弈状态,充其量只是无序的“电梯行情”,上涨空间自然被锁死。遇到这类没有主力参与的股票,无需任何留恋,直接“划走”。 法则二:放量看方向,回踩找位置(寻找买点) 主力资金在底部完成首轮启动后,出于洗盘拉升的需要,极少会直接走出单边连续暴涨,通常会借助回调洗刷浮筹。只要主力资金发力的方向明确,且股价回踩5日均线时未跌破支撑、5日均线本身保持向上拐升态势,这个回踩点就是多头筹码的动态支撑位,也是重点观察与寻机建仓的核心买点。 请牢记这条核心口诀:“放量看方向,回踩找位置”。 法则三:加速偏离先兑现,回踩不破再接回(持仓与止盈) 当股价出现加速拉升、明显偏离5日均线时,乖离率过高会导致短线获利盘涌出,此时切忌盲目幻想股价会无休止地暴涨。策略上应当果断锁定并兑现一部分计划内的利润。锁住既得利润是计划内的理性选择;相反,若执着于赚取预期外的最后一滴利润,反而极易遭受预期外的深度亏损。 兑现部分利润后,若后续股价回踩5日均线不破,甚至5日均线重新拐头向上,再将减掉的仓位接回也完全来得及。这种操作看似放弃了一小段波动,实则是“以高确定性换取账户权益曲线的平滑向上”。 法则四:收盘跌破不硬扛,控制风险永远第一(风险控制) 每日临近收盘时,必须将其设定为风控防线的检验时刻。重点观察收盘前股价能否重新站上5日均线。如果股价依然收在5日均线下方,必须果断进行减仓,绝不盲目死扛。 卖飞了,后续趋势修复时还可以寻找机会重新补仓;但死扛一旦遇到趋势破位,面临的可能就是无底深渊。想要在股市中长期生存,必须时刻将风控置于利润之前: “永远要先想着控制风险,再想着赚多少钱。” 法则五:连续三日收不回即清仓,指标失灵果断换股(止损与离场) 在跌破均线后的风险防范上,必须严格遵守“越跌越卖”原则,并分情况进行标准化处置: **●**彻底离场原则:短线强势股的5日均线是多方的生命线。若股价连续三个交易日都无法重新站回5日均线(尤其是股价处于高位时),从供需关系来看,意味着5日均线已由“动态支撑”转化为“强动态阻力”,多方动能彻底衰竭。此时无法预知下方何处才能止跌,切勿与市场较劲,必须果断清仓保留本金。离场后,必须等待“5日均线再度拐头向上,且股价也重新站上均线”这一双重确认信号同时出现时,方可考虑重新进场。 ●**应对震荡市失灵:若你的交易陷入“一追就跌,一割就涨”的怪圈,且连续失败两次**,这就明确宣告该股已进入无序的震荡趋势,5日均线已经暂时失灵。此时不要硬扛或跟股票死磕,直接换股离场,去寻找股价与5日均线均明显向上的标的,让技术指标重新为你服务。 建立属于你的交易规则 从筛选标的、寻找买点,到持仓止盈、风控离场,上述5条铁律构成了一套完整的短线交易规则闭环。 需注意的是,交易并非死板硬套。若你的操作风格偏向波段,或标的股票波动基底较大,亦可将这套规则同理套用至10日或20日均线,找到最契合你自身节奏的均线载体。 虽然这些规则看起来简单粗浅,但能否克服人性的贪婪与恐惧、彻底执行纪律,才是拉开普通投资者与资深交易员盈利差距的关键。规则即是心性修炼的具象化。 在接下来的交易中,你是准备继续在复杂的指标里自我欺骗,还是开始用一根简单的均线来约束自己的情绪?