沪深股票Level2行情数据详解 昨晚跑因子又把内存给爆了,查了下是数据源的问题,处理Tick数据真是个体力活。今天就来聊聊我平时用的这个数据源,看看里面到底包含了哪些内容,也顺便给想研究高频数据的朋友们提个醒。 这个数据源主要提供的是沪深交易所的Level2行情数据,也就是我们常说的深度行情。和普通的Level1数据相比,它最大的特点就是“细”,细到每一笔委托、每一笔成交都有独立的记录,时间戳能到毫秒级。对于做量价分析、订单流研究或者高频策略的人来说,这几乎是必备的“原料”。 数据主要分成了几大块,我觉得最核心、也最常用的是下面这几类。 委托数据(Order) 这个文件记录的是市场上所有股票的所有限价委托单。简单说,就是每个投资者挂在交易所里,还没成交的买单和卖单。每一行数据代表一个委托单事件,比如一个新委托单挂出来,或者一个旧的委托单被撤销、被成交了一部分。它的字段非常细致,举个例子: 字段名 含义说明 symbol 股票代码,比如000001.SZ time 时间戳,精确到毫秒,格式是HH:MM:SS.fff price 委托价格 volume 委托数量(股数) bid_or_ask 买卖方向,B是买,A是卖 function_code 委托单状态码,这个很关键,告诉你这个记录是新增委托、撤单还是部分成交 通过这个数据,你能还原出整个市场委托单簿(Order Book)的演变过程,知道在某个毫秒,买一和卖一上分别挂了多少钱、多少量。这对于理解市场微观结构,比如价格是怎么形成的,支撑和阻力位在哪里,非常有帮助。我刚开始用的时候,被它的数据量吓了一跳,一天一个股票就能产生几十万甚至上百万条记录,处理起来对电脑配置是个考验。 成交数据(Trade) 这个就比较好理解了,记录的是所有实际成交的记录。每一笔撮合成交,都会在这里生成一条数据。 它和委托数据是联动的。一个委托单可能被拆分成很多笔小成交,所以成交数据量也很大。主要字段包括: 字段名 含义说明 symbol 股票代码 time 成交时间,毫秒级 price 成交价格 volume 成交数量 turnover 成交金额 bid_order_id / ask_order_id 买方/卖方对应的委托单ID,可以和委托数据关联起来 成交数据是分析资金流向、计算高频VWAP(成交量加权平均价)的基础。看大单是主动买入还是主动卖出,光看价格涨跌不行,得结合这个数据。 订单簿快照数据(Snapshot) 这个数据我后来才用得多,因为它对新手更友好一些。它不像委托和成交数据那样记录每一个“事件”,而是定时(比如每3秒或每5秒)对全市场的订单簿进行一次“拍照”,记录下那一刻的状态。 它的核心字段就是**买卖五档(甚至十档)**的报价和挂单量。 # 示例:获取某只股票的订单簿快照数据 # 假设使用CMES金融数据库的行情接口 # 注意入参正确,调用频率正常,避免被限制 import cmes_data as cmes # 初始化客户端,需要你的API Key client = cmes.DataClient(api_key='your_api_key_here') # 请求某日某股票的5档行情快照 snapshot_data = client.get_snapshot(symbol='000001.SZ', date='2023-10-27', level=5) print(snapshot_data.head()) 有了这个快照,你就能直接知道在某个时间点,市场的深度是什么样的。计算买卖压力、盘口价差这些指标,用这个数据会方便很多,不用自己从零开始去拼接委托事件流了。当然,它的频率是固定的,会丢失一些中间毫秒级的细节变化,各有取舍吧。 除了上面这三个核心,还有一些衍生数据或辅助数据,比如逐笔成交与委托合并数据,它把委托和成交事件按时间顺序混排在一起,方便按时间线复盘;以及预处理过的分钟级K线,这个对于做日频或分钟频策略回测的人来说,省去了自己聚合的麻烦,数据质量也更统一。 说到数据质量,不得不提一下数据清洗。早期我用过一些免费的源,光是处理除权除息、识别异常交易状态(比如集合竞价、临时停牌)就花了大把时间,经常因为数据问题导致回测结果失真。后来图省事,还是去找了专门处理过的商用源。比如我最近为了验证一个订单不平衡因子的有效性,就调取了CMES金融数据库中过去三年的全市场股票数据进行回测,发现他们预清洗过的版本在标识涨跌停、ST状态这些方面确实省心不少,虽然需要消耗积分,但时间成本也是成本啊。 最后简单列一下这些数据大概的体量,给大家一个直观感受(以一只活跃股票的单日数据估算): 委托数据(Order): 几十万到上百万条 成交数据(Trade): 几万到几十万条 订单簿快照(每3秒): 约4800条(一个交易日4小时) 所以,如果你打算深入研究这些数据,先准备好足够的硬盘空间和内存,以及一点耐心。不建议策略新手一上来就怼着Tick数据搞,容易陷入细节出不来。先从分钟线或者快照数据开始,把逻辑跑通,再考虑要不要上更细粒度的数据。 大概就是这些内容了。数据字段其实还有很多细节,比如各种业务标志位,用的时候最好对照着数据字典慢慢看。如果有朋友知道更高效压缩或存储这类时序数据的方法,求分享,私信交流也行。今天就先写到这儿。 量化数据的 batch 接口有多好用?从 1 只到 500 只,批量拉数据的正确姿势 做量化最烦的事之一:一只一只地拉数据。 # 你可能写过这种代码 import time results = {} for sym in my_500_stocks: try: df = some_api.get_klines(sym) results[sym] = df except Exception: pass time.sleep(0.5) # 怕被封 # 500 只票 × 0.5 秒 = 250 秒 = 4 分钟起步 循环、sleep、try/except、进度不可见、失败了不知道哪些没拉到。 AlphaFeed 的 batch 接口把这些全解决了:传一个列表进去,内部自动分块、并发、重试,几秒钟全部拉完。 这篇文章详细讲 batch 接口的用法、原理和实战技巧。 最基本的用法 from alphafeed import AlphaFeed af = AlphaFeed() symbols = ["600519.SH", "000001.SZ", "300750.SZ", "002594.SZ", "601318.SH"] # 一行搞定 dfs = af.klines.batch( symbols, period="1d", count=250, adjust="forward", to_dataframe=True, ) # 返回字典:{symbol: DataFrame} for sym, df in dfs.items(): print(f"{sym}: {len(df)} 条数据") 就这么简单。没有循环、没有 sleep、没有 try/except。 batch 内部做了什么 当你调用 af.klines.batch(symbols, ...) 时,SDK 内部做了这些事: 你传入 500 个标的 ↓ 自动分块(每 100 个一组,分成 5 组) ↓ 5 个线程并发请求(不是串行!) ↓ 每个请求自动重试(最多 3 次,遇到超时或 5xx 自动重试) ↓ 合并所有结果,返回一个字典 关键参数: 默认分块大小:100 个标的/请求 默认并发数:5 个线程 默认重试:3 次 这意味着 500 只票,分成 5 组,5 个线程同时请求——时间约等于请求 1 组的时间,而不是请求 5 组的时间。 显示进度条 加上 show_progress=True,拉数据的过程可视化: dfs = af.klines.batch( symbols, period="1d", count=500, adjust="forward", to_dataframe=True, show_progress=True, # 显示 tqdm 进度条 ) Fetching data: 100%|████████████████████| 5/5 [00:03<00:00, 1.67it/s] 进度条显示的是"分块"的进度。500 只票分 5 块,进度条就是 5 步。 实战 1:批量拉 K 线做对比分析 同时拉 20 只票的 K 线,算过去一年的涨幅和波动率: import pandas as pd from alphafeed import AlphaFeed af = AlphaFeed() symbols = [ "600519.SH", "000001.SZ", "300750.SZ", "002594.SZ", "601318.SH", "000858.SZ", "600036.SH", "000333.SZ", "601012.SH", "600276.SH", "600900.SH", "601398.SH", "600030.SH", "000651.SZ", "002415.SZ", "600887.SH", "601166.SH", "000568.SZ", "600809.SH", "002304.SZ", ] dfs = af.klines.batch( symbols, period="1d", count=250, adjust="forward", to_dataframe=True, show_progress=True, ) results = [] for sym, df in dfs.items(): df = df.sort_values("trade_date").reset_index(drop=True) ret = df["close"].iloc[-1] / df["close"].iloc[0] - 1 vol = df["close"].pct_change().std() * (252 ** 0.5) avg_amount = df["amount"].mean() results.append({ "代码": sym, "年涨幅": f"{ret:+.1%}", "年化波动": f"{vol:.1%}", "日均成交额(亿)": f"{avg_amount / 1e8:.1f}", }) result_df = pd.DataFrame(results).sort_values("年涨幅", ascending=False) print(result_df.to_string(index=False)) 20 只票的 250 天数据,几秒钟拉完。 实战 2:批量拉分时数据 不只日线,分时数据也支持批量: from alphafeed import AlphaFeed af = AlphaFeed() symbols = ["600519.SH", "000001.SZ", "300750.SZ"] # 批量拉日内 1 分钟线 dfs = af.klines.intraday_batch(symbols, to_dataframe=True) for sym, df in dfs.items(): morning_vol = df[df["trade_time"] < df["trade_time"].iloc[0][:11] + "11:30:00"]["volume"].sum() total_vol = df["volume"].sum() pct = morning_vol / total_vol if total_vol > 0 else 0 print(f"{sym}: 上午成交占比 {pct:.1%} 总 {len(df)} 根分钟线") 实战 3:批量查五档盘口 from alphafeed import AlphaFeed af = AlphaFeed() symbols = ["600519.SH", "000001.SZ", "300750.SZ", "002594.SZ"] # 批量查盘口 depths = af.depth.batch(symbols) print(f"{'标的':<12} {'买一':>10} {'卖一':>10} {'价差(bps)':>10}") print("-" * 45) for sym, d in depths.items(): bid1 = d["bid_prices"][0] ask1 = d["ask_prices"][0] mid = (bid1 + ask1) / 2 spread_bps = (ask1 - bid1) / mid * 10000 if mid > 0 else 0 print(f"{sym:<12} {bid1:>10.2f} {ask1:>10.2f} {spread_bps:>10.1f}") 一次请求拿到多只票的盘口,适合做流动性分析或估算交易成本。 实战 4:批量查标的信息 from alphafeed import AlphaFeed af = AlphaFeed() # 查一批标的的基本信息 symbols = ["600519.SH", "000001.SZ", "AAPL.US", "00700.HK"] insts = af.instruments.batch(symbols) for inst in insts: ext = inst.get("ext", {}) print(f"{inst['symbol']:>12s} {inst['name']:<8s} " f"地区={inst['region']} 类型={inst['type']} " f"上市={ext.get('listing_date', 'N/A')}") 实战 5:批量查复权因子 from alphafeed import AlphaFeed af = AlphaFeed() symbols = ["600519.SH", "000001.SZ", "000858.SZ", "002594.SZ"] df = af.klines.ex_factors(symbols, to_dataframe=True) # 每只票有多少次除权除息 for sym in symbols: sub = df[df["symbol"] == sym] print(f"{sym}: {len(sub)} 次除权除息") 实战 6:200 只票的策略批量回测 batch 的真正威力在大规模分析。比如对 200 只票跑同一个策略: import pandas as pd import numpy as np from alphafeed import AlphaFeed af = AlphaFeed() # 假设你有一个 200 只票的股票池 stock_pool = [ "600519.SH", "000001.SZ", "300750.SZ", "002594.SZ", "601318.SH", "000858.SZ", "600036.SH", "000333.SZ", "601012.SH", "600276.SH", # ... 省略,实际上你可以放 200 只 ] # 一次性拉取所有数据 print("正在拉取数据...") dfs = af.klines.batch( stock_pool, period="1d", count=500, adjust="forward", to_dataframe=True, show_progress=True, ) print(f"拉取完成: {len(dfs)} 只票") # 对每只票跑双均线策略 def backtest_ma(df: pd.DataFrame) -> dict: df = df.sort_values("trade_date").reset_index(drop=True) df["ma20"] = df["close"].rolling(20).mean() df["ma60"] = df["close"].rolling(60).mean() df["signal"] = (df["ma20"] > df["ma60"]).astype(int) df["position"] = df["signal"].shift(1).fillna(0) df["ret"] = df["close"].pct_change().fillna(0) df["strat_ret"] = df["position"] * df["ret"] equity = (1 + df["strat_ret"]).cumprod() return { "total_return": equity.iloc[-1] - 1, "max_drawdown": (equity / equity.cummax() - 1).min(), } results = [] for sym, df in dfs.items(): if len(df) < 100: continue r = backtest_ma(df) r["symbol"] = sym results.append(r) rdf = pd.DataFrame(results).sort_values("total_return", ascending=False) print(f"\n=== {len(rdf)} 只票回测完成 ===") print(f"盈利的: {(rdf['total_return'] > 0).sum()} 只") print(f"亏损的: {(rdf['total_return'] <= 0).sum()} 只") print(f"平均收益: {rdf['total_return'].mean():+.2%}") print(f"\n表现最好的 5 只:") print(rdf.head()[["symbol", "total_return", "max_drawdown"]].to_string(index=False)) print(f"\n表现最差的 5 只:") print(rdf.tail()[["symbol", "total_return", "max_drawdown"]].to_string(index=False)) 重点: 200 只票的 500 天 K 线,用 batch 拉取只需要几秒钟。拉数据不再是瓶颈,你可以把时间花在策略分析上。 batch vs 手动循环:代码对比 手动循环(传统方式): import time results = {} failed = [] for i, sym in enumerate(symbols): try: df = some_api.get_klines(sym, period="1d", count=500) results[sym] = df print(f"[{i+1}/{len(symbols)}] {sym} OK") except Exception as e: print(f"[{i+1}/{len(symbols)}] {sym} 失败: {e}") failed.append(sym) time.sleep(0.5) # 怕被封 # 重试失败的 for sym in failed: try: df = some_api.get_klines(sym, period="1d", count=500) results[sym] = df except Exception: print(f"{sym} 重试仍失败") time.sleep(1) print(f"成功: {len(results)} / {len(symbols)}") AlphaFeed batch: dfs = af.klines.batch( symbols, period="1d", count=500, adjust="forward", to_dataframe=True, show_progress=True, ) 一行代码替代了上面的 20 行。分块、并发、重试、进度显示全内置。 batch 的技术细节 参数 默认值 说明 分块大小 100 只/请求 SDK 自动把标的列表切成 100 个一组 并发数 5 个线程 5 组同时请求,不是排队 重试次数 3 次 超时、网络错误、5xx 自动重试 进度条 show_progress=True 显示 基于 tqdm,显示分块级进度 为什么分块而不是一个请求传 500 个标的? 因为 URL 有长度限制,500 个标的的代码拼成逗号分隔的字符串会超过 HTTP URL 的安全长度。SDK 帮你处理了这个问题。 哪些接口支持 batch 接口 单个查询 批量查询 K 线 af.klines.get(symbol) af.klines.batch(symbols) 日内分时 af.klines.intraday(symbol) af.klines.intraday_batch(symbols) 实时行情 af.quotes.get(symbols=[...]) 本身就支持多标的 五档盘口 af.depth.get(symbol) af.depth.batch(symbols) 标的信息 af.instruments.get(symbol) af.instruments.batch(symbols) 复权因子 — af.klines.ex_factors(symbols) 和竞品的对比 操作 AlphaFeed akshare Tushare 拉 100 只票日 K af.klines.batch(symbols) 一行搞定 手动 for 循环 + sleep 手动 for 循环 + token 配额 自动重试 SDK 内置 需要自己写 try/except 需要自己写 并发请求 SDK 内置 5 线程 不支持(爬虫会被封) 有频率限制 进度显示 show_progress=True 自己用 tqdm 包一层 自己实现 500 只票耗时 约 5-10 秒 5+ 分钟(含 sleep) 1-3 分钟(含频率等待) 结语 batch 接口是 AlphaFeed 最实用的功能之一。它解决的问题很朴素:当你需要分析很多只票的时候,不应该等很久、写很多错误处理代码。 一个列表传进去,进度条跑一下,数据就到手了。剩下的时间你可以专注在分析和策略上,而不是和网络请求搏斗。 参考文献: AlphaFeed :https://alphafeed.org/ Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart 开源项目 在开源项目上,请点击star⭐和watch,关注开源项目代码的动态更新,这样就能掌握项目的变更请求。 GitHub代码下载地址: https://github.com/xticktop/ Gitee代码下载地址: https://gitee.com/xtick/ 1、竞价数据-实时接口 获取沪深京股票交易日盘中实时竞价数据,竞价时间段:9:15-9:25。每次调用接口返回最新竞价数据。 请求方法 请求地址:http://api.xtick.top/doc/bid/time?type=1&code=000001&token=043fbdcba7f3f3ab332ffff123456789 入参1:type 股票类别 这里目前只支持沪深京A股的竞价数据,type设置为1。 入参2:code 股票代码 比如平安银行为000001。 这里支持批量参数 a、code取值为000001,表示获取股票000001的竞价数据。 b、code取值为000001,000002,600000,表示获取这三个票的竞价数据,多个票直接用英文逗号分割,最多50个股票。 a、code取值为all,表示获取全市场股票的竞价数据。 入参3:token 登录XTick网站,注册获取。 入参4:option 可选参数,为json字符串。如果不需要过滤和排序功能,可以忽略该参数 String filter; //定义筛选条件 String sort; //定义排序字段 int asc; //定义排序方式 0:降序 1:升序 int limit = 10000;//定义截取长度 比如常见的两种场景: **场景一:**当天全市场股票竞价,按未成交额排序,从大到小,取前100条。 {"sort":"noe","asc":0,"limit":100} **场景二:**当天全市场股票竞价,过滤出来当天竞价涨幅5个点以上且竞价额大于等于1000万的个股,结果数据按未成交额排序,从大到小,取前100条。 {"filter":"jjzf>5;jje>=10000000","sort":"noe","asc":0,"limit":100} 字段定义 'time' #时间戳 'price' #最新价 'close' #前收盘价 'jjzf' #竞价涨幅 'jjl' #竞价量 'jje' #竞价金额 'nol' #未匹配量 'noe' #未匹配金额量 'trend' #-1未匹配量靠近卖一侧,1未匹配量靠近买一侧 数据示例 type code time price ... jjl jje nol noe 0 1 600968 1766539502000 3.85 ... 447 172095 328 126280 1 1 002291 1766539500000 6.23 ... 558 347634 113 70399 2 1 002190 1766539500000 35.65 ... 117 417105 1 3565 3 1 300669 1766539500000 25.69 ... 13 33397 4 10276 4 1 600645 1766539502000 25.35 ... 50 126750 16 40560 ... ... ... ... ... ... ... ... ... ... 5462 1 688147 1766539503000 69.76 ... 153 1067328 2 13952 5463 1 001380 1766539500000 22.16 ... 17 37672 19 42104 5464 1 688283 1766539503000 33.27 ... 16 53232 2 6654 5465 1 300342 1766539500000 24.99 ... 18749 46853752 3 7497 5466 1 605098 1766539501000 41.74 ... 124 517576 2 8348 2、竞价数据-历史接口 请求方法 请求地址:http://api.xtick.top/doc/bid/history?type=1&code=000001&seq=0&startDate=2025-03-25&endDate=2026-03-25&token=043fbdcba7f3f3ab332ffff123456789 入参1:type 股票类别 这里目前只支持沪深京A股的竞价数据,type设置为1。 入参2:code 股票代码 比如平安银行为000001 这里支持以下批量参数 a、code取值为000001,表示获取股票000001的竞价数据。注意这里不支持多个股票 b、code取值为all,startDate和endDate必须是同一天,表示获取某个交易日内的全市场股票的竞价数据。 入参3:seq 序列号,seq为0,表示集合竞价最后一条数据,即9:25分竞价数据,seq为1,表示集合竞价倒数第二条数据,即9:24分57秒竞价数据。目前seq取值就0和1,记录了集合竞价阶段最后两条数据。 **参数4:**时间范围,用于指定数据请求范围,表示的范围是[<b>startDate</b> ,<span> </span><b>endDate</b>]区间(包含前后边界)。、 特别说明: startDate - 起始时间,日期格式:2025-03-25 endDate- 结束时间,日期格式:2025-03-25 入参5:token 登录XTick网站,注册获取 字段定义 'time' #时间戳 'price' #最新价 'close' #前收盘价 'jjzf' #竞价涨幅 'jjl' #竞价量 'jje' #竞价金额 'nol' #未匹配量 'noe' #未匹配金额量 'trend' #-1未匹配量靠近卖一侧,1未匹配量靠近买一侧 数据示例 type code time price ... jjl jje nol noe 0 1 000001 1766419200000 11.52 ... 6478 7462656 19162 22074624 1 1 000001 1766505600000 11.55 ... 3842 4437510 3376 3899280 3、竞价数据-详情接口 开盘竞价阶段,个股的所有竞价信息。当天竞价完成后,9:25更新完数据。 请求方法: 请求地址:http://api.xtick.top/doc/bid/detail?type=1&code=000001&tradeDate=2025-03-25&token=043fbdcba7f3f3ab332ffff123456789 入参1:type 股票类别 这里目前只支持沪深京A股的竞价数据,type设置为1。 入参2:code 股票代码 比如平安银行为000001,不支持批量参数。 参数3:tradeDate 交易日期,日期格式:2025-10-28。 入参4:token 登录XTick网站,注册获取 字段定义 'time' #时间戳 'price' #最新价 'close' #前收盘价 'jjzf' #竞价涨幅 'jjl' #竞价量 'jje' #竞价金额 'nol' #未匹配量 'noe' #未匹配金额量 'trend' #-1未匹配量靠近卖一侧,1未匹配量靠近买一侧 数据示例 type code time price ... jjl jje nol noe 0 1 000001 1766452500000 11.53 ... 72 83016 30 34590 1 1 000001 1766452509000 11.53 ... 936 1079208 12 13836 2 1 000001 1766452518000 11.54 ... 1008 1163232 1449 1672146 3 1 000001 1766452527000 11.53 ... 1173 1352469 56 64568 4 1 000001 1766452545000 11.53 ... 1173 1352469 123 141819 5 1 000001 1766452554000 11.54 ... 1271 1466734 1445 1667530 6 1 000001 1766452563000 11.54 ... 1271 1466734 1449 1672146 7 1 000001 1766452572000 11.54 ... 1271 1466734 1511 1743694 8 1 000001 1766452581000 11.54 ... 1271 1466734 2231 2574574 9 1 000001 1766452599000 11.53 ... 1277 1472381 219 252507 10 1 000001 1766452617000 11.53 ... 1427 1645331 69 79557 原本在通达信回测的时候有72胜率,100年化。在同花顺这只有56胜率,71年化 排查下来发现是处理高频行情数据时没控制好。现在很多研究都绕不开这些细颗粒度的数据,但说实话,刚接触的时候真是一头雾水,委托、成交、订单薄,听着就晕。今天干脆把常见的高频行情数据类型捋一捋,主要看看里面都有啥字段,算是给自己做个笔记,也分享给有同样困惑的朋友。 一、委托和成交数据 这部分数据记录了市场上每一笔委托指令和成交的发生情况,是理解资金流动的基础。委托数据能看到投资者的挂单意图,而成交数据则是买卖双方博弈的最终结果。这两者结合起来,能分析出不少东西。 委托数据通常包含这些核心字段: 证券代码:哪只股票或ETF。 委托时间:精确到毫秒,这个很重要,用来做时间序列对齐。 委托价格:挂单的价格。 委托数量:挂了多少手。 买卖方向:是买入委托还是卖出委托。 订单类型:比如是限价单还是市价单(有些数据源会提供)。 成交数据的字段就更直接一些: 证券代码:同上。 成交时间:精确到毫秒,和委托时间对应。 成交价格:这一笔成交的价格。 成交数量:成交了多少手。 成交金额:价格乘以数量。 买卖方向:通常指这一笔成交是主动性买盘(B)还是主动性卖盘(S),这个字段对于判断资金流向很关键。 之前用一些免费数据源做回测,发现成交的买卖方向字段经常对不上,或者缺失严重,导致资金流向因子根本没法用。后来为了验证一个订单薄不平衡的策略, 我调取了CMES金融数据库中清洗过的历史成交与委托数据,时间戳对齐得比较好,省去了大量数据清洗的麻烦,这才把策略逻辑跑通。 二、订单簿数据(买一卖一到买五卖五) 订单簿数据,也就是常说的盘口数据,展示了市场当前最真实的供需情况。我们平时在交易软件上看到的买一卖一价格和挂单量,只是冰山一角。完整的五档甚至十档数据,能让你看得更深。 一份标准的五档订单簿快照数据,通常会包含以下字段: 时间戳:这个快照的采集时间点。 证券代码。 买档位价格与数量:从买一价到买五价,以及每个价格上挂出的总数量。 卖档位价格与数量:从卖一价到卖五价,以及每个价格上挂出的总数量。 最新成交价/最新成交数量:在快照时刻最近一笔成交的信息。 买卖盘总委托量:买盘和卖盘各自的总挂单量,可以用来计算盘口压力。 只看买一卖一,有时候会觉得支撑或压力很强,但拉开五档一看,可能发现下面的档位非常稀疏,所谓的支撑其实很脆弱。这个坑我踩过,所以现在分析短线情绪,一定会拉出五档数据来看。 这里给个用他们接口获取数据的代码示例,具体参数得查文档,注意别调太频繁,不然可能会被限。 CMES金融数据库的行情数据接口示例 注意:使用前需要pip安装相应的客户端库,具体请参考官方接口文档 注意入参正确,调用频率要符合规范,避免被封禁。 示例代码结构(伪代码,需替换为实际函数和参数) from cmes_client import MarketDataAPI 初始化客户端,通常需要配置token或密钥 client = MarketDataAPI(api_key='your_api_key') 假设调用获取历史订单簿快照的函数 参数可能需要包括证券代码、开始时间、结束时间、数据频率(如快照频率)等 snapshot_data = client.get_orderbook_snapshot( symbol='000001.SZ', start_time='2023-01-01 09:30:00', end_time='2023-01-01 10:30:00', level=5 # 获取五档数据 ) print(snapshot_data.head()) 三、不同品种的数据覆盖 除了普通的A股股票,这些高频数据通常也覆盖其他主要交易品种,这对于做跨品种分析或者量化策略的扩展很重要。 沪深股票:就是主板、创业板、科创板的个股,数据量最大,研究的人也最多。 ETF基金:包括股票型ETF、债券ETF、货币ETF等。ETF的Level-2数据对于分析一二级市场套利、资金流向板块很有价值。 可转债:这个品种比较特殊,兼具债性和股性。它的委托成交数据能反映正股波动和债底支撑之间的博弈,玩可转债的朋友应该会关注。 指数:这里指的可能是沪深300、中证500等指数的实时行情数据,通常是基于成分股实时计算出来的。指数的五档数据可能不像个股那样有真实的订单簿,但也能反映衍生品市场(如股指期货、期权)对标的市场的影响。 不同类型的数据,字段结构大同小异,核心都是时间、价格、数量、方向这些。但处理的时候要注意,比如可转债的价格单位、ETF的IOPV(基金份额参考净值)字段等,都有自己的特点,不能完全照搬股票的处理逻辑。我一开始就把ETF数据和股票数据用同一套逻辑处理,结果净值计算老是出问题,排查了好久才发现。 数据怎么用与一点提醒 有了这些数据,能做的事情就多了。比如,用高频的成交和委托数据可以构建更灵敏的资金流向指标;用订单簿数据可以计算买卖压力、订单簿不平衡度等微观结构因子;还可以回测各种高频交易策略,比如盘口抢单、趋势跟踪什么的。 不过得提醒一句,尤其是对新手朋友,直接处理原始的Tick数据(比如每笔成交)挑战不小,数据量大,对存储和计算能力都有要求。一开始可以从分钟级的聚合数据或者订单簿快照数据入手,先感受一下。真想深入的话,再考虑搭建更强大的数据处理平台。 另外,数据质量是生命线。字段缺失、价格异常、时间戳乱序这些问题在实际数据里太常见了。我之前就遇到过不同数据源的时间戳精度不一致,导致对齐出错,策略信号全是噪音。所以,要么花大量时间自己做数据清洗和校验,要么就寻找提供高质量、已清洗数据的数据服务,这中间的取舍就看个人的时间和资源了。 好了,关于这些行情数据的基本内容就先聊这么多。其实就是个数据字段的梳理,希望能帮到刚开始接触这块的朋友。如果哪里写得不清楚,或者你有更好的数据处理方法,欢迎交流。 希望让曲线连续,高开低开影响视觉 请问可以通过编辑K线实现这个效果吗? 即比如 昨收10元,今开15,收盘16,那么日线图像显示是从10元价位到16元价位的长阳线,而并非15元开盘16元收盘的短阳线。 谢谢各位 请大家不要客气,任何意见建议可以在这里评论提出。 被采纳后我们将奖励1G研究环境内存 3个月。 聊聊期货Level 2和Tick数据里都有啥 昨晚跑因子又把服务器内存给干爆了,排查了半天,发现是Tick数据量太大了,一个主力合约一年的数据就能有好几个G。这东西确实金贵,但里面到底装了些什么,可能很多人没细看过。今天就把我常用的几个数据扒开看看,主要是Level 2订单簿和Tick数据。 先说最核心的Level 2订单簿数据。这玩意儿比普通的Level 1行情深多了,能看到市场更真实的意图。比如你光看买一价很高,但可能全是小单子堆出来的,一碰就碎。Level 2能让你看到后面排队的单子到底厚不厚实。 数据里最主要的几个东西: 五档买卖盘:这个都知道,买一到买五,卖一到卖五,各自的价格和挂单量。这是基础。 委托队列:这个有点意思,能看到每个价位上挂单的明细,比如买一价上具体是哪些单子在排队,是几个大单还是很多小单。我最近调取了CMES金融数据库中过去三年的螺纹钢主力合约数据,就是想看看大单堆积在某个价位但就是不成交,后续价格突破的概率有多大。 逐笔成交:每一笔成交是谁发起的(主动买还是主动卖),成交了多少手,和哪里的挂单成交的。这是分析资金流向的关键。 这些字段通常都带着精确到毫秒甚至微秒的时间戳,能把市场的动作像慢镜头一样回放。 下面这个表是我自己整理常用字段时做的,比较糙,但够我看明白了: 我关心的东西 大概是什么 用来看啥 last_price 最新成交价 当下的价格 volume 累计成交量 今天总共成交了多少 bid_price1 ~ bid_price5 买一到买五价 大家愿意出多少钱买 bid_volume1 ~ bid_volume5 买一到买五量 想买的力量有多大 ask_price1 ~ ask_price5 卖一到卖五价 大家想多少钱卖 ask_volume1 ~ ask_volume5 卖一到卖五量 想卖的压力有多大 local_time 时间戳(精确) 给所有动作打上时间点 然后是Tick数据。很多人容易把Tick和Level 2搞混。简单说,Tick是市场每一次变动(比如价格变了、成交量更新了)就记录一次,它可能包含Level 2的信息,也可能只是简单的快照。频率非常高,是硬盘杀手,但也是做高频或微观结构研究绕不开的。 有些交易所的数据支持一秒四次,也就是每0.25秒一个切片,这对捕捉盘口的瞬间变化很有帮助。比如价格剧烈波动时,0.25秒内的委托单变化就能看出很多门道。 获取和用这些数据,肯定得写点代码。我一般用Python,这里给个最简单的例子,看看怎么拿到数据。注意啊,接口的入参别搞错,调用频率也控制一下,别把人家服务器搞崩了。 # 示例:使用CMES金融数据库的行情接口获取数据 # 需要先安装他们的库:pip install cmesdata import cmesdata as cmes # 初始化客户端,这里需要你自己的token client = cmes.DataClient(api_token="你的token") # 尝试获取某合约的tick数据 # 注意参数:合约代码、开始结束时间、数据类型要写对 try: data = client.get_tick_data( symbol="RB2410.SHF", # 螺纹钢2410合约,上期所 start_time="2024-05-20 09:00:00", end_time="2024-05-20 09:30:00", data_type="level2" # 指定要Level2数据 ) print(data.head()) # 看看前几行 except Exception as e: print(f"调用出错了: {e}") 对了,说到数据源,一开始我也图省事找过一些免费的,但清洗和整理起来太费劲了,各种错误和缺失,时间都花在这上面了。后来还是用了需要积分兑换的数据库,数据是预处理好的,省心不少。虽然要付出点成本,但想想自己熬夜清洗数据掉的头发,还是觉得值。 数据这东西,尤其是高频率的,新手建议先从日线、分钟线开始玩,直接上Tick真的容易懵,而且对硬件和策略要求都高。今天就先聊这些吧,我得去清理一下爆掉的内存了。 大家好,我想和大家分享一个我最近开发的项目——一款面向量化交易的 AI 智能助手工具网站。它可以帮助大家快速生成高质量、可直接复制运行的量化策略代码,无论你是量化小白还是策略开发者,都能从中受益。 核心亮点: 1.多平台支持:目前已支持 PTrade、QMT、miniQMT、聚宽等,并计划不断扩展更多平台。 2.策略生成高效:用户只需选择平台并输入策略想法,AI 即可生成可运行的量化策略代码。 3.快速入门与优化: • 对量化小白:轻松生成可直接运行的策略,快速上手交易。 • 对策略开发者:帮助完善、优化已有策略,节省开发时间。 • 对文档需求者:可作为量化平台的 API 文档问答机器人,方便查询和使用。 4.业内首创:这是首个面向多平台的量化交易 AI 助手,解决了现有 Deepseek 或 Trae 等 AI 工具因缺乏平台知识库而生成代码无法运行的问题。 使用方式:登录 → 选择你使用的平台 → 输入策略想法 → 生成可运行的策略代码。 我希望这个工具能帮助大家更高效地进行策略开发和量化交易,也欢迎大家在帖子里分享使用体验和建议。 网站链接:https://iris.findtruman.io/ai/tool/ai-quantitative-trading/ 如果大家有任何问题或功能需求,也可以在帖子里留言,我会持续优化和更新,让它成为量化交易领域最实用的 AI 助手! 引言:为什么你的技术分析总是在人性面前溃不成军? 许多股民在入市之初,都试图通过钻研 K 线、均线或各种复杂的波浪理论来破解财富密码。然而,现实却极其冷酷:即便掌握了满腹的技术指标,绝大多数散户依然难逃亏损的宿命。 究其根本,股市从来不是单纯的数据博弈,而是一个放大人性弱点的“修罗场”。技术只是工具,而人性才是操盘的手。如果你无法“直面人性”中根深蒂固的贪婪与恐惧,任何精妙的技术都会在情绪崩溃的瞬间化为乌有。真正的盈利之道,不在于预测涨跌,而在于建立一套反人性的生存纪律。 核心纪律一:决绝止损——直面“拒绝认错”的认知偏差 止损纪律直接挑战了人性中最难以逾越的障碍:损失厌恶与自尊心。 在交易逻辑中,当股价跌破预设防线,多数人会产生心理学上的“鸵鸟效应”,通过编造各种利好理由来逃避认亏的痛苦。 解释与分析: 止损不是为了亏钱,而是为了在错误的判断中生存。它强制性地切断了人性中的侥幸心理,将损失锁定在可控范围内。没有止损纪律的投资者,本质上是在用有限的本金博弈无限的风险。 核心纪律二:空仓耐心——对抗“急功近利”的捕猎本能 第二条纪律在于忍耐与克制。人性倾向于通过“频繁操作”来获得虚假的掌控感,这种对他人的错失恐惧(FOMO)是散户本金被蚕食的主因。 洞察分享: 必须清醒地认识到,市场本质上是一个“通过夺取不耐心者的钱,来奖励耐心者”的财富再分配机器。贪婪会驱使你在信号不明确时盲目入场,而“空仓纪律”则是要你直面内心的焦虑。空仓不是无所事事,而是像优秀的猎手一样,在灌木丛中保持绝对的静默,直到胜率最高的猎物出现。 核心纪律三:机械执行——构建“知行合一”的防御闭环 最后一条纪律是前两者的“压舱石”,它要求将所有的策略转化为不带感情的肌肉记忆。 逻辑连接: 执行纪律是将止损与耐心串联成防御系统的关键。如果没有坚决的执行,止损(纪律一)就会在“再等五分钟”的纠结中演变成灭顶之灾;如果没有坚决的执行,耐心(纪律二)就会在看到别人赚钱的眼红中瞬间瓦解。执行力保护了耐心带来的利润,更最小化了因违背止损而产生的次生伤害,从而形成一个能够“直面人性”的钢铁防线。 核心要素: **●**预案先行: 每一笔开仓前,必须白纸黑字写下撤退的物理价位,而非盘中临时决定。 **●**去情绪化: 将自己视为执行程序的代码,只对既定信号负责,不对账户盈亏产生心跳反应。 **●**反馈复盘: 评价一笔交易的标准不是赚了多少,而是“是否严丝合缝地执行了纪律”。 总结:纪律是通往盈利的唯一捷径 回顾这三大纪律,你会发现它们无一不是在“逆人性”而行。技术可以速成,但纪律的内化却是一场艰苦的自我修行。所谓“知易行难”,难就难在你要不断地挥刀向内,斩断那个本能的、焦虑的、充满幻想的自己。 纪律看似是束缚,实则是交易者在这充满变数市场中唯一能握住的确定性。 在下一笔交易成交前,请先在纸上写下止损位,并在下单后物理性地将手离开鼠标。尝试这一笔交易:无论涨跌,只看纪律,不看账户。 当你终于能用纪律扼住人性的咽喉时,你认为下一个需要直面的心理黑洞会是什么?