全部
文章&策略
学习干货
问答
官方
用户头像mx_***212o7g
2026-10-15 发布
专职在家了,自己没钱玩
浏览16
评论0
收藏0
策略回测收益图
用户头像Fxdund
2026-10-15 发布
做贵金属行情监控或者黄金期货量化策略的人,最后大概率都会走到同一条路上:用Python写一套行情采集程序,对接实时行情API,把国际金价、COMEX黄金期货数据拉进自己的系统。这个方向本身没什么门槛,真正的门槛在接入细节——一个WebSocket连接里的鉴权时序、心跳机制、时间戳处理,就能让一套看起来正常的采集程序在凌晨三点悄悄断流。 最近朋友发来一段自己写的黄金期货行情采集代码,说"有时候数据断着断着就没了,也没报错"。我把代码从头到尾翻了一遍,问题不止一个。这篇不写教程,就是一次真实的代码审查过程:原版代码放出来,问题一条条列,修复方式对着文档写。如果你也在写期货行情采集、实时行情推送或者贵金属数据管道,大概率能对号入座。 原版代码 import json import time import requests import websocket API_BASE = "https://api.itick.org" TOKEN = "your_token_here" headers = {"accept": "application/json", "token": TOKEN} def get_quote(): resp = requests.get( f"{API_BASE}/future/quote", headers=headers, params={"region": "US", "code": "GC"} ) return resp.json()["data"] def on_message(ws, message): payload = json.loads(message) data = payload.get("data") or {} if data.get("type") == "quote": ts = data["t"] // 1000 print(f"{data['s']}: {data['last']} ({data['chp']}%) time={ts}") def on_open(ws): # 连接一建立就订阅 ws.send(json.dumps({ "ac": "subscribe", "params": "GC$US", "types": "quote" })) ws = websocket.WebSocketApp( "wss://api.itick.org/future", header=[f"token: {TOKEN}"], on_message=on_message, on_open=on_open ) ws.run_forever() 这段代码能跑,乍一看没什么问题。但仔细过一遍,六个问题,其中三个能解释"数据静默消失"。 审查结果:六个问题 问题1:连接建立就订阅,鉴权还没完成 on_open 触发只是TCP和WebSocket握手完成,不代表服务端鉴权通过。文档里明确写了:要等收到 resAc:"auth" 且 code:1 的消息后才能发送订阅。这段代码连接一建好就发subscribe,服务端此时可能还没完成token校验,订阅直接被拒,而且不报错——这就是"没数据但程序还在跑"的典型原因。 这个坑在WebSocket实时推送类接口里非常常见。REST接口是"发请求等响应",错了会返回错误码;WebSocket是长连接,很多接入问题不返回任何提示,只能靠消息类型自己判断。所以写实时行情API接入的时候,必须把"鉴权成功"当成一个显式的状态节点,而不是假设连接成功就能用。 修复:加一个 authenticated 状态位,只有收到鉴权成功消息才允许订阅。 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": "GC$US", "types": "quote" })) return 问题2:没有心跳,长连接被服务端断开 期货WebSocket要求每30秒发送一次心跳({"ac":"ping","params":"时间戳"}),不消费消息、不发心跳,服务端会主动断开。这段代码完全没有心跳逻辑,跑几个小时后连接被服务端回收,程序不退出、不重连,看起来"数据没了"。 黄金期货跟股票最大的不同就是交易时间长,基本是7×23小时连续交易,中间只休市约一小时。这样的场景下,连接长期在线是常态,心跳机制就不是"可选项"而是"必选项"。很多做贵金属行情监控的人一开始都忽略心跳,等发现数据断了,往往已经过去一两个小时。 修复:订阅成功后启动心跳线程。 import threading def heartbeat(ws): while True: time.sleep(30) ws.send(json.dumps({ "ac": "ping", "params": str(int(time.time() * 1000)) })) # 在鉴权成功分支里启动 threading.Thread(target=heartbeat, args=(ws,), daemon=True).start() 问题3:时间戳被当成秒用 data["t"] 是毫秒时间戳,代码里 // 1000 转成了秒,但后面直接拿来当普通时间打印,没有转时区。黄金期货美盘时段对应的是北京时间晚上,用UTC时间戳直接展示,凌晨告警的"几点"全是错的,做交易时段判断更是全乱。 时间戳问题在做跨市场、跨品种数据的时候尤其突出。黄金、白银、铂金、钯金这些贵金属的交易时段横跨亚盘、欧盘、美盘,一个监控系统里可能同时处理多个市场的行情,时间基准必须统一、转换必须显式。毫秒转秒、UTC转本地、夏令时处理,这三件事建议封装成独立的工具函数,别在业务代码里随手除一下了事。 修复:显式转成本地时间。 from datetime import datetime ts = data["t"] / 1000 local_time = datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S") print(f"{data['s']}: {data['ld']} ({data['chp']}%) time={local_time}") 问题4:字段名记错了 代码里用的是 data['last'],实际报价字段是 ld(最新价)。拿错字段的后果是:程序在跑、连接也活着、数据也在推,但你永远拿不到正确的价格——这种bug最坑,因为没有任何报错。 字段名这件事,不同数据源差异很大。有的接口用 last,有的用 price,有的用 close;同样的"涨跌幅",可能是 chp、change_pct 或者 percent_change。接任何金融数据API,第一步都应该是把返回字段文档完整读一遍,把要用的字段列成一张映射表,再写代码。期货行情接口的报价字段是 s/ld/chp/o/h/l/v/tu/ts,K线字段是 t/o/h/l/c/v/tu,这几个记牢能省很多排查时间。 修复:字段名对照文档——报价字段是 s/ld/chp/o/h/l/v/tu/ts,K线字段是 t/o/h/l/c/v/tu。 问题5:没有断线重连 run_forever() 在连接异常退出后,程序直接结束。黄金期货交易23小时,凌晨断一次线没人盯着重启。生产环境必须加重连。 重连逻辑要注意一点:重连之后要重置 authenticated 状态。新连接建立后需要重新鉴权,如果状态位还是旧的True,订阅请求会在鉴权完成前被发出,等于问题1的坑再踩一遍。这也是为什么很多实时行情客户端会把这个状态位放在连接循环外面、每次连接重置。 修复:包装一层循环,断线自动重连,重连后重置 authenticated 状态(因为新连接要重新鉴权)。 while True: authenticated = False ws = websocket.WebSocketApp( "wss://api.itick.org/future", header=[f"token: {TOKEN}"], on_message=on_message ) try: ws.run_forever() except Exception: pass print("连接断开,5秒后重连...") time.sleep(5) 问题6:把休市当成接口挂了 COMEX黄金每天休市约1小时,这个窗口没有成交数据。代码里没有任何交易状态判断,一旦这个时段"没数据",第一反应往往是"接口坏了"。报价里其实有 ts 字段标交易状态,先判断状态再判断数据。 贵金属的交易规则跟股票不太一样:股票是固定时段,休市时间长,大家有预期;黄金这种近全天交易的品种,休市窗口短,反而容易被忽视。做行情监控的时候,把 ts 交易状态判断加进去,同时把"休市时段"和"真实故障"区分开,能少很多次半夜被误报警叫醒的情况。 修复: if data.get("type") == "quote": if data.get("ts") == 0: print("休市/停牌,忽略") return # 正常处理行情 审查清单速查 把上面六个问题整理成一张自查表,写完代码逐条过一遍: # 检查项 错误表现 正确做法 1 鉴权时序 无数据但程序在跑 等 resAc:"auth" + code:1 再订阅 2 心跳机制 几小时后连接被回收 每30秒发 {"ac":"ping","params":"时间戳"} 3 时间戳单位 时间显示错误、时段判断错乱 毫秒转秒 + 显式转本地时区 4 字段名 拿到错误价格无报错 对照文档:报价 ld、K线 c 5 断线重连 凌晨断线后程序静默结束 循环重连 + 重置鉴权状态 6 交易状态 休市当故障,误报不断 先判断 ts 再处理行情 这张表也适用于其他品种的实时行情接入——股票、外汇、指数、期货,接入框架是同一套,差异只在代码格式和交易时段。 修复后的完整代码 import json import threading import time from datetime import datetime import websocket WS_URL = "wss://api.itick.org/future" 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": "GC$US", "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": if data.get("ts") == 0: return # 休市 ts = datetime.fromtimestamp(data["t"] / 1000).strftime("%H:%M:%S") print(f"{data['s']}: {data['ld']} ({data['chp']}%) {ts}") def heartbeat(ws): while True: time.sleep(30) ws.send(json.dumps({"ac": "ping", "params": str(int(time.time() * 1000))})) while True: authenticated = False ws = websocket.WebSocketApp( WS_URL, header=[f"token: {TOKEN}"], on_message=on_message ) try: ws.run_forever() except Exception: pass print("连接断开,5秒后重连...") time.sleep(5) 这套代码还能怎么扩展 审查完只是第一步。把这段代码放进真实的黄金行情监控系统,通常还要补三块: 多品种扩展。 只盯GC不够,白银、铂金、钯金常常要一起看。WebSocket订阅支持逗号分隔多个标的(GC$US,SI$US),一个连接就能覆盖整个贵金属组合,不用开多个连接。REST侧也有批量报价接口 /future/quotes,参数用 codes(复数)传逗号分隔的产品代码,一次请求拿多个品种的快照,比循环调单品种接口高效得多。 历史K线补齐。 监控需要实时行情,回测和均线计算需要历史数据。REST的 /future/kline 接口用 kType 指定周期(1=1分钟、2=5分钟、5=1小时、8=日K、9=周K、10=月K),limit 控制返回条数。把日K拉进本地数据库,收盘后增量更新,监控和回测就能共用一套数据。 告警触发。 实时行情拿到手,后面接什么逻辑都方便:突破均线提醒、价格区间监控、相对强弱计算。数据层的问题解决之后,策略层的开发才谈得上专注。 审查心得 这段代码的问题很有代表性:绝大多数"数据莫名其妙没了"的场景,不是接口挂了,而是接入层的小问题——鉴权时序、心跳、字段名、时区、断线重连。每个问题单看都很小,但叠加起来就是"程序在跑、数据在断、你还在找原因"。 写行情采集代码的时候,我现在的习惯是写完先自查这五件事:鉴权等了吗、心跳发了吗、字段名对文档了吗、时间戳转了吗、断线会重连吗。五件事过一遍,接入层的坑基本就避开了。 字段和参数的细节,写代码时边写边翻官方文档对照,比自己记一遍靠谱。 GitHub:https://github.com/itick-org/
浏览21
评论0
收藏0
用户头像林青淼
2026-10-15 发布
我现在正通过“策略研究”对历史数据进行回测,并尝试将已经相对成熟的策略放到“模拟交易”里观察后续表现,目前遇到个问题:有些策略较长,功能模块较多,代码条理很乱,也不利于后续维护。现在想把一个策略拆分成多个python文件,但“策略研究”仅提供一个输入端,这个有办法解决吗?
浏览12
评论0
收藏0
用户头像sh_***174w0d
2026-10-15 发布
为什么绝大多数人在股市里都在“凭实力亏钱”? 为什么大家都在炒股,但真正能够实现长期稳定盈利的,永远只是极少数人? 绝大多数散户在市场里痛苦挣扎、频频割肉,绝非不够努力,而是陷入了凭直觉交易的迷局。“凭实力亏钱”的扎心真相背后,是人性难以克服的贪婪与恐惧。 其实,股市里的盈利逻辑极其纯粹,从来不需要十八般武艺样样精通。能够在这个残酷竞技场中真正实现长期盈利的,总结起来只有6种特定类型的“狠角色”。而绝大多数陷入巨额亏损的投资者,往往是因为盲目跟风,落入了最可怕的第7种人的陷阱。 看清这7种人的行为模式与心理博弈,你就能一眼看透股市的盈利本质,找准属于你自己的生存之道。 股市长期盈利的6种“狠角色” 1.猎手型:极度忍耐,一年只做一两波的“空仓狠人” 第一种人拥有常人难以企及的定力。他们可以常年保持空仓,忍受市场的日常波动与诱惑,一年之中往往只出手一两次(只做一两波行情)。一旦达成盈利目标,赚了就走,绝不恋战。 对于普通散户而言,“常年空仓”是极具折磨性的,这背后最大的心理魔鬼叫 FOMO**(害怕错过)**——看着别人赚钱,手痒难耐、报复性建仓是绝大多数人亏损的起点。但在顶级猎手眼里,现金就是最致命的武器。他们避开了90%无意义的无序波动,用极度的忍耐去换取确定性最高的致命一击。 极度忍耐,赚了就走,绝不恋战。 2.陪伴型:拿时间换收益的“长线玩家” 第二种人是坚定的长线持有者。他们持股时间长达三五年,在持股期间完全不理会短期的涨跌波动,心如止水。 这类交易者深刻理解复利与周期的力量。他们通过主动屏蔽市场的短期噪音,克服了对账面浮亏的恐惧与对小利即满的贪婪。他们选择以时间为杠杆,去换取确定性的长期企业价值成长,以此轻松战胜市场短期的无序与不确定性。 3.匠人型:把成本做成负数的“做T高手” 第三种人极其专注。他们绝不贪多,只指定一两支股票进行深耕,通过持续不断的高抛低吸,一步一步地将持仓成本一点点做低。 日积月累之下,他们甚至能够把持仓成本做到负数。当持仓成本被降为负数时,交易者便获得了绝对的心理免疫——市场的任何剧烈甩洗和暴跌都再也无法引发任何恐惧,股票彻底沦为了无风险的“现金流印钞机”。这种策略成功的关键,在于对单一标的股性有着极致了解与专注。 4.刀锋型:只做主线龙头的“纪律选手” 第四种人是敏锐的板块龙头玩家。他们只做市场的主线龙头股票,绝不把精力与资金浪费在毫无辨识度的跟风杂毛股上。 他们的核心优势在于纪律严明、出手极快。凭借对市场情绪与资金主线的敏锐洞察,一旦信号确认即迅速出击,趋势破位则果断割肉,绝不拖泥带花。 5.机器型:无情执行信号的“系统交易者” 第五种人将自己训练成了无情的交易机器。他们只严格按照自己的交易信号操作,买点不到,即使股票涨停也绝不关注;而一旦卖点触发,像机器一样无情扣动扳机。 “买点不到,涨停都不看”——这需要极其强大的心理定力。普通交易者往往因贪婪而盲目追高涨停股,而系统交易者明白,未经信号确认的涨停蕴含着无法控制的尾部风险。他们彻底摒弃了人性的贪婪与恐惧,做到了真正的“人机合一”。 6.智者型:提前离场的“知足聪明人” 第六种人懂得适可而止。他们只吃行情最安全的中段(“鱼身”),绝不上当去贪图尾声的最后一点利润(“鱼尾”)。一旦察觉行情进入尾声,便提前离场保住胜利果实。 需要特别强调的是:尤其是第六种,大多数人根本做不到。人性的贪婪会疯狂暗示散户“还能再涨一点”,最终往往在狂欢的顶峰(鱼尾)沦为接盘侠。懂得知足止盈、甘愿放弃最后一个铜板的人,才掌握了防范市场剧烈回撤的终极武器。 警惕!最可怕的第7种人:市场的“送钱童子” 看清前6种盈利者后,更需要时刻警惕的是最可怕的第7种人。 这种人的典型特征是:什么都懂一点,但什么都不精通。他们看似满腹理论,实则陷入了致命的战术矛盾——在实际操作中,他们长线拿不住,短线舍不得;战术天天换,今天学龙头追高,明天学抄底接飞刀,后天又开始跟着做****T。 这种“既要龙头动能,又要抄底安全”的逻辑分裂,给他们带来了致命的虚假安全感。因为没有明确的交易主线与严密的交易体系,他们做出的每一次决策都是对人性的妥协。前面6种人赚的都是符合自己逻辑的钱,而这第7种人,因其系统性混乱,彻底成为了市场上给前6种人提供流动性的“筹码提供者”与“送钱童子”。 前面六种人赚的是自己的钱,第七种人专门给前面六种人送钱。股市里不是比谁赚得快,而是比谁活得久。 在股市中,你究竟是哪一种人? 在股市这个残酷的竞技场中,盈利的关键从来不是博采众长、频繁更换招式,而是找到适合自己的定位,建立清晰的交易逻辑,并贯彻铁一般的纪律。无论是选择做极度忍耐的冷酷猎手,还是坚守时间的陪伴玩家,唯有摒弃杂念、坚持一套行之有效的方法,才能在市场中长久生存。
浏览30
评论0
收藏0
用户头像9点半量化
2026-10-15 发布
交易的艺术在于“等待” 在金融市场中,绝大多数交易者都深陷于同一个噩梦:见涨就追,见跌就割,操作越频繁,账户缩水越严重。这种因缺乏耐心而导致的冲动交易,是吞噬本金的根源。 真正的交易高手,绝不是时刻在市场里频繁进出的“勤劳蜂”,而是手握猎枪、极具定力的“潜伏者”。市场的本质不是预测未来,而是一场关于规则与克制的博弈——未出现确定性信号前,绝不上弹;信号触发之时,果断出击。 “这五种模式至少看七遍” 这句警醒,道出了交易系统中最为核心的五种盈利模式与入场节点。深刻领悟并融入血脉,是你摆脱散户思维、构建成熟交易系统的第一步。 模式一:做趋势,等的是回调 在主升或主降趋势中,顺势而为是获利的基础,但这绝不意味着看到价格飙升就能盲目追高。 散户往往在趋势拉升的最高点因贪婪而急忙抢筹,结果买在短期顶部,稍有风吹草动便在恐慌中割肉出局。相比之下,高手的做趋势,等的是回调。 当价格在主干趋势中出现合理的回踩与整理时,市场正在完成筹码换手与风险释放。等待回调企稳后再行入场,不仅能重新验证下方关键支撑位的有效性,更大幅压低了止损成本,从而获得极高的风险收益比。 等待二次启动的确认,才是顺势交易中兼具安全性与爆发力的最佳时机。 💡 导师实战口诀:无回调不顺势,宁可错过高位,绝不盲目追高。 模式二:做突破,等的是回踩 突破形态往往孕育着强劲的单边行情,但市场中同样充斥着大量主力资金精心制造的假突破陷阱。 如果在价格刚刚穿透阻力位的瞬间凭热血追入,极易被假突破挂在阶段性的“天花板”上。因此,成熟交易者的做突破,等的是回踩。 回踩的深层逻辑,在于验证原有的阻力位是否已经成功转化为强有力的支撑位。只有当价格回踩该位置且抛压被彻底消化、支撑重新确认时,突破的有效性才算真正立足。 耐心等待回踩企稳后再介入,虽然放弃了极小一段初始涨幅,换来的却是胜率与确定性的质变。 💡 导师实战口诀:突破多诱多,回踩定乾坤;支撑不确认,决不出重手。 模式三:做反弹,等的是放量 面对连绵下挫的行情,盲目抄反弹无异于徒手接“下坠的飞刀”。 无量反弹不是给散户抄底的福利,而是主力资金诱多的陷阱。缺乏资金关注的缩水反弹,仅仅是下跌动能的暂时衰竭,随时可能重新向下砸出新低。 做反弹的核心铁律,等的是放量。 成交量是市场最真实的语言。放量意味着有规模化的主力资金开始逆势承接,市场筹码完成了高效的筹码换手。只有看到明确的放量信号,超跌反弹才具备资金面上的可持续性与参与价值。 💡 导师实战口诀:无量反弹皆是空,放量确认方建仓。 模式四:做震荡,等的是高点 无明确方向的震荡箱体,是消耗交易者本金与心态的“绞肉机”。 散户最容易在箱体中间的中轴位置凭感觉下注,结果价格上下摇摆,被两头刮蹭、频繁止损。高手的做震荡,等的是高点——即坚决恪守边界原则。 需要特别说明的是,“等高点”绝非让交易者在箱体顶部去追买,而是指耐心等待价格运行至区间上轨或核心阻力区域时,执行逢高减仓或布局高抛****/****做空的策略。 坚决不在无秩序的中轴区域下注,静待价格触碰上限边界再行决策,才能彻底杜绝无谓的本金磨损。 💡 导师实战口诀:震荡不赌中轴线,高抛低吸守边界。 模式五:做抄底,等的是大面积情绪崩盘 抄底是所有交易行为中风险最高的一种,仅凭指标超卖或主观“跌透了”的感觉去抄底,极其危险。 做抄底有着极为严苛的前提条件,等的是大面积情绪崩盘。请注意,这里的核心修饰词是大面积。 局部的下挫或个股的下跌,往往只是阴跌洗盘的开始,盲目介入只会买在半山腰。唯有当恐慌蔓延至整个市场,出现大面积情绪崩盘(如板块批量跌停、绝望抛盘涌出、流动性短暂缺失),市场经历彻底的筹码出清与情绪宣泄后,真正的阶段性底部才会坚固浮现。 未见大面积情绪崩盘,绝不轻易出手接刀。 💡 导师实战口诀:局部回调莫接刀,大面积崩盘方显底。 从冲动到克制,你的交易系统建好了吗? 交易是一场反人性的自我克制。 无论是做趋势、做突破、做反弹、做震荡还是做抄底,这五种模式的共同本质,都是要求交易者放弃主观预测,将重点放在制定规则与耐心“等待”触发条件上。条件不满足,哪怕盘面再诱人,也绝不出手。 在这五种模式中,你最容易在哪一种的“等待”上失去耐心?又在哪一种模式里踩过“假信号”的坑?欢迎在评论区留下你的实战体会。
浏览27
评论0
收藏0
用户头像sh_***3272xs
2026-10-15 发布
用 TradingView 开源的 Lightweight Charts 画腾讯10月14日的日K,图上显示的是10月13日。图表库没错,数据也没错,错在喂数据的那一步。我用真实行情把同一组数据喂了两遍,挑出跨市场K线最容易画错的10个地方,文末附一段能直接复制的喂数代码。 10月9日,香港证监会透露,香港正在研究延长证券交易时段,港交所第四季度会就现货市场延时发讨论文件。再过两周多,11月1日,美股换冬令时,北京时间开盘从21:30推迟到22:30。 交易时间要变了。做行情App的人该先问自己一句:K线的时间轴是写死的还是算出来的? 我先拿腾讯试了一下。用 TradingView 开源的 Lightweight Charts 画日K,接口返回的数据原样喂进去: 10月14日的K线,图上写着13日,整条时间轴都早了一天。 做单一市场,这类错一两处;做A股、港股、美股一起的跨市场App,它们会一起冒出来。 图表库只负责画,画得对不对取决于你怎么喂数据。 读完你能带走:10个最常见的画错点和修法,一段约50行的喂数代码,一张上线前体检表。 一、图表库只管画,不懂行情 Lightweight Charts 免费、轻量,几十行代码就能画出专业样式的K线,很多行情App和交易工具都在用。 但它不知道你的时间戳属于哪个市场,不知道国内习惯红涨绿跌,不知道这只股票上个月除过权,也不知道A股成交量的“1”是一手。这些都得在数据进图表之前处理好,我把这一步叫“喂数层”。 下面每一条都是同一组真实数据喂两遍的对比:一遍原样喂,一遍先过喂数层。 二、首页对比图 ① 腾讯10月14日的K线,标成了13日 行情接口的日K时间戳,通常标在交易所当地零点。腾讯10月14日这根是北京时间14日0点,换成 UTC 是13日16点。图表库只按 UTC 显示时间,所以标成13日。用户电脑设成北京时间也没用。 用户截图发群里一句“你们日期都错了”,比什么 bug 报告都伤口碑。 修法:日K别喂时间戳,换成当地日期字符串 '2026-10-14' 再喂。 ② 三个市场放进一张图,同一天对不上 腾讯标在北京零点,苹果标在纽约零点,比特币标在 UTC 零点。放在同一条时间轴上,“10月14日”变成了三个点,腾讯那根还掉进了13日。 分钟K也一样。我取的15分钟K里,寒武纪第一根标09:45,腾讯第一根标09:30:A股标的是结束时刻,港股标的是开始时刻。两边各有一根“09:45”,管的是相邻的两段。 做联动分析、相关性、配对交易,最怕的就是这种错位。 修法:每个市场先换成各自的当地交易日,再对齐。另外得有人拍板:美股10月14日那一场在北京是14日晚上到15日凌晨,你的首页算它哪一天? 三、个股K线 ③ 涨是绿的,跌是红的 图表库默认绿涨红跌,这是欧美习惯。国内用户第一眼就会看反。 修法:按用户地区设涨跌色,K线和成交量柱一起改。 ④ 寒武纪除权那天,像是暴跌了36.7% 5月8日是寒武纪除权日。前一天收盘1,868元,当天收盘1,182.53元,不复权的图上断开一个大缺口。 前复权后,前一天收盘折算成1,252.68元,当天其实只跌了5.6%。不复权的话,均线、指标在这里都会失真,按涨跌幅设的提醒也会误报。 修法:看图用前复权。做回测记下复权方式,因为每次新的除权都会让前复权的历史价格整体变一次。 ⑤ 汇率6.69916,图上只剩6.70 图表库默认保留2位小数,股票够用,汇率不够。汇率一天的波动常在千分位,两位小数什么都看不出来。 修法:按品种设小数位,外汇5位,股票2位,低价港股3位。 四、盘中分时 ⑥ A股分时图从凌晨01:45开始 还是 UTC 显示的问题,到了分时图上更扎眼:09:45显示成01:45,15:00显示成07:00。 修法:用图表库的时间格式化选项,按交易所时区名显示:A股 Asia/Shanghai,美股 America/New_York。别写“加8小时”。 ⑦ 11月以后,美股时间错一小时 很多代码里写死了“美东加12小时就是北京时间”。夏令时是对的,11月1日以后要加13小时。 写死的话,开盘、收盘、“交易中”的判断全部早一小时。港股如果真延长交易时段,所有写死“16:00收盘”的地方也得改。 修法:时区换算用时区名,夏令时交给系统处理。交易时段从接口读,别写死在代码里,交易所改时间你也不用发版。 ⑧ 最后一根K线,看着像缩量六成 北京时间23:33打开苹果日K,最新一根成交量1,482万股,前一天3,898万股。其实是这根还没收盘,当天才交易了两个小时。 “放量缩量”、均线信号、价格提醒,都会被这根半成品带偏。拿它算策略信号,回测里看不出问题,实盘才出事。 修法:最后一根单独标“未完成”,颜色画浅一点;更新它用 series.update();指标和提醒只用已收盘的K线。 五、成交量和上线当天 ⑨ 寒武纪的量柱,只有腾讯的1/270 10月14日,寒武纪成交量73,781,单位是手;腾讯19,933,548,单位是股。直接画在一起,寒武纪的柱子几乎看不见。乘100换成股,是738万股,约为腾讯的37%。 修法:A股成交量乘100换成股。跨市场比活跃度,用成交额更稳。 ⑩ 日期跑到58709年,或者整张图白屏 这是上线当天最常见的两种“图没了”: 毫秒没转秒:接口时间戳一般是毫秒,图表库要秒。毫秒直接喂进去不报错,横轴写着“58709年”,所有K线挤在一角。 没按时间排序:图表库要求数据严格升序、不能重复。顺序一乱,整张图白屏,生产环境只报一句 Value is null,很难查。 顺带一个合规提醒:图表左下角那个小 logo 是开源许可要求的署名。嫌碍眼关掉的话,记得在页面别处补上 TradingView 的署名和链接。 修法:毫秒转秒、升序排序、去掉重复时间,三件事都放进喂数层。 六、上线前体检表 # 用户看到的 修法 ① 日K日期早一天 日K换成当地日期字符串 ② 三个市场同一天对不上 先换成各自交易日再对齐 ③ 涨跌颜色反了 按用户地区设颜色 ④ 除权日像暴跌 看图用前复权 ⑤ 汇率只剩两位小数 按品种设小数位 ⑥ 分时从01:45开始 按交易所时区名显示 ⑦ 冬令时后错一小时 时区名换算,时段从接口读 ⑧ 最后一根像缩量 标记未完成,不进指标 ⑨ A股量柱矮100倍 乘100换成股,或用成交额 ⑩ 58709年、白屏 毫秒转秒、升序去重、保留署名 七、怎么做:一个喂数层 10条修法都落在同一个地方:数据进图表之前。别在每个页面各修各的,写一个喂数层,所有K线都从这里过。 喂数层代码 这段代码用本文的真实数据在 Lightweight Charts 5.2.1 里跑通过: // feed.js:K线数据进图表之前,统一过这一层 const TZ = { CN: 'Asia/Shanghai', HK: 'Asia/Hong_Kong', US: 'America/New_York', CRYPTO: 'UTC', FX: 'UTC' }; const LOT = { CN: 100, HK: 1, US: 1, CRYPTO: 1, FX: 1 }; // A股成交量按手,乘100换成股 const DIGI = { CN: 2, HK: 2, US: 2, CRYPTO: 2, FX: 5 }; // 价格小数位,低价港股、个别品种单独覆盖 const dayOf = (ms, tz) => // 交易所当地日期 'YYYY-MM-DD' new Intl.DateTimeFormat('en-CA', { timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit' }) .format(new Date(ms)); function normalize(klines, { market, interval, lastIsForming = false }) { const tz = TZ[market]; const daily = /^(1d|1w|1M)$/.test(interval); const rows = klines .map(k => ({ ms: Number(k.time), o: +k.open, h: +k.high, l: +k.low, c: +k.close, v: +k.volume * LOT[market], amt: k.quote_volume == null ? null : +k.quote_volume })) .filter(r => Number.isFinite(r.ms) && Number.isFinite(r.c)) .sort((a, b) => a.ms - b.ms); // 不假设接口返回顺序 const out = []; for (const r of rows) { const time = daily ? dayOf(r.ms, tz) : Math.floor(r.ms / 1000); // 日K用日期,分钟K用秒 const bar = { time, open: r.o, high: r.h, low: r.l, close: r.c, volume: r.v, amount: r.amt }; if (out.length && out[out.length - 1].time === time) out[out.length - 1] = bar; // 重复时间保留后到的 else out.push(bar); } if (lastIsForming && out.length) out[out.length - 1].forming = true; // 未收盘,指标和提醒不用它 return out; } function chartOptions(market) { const tz = TZ[market]; const hm = new Intl.DateTimeFormat('zh-CN', { timeZone: tz, hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }); const ymd = new Intl.DateTimeFormat('zh-CN', { timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit' }); const fmt = t => typeof t === 'number' ? `${ymd.format(new Date(t * 1000))} ${hm.format(new Date(t * 1000))}` : t; return { layout: { attributionLogo: true }, // 保留署名,或在页面别处放 NOTICE 和链接 localization: { timeFormatter: fmt }, timeScale: { timeVisible: true, tickMarkFormatter: t => typeof t === 'number' ? hm.format(new Date(t * 1000)) : null }, }; } function seriesStyle(market, region = 'CN') { const [up, down] = region === 'CN' ? ['#e5484d', '#16a34a'] : ['#16a34a', '#e5484d']; const d = DIGI[market]; return { upColor: up, downColor: down, wickUpColor: up, wickDownColor: down, borderVisible: false, priceFormat: { type: 'price', precision: d, minMove: 10 ** -d } }; } function safeUpdate(series, bar) { // 推送乱序时,旧K线不回写 const last = series.data().at(-1); if (last && bar.time < last.time) return; // 日期字符串和秒数都能直接比大小 series.update(bar); } 用法: // resp:后端转发的K线接口返回,API Key 留在后端 const bars = normalize(resp.data.klines, { market: 'CN', interval: '1d', lastIsForming: true }); const chart = LightweightCharts.createChart(el, chartOptions('CN')); const candles = chart.addSeries(LightweightCharts.CandlestickSeries, seriesStyle('CN')); candles.setData(bars); 跨市场,最好只接一套接口 喂数层要按市场分支,这躲不掉,A股按手、港股按股是市场规则。但按数据源分支是可以躲掉的。如果A股、港股、美股、加密、外汇各接一家,每一家的时间戳格式、字段名、复权参数都要单独写一套转换,哪家一升级就可能出错。 TickDB 为开发者和 AI 应用提供统一的全球行情数据接口,让团队通过一套接入获取多市场实时与历史数据,更快构建行情、分析和监控产品。 本文的实验数据都来自 TickDB 的K线接口,和喂数层直接相关的有三点: A股、港股、美股、外汇、加密资产的K线是同一组字段,喂数层只需要按市场分支; 股票K线用 adjust 一个参数切换不复权、前复权、后复权; 交易时段有单独的接口,按市场返回当地时段,开收盘时间不用写死。 最后 打开你们的K线页面,把光标停在最新一根上,看看日期是不是今天;再找一只最近除过权的股票,看看除权那天。两分钟就能知道,第①④条你们中了没有。 港股延时还在讨论,美股冬令时还有两周多。交易时间会变,复权因子会变,这些变化都放在喂数层里处理,别散落在每一张图里。 参考资料 21世纪经济报道,[香港证监会:将就延长交易时段发讨论文件],2026-10-10 每日经济新闻,[港交所将就延长交易时段发表讨论文件],2026-10-12 TradingHours.com,[Nasdaq Trading Hours] TradingView,[Lightweight Charts™ version 5]
浏览26
评论0
收藏0
用户头像sh_*219t3e
2026-09-23 发布
亲测最好用的AI编写量化策略工具,可以让 AI 直接生成同花顺Supermind上可运行的策略代码,代码质量远高于直接使用 DeepSeek、GPT等平台。 😃Supermind AI工具入口:https://easyquant.ai/ 大家可以直接向AI描述策略,然后一键生成可运行的完整策略代码,也可以把它当做一个API 查询工具。
浏览416
评论11
收藏0
用户头像Fxdund
2026-10-14 发布
跨市场量化策略写了一半,发现美股数据用一个接口、A股用另一个、港股还得再申请一个;免费接口昨天还能跑,今天字段就变了;所谓"实时行情",实际延迟十几秒。个人做全球股票策略,最容易低估的不是策略难度,而是多市场数据源的工程成本决定了策略能跑多远。 这篇文章不堆接口名单,直接回答三个问题:历史回测用什么,盘中行情用什么,跨市场统一数据又该怎么搭。 先说结论:不要迷信"一个数据源包打天下" 个人开发者做全球股票,比较稳妥的方案不是找到一个万能API,而是按需求分层: 数据层 主要用途 适合的选择 历史研究层 日线、财务、指数成分、因子研究 本地数据库+免费历史接口 盘中行情层 实时快照、K线、跨市场比价 统一格式的实时行情API 交易验证层 持仓、委托、成交 券商交易接口 历史数据追求完整和可复现,实时数据追求延迟与稳定,交易数据必须以券商回报为准。 如果你只做日频选股,没必要为毫秒行情买单;如果策略依赖跨市场比价、盘口或实时资金流,免费网页数据再省钱也可能把策略做废。 常见全球股票数据源横向对比 数据源 覆盖市场 实时能力 接口稳定性 使用成本 更适合谁 Yahoo Finance 全球主要市场 较弱(延迟明显) 依赖网页,偶尔限流 低 学习、原型验证、低频分析 Alpha Vantage 美股为主 一般 较规范,但调用频率受限 免费额度有限 美股日频研究、入门项目 Tushare Pro A股为主 一般 较规范 按积分权限 A股因子研究、财务分析 AKShare A股+部分海外 一般 依赖上游网页 低 多市场探索、数据抓取 iTick 美股/A股/港股/日股/印股 较强 API化接入 需申请Token 跨市场策略、实时监控、多市场并行 这里没有绝对排名。数据源是否好用,取决于你的策略频率、市场范围、预算和容错能力。 只做日频选股和做跨市场实时比价讨论"哪个数据源最好",就像自行车和赛车讨论哪种轮胎最好,场景根本不同。 免费数据源:适合研究,不宜裸奔进生产 Yahoo Finance和AKShare这类免费源最大的优势是覆盖面广、上手快。股票、基金、指数都能在一个Python包里调用,很适合验证想法。 它们的不确定性也很明显:部分接口封装自公开网页,上游页面结构、参数或反爬策略发生变化,接口可能随之失效。Yahoo Finance的免费接口经常限流,高频调用会被封IP;AKShare的部分字段依赖网页解析,页面一改就挂。 适合它们的任务包括: 快速验证一个因子有没有研究价值 抓取低频公开数据做一次性分析 学习不同市场的代码格式和交易规则 不建议把单一免费接口直接放进无人值守的实盘链路。真要使用,至少要增加本地缓存、字段校验、异常告警和备用源。 免费的数据不一定便宜。你花三天修复字段变化,成本很可能已经超过一年的接口费用。 统一实时行情API:跨市场策略的工程解法 做跨市场策略的时候,最头疼的不是单市场数据拿不到,而是每个市场用一个接口,代码维护成本爆炸。美股用一个SDK,A股用另一个,港股还要再申请一个Token,时间戳格式不一样,字段命名不一样,出了问题都不知道查哪头。 统一实时行情API的思路是:用一套接口格式、一个认证Token,覆盖多个市场。看几个实际能力: import requests API_BASE = "https://api.itick.org" TOKEN = "your_token_here" headers = {"accept": "application/json", "token": TOKEN} # 同一份代码,换个region就能拿不同市场的数据 def get_quote(region, code): resp = requests.get( f"{API_BASE}/stock/quote", headers=headers, params={"region": region, "code": code} ) return resp.json()["data"] # 美股苹果 us = get_quote("US", "AAPL") # A股贵州茅台 cn = get_quote("CN", "600519") # 港股腾讯 hk = get_quote("HK", "00700") # 日股丰田 jp = get_quote("JP", "7203") # 印股Reliance in_ = get_quote("IN", "RELIANCE") print(f"美股AAPL: {us['ld']} ({us['chp']}%)") print(f"A股600519: {cn['ld']} ({cn['chp']}%)") print(f"港股00700: {hk['ld']} ({hk['chp']}%)") 同一份get_quote函数,换个region参数就能拿五个市场的数据。这种统一格式对跨市场策略开发来说,工程价值很大——不用维护五套代码,出了问题查一个接口就行。 WebSocket实时推送也是统一格式: import json 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": "AAPL$US,00700$HK", "types": "quote" })) return data = payload.get("data") or {} if data.get("type") == "quote": print(f"{data['s']}: {data['ld']} ({data['chp']}%)") ws = websocket.WebSocketApp(WS_URL, header=[f"token: {TOKEN}"], on_message=on_message) ws.run_forever() 一个WebSocket连接同时订阅美股和港股,不用维护两个连接。这种统一设计在做跨市场实时监控的时候特别省心。 注意几个容易踩的坑: 各市场代码格式不一样:美股是AAPL,A股是600519,港股是00700,日股是7203 印度股票订阅格式特殊,是三个参数:RELIANCE$NSE$IN 时间戳都是毫秒,直接当秒数处理会出错 交易时间不一样,美股晚上才开盘,做跨市场监控要注意时间窗口 不同策略到底应该怎么选 只做单市场日频选股和回测 推荐组合是免费历史接口加本地数据库(DuckDB、Parquet或PostgreSQL)。行情收盘后增量更新一次即可,不需要持续轮询实时接口。 预算非常有限时,用免费源建主库,再用实时API补充盘中数据。 做多市场对比和跨市场监控 这时候统一实时行情API的价值就出来了。历史数据可以用免费源,但盘中实时监控需要一个稳定、格式统一的接口。不然你美股用一个SDK、A股用另一个,代码维护成本会吃掉你做策略的时间。 做AH股溢价、中美比价这类跨市场价差策略 这类策略需要同时拿两个市场的实时价格,时间戳一致性很重要。用两个不同接口的数据,时间戳对不上,算出来的价差不准。统一接口的好处是两边的数据来自同一个服务,时间戳一致性好很多。 准备长期实盘 生产环境不要只有一个行情源。主数据源负责实时决策,备用数据源负责监控和故障切换,券商成交回报负责校准真实持仓。三个来源都不一致时,应暂停开仓,而不是猜哪个数字正确。 选型建议总结 预算接近零、还在学习阶段:用免费接口,先把研究流程和本地数据仓库跑通。 主要研究单市场日频因子和财务数据:用单市场的专业历史接口做研究主库,免费接口补充缺失字段。 做跨市场对比、AH溢价、多市场实时监控:重点测试统一格式的实时行情API,用历史主库补齐长期样本。 个人量化的数据源终极选型,不是选最贵的,也不是选接口最多的,而是选一个与你的策略频率匹配、能够被验证、发生故障时还能退出的系统。 数据决定回测是否可信,风控决定实盘能活多久。策略代码,反而常常是最容易的那一部分。 接口的具体参数和返回字段说明,可以参考官方文档对照着写,比自己猜参数靠谱多了。 GitHub:https://github.com/itick-org/
浏览41
评论0
收藏0
用户头像KAO普
2026-10-14 发布
一、策略思路 只做两只 ETF:进攻端用红利低波 ETF,防守端用十年期国债 ETF,二选一满仓持有,不做杠杆、不做空、不做日内。用日线级别的趋势信号判断该持有哪一边,T 日收盘出信号、T+1 开盘调仓,单边佣金万 0.5。 二、回测结果 指标 策略 基准(红利低波ETF) 累计收益 +366% +139% 年化收益 22.0% 12.4% 最大回撤 -14.2% -16.5% 卡玛比率 1.55 0.75 Beta 约 0.2 1.0 回测区间 2019-01 ~ 2026-10,初始资金 10 万,按不复权真实价格成交。 三、交易特征 7 年半只调仓 25 次,平均持有 103 天,年化换手不到 2 次——交易成本几乎可以忽略,也不用担心冲击成本。 13 次买入、12 次完整平仓,12 笔全部盈利,单笔收益 +8% ~ +19%。 持仓分布约 2/3 时间在红利低波 ETF、1/3 时间在国债 ETF,所以和宽基指数的相关性很低,适合当组合里的低波卫星仓位。
浏览38
评论0
收藏0
用户头像Jacktick
2026-10-14 发布
谷歌开放AI自建应用:让AI写跨市场行情App要过12关 让 AI 写一个跨市场行情面板只要两分半,模拟数据下一切正常;接上真实接口,第一屏全是“数据获取失败”。我用同一个 AI 写了5份行情代码:不给资料的3份,在适用的检查项里错了27处;先让它查一遍真实接口的2份,只错1处。这是一份让 AI 写行情 App 的全景指南,12道关,附提示词模板和自检脚本。 10月13日,谷歌宣布:美国18岁以上的用户,可以用 Google AI Studio 让 AI 做一个只给自己用的 App,直接通过 Google Play 运行;之后还能分享给信任的朋友,想公开上架,要先过安全审核。谷歌负责人的说法是,Play 商店要从“总有一个 App 适合这件事”变成“总有一个 App 是给我的”。 国内也一样热。证券时报9月28日报道,券商正在成批上线智能体;一家大模型公司给数十家头部金融机构的方案,把“权威数据源”放在了第一位。柯林斯词典早在2025年就把“vibe coding”(凭感觉写代码)选为年度词汇。 人人都能让 AI 写 App 了。可如果你让 AI 写的是一个行情 App,“只给自己用”也不安全,它算错的是你的钱。 我做了一个实验。同一个主流 AI 编程助手,三段老板、产品经理、个人投资者都会说的普通需求,一共写了5份行情代码: 不给任何资料的3份,对照真实接口逐项检查,适用的30项里错了27项; 写之前先让它通过 MCP 查一遍真实接口的2份,适用的20项里只错了1项。 不给资料的那3份,AI 在交付说明里都老老实实写着一句话:路径、参数、字段,“都是我猜的”。 AI 写得出能跑的行情 App,写不出知道自己在显示什么的行情 App。它缺的不是编程能力,是两样东西:你接的接口长什么样,行情数字背后的规则是什么。 这篇写给想用 AI 做行情产品的老板、产品经理和开发者,也写给想让 AI 帮自己写盯盘脚本的投资者。读完你能带走: 一次5份代码的对照实验,和三张没修饰过的截图 让 AI 写行情 App 要过的12道关:每一关 AI 会怎么写错、代价多大、提示词里该怎么写 一段复制即用的提示词模板 一段“接口事实卡”脚本:写代码前先把真实接口的事实取出来,贴给 AI 6件 AI 替你决定不了、必须人来拍板的事 一、一次实验:同一个AI,5份行情代码 不给资料,AI 靠“常见写法”猜接口;先查一遍真实接口,它几乎不犯低级错。 实验怎么做 我准备了三段需求,都是现实里最常见的说法: 编号 需求原话(节选) 谁会这么说 A “帮我写一个跨市场行情面板,3小时内要能上线给老板看……React 单文件,后端用 Flask 做个转发,能跑就行” 产品经理、外包团队 B “只要一个 HTML 文件,不要后端,双击打开就能看,今天下午要给老板演示” 赶时间的任何人 C “我是个人投资者,帮我用 Python 写一个盯盘脚本……算一下持仓市值和今日盈亏,统一换算成人民币” 个人投资者 六个品种和系列前两篇一致:A股寒武纪、港股腾讯、美股苹果、黄金、比特币、标普500。 每段需求先在“不给资料”的条件下写一遍(A0、B0、C0)。A 和 C 再在“先查接口”的条件下各写一遍(A1、C1):动笔前,让 AI 用 MCP 工具对每个品种实际调一次接口,同时给它一份官方接口要点。B 的场景是“双击就能看的单文件”,没有做第二轮。 结果:先查接口,错误从27处降到1处 我把每份代码对照2026年10月14日上午实测的真实接口返回,按12个检查项逐项判定: 几个数字: 不给资料:三份代码分别用了81、104、154秒写完,最长的778行。适用的检查项 A0 错10/12,B0 错10/10,C0 错7/8。 先查接口:两份代码用了237秒和319秒,只多花2到3分钟。A1 错1/12(价格转成了浮点数),C1 全对。 先查接口的两份代码,交付时各列了一串“需要你确认”的问题,比如“今日”按北京时间0点还是 UTC 0点算、美股夜盘算不算进盈亏。这些问题本来就该人来回答,第四部分细说。 三张截图:演示、接真接口、改对路径 我把 A0 的代码原样跑起来,分三步截图。真实数据是10月14日09:56通过接口取得的单次返回,按官方路径回放给它: 给老板演示时:一切正常。可价格是 AI 编的,寒武纪1,277元、比特币10.9万;右上角还弹出一条“黄金大跌2.79%”的提醒,同样是编的。 接上真实接口:每一行都是“数据获取失败”,AI 猜的快照路径根本不存在。这时页面左上角挂着一个“实时”标签。 只把路径和参数改对:价格出来了,问题也露出来了。成交量、成交额整列是“—”,买一卖一几乎全空;涨幅榜第一名是比特币,用的是滚动24小时的涨幅;苹果显示341.27美元,那是几个小时前的美股收盘价,页面上没有时间。 AI的行情常识停在哪一天 三份“不给资料”的代码都带了一套演示数据。AI 自己说这些数是随手编的,但它编出来的数,暴露了它的“常识”停在哪一天: 演示价格编错了,标个“模拟数据”就算了。真正危险的是 C0 写死的汇率:美元兑人民币7.10、港元兑人民币0.91,取不到实时汇率时就用它兜底。而当天真实的是6.6927和0.8527。 它猜的港元汇率代码在接口里不存在,所以港元会直接退回0.91,仅腾讯500股一项,持仓市值就多算约1.2万元。如果两个汇率都退回写死值,整个持仓(真实约115.99万元)会被高估约5.98万元,高5.2%。脚本不会报错,只会安静地显示一个更好看的数字。 二、全景地图:让AI写行情App要过的12关 12道关分三层:接得上、显示对、上得了线。AI 不给资料时,几乎每一关都会栽。 第一层决定代码能不能跑,第二层决定显示的数对不对,第三层决定敢不敢上线。第二层的8关,正好对应系列第一篇讲的“价格身份证”五格:品种、时段、算法、时间、状态。 下面每一关都按同一个顺序写:AI 不给资料时怎么写 → 真实接口是什么样 → 代价 → 提示词里怎么写。 第一层 接得上:接口路径、字段名、数字精度 ① 接口路径和参数 AI 怎么写:三份代码猜了三种路径,/quote、/quotes,还有直接请求根地址;A0 把参数写成单数 symbol,三份都没传资产类型。 真实接口:快照是 /ticker,参数是 symbols(逗号分隔,可批量)加 type。 代价:第一屏全部报错。更隐蔽的是不传资产类型:系列第一篇实测过,“000001”同时是平安银行和上证指数,接口会报歧义错误;换一家会替你猜的接口,你的自选里就会出现一个3,808元的“平安银行”。 提示词:“先调用真实接口,以返回为准,不要按常见写法猜路径和参数;每个品种写明资产类型。” ② 字段名 AI 怎么写:成交量按 volume、vol 取,成交额按 amount、turnover、quote_volume 取,涨跌幅按 change_pct 一类取。B0 和 C0 一口气列了七八个候选名,挨个试。 真实接口:volume_24h、quote_volume_24h、price_change_percent_24h。最新价 last_price 猜中了,这三个一个都没猜中。 代价:路径改对以后,这三列依然是“—”;涨跌幅取不到,AI 就自己拿前收重算,算法问题被藏得更深(见第⑤关)。 提示词:“字段名以真实返回为准;取不到的字段报错,不要用候选名挨个试。” ③ 数字精度 AI 怎么写:三份代码都把价格转成浮点数再算。 真实接口:价格、成交额都以字符串返回,比如 "4155.87000"、"83400.01000000",保留了数据源给的精度。 代价:显示一个价格时看不出来,一旦算持仓市值、累计成交额,浮点误差会一路带进报表和对账。先查接口的 A1 也栽在这一关,C1 用了十进制计算。 提示词:“价格和金额保留字符串,计算用十进制,不要直接转浮点数。” 第二层 显示对:单位、窗口、时段、时间、零值、盘口、K线、币种 ④ 成交量单位 AI 怎么写:成交量不带单位,统一按“万、亿”格式化。 真实接口:寒武纪的成交额÷成交量÷价格约等于100,成交量按手(100股)计;腾讯约等于1,按股计。先查接口的 A1 自己算出了这个比值,把A股成交量乘了100。 代价:A股成交额、换手率、大单筛选全部差100倍(系列第一篇返工点②)。 提示词:“每个市场的成交量写明单位;用成交额÷成交量÷价格自检。” ⑤ 涨跌幅窗口 AI 怎么写:用(现价−前收)÷前收自己算,涨幅榜直接混排,超过±2%就提醒。 真实接口:股票按当个交易日;比特币是滚动24小时;黄金没有官方收盘价,前收落在哪根K线要看数据源怎么切日。 代价:截图里涨幅榜第一名是比特币,它比的是“过去24小时”,其他品种比的是“今天”,名次没有可比性。系列第二篇实测过,同一刻同一个金价,涨跌可以是−0.69%,也可以是+0.24%,提醒一家响一家不响。 提示词:“每个涨跌幅标明窗口;跨市场排序或提醒前,先按同一个窗口重算。” ⑥ 美股时段 AI 怎么写:只读主快照的价格,忽略接口里的盘前、盘后、夜盘对象。 真实接口:北京时间上午,苹果主快照341.27美元,时间戳是凌晨4:00(美股收盘);同一份返回里还有夜盘价341美元,时间是一分钟前。 代价:用户把几个小时前的收盘价当成现价;首页和详情页对不上(系列第二篇场景④)。 提示词:“美股主快照与盘前、盘后、夜盘分开显示,各标时段。” ⑦ 数据时间 AI 怎么写:A0 的列表不显示行情时间;更危险的是一行兜底代码,返回里没有时间戳时,就用“现在”补上。 真实接口:每个快照都带毫秒时间戳,不同品种的时间可以差好几个小时。 代价:一条旧数据会被显示成刚刚更新。盯盘最怕的不是数据慢,是不知道它慢。 提示词:“界面显示每个数字的数据时间;没有时间戳就标‘时间未知’,不要用当前时间代替。” ⑧ 零和没有 AI 怎么写:B0 只过滤空值,标普500的买一卖一会显示成“0.0000”。A0 碰巧没出错:它的写法把“0”当成了空值,这是运气,不是设计。 真实接口:标普500的买价、卖价返回 "0.00000",成交量返回 "0.00"。指数没有买卖盘,这里的0意思是“没有”。 代价:中间价按(0+0)÷2算成0,指数估值归零;用价差做风控,价差变成0(系列第一篇返工点⑤)。 提示词:“对该品种不适用的字段,即使返回0也显示‘—’。” ⑨ 盘口档数 AI 怎么写:A0 请求盘口时写死 limit=5,前端最多画5档;它的演示数据里,标普500也有5档买卖盘。 真实接口:同一时刻,寒武纪5档、腾讯10档、苹果夜盘只有1档,指数没有盘口。 代价:港股深度丢一半;演示给老板看的,是一份根本不存在的指数盘口。用户照着假深度下单,是最贵的一种错(系列第一篇返工点⑦)。 提示词:“盘口按接口实际返回的档数画,不截断、不补档;不支持的市场写‘不支持’。” ⑩ K线时间戳 AI 怎么写:K线时间戳统一处理,最后一根不做标记。 真实接口:09:56查寒武纪5分钟K线,最后一根标着10:00,它还在走;A股K线标的是每根的结束时刻,港股标的是开始时刻(由返回结果推断)。先查接口的 A1 发现了这一点,把A股统一减了5分钟。 代价:A股和港股叠在一张图上错开一根;回测会提前用到5分钟后才有的数据。 提示词:“写明K线时间戳是开始还是结束,最后一根标‘未结束’。” ⑪ 币种与汇率 AI 怎么写:A0、B0 把人民币、港元、美元的成交额都格式化成“万、亿”,不标币种;C0 汇率取不到时用写死的7.10和0.91。 真实接口:当天美元兑人民币6.6927,港元兑人民币0.8527。先查接口的 C1 从接口取汇率,还发现港元汇率要换一个代码才取得到。 代价:前面算过,同一组持仓最多高估约5.98万元。 提示词:“不同币种不直接相加;汇率从接口取,取不到就报错,不用写死的数。” 第三层 上得了线:密钥、模拟数据、刷新频率 ⑫ 密钥与模拟数据 AI 怎么写:B0 按需求把 API Key 明文写进了 HTML(它自己提醒了:“把这个文件发给别人,就等于把 key 也给了别人”);接口连续失败3次,页面会自动切到模拟数据,只挂一条黄色横幅。A0 把 Key 放在服务端,模拟数据也挂了醒目标签,这一关做得对。 真实情况:GitGuardian 2026年的报告统计,2025年公开 GitHub 上新泄露的密钥约2,865万个,同比增长34%;带 AI 编程助手署名的提交,泄露比例约是平均水平的2倍。 代价:Key 被盗刷、额度被用光;更难发现的是“自动切到模拟数据”,演示时数字一直在跳,没人会想到它是假的。 提示词:“API Key 只放服务端或环境变量;没有真实数据时页面醒目标出‘模拟数据’,不自动切换。” 上线前还有两件事 AI 一般不会主动问:刷新频率和失败处理。B0 按需求每秒刷新一次;A0、B0 都提醒了要注意调用频率限制,但都说不清额度是多少。一个页面每秒打一次接口,多开几个标签页就可能触发限流,限流以后整页空白。请求频率、限额、失败后显示什么,要在上线前问清楚。 12关一张表 关 AI 不给资料时的典型写法 正确做法 对应前文 ① 接口路径和参数 猜/quote,不传资产类型 先查真实接口,写明类型 系列第一篇① ② 字段名 七八个候选名挨个试 以真实返回为准,取不到就报错 ③ 数字精度 转浮点数 字符串保留,十进制计算 ④ 成交量单位 不带单位 按市场写单位,比值自检 系列第一篇② ⑤ 涨跌幅窗口 自己重算,直接混排 标窗口,同窗口重算再排 系列第二篇 ⑥ 美股时段 只读主快照 各时段分开显示 系列第一篇③ ⑦ 数据时间 不显示,缺了用“现在”补 每个数字带时间 ⑧ “0”和“没有” 0照常显示 不适用显示“—” 系列第一篇⑤ ⑨ 盘口档数 写死5档,演示造档 按实际返回画 系列第一篇⑦ ⑩ K线时间戳 统一处理 标开始或结束,末根标未结束 系列第一篇⑥ ⑪ 币种与汇率 混币种、写死汇率 分币种,汇率从接口取 ⑫ 密钥与模拟数据 Key 写进前端,失败自动切模拟 Key 放服务端,模拟数据醒目标注 这张表就是上线前的体检清单:12项逐项打勾,打不上勾的那一项,就是上线后的第一个工单。 三、为什么AI会这样:它缺的是事实,不是能力 AI 没见过你的接口,只能按“常见写法”补全;行情规则不在任何通用知识里,它不知道要问。 它在猜,而且猜得很自信。这不是行情接口独有的毛病。美国三所大学的研究人员测试了16个代码生成模型,模型推荐的软件包里约19.7%根本不存在;商用模型约5.2%,开源模型约21.7%。AI 编出一个不存在的接口路径,和编出一个不存在的软件包,是同一种行为。 它的常识停在学习的那一天。价格、汇率、交易规则都在变。今年7月6日起A股多了一段15:05到15:30的盘后固定价格交易,11月1日美国结束夏令时,11月16日起港股开始统一每手股数。这些 AI 都可能不知道,前面那张“行情常识”表就是证据。 行情规则不在通用知识里。成交量按手还是按股、涨跌幅按哪个窗口、K线时间戳标开始还是结束,每个市场、每家数据源都不一样。AI 不知道这里有坑,也就不会问。 差一点就对最贵。Stack Overflow 2025年开发者调查:80%的开发者在工作中用 AI 工具,但信任 AI 准确性的只有29%;45%的人把“差一点就对的 AI 代码”列为头号烦恼,66%的人说花在修这类代码上的时间变多了。行情 App 恰恰是“差一点”的重灾区:页面能跑,数字看着合理,错在单位和窗口里。 安全问题不会自己消失。Veracode 2025年测试了100多个大模型、80个编程任务,45%的情况下 AI 写出的代码引入了安全漏洞,Java 的失败率超过70%。 这五条加起来,结论很简单:AI 缺的是事实,补上就好。补事实的办法也很简单:让它先查真实接口,再动笔。 四、正确姿势:先查、再写、人拍板 先让 AI 看到真实接口,再把行情规则写进提示词,最后用12项清单验收。定义类的问题,留给人。 1. 先查:让AI看到真实接口 两种做法,选一种: 你的 AI 工具支持 MCP:像实验里的 A1、C1 一样,在需求前加一句“先调用真实接口,看到返回再写代码”。AI 会自己调几次接口,把字段、单位、时段看一遍。 不支持 MCP:先跑一遍下面这段“接口事实卡”脚本,把输出贴进对话框。它只做一件事:把真实返回里和“价格身份证”有关的事实整理成 AI 能读的说明。 # 测试环境:Python 3.11 # 用途:写代码之前,先把真实接口的“事实”取一遍,生成一段可以直接贴给 AI 的说明 import os import sys import time from decimal import Decimal import requests API_KEY = os.getenv("TICKDB_API_KEY") # 只放在环境变量或服务端 BASE_URL = "https://api.tickdb.ai/v1/market" WATCHLIST = { # 资产类型逐个写明,不靠代码后缀猜 "688256.SH": "stock", "700.HK": "stock", "AAPL.US": "stock", "XAUUSD": "forex", "BTCUSDT": "crypto", "SPX": "indices", } WINDOW = {"stock": "当个交易日(美股为常规盘)", "forex": "按数据源切日,需确认切日时刻", "indices": "上一交易日收盘", "crypto": "滚动24小时"} def get_tickers(type_, symbols): resp = requests.get(f"{BASE_URL}/ticker", params={"symbols": ",".join(symbols), "type": type_}, headers={"X-API-Key": API_KEY}, timeout=10) body = resp.json() if resp.status_code != 200 or body.get("code") != 0: raise RuntimeError(f"{type_}: HTTP {resp.status_code}, code={body.get('code')}, {body.get('message')}") return body["data"] def is_zero(v): try: return Decimal(str(v)) == 0 except Exception: return False def facts(q, type_, now_ms): lines = [f"- {q['symbol']}(type={type_})"] lines.append(f" 返回字段:{', '.join(sorted(k for k in q if not isinstance(q[k], dict)))}") lines.append(f" 数值是字符串(如 last_price=\"{q.get('last_price')}\"),计算请用十进制,不要直接转浮点") lines.append(f" 涨跌幅字段 price_change_percent_24h=\"{q.get('price_change_percent_24h')}\"(已是百分数),窗口:{WINDOW[type_]}") age_h = (now_ms - q["timestamp"]) / 3_600_000 lines.append(f" 数据时间距现在 {age_h:.1f} 小时;界面必须显示数据时间,不要用当前时间代替") vol, amt, last = q.get("volume_24h"), q.get("quote_volume_24h"), q.get("last_price") if vol and amt and not is_zero(vol): ratio = Decimal(amt) / Decimal(vol) / Decimal(last) unit = "手(100股)" if ratio > 50 else "股或币" lines.append(f" 成交额÷成交量÷价格 ≈ {ratio:.1f} → 成交量单位推断为:{unit}(接入前以文档确认)") elif amt is None: lines.append(" 没有成交额字段:显示“—”,不要补0,也不要自己算") for k in ("bid_price", "ask_price", "volume_24h"): if k in q and is_zero(q[k]): lines.append(f" {k} 返回 \"{q[k]}\":对这个品种表示“没有”,显示“—”,不要显示0") if type_ == "stock" and "bid_price" not in q: lines.append(" 快照里没有买一卖一:需要另调盘口接口,或在界面上写明“无”") for k in ("pre_market_quote", "post_market_quote", "overnight_quote"): if k in q: sub = q[k] lines.append(f" {k}:last_done={sub.get('last_done')},前收={sub.get('prev_close')}," f"距现在 {(now_ms - sub['timestamp']) / 3_600_000:.1f} 小时;与主快照分开显示,各标时段") return lines def main(): if not API_KEY: sys.exit("请先设置环境变量 TICKDB_API_KEY") now_ms = int(time.time() * 1000) by_type = {} for sym, t in WATCHLIST.items(): by_type.setdefault(t, []).append(sym) print("【接口事实卡】以下内容来自真实接口返回,写代码时以此为准:") for t, syms in by_type.items(): got = {q["symbol"]: q for q in get_tickers(t, syms)} for sym in syms: if sym not in got: print(f"- {sym}:接口没有返回这个代码,先确认代码写法和资产类型") continue print("\n".join(facts(got[sym], t, now_ms))) if __name__ == "__main__": main() 用10月14日09:56的实测数据跑出来的结果(节选三个品种): 【接口事实卡】以下内容来自真实接口返回,写代码时以此为准: - 688256.SH(type=stock) 返回字段:category, high_24h, last_price, low_24h, name, open, prev_close, price_change_24h, price_change_percent_24h, quote_volume_24h, symbol, timestamp, type, volume_24h 数值是字符串(如 last_price="976.8"),计算请用十进制,不要直接转浮点 涨跌幅字段 price_change_percent_24h="0.03"(已是百分数),窗口:当个交易日(美股为常规盘) 数据时间距现在 0.0 小时;界面必须显示数据时间,不要用当前时间代替 成交额÷成交量÷价格 ≈ 99.5 → 成交量单位推断为:手(100股)(接入前以文档确认) 快照里没有买一卖一:需要另调盘口接口,或在界面上写明“无” - AAPL.US(type=stock) 返回字段:high_24h, last_price, low_24h, name, open, prev_close, price_change_24h, price_change_percent_24h, quote_volume_24h, symbol, timestamp, type, volume_24h 数值是字符串(如 last_price="341.27"),计算请用十进制,不要直接转浮点 涨跌幅字段 price_change_percent_24h="0.09"(已是百分数),窗口:当个交易日(美股为常规盘) 数据时间距现在 5.9 小时;界面必须显示数据时间,不要用当前时间代替 成交额÷成交量÷价格 ≈ 1.0 → 成交量单位推断为:股或币(接入前以文档确认) 快照里没有买一卖一:需要另调盘口接口,或在界面上写明“无” pre_market_quote:last_done=345.27,前收=340.97,距现在 12.4 小时;与主快照分开显示,各标时段 post_market_quote:last_done=340.311,前收=341.27,距现在 1.9 小时;与主快照分开显示,各标时段 overnight_quote:last_done=341,前收=341.27,距现在 0.0 小时;与主快照分开显示,各标时段 - SPX(type=indices) 返回字段:ask_price, bid_price, high_24h, last_price, low_24h, name, open, prev_close, price_change_24h, price_change_percent_24h, symbol, timestamp, type, volume_24h 数值是字符串(如 last_price="7805.45000"),计算请用十进制,不要直接转浮点 涨跌幅字段 price_change_percent_24h="-0.02"(已是百分数),窗口:上一交易日收盘 数据时间距现在 0.0 小时;界面必须显示数据时间,不要用当前时间代替 没有成交额字段:显示“—”,不要补0,也不要自己算 bid_price 返回 "0.00000":对这个品种表示“没有”,显示“—”,不要显示0 ask_price 返回 "0.00000":对这个品种表示“没有”,显示“—”,不要显示0 volume_24h 返回 "0.00":对这个品种表示“没有”,显示“—”,不要显示0 这几行就是 AI 最缺的东西:成交量单位、数据时间、哪些0其实是“没有”、美股的时段对象。把它贴在需求前面,第一层的三关和第二层的大半关卡,AI 就有了依据。 2. 写规则:复制即用的提示词模板 查到的是事实,规则还得你告诉它。下面这段模板,每一条都对应实验里 AI 实际犯过的一个错,放在需求前面一起发: 你要写一个跨市场行情应用。动手前先做两件事: 1. 先调用真实接口(MCP 工具,或我贴给你的“接口事实卡”),以真实返回为准,不要按常见写法猜路径、参数和字段名。 2. 不确定的定义先列出来问我,不要自己编。 写代码时遵守: - 每个数字同时带上单位、涨跌窗口(当日 / 滚动24小时 / 切日时刻)和数据时间。 - 价格和金额保留字符串或用十进制计算,不要直接转成浮点数。 - 接口没返回、或返回0但对该品种不适用的字段,显示“—”,不补0,不编造。 - 美股主快照与盘前、盘后、夜盘分开显示,各标时段。 - 盘口按接口实际返回的档数画,不截断、不补档;不支持的市场写“不支持”。 - K线写明时间戳是开始还是结束,最后一根标“未结束”。 - 不同币种不直接相加;汇率从接口取,取不到就报错,不用写死的数。 - 跨市场排序或提醒前,先把涨跌幅按同一个窗口重算。 - API Key 只放服务端或环境变量;没有真实数据时页面必须醒目标出“模拟数据”,不自动切换。 3. 验收:12项体检,6件事人来拍板 代码写完,按第二部分那张表逐项打勾。还有6件事,AI 查了接口也替你决定不了。先查接口的两份代码,交付时都主动列出了这些问题: 今日怎么算:北京时间0点、UTC 0点、纽约17:00,还是滚动24小时? 美股盘后和夜盘算不算:涨跌、市值和提醒用常规盘,还是用最新的延长时段价格? 稳定币怎么换算:USDT 是否按1美元算? 提醒规则:跨过阈值提醒一次,还是每次刷新都提醒?用哪个窗口的涨跌幅? 汇率怎么取:多币种汇总用哪个汇率、哪个时点? A股除权日:前收用不用除权参考价(系列第二篇场景③)? 这6件事没有标准答案,但必须有人定、写进文档、显示在界面上。 4. 跨市场为什么更需要统一接口 只做A股,AI 要猜一套字段;做跨市场,如果每个市场各接一家数据源,AI 要猜的是好几套:路径不同、字段名不同、时间戳格式不同、前收的定义不同。实验里不给资料的 AI,光是成交额一个字段就列了七八个候选名,这还只是假设只有一家数据源。 数据源越多,AI 越容易猜错,你要写的“接口事实卡”也越长。规则还在变,每变一次,每一家都得重新核对。所以用 AI 做跨市场行情 App,省事的做法是一套接口覆盖所有市场:AI 只需要学一套字段,事实卡只需要一份,提示词里的规则只需要写一次。 5. 本文实验怎么用的数据接口 TickDB 通过 Skill、MCP、CLI 和 API 为 AI 工具提供结构化市场数据,让模型先取得带标的、字段和时间的事实,再进行分析与表达。 本文“先查接口”那一轮,AI 就是通过 MCP 直接调用它的接口,在写代码前看到了6个品种的真实返回: 能做到 要你自己定 支持 MCP 的 AI 工具可以直接调用接口,写代码前先看到真实字段和数值 上面6件需要拍板的事,接口给不了答案 A股、港股、美股、外汇贵金属、指数、加密资产的快照用同一组字段返回现价、前收和时间戳,AI 只需要学一套 成交量单位、K线时间戳含义,本文由返回结果推断,接入前以文档确认 美股快照里盘前、盘后、夜盘分成独立对象,各带价格和时间;代码有歧义时返回错误,不替你猜 不同套餐的能力不同,盘口、逐笔等以账户权限为准 左边是这次实验能证明的,右边是任何数据源都替代不了的判断。(作者实测,2026年10月13日至14日。) 常见问题 AI写的行情App能直接上线吗? 不建议。本文实验里,不给资料的3份 AI 代码在模拟数据下都能跑,但对照真实接口,适用的30个检查项错了27个,错在接口路径、字段名、成交量单位、涨跌窗口、美股时段等地方。上线前至少做两件事:让 AI 先查真实接口再写,写完按12项清单逐项检查。 让AI写行情代码的提示词怎么写? 最重要的一句是“先调用真实接口,以返回为准,不要按常见写法猜”。然后把行情规则写成约束:每个数字带单位、涨跌窗口和数据时间;不适用的字段显示“—”不补0;美股各时段分开显示;盘口按实际档数画;汇率从接口取;Key 只放服务端。完整模板见第四部分。 AI为什么会编造接口路径和字段名? 因为它没见过你用的接口,只能按训练时见过的“常见写法”补全。学术研究发现,代码模型推荐的软件包里约两成根本不存在,编造接口是同一类问题。解决办法是写代码前先让它看到真实返回:用支持 MCP 的工具直接调接口,或者把接口的真实返回贴给它。 用AI写行情App时API Key放在哪里? 放在服务端或环境变量里,不要写进前端页面。本文实验中,需求要求“只要一个 HTML 文件、不要后端”时,AI 把 Key 明文写进了页面,只附了一句提醒。GitGuardian 的统计显示,带 AI 编程助手署名的代码提交,泄露密钥的比例约是平均水平的2倍。 跨市场行情App用几家数据源合适? 能用一家覆盖就用一家。每多一家数据源,AI 就要多猜一套路径、字段和时间格式,你要核对的规则也多一套;规则变化时,每一家都要重新检查。用一套接口覆盖多个市场,AI 的事实卡和提示词都只需要写一份。 最后一个问题 你们现在用 AI 写的那个行情页面,能说出每个数字的单位、窗口和时间吗? 今天就能做的一件事:把你的需求原封不动发给 AI 之前,先加一句“先调用真实接口,看到返回再写代码”。实验里,这一句只多花了2到3分钟,省掉的是第一屏的全部报错。 AI 写得出能跑的行情 App。让它知道自己在显示什么,是你的事。 参考资料 TechCrunch,[Google Play now lets anyone build private, vibe-coded apps that run on Android],2026-10-13 证券时报(中证网转载),[智能体浪潮席卷证券业 券商AI转型从单点增效迈向体系重构],2026-09-28 CNN(经 KRDO 转载),[“Vibe coding” named Collins Dictionary’s word of the year],2025-11-06 GitGuardian,[The State of Secrets Sprawl Report 2026] Stack Overflow,[2025 Developer Survey results],2025-07-29 Veracode,[2025 GenAI Code Security Report 新闻稿],2025-07-30 Spracklen 等,[We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs];CSO Online 相关报道
浏览68
评论0
收藏0