全部
文章&策略
学习干货
问答
官方
用户头像sh_**729dg0
2026-09-08 发布
A股Level2毫秒行情数据到底长啥样?逐笔成交、委托、十档盘口一探究竟 我以前一直以为Level2就是多了几档挂单,直到自己跑数据才发现,Tick级别的世界和分钟线完全不是一个物种。这里把数据拆开,就事论事,聊聊字段和坑。 逐笔成交(Tick Transaction) 这个表记录的是每一笔实际发生的成交,不是切片,是真正的“过一笔记一笔”。字段大概长这样: 字段名 说明 备注 代码 证券代码 6位数字 时间 精确到毫秒 格式HHMMSSmmm 价格 成交价 单位:元 成交量 股数 手数要自己除100 成交额 元 通常直接给 买卖方向 B/S 主动买/主动卖,部分数据源可能还有个中性 成交序号 全局唯一标识 按天滚动 我拿到数据第一反应是去看那些大单打出来的时候,盘口瞬间被吃掉几档,那种感觉就跟看游戏里的伤害飘字一样。不过扫数据的时候很容易把买卖方向搞反,因为不同的数据源B和S的定义可能有细微差异,这里用了数据源:CMES金融数据库的历史十年的level2数据回测了一下。 逐笔委托(Tick Order) 这个很多人会搞混,它记录的是每一笔申报进入交易所撮合引擎的委托,不是成交。你看到的挂单变化,就是这些委托堆出来的。关键字段: 字段 含义 注意 委托时间 毫秒级 可能是交易所收到时间 委托序号 对应委托编号 可以和成交表关联 委托类型 1买/2卖 有些数据源用01/02 委托价格 申报价 市价单可能为0或者999999 委托量 股数 原始申报量 撤单标志 0正常/1撤单 如果这笔委托后来撤了 我经常用这个表去还原盘口的挂单队列,但说实话,就算有数据,要准确模拟撮合规则还是很难,因为交易所的规则细节太多,只能做近似。另外,逐笔委托的数据量比成交还要大好几倍,一天几千万行,处理起来电脑风扇直接起飞。 有时候跑这种数据,我会直接用现成的接口,省的自己扒文件。比如像下面这样,几行代码就能把数据拉下来,不过调用频率要注意,别太频繁被限制: # 安装方法:pip install cmesdata -i https://pypi.org/simple # 具体版本和文档见:https://cmes-data.com/download.html?type=vip from cmesdata import CMESDataAPI # 初始化CMES金融数据库的行情接口,注意入参正确,调用频率正常 api = CMESDataAPI(api_key="your_key_here") # 获取逐笔成交数据,参数要严格按文档来,日期格式别搞错 trade_data = api.get_tick_transaction( symbol="000001.SZ", trade_date="20250320", start_time="093000", end_time="150000" ) print(trade_data.head()) 上面的代码只是示例,实际用的时候记得把key换成自己的,而且每次请求的数据量不要太大,建议分时段拉取,否则容易超时。 十档行情(Level2 Market Depth) 十档行情就是买卖各10档的挂单快照,关键它还是推送式的,每3秒一个快照(深交所可能更频繁),但有些字段是毫秒更新的。这个表和上面的逐笔委托结合起来,可以大概看出盘口变化的节奏。 字段 说明 更新时间 快照时间戳 买1-买10价 价格 买1-买10量 委托量 卖1-卖10价 价格 卖1-卖10量 委托量 总买量/总卖量 部分数据源提供 加权均价 部分提供 我本来以为十档行情能直接用来做高频策略,后来发现快照之间有延迟,而且频繁的挂撤单根本反映不出来,真正能捕捉到那种微妙变化的,还是得靠逐笔委托去拼。十档行情更适合做静态的盘口深度分析,或者配合k线观察阻力位。 数据更新频率和文件大小 这个数据源声称每日更新,毫秒级别。但实际我下载的时候,发现有些交易日的数据会延迟到晚上8点后才全部落库,所以做日内策略的话,实时性得自己评估。文件大小方面,单只股票一天三个表加起来压缩后大概几百兆,解压后几个G,硬盘小的同志谨慎。 一句话感想 这种行情数据比想象中要“脏”,很多字段需要自己清洗,而且不同交易所的格式还不完全一致。如果你只是想看盘口,十档就够了;想做事件驱动,优先看逐笔成交;想挖得更深,那逐笔委托和十档联动才是王道。至于怎么联动,网上教程一堆,但真正跑通的人很少,因为数据太大,每一步都卡。
浏览11
评论0
收藏0
用户头像sh_*219t3e
2026-09-08 发布
面上的 DS、豆包等工具好很多。 👉 SuperMind AI量化代码生成平台 这个工具最大的特点是直接和 AI 对话就能生成完整可运行的Supermind量化策略代码。你不需要懂 Python、C# 或策略 API,只要用自然语言描述你的交易逻辑,比如:“当5日均线向上突破20日均线时买入,反向时卖出。” AI 就会自动帮你生成完整策略代码,并能直接在平台上运行。 相比于通用大模型的输出,这个平台针对量化交易进行了专门优化生成的代码结构更清晰,逻辑更准确,对策略逻辑的理解更接近量化开发者的思路,并且可用作 API 查询或策略自动生成工具 之前上线后,很多朋友反馈代码质量和可运行性都非常高,几乎不需要再手动修改。现在我们的AI量化代码生成平台已经全面支持 Supermind,你可以直接体验。如果你之前在用 DS、豆包等平台,不妨试试看这个版本,可能会刷新你对AI 写量化策略的想象。
浏览45
评论0
收藏0
用户头像sh_***174w0d
2026-09-08 发布
引言:被忽视的“买卖博弈”指标 想要精通市场交易的微观结构,必须学会穿透 K 线的表象。在股市中,大多数普通股民的目光往往被股价的红绿跳动紧紧锁住,看到飘红就盲目乐观,看到变绿就惊慌失措。然而,这种只看结果而忽略底层成交逻辑的做法,往往让投资者陷入陷阱:为什么有时候明明买的人很多(外盘大),股价却在阴跌? 作为投资者,如果你想真正洞察主力资金的底牌,就必须使用“显微镜”去观察——这就是“内外盘”指标。它揭示了买卖双方在特定价格上的博弈真相,是解读主力行为的关键密码。 核心概念:房子里的博弈论 在进入实战分析前,作为一名金融分析师,我首先要为你正本清源。内外盘并非简单的买卖统计,其核心在于主动性: ●内盘(Inside Disk): 标志为绿色,代表主动性卖出。它是指以“买入价”(Bid Price,委买价)直接成交的成交量。内盘大,说明空方急于离场,不惜在更低的价格主动成交。 ●外盘(Outside Disk): 标志为红色*,代表主动性买入。它是指以“卖出价”(Ask Price,委卖价)直接成交的成交量。外盘大,说明多方急于介入,愿意支付更高的价格。 为了让大家更形象地理解,我们可以借用源材料中的“房子”比喻: “这两个单词可厉害了,它说明买卖双方都认为对方是傻瓜。内盘的意思就是里面的人想出去,外盘就是外面的人想进来。” 顺势而为:量价齐升的理想形态 在健康的交易环境中,内外盘通常遵循基本的供需逻辑。我们要关注以下三种常态: ●**外盘明显小于内盘,且放量下跌: 这是市场中最常见的看跌信号**。内盘激增说明主动抛售欲望极强,主力正在不计成本地果断出货。此时不应抱有幻想,离场是保护资金的最佳选择。 ●**外盘远大于内盘,且量价齐升: 当主动性买入远超卖出,且伴随成交量放大和价格上涨,说明市场处于典型的供不应求**状态,股价往往会顺势开启主升浪。 ●**平衡态(内外盘相当): 当“想进来的”和“想出去的”力量达到动态平衡,股价通常进入横盘震荡**期,此时应持币观望。 深度反直觉(一):底部区域的打压吸筹 实战中,高手往往能识别出“反逻辑”的信号。最典型的情况是:外盘大于内盘,但股价不涨反跌。 按照常规逻辑,买气足应涨价,但不涨反跌说明“不按套路出牌”。这通常发生在低位区域,是主力在故意“做妖”。主力利用手中的筹码对敲打压,营造恐慌气氛,迫使意志不坚定者交出廉价筹码,而自己在低位默默吸收。这种现象被称为打压吸筹,看清这一点,你才能从止损的盲从者转变为跟随主力的获利者。 深度反直觉(二):高位拉升的“诱多”陷阱 另一种极度危险的背离是:内盘远大于外盘,股价却在上涨。 这种现象通常发生在股价已有一段涨幅后。明明想卖的人更多,股价却反直觉拉升,这往往是主力的诱多行为。主力通过少量资金对敲拉高股价吸引眼球,实则在上方挂单、下方撤单,边拉边卖。这是一种虚假繁荣,其本质是主力为了出货而掩人耳目。此时的策略只有一个字:溜。 沉默的真相:缩量与高度控盘 当内外盘都只有极小的成交量,且成交量持续萎缩时,我们必须通过历史走势来定性: ●无人问津的“僵尸股”: 如果该股已长时间下跌且缺乏波动,说明市场人气丧失,既没人买也没人卖。 **●**主力高度控盘: 股价在经历过放量拉升后,在高位或中位缩量震荡,说明大部分筹码已被主力锁定,随时可能发动二次进攻。 【高级导师 Pro Tip】: 判别方法很简单——如果股价在长期阴跌后缩量,大概率是僵尸股;如果股价在近期放量大涨后,缩量却能横盘守住价格,则是高度控盘**的标志,应“多看少动”,等待放量突破的瞬间。 进阶口诀:内外盘实战的“位置决定论” 为了帮助大家快速记忆,我整理了一套实战口诀。请注意,所有的口诀必须结合股价的高低位置来运用: **●**外盘偏大,股价看涨 **●**内盘偏大,股价看跌 ●**外大价跌,主力出逃(注:此句特指高位区域**,主力借外盘大、人气高的假象掩护撤退;若在低位则参考前文的吸筹逻辑) ●**内大价涨,主力吸筹(注:这代表主力在以更低的价格“偷偷买入”,即隐藏买盘**,是典型的反向吸筹形态) 总结与反思:指标背后的“人心” 内外盘不是孤立的数据,它是人性贪婪与恐惧的实时映射。作为一名理性的投资者,你绝不能仅仅盯着数值的绝对大小。 总结一句话:必须结合股价近期走势是否处于低位来综合研判。 指标是死的,但其背后的博弈是活的。 财富智慧交流: 在你的股市生涯中,是否也曾被“外盘巨大却股价暴跌”的情况深度“套路”过?你是如何看透红绿表象,识别出主力真实意图的?欢迎在评论区分享你最深刻的一段实战反思,我们一起穿透迷雾,看清本质。
浏览34
评论0
收藏0
用户头像sh_*2176oo
2026-09-08 发布
一句话回答: A 股、美股、港股的休市日不一样(国庆 A 股休、感恩节美股休……),直接把两地价格按行号并排就会错位,算出来的相关性全是假的。正确做法是用 AlphaFeed 分别取各市场 K 线、从数据本身推导真实交易日历,再按交易日交集对齐后计算——几行 pandas 就能做对。 为什么会有这个问题 跨市场做联动、对冲、相关性时,最常见的错误是"两个序列长度不同就截齐、或直接 reset_index 后相减"。但: A 股独有假期:春节、国庆长假期间 A 股休市,美股照常。 美股独有假期:感恩节、马丁·路德·金日、阵亡将士纪念日等,A 股照常。 港股又是一套:兼有内地与西方假期。 不对齐日历,收益率序列会整体"串行",相关系数、beta、价差都不可信。 分步骤解决 第 1 步:分别取各市场 K 线,推导交易日历 AlphaFeed 的 K 线里 trade_date 就是该市场的真实交易日(有数据=当天开市),据此直接得到各市场日历: from alphafeed import AlphaFeed import pandas as pd af = AlphaFeed() # 读取 ALPHAFEED_API_KEY a = af.klines.get("600519.SH", period="1d", count=250, to_dataframe=True) # A 股 us = af.klines.get("AAPL.US", period="1d", count=250, to_dataframe=True) # 美股 hk = af.klines.get("00700.HK", period="1d", count=250, to_dataframe=True) # 港股 cal_a, cal_us, cal_hk = set(a["trade_date"]), set(us["trade_date"]), set(hk["trade_date"]) print("A 交易日:", len(cal_a), "US:", len(cal_us), "HK:", len(cal_hk)) 各市场 count=250 覆盖的自然时间范围不同(因为休市日不同),所以下一步要先裁到共同区间再比较。 第 2 步:裁到共同区间,看日历差异 lo = max(min(cal_a), min(cal_us), min(cal_hk)) hi = min(max(cal_a), max(cal_us), max(cal_hk)) fa = {d for d in cal_a if lo <= d <= hi} fu = {d for d in cal_us if lo <= d <= hi} print("A 开市但美股休市:", sorted(fa - fu)[:6]) print("美股开市但 A 股休市:", sorted(fu - fa)[:6]) 实测(约一年窗口)差异样例: 差异类型 数量(示例窗口) 典型日期 原因 A 开市 / 美股休 6 11-27、12-25、01-19、04-03 感恩节、圣诞、MLK 日、耶稣受难日 美股开市 / A 股休 16 10-01~10-08 A 股国庆长假 三地共同交易日 230 — 用于跨市场对齐的可靠集合 第 3 步:用交易日交集对齐后再计算 不要按行号对齐,要按 trade_date inner join(交集),只在两地都开市的日子比较: la = a[["trade_date", "close"]].rename(columns={"close": "a_close"}) lu = us[["trade_date", "close"]].rename(columns={"close": "us_close"}) merged = pd.merge(la, lu, on="trade_date", how="inner").sort_values("trade_date") merged["a_ret"] = merged["a_close"].pct_change() merged["us_ret"] = merged["us_close"].pct_change() corr = merged[["a_ret", "us_ret"]].dropna().corr().iloc[0, 1] print(f"共同交易日: {len(merged)} A/US 日收益相关系数: {corr:.3f}") 关键点:how="inner" 自动丢掉任一方休市的日子,剩下的才是可比的同步样本。 第 4 步:注意"隔夜时差"——是否要错位一天 A 股白天收盘时,美股尚未开盘(当日美股是北京时间当晚才交易)。研究"美股隔夜 → 次日 A 股"的传导时,应把美股收益滞后一天再对齐: merged["us_ret_lag1"] = merged["us_ret"].shift(1) # 昨夜美股 -> 今日A股 lead = merged[["a_ret", "us_ret_lag1"]].dropna().corr().iloc[0, 1] print(f"昨夜美股 vs 今日A股 相关: {lead:.3f}") 是否错位取决于你的研究问题:同步联动用当日对齐,跨市场传导/择时用滞后对齐。别把两者混为一谈。 关键坑与注意事项 不要按行号/长度截齐:各市场交易日不同,行号对齐必然错位。永远按 trade_date join。 trade_date 是各市场的本地交易日:无需自己维护假期表,有 K 线数据的那天就是开市日。 时区:日线用本地交易日对齐即可;只有做分钟级跨市场同步时才需要把 timestamp(毫秒 UTC)转到统一时区处理。 停牌 vs 休市:个股停牌(volume=0)与整个市场休市不同,跨市场对齐用指数/宽基或多只票求并集更稳。 美股/港股 K 线 amount=0(用 volume),跨市场比成交额时要注意口径。 常见问题(FAQ) Q:我需要自己维护各国交易日历吗? A:不用。AlphaFeed K 线的 trade_date 就是该市场真实开市日,直接从数据推导日历、取交集即可。 Q:为什么两地 count=250 拿回来日期对不齐? A:因为休市日不同,同样 250 根 K 线覆盖的自然日区间不同。先裁到共同区间 [lo, hi] 再比较。 Q:算相关性该用当日还是滞后对齐? A:研究同步联动用当日 inner join;研究"隔夜传导/择时信号"把先行市场收益 shift(1) 再对齐。 Q:需要付费吗? A:跨市场 K 线(A/美/港)属基础能力,有免费额度;大规模批量与全市场池见 Starter 及以上,详见定价页。 小结 跨市场分析的第一道坎不是模型,而是交易日历对齐。用 AlphaFeed 各市场 K 线的 trade_date 推导真实日历、按交易日交集 inner join,再决定是否按隔夜时差错位一天——把对齐做对,相关性、beta、价差才可信。 参考 AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
浏览24
评论0
收藏0
用户头像9点半量化
2026-09-08 发布
引言:为什么“不买”比“买什么”更重要 在股市中,很多散户投资者常常陷入一种无效的勤奋:每天废寝忘食地研究基本面、死守盯盘,却依然在“踩雷”和亏损中挣扎。其实,作为一个在市场摸爬滚打多年的策略分析师,我始终认为:投资的第一法则是生存。 在复杂的交易博弈中,识别并避开那些高风险的“必亏”标的,其重要性远超寻找所谓的翻倍黑马。学会在诱惑面前保持空仓,不仅是一种境界,更是保护你辛苦钱的铁律。 第一类:深陷下降通道的“自由落体” 趋势的形成绝非偶然,它是市场中多重因素产生共振并形成合力后的结果。我常说,趋势一旦形成就不容易改变,就像高速下行的列车,试图去挡住它只会粉身碎骨。 判定标准: 如果股价长时间运行在 **10 ****日、**20 日均线下方,且波动的高点和低点都在不断下移,反弹力度一波比一波弱。 深度警示: 散户最容易产生的错觉是“跌得够多了,该反弹了”。但在下降趋势中,股价会不断创出新低。 专业建议: 必须等到明显的“起稳迹象”出现——例如均线开始走平并粘合、小阳线比例增多、底部起稳平台真正走出。在此之前,任何抄底都是在接下落的飞刀。 “下跌趋势不言底,上涨趋势不言顶。在趋势面前,不要用主观臆断挑战市场规律。” 第二类:趋势破位,尤其是“主跌三浪” 趋势一旦破位,意味着原有的支撑逻辑彻底瓦解。在技术派眼中,最致命的陷阱就是“主跌三浪”的开启。 技术逻辑: 在一个标准的下跌序列中,经历了一浪初跌和二浪微弱反弹后,当第三浪正式破位下行时,才是杀伤力最惊人的阶段。 风险警告: 主跌三浪通常跌幅最大、速度最快,也是大部分散户账户被腰斩甚至清零的区域。如果三浪正在途中或刚刚开启,切记:绝不可入场捡便宜。 第三类:毫无波动的“心电图”僵尸股 有些股票的分时走势非常诡异,全天几乎没有起伏,看起来就像一条平直的“心电图”。 特征识别: 分时图波动极微,换手率常年在 0.5% 左右。 深度反思: 这种走势通常出现在“四大行”这种超大盘股中,这尚属正常;但如果一个小盘股走出这种“心电图”,说明该股已彻底被市场抛弃。 致命伤: 这类股没有震荡差价,你进去可能连手续费都赚不回来。更可怕的是它消耗了你的时间成本——在股市中,资金的周转率就是生命,被僵尸股锁死资产是极大的资源浪费。 第四类:大股东减持的“接盘陷阱” 大股东公告减持,是公司内部人对自家股票价值的变相“投低票”。 心理博弈: 减持的借口可以有千百种,但动作只有一个:真金白银的卖出离场。 大股东离场意味着大笔筹码将直接砸向二级市场,如果没有相应量级的大资金接盘,散户那点资金量根本挡不住抛压。 核心准则: 大股东减持会严重打击市场信心。记住,作为投资者,不要听他们嘴上说得多么冠冕堂皇,要看他们实际是怎么操作资金的。 别去做那个承接抛盘的“接盘侠”。 第五类:利好兑现后的“见光死” 散户最爱追利好,而主力最爱借利好出货。 逻辑拆解: 市场炒作的是“预期”。当利好还在预期阶段时,股价往往已经提前拉升到目标位。 策略启发: “当一个利好已经是全世界都知道的秘密时,它还有价值吗?” 当利好真正落地之日,往往就是主力资金利用热度派发筹码、功成身退之时。这类股票在消息公布瞬间,往往就是股价的阶段性顶峰。 第六类:股东人数激增的“筹码散乱” 个股的股本是固定的,股东人数的变化本质上反映了筹码的流向:是从庄家手中流向散户,还是反之。 筹码分配逻辑: 股东人数突然大幅增加,说明主力已经成功把手中的大额筹码,拆散并派发给了无数的小散户。 ●筹码状态:高度集中 股东人数:股东人数少,多为“强力手”持有 市场表现:控盘度高,易形成合力,能走出独立行情 ●筹码状态:极端分散 股东人数:股东人数激增,多为“弱势手”持有 市场表现:人心不齐,拉升时抛压巨大,极难形成合力 结论: 筹码越分散的票,越难产生上涨共振,也就越没有参与价值。 第七类:无业绩、无题材的“三无股票” 在股市赚钱通常只有两条路:要么赚公司成长的钱(业绩),要么赚未来愿景的钱(题材)。 流动性陷阱: 如果一家公司既没业绩支撑,又讲不出题材故事,这就是典型的“三无股票”。 结局预测: 没有业绩,随时面临退市风险;没有题材,主力根本不会花大价钱去推升股价。即使主力硬拉,由于缺乏故事吸引散户**“接货”****,最终筹码还是会砸在主力自己手里。** 所以,这类股既拿不住,也没盼头。 结语:构建你的交易防线 作为一名策略师,我最后想送给大家一句话:在股市中,学会“忍耐”和“克制”远比学会“进攻”更难。避开这 7 种“地雷”股,是构建成熟交易体系的基石。 空仓观望并不可耻,盲目入场才是对本金的不负责。只有先守住防线,你才有机会在未来的牛市中发动反攻。
浏览29
评论0
收藏0
用户头像sh_*219t3e
2026-09-08 发布
亲测最好用的AI编写量化策略工具,可以让 AI 直接写各个平台的策略代码,直接生成可运行的策略代码,代码质量远高于直接使用 DeepSeek、Trae 等平台。大家可以直接用描述策略,然后一键生成可运行的完整策略代码,也可以把它当做一个API 查询工具。 最新消息,已经支持SuperMind等主流量化平台啦,并且实盘亲测过了,很适合小白用户,上线之后获得了非常多朋友的好评。 🚀️Supermind AI量化助手:https://easyquant.ai
浏览32
评论0
收藏0
用户头像sh_*219t3e
2025-09-29 发布
之前我分享过一个小工具网站,支持国内主流量化平台,可以让 AI 直接帮你写各个平台的策略代码,直接生成可运行的策略代码,代码质量远高于直接使用 DeepSeek、Trae 等平台。上线之后获得了非常多朋友的好评。 大家可以直接用描述策略,然后一键生成可运行的完整策略代码,也可以把它当做一个API 查询工具。 AI工具平台:https://iris.findtruman.io/ai/tool/ai-quantitative-trading/ 我看平台正在开发SuperMind支持,很快就能支持同花顺了
浏览4699
评论82
收藏14
用户头像sh_****447dvu
2026-09-08 发布
摘要:在量化研究与策略开发工作中,不少研究者会直接通过A股 API获取原始Tick,自主聚合生成1分钟K线,用于回测、因子计算与策略仿真。多数人会将该过程理解为简单的数据分组,但在真实行情流环境下,跨分钟报文乱序、重复Tick推送、K线闭合时机判定等边界问题,会造成OHLCV结果偏移,直接影响回测结论可靠性。本文从实际开发案例出发,梳理故障诱因,给出工程处理方案,并重点说明该环节对回测、模型开发的数据价值。 引言 在量化策略研究中,分钟级K线是因子挖掘、策略回测、仿真验证最常用的数据基础。获取分钟K线有两种主流路径:直接调用平台封装好的K线接口;或者拉取底层Tick逐笔数据,在本地/服务端自行聚合生成OHLCV。 选择自行聚合Tick的研究者,往往是为了获得更高的数据自由度:可以自定义聚合逻辑、适配特殊的采样规则、也便于做数据校验与二次加工。直观来看,聚合逻辑十分简单:将同一自然分钟内全部成交Tick归集,计算开盘、最高、最低、收盘,累加成交量,即可得到1分钟K线。 但在真实的行情流接入场景下,网络传输、接口重连、行情源推送机制会带来一系列边界问题。这些问题不会造成程序崩溃,属于静默式的数据偏差,却会直接传导至回测结果,造成策略绩效失真、因子有效性误判。 笔者在工具开发与策略数据预处理的过程中,就多次遇到本地聚合K线与基准行情存在差异的现象。复盘后发现,问题并非来自OHLCV计算公式,而是集中在三个容易被研究人员忽略的环节:Tick的时间归属判定、乱序与跨分钟成交处理、重复报文的幂等过滤,以及K线何时判定完成。 本文将结合实战经验,阐述问题根因,给出可落地的处理逻辑,并说明数据处理环节如何保障回测与模型研究的数据可靠性。代码仅作逻辑演示,研究者可以根据自身研究环境适配调整。 一、真实场景下的数据异常案例 项目早期版本,曾采用一种非常普遍的简易实现:以WebSocket报文到达本地服务器的接收时间,作为Tick归属对应分钟K线的判断依据。 取一组A股盘中真实成交时间样本:** **09:30:59.800、09:30:59.950、09:31:00.020 依据交易所实际撮合发生的时间,前两笔Tick应当归属09:30这根K线,最后一笔归属09:31 K线。 但网络传输不保证报文严格按照时间顺序抵达,程序实际接收顺序有可能发生错乱:** **09:30:59.950 → 09:31:00.020 → 09:30:59.800 在接收时间作为分组依据的逻辑下,延迟到达的09:30:59.800会被错误归入09:31的K线。直接后果是相邻两根K线的价格区间、成交量同时发生偏移。若该K线直接用于回测,会改变开平仓触发条件、收益率、最大回撤等核心指标,严重时会出现“回测表现很好,模拟盘实盘效果完全脱节”的现象。 另一类高频异常来自连接重连后的报文补发。当WebSocket链路断开重建,部分A股 API会回放最近一段时间的Tick快照。若缺少去重逻辑,同一笔成交会被重复纳入统计。 示例:同一笔成交真实成交量为100,报文被推送两次。聚合后统计成交量变为200。成交量是量价类因子、流动性指标的核心输入,成交量虚高会直接破坏因子分布,对统计模型、机器学习特征工程带来干扰。 研究提示:这类静默偏差无法通过程序异常捕获发现,必须将聚合输出结果和权威基准数据集做抽样比对校验,才能够识别。对于量化研究而言,数据校验应当作为回测流程的前置步骤。 二、核心问题拆解 2.1 跨分钟边界乱序:区分成交时间与报文接收时间 处理Tick行情,必须严格区分两组时间维度,这是保证聚合正确性的基础: Tick自带成交时间戳:交易所撮合完成的真实时刻,这是划分时间桶的唯一可信依据; 报文接收时间:Tick数据包到达研究机器/服务端的系统时刻。该时间受网络抖动、行情源调度、系统负载影响,不可用于K线分组。 在实时数据流场景,较早发生的成交,报文晚于下一分钟数据到达属于客观现象。 还有一处极易忽略的细节:接收到新一分钟的第一条Tick,并不等价于上一分钟全部成交报文接收完毕。即便聚合逻辑已经切换至新的时间窗口,上一分钟的延迟报文依然可能后续抵达。如果直接丢弃迟到Tick,会造成K线成交记录缺失,带来另一种形式的数据失真。 2.2 重复Tick报文:对研究结果的影响高于乱序 重复报文的触发场景:WebSocket断线重连、订阅会话重启、消息队列重复消费。 乱序问题只是将成交记录分配至错误K线;而重复Tick会直接放大成交量统计值,改变量价特征的原始分布。对于动量、量比、流动性类因子,该类污染带来的模型偏差会非常显著。 重复Tick示例: 09:30:12.123 15.20 100 09:30:12.123 15.20 100 未做去重处理,聚合得到成交量200,市场真实成交量仅为100。 研究认知提醒:仅依靠时间戳+价格+成交量组合生成复合Key,无法做到百分之百可靠去重。A股真实撮合过程中,客观存在多笔独立成交恰好拥有完全一致的时间、价格、成交量。复合Key存在误删除有效成交样本的风险,在研究文档中需要记录该约束。若接口提供成交唯一ID或全局序列号,应优先采用ID做幂等。 三、面向量化研究的工程处理方案 下面给出的方案,兼顾实时数据流处理与历史Tick离线回测加工两种研究场景。 3.1 时间桶划分:以Tick原生成交时间作为唯一标准 制定处理规则:K线时间桶归属,仅采信Tick载荷内部携带的交易所成交时间戳,报文接收时间不参与任何分组逻辑。 将Unix时间戳换算为分钟粒度的时间桶标识: minute = tick_timestamp // 60 也可以格式化为2026‑09‑07 09:30形式字符串Key,用来映射内存中的K线聚合对象。 该规则同时适用于实时流处理,以及本地批量回放历史Tick做离线聚合的场景。 3.2 设置有限滑动缓冲窗口,兼容跨分钟迟到报文 网络上很多示例代码,会在检测到分钟切换时直接闭合上一根K线: if tick_minute != current_minute: finalize(current_kline) current_kline = create_kline(tick) current_minute = tick_minute else: update_kline(current_kline, tick) 该逻辑在报文完全有序的理想样本下可以运行,但真实行情流会出现迟到报文。当已经切换至新分钟,再次收到上一分钟的Tick,直接丢弃会丢失真实成交样本。 实现方案:维护一个容量受限的滑动内存缓冲区,仅保留最近3‑5分钟的K线聚合实例。 每一条Tick进入处理流程,解析其原生成交时间戳; 根据时间戳匹配缓冲区内对应分钟的K线对象,执行更新; 只有Tick的时间已经超出缓冲区时间范围,才执行丢弃。 该设计可以兼容网络抖动带来的短时乱序。对于离线批量回放历史Tick数据,缓冲窗口同样适用,用来处理历史数据源内部本身存在的乱序记录。 3.3 两级幂等去重策略,适配不同接口能力 针对重复Tick,采用分层去重逻辑,适配不同A股 API接口的字段能力: 若接口返回成交ID、全局序列号等唯一标识,优先基于唯一ID做幂等过滤,这是可靠性最高的方案: if tick_id in processed_ticks: return processed_ticks.add(tick_id) 接口无唯一标识字段时,组合标的代码、时间戳、价格、成交量生成复合去重Key: dedup_key = ( symbol, timestamp, price, volume ) 研究侧注意事项:复合Key仅降低重复统计概率,不能完全消除误判风险。如果你的研究对成交量精度要求极高,建议尽量选用携带成交唯一编号的数据源;同时可以定期抽样比对聚合结果与基准行情的成交量分布。 3.4 处理链路分层,便于研究调试与复现 为方便定位数据异常、便于离线回放复现问题,建议不要将接收、清洗、聚合全部耦合在同一个函数内,将处理链路拆分为三层,职责解耦: 层级 核心职责 接收层 维护WebSocket会话,拉取A股 API原始Tick;离线场景负责读取本地Tick数据集 清洗层 时间合法性校验、Tick幂等去重、过滤异常脏样本 聚合层 基于清洗完成的Tick样本,计算分钟OHLCV指标 基础WebSocket客户端示例(仅演示连接结构): import websocket import json def on_message(ws, message): data = json.loads(message) for tick in data.get("data", []): process_tick(tick) ws = websocket.WebSocketApp( "wss://api.alltick.co/stock/websocket", on_message=on_message ) ws.run_forever() 说明:实际开发需要按照对应API文档配置订阅参数、完成字段映射;离线回测场景可去掉WebSocket部分,直接迭代本地Tick文件。 3.5 区分实时展示与回测落库,重新定义K线完成时机 一个普遍误区:直接使用服务器系统时钟,判定一根分钟K线已经闭合。 系统时钟走到09:31:00,仅代表物理时间进入新一分钟,不能证明09:30全部Tick样本已经接收完毕。如果此时直接固化K线用于回测,后续迟到的成交样本会被丢失。 推荐处理方式:设置短暂等待缓冲窗口,也可以结合行情源的报文序列号辅助判断K线是否可以安全闭合。同时拆分两条数据输出链路: 实时预览链路:用于实时观察行情,优先保证响应速度,允许K线指标在窗口内短暂修正;该链路输出数据不建议直接用于回测与模型训练。 回测/持久化链路:牺牲少量时效性,等待缓冲窗口结束,确认不再有迟到Tick流入,完成全部去重与修正之后,再固化为最终版OHLCV,作为回测、因子计算、模型训练的基准输入数据。 研究实践经验:回测所用的数据集,应当采用第二条链路的固化结果,不要直接使用实时未闭合的K线。 四、多标的场景下的资源与性能优化 当研究工作需要同时处理多只标的Tick流,内存与计算开销会快速上升,分享几项实操优化手段: 约束K线缓冲区时间范围:不要在内存完整保存整个交易日全部K线对象。结合A股交易时间,缓冲区仅维持最近3‑5分钟;过期K线对象释放内存,历史结果落盘存储。离线批量处理时,也可以分时间分片处理,控制内存占用。 定时清理去重集合:存储tick_id、复合dedup_key的集合不能无限膨胀。定时清理窗口时间之外的记录,降低GC压力,规避内存泄漏。 标的差异化处理逻辑:对于成交高频的活跃标的,优化K线更新逻辑,减少不必要对象拷贝;对于成交稀疏的标的,复用通用聚合逻辑,避免过度设计增加调试成本。 五、对量化研究的启示与总结 将Tick聚合生成1分钟K线,并不只是简单的分组运算。时间桶分配、乱序兼容、重复报文幂等、K线闭合时机,这些工程细节直接决定数据集质量,进一步影响因子挖掘、策略回测、机器学习模型训练的结论可信度。 在量化研究流程中,大家往往会把重心放在策略算法、模型调参上,而容易忽视底层行情预处理环节。但大量实践表明,很多回测与模拟盘表现不一致问题,根源来自底层数据的静默偏差,而非策略逻辑本身。 建议在研究流程中增加固定的数据校验环节:定期抽样比对聚合生成的OHLCV与权威基准行情,对价格、成交量分布做统计校验,尽早发现聚合逻辑的缺陷。 本文中全部代码仅为原理演示。在正式研究环境中,还需要补充异常捕获、连接自动重连、日志埋点,方便问题复现排查。在数据源选型上,可以借助AllTick API获取原始Tick数据,结合本文介绍的处理逻辑完成二次聚合,构建自己的研究数据集。
浏览39
评论0
收藏1
用户头像me_361829775857
2026-09-08 发布
A股Level2行情数据到底有哪些?逐笔成交、委托、十档全搞明白 说真的,折腾Level2数据这阵子没少踩坑。网上各种文档念得头头是道,就是没人告诉你东西长什么样、字段是什么意思。我干脆自己从头捋一遍,省得下回又忘。 先泼冷水:Level2不是开了就能直接拿来赚钱的圣杯,它就是更细的行情数据,沪深交易所发布的逐笔级别的数据,A股市场才有。如果你还在看Level1的五档和每分钟快照,那Level2相当于把蒙在行情上那层纱给掀了,底下全是毫秒级的拥挤。 主要就三类数据:逐笔成交、逐笔委托、十档行情。三者不是并列关系,是互相补充,拿到手大小也差很多,十档行情文件最大,逐笔委托其次,逐笔成交稍微小点。 逐笔成交 你可以把它理解为每一笔实际撮合成功的交易记录,已经配对好的。不是每三秒给你推一次,而是有成交就推,毫秒级。 字段大概长这样(我挑几个必看的): 字段名 说人话 证券代码 股票代码 成交时间 精确到毫秒,比如093001020 成交价格 这笔成交价 成交量 手数 成交金额 金额 买卖方向 B主动买 / S主动卖 / 不确定 成交编号 交易所给的一笔唯一编号 别小看买卖方向,这才是精华。Level1里成交明细只有成交价和量,根本分不清是谁主动吃的。Level2里能看出来是挂在卖一被吃掉的,还是直接砸到买一的,这对判断大单有没有怂了很有用。不过要小心,有些成交是左右手倒腾,交易所标记成“不确定”,你不要被红绿柱骗了。 逐笔委托 这个更狠,是交易所收到的每一笔挂单,包含撤单。你看到的盘口挂单量变化,就是逐笔委托推出来的。但是注意,深交所和上交所的委托数据不一样: 深圳:有逐笔委托,能看到挂单价格、数量、委托类型(加单、撤单)。 上海:目前没有公开的逐笔委托,只有逐笔成交和十档行情。所以想用沪市做委托流分析,醒醒吧,没门。 深交所逐笔委托字段: 字段 含义 委托时间 毫秒级时间戳 委托价格 委托价 委托数量 手数 委托类型 1:买 2:卖 3:撤单 订单编号 委托编号,和成交关联用 遗憾的是,撤单是看不出具体撤哪一单的,只能知道有人在某个价格撤了多少手,没法直接定位到之前那笔挂单。做拆单策略的话,得靠订单编号和成交数据拼,非常蛋疼。 十档行情 Level1只给五档,Level2给十档,也就是买一到买十、卖一到卖十,每个价位上的挂单量。这玩意儿是快照,不是每笔委托都推,通常3秒发一次,或者有变化才发,但能反映盘口深度。 数据量巨大,一个股票一天十档行情文件能有几十MB,要是全市场4000多只股票,一天下来小几百GB,硬盘紧张的主儿得掂量。 字段: 字段 备注 行情时间 快照生成时间 买1-10价 委托价格 买1-10量 挂单量 卖1-10价 同上 卖1-10量 同上 别只看买一卖一,很多胖手指单子会在买五卖五附近堆着,观察撑压比肉眼数档位靠谱。 怎么拿到这些数据 券商一般提供Level2行情,但只能实盘的时候用,想回测历史数据就难了。很多做量化的人会买数据,我也找过不少渠道,最后发现有个叫数据源:CMES金融数据库的,专门提供A股历史Level2行情下载,可以按天下载,不用自己存,数据从2018年开始有,每天更新,关键是能用Python直接调,不需要自己写复杂的爬虫。 用了大概一星期才把接口搞顺,主要是token和频率限制。他们的接口文档在这:https://cmes-data.com/download.html?type=vip ,安装就一行: pip install cmesdata 调用示例,拿某天某只股票的逐笔成交: from cmesdata import CMESData # CMES金融数据库的行情接口,注意入参正确,调用频率正常 client = CMESData(api_key="你的token") # 获取2025年3月1日平安银行逐笔成交 tick = client.get_tick( symbol="000001.SZ", date="2025-03-01", trade_type="transaction" ) print(tick.head()) 它会返回一个DataFrame,字段就是上面说的那些。十档行情用 trade_type="orderbook",逐笔委托用 trade_type="order",注意沪市一调用委托就会报错,因为没数据,这个坑我踩过,别犯傻。 频率上,免费账户一天能调个几十次,够自己研究用,要是全市场扫,得买高级版,否则会触发限流,接口会返回一堆让人崩溃的403。 最后想说的 别指望数据到手就能干活,这些Level2数据量极大,而且很多噪声,比如虚假挡单、诱导撤单,不经过清洗基本没法用。清洗规则又因人而异,我自己光过滤异常成交就写了好几百行代码。所以拿到数据只是第一步,后面打磨才是大头。 有机会再聊聊怎么把这些毫秒级数据转成有用的因子,今天就先记这些,不然又忘光了。
浏览46
评论0
收藏1
用户头像sh_*2176oo
2026-09-08 发布
一句话回答: 只按单一指标(比如只看涨幅或只看换手)排名,噪声大、容易追高。更稳的做法是把多个因子各自标准化(z-score)后加权求和做综合打分。用 AlphaFeed 一次拿到全 A 实时快照 + 批量 K 线 + 流通股本,几十行就能跑出一份可复现的多因子选股清单。 为什么要多因子而不是单指标 单看动量:容易在高位接盘,回撤大。 单看换手率:热度高不代表趋势好,可能是出货。 单看小市值:壳票、垃圾股混入,风险集中。 把它们各自标准化后合成一个分数,让"趋势向上 + 有资金关注 + 盘子不过大"同时成立的票排到前面,比任何单一指标都稳。因子标准化是关键:不同量纲(涨幅是小数、市值是亿级)不能直接相加。 分步骤解决 第 1 步:取全 A 实时快照(含换手率) from alphafeed import AlphaFeed import pandas as pd, numpy as np af = AlphaFeed() # 读取 ALPHAFEED_API_KEY q = af.quotes.get(universes="CN_Stock", to_dataframe=True) print("全 A 数量:", len(q)) # 实测约 5556 只 快照里可直接用的因子字段(ext.* 均为小数,如涨跌幅 0.03 = 3%): 字段 含义 因子方向 ext.turnover_rate 换手率(小数) 越高越有资金关注(+) ext.change_pct 当日涨跌幅(小数) 短期动量参考 ext.amplitude 当日振幅(小数) 活跃度/风险 last_price 最新价 配合股本算市值 演示用前若干只做子集;实盘可对全量或先做流动性过滤(如剔除换手率过低、停牌)。 sub = q.head(300).copy() # 演示子集;生产可用全量 syms = sub["symbol"].tolist() 第 2 步:用批量 K 线算动量因子 klines.batch(..., to_dataframe=True) 返回 {symbol: DataFrame} 字典,逐票算近 60 日涨幅作动量: kb = af.klines.batch(syms, period="1d", count=60, adjust="forward", to_dataframe=True) mom = {} for s, d in kb.items(): d = d.sort_values("trade_date") if len(d) > 1: mom[s] = d["close"].iloc[-1] / d["close"].iloc[0] - 1 # 60日动量 sub["mom60"] = sub["symbol"].map(mom) 用 adjust="forward"(前复权)算动量,避免分红送股导致的假跳空污染收益率。 第 3 步:用 instruments 取流通股本算市值 insts = af.instruments.batch(syms) # 返回 list[dict] float_shares = {i["symbol"]: (i["ext"].get("float_shares") or 0) for i in insts} sub["float_shares"] = sub["symbol"].map(float_shares) sub["float_mcap"] = sub["last_price"] * sub["float_shares"] # 流通市值 第 4 步:z-score 标准化 + 综合打分 def z(x): x = x.astype(float) return (x - x.mean()) / x.std(ddof=0) logcap = np.log(sub["float_mcap"].replace(0, np.nan)) sub["score"] = ( z(sub["mom60"].fillna(0)) # 动量越大越好 (+) + z(sub["ext.turnover_rate"].fillna(0)) # 换手越活跃越好 (+) - z(logcap.fillna(logcap.mean())) # 市值越小越好 (-),取对数抑制极值 ) top = sub.sort_values("score", ascending=False).head(20) print(top[["symbol", "ext.name", "mom60", "ext.turnover_rate", "float_mcap", "score"]].to_string(index=False)) 实测(子集内)打分靠前的标的同时具备"近 60 日上涨 + 换手活跃 + 流通盘不大"的特征,与直觉一致。权重与因子方向可按你的策略调整(如加上振幅惩罚、行业中性化)。 第 5 步:封装成可复用打分器 def factor_score(n=300, count=60, weights=(1, 1, -1)): af = AlphaFeed() q = af.quotes.get(universes="CN_Stock", to_dataframe=True).head(n).copy() syms = q["symbol"].tolist() kb = af.klines.batch(syms, period="1d", count=count, adjust="forward", to_dataframe=True) q["mom"] = q["symbol"].map({s: (d.sort_values("trade_date")["close"].iloc[-1] / d.sort_values("trade_date")["close"].iloc[0] - 1) for s, d in kb.items() if len(d) > 1}) fs = {i["symbol"]: (i["ext"].get("float_shares") or 0) for i in af.instruments.batch(syms)} q["mcap"] = q["last_price"] * q["symbol"].map(fs) zc = lambda x: (x.astype(float) - x.astype(float).mean()) / x.astype(float).std(ddof=0) lm = np.log(q["mcap"].replace(0, np.nan)) wm, wt, wc = weights q["score"] = (wm * zc(q["mom"].fillna(0)) + wt * zc(q["ext.turnover_rate"].fillna(0)) + wc * zc(lm.fillna(lm.mean()))) return q.sort_values("score", ascending=False) print(factor_score().head(10)[["symbol", "ext.name", "score"]].to_string(index=False)) 关键坑与注意事项 量纲不统一不能直接相加​:务必先 z-score(或排名百分位)标准化,市值这类右偏因子建议取对数。 未来函数:因子和收益要错开——用 t 日之前的数据打分、t+1 日再买入回测,别用当日收盘价算完立刻"成交"。 快照是实时值:quotes 是当前行情,做历史回测的因子要用对应日期的 K 线/横截面,别用今天的换手率去回测历史。 别只追分数最高:小市值 + 高换手也可能是妖股/风险票,需叠加流动性、ST 过滤与风控。 全量批量:对 5000+ 只全量跑 K 线批量耗时较长,klines.batch 支持 max_workers/batch_size,注意接口额度。 常见问题(FAQ) Q:因子权重怎么定? A:本文用等权(动量+、换手+、市值-)做演示。生产中可用回测网格、IC 加权或等风险权重;先把标准化做对,权重再迭代。 Q:能加更多因子吗? A:可以。振幅(ext.amplitude)、波动率(K 线算)、总/流通市值(instruments.ext)都能作因子,统一 z-score 后并入打分即可。 Q:需要付费吗? A:quotes 全市场池(universes)需 Starter 及以上;单票/批量 K 线与 instruments 有免费额度。详见定价页。 小结 多因子选股的本质是"把多个不同量纲的信号统一到可比的尺度上再合成"。用 AlphaFeed 一次取全 A 快照 + 批量 K 线 + 股本,z-score 打分几十行搞定,且可复现、可扩展。记住先标准化、防未来函数、加风控,分数才有意义。 参考 AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
浏览34
评论0
收藏0