1. 防刷护盾:若程序存在频繁断开重连的死循环逻辑,IP 将被永久拉黑。
2. 消费性能:Level2 数据量极大。若客户端处理过慢导致 TCP 缓冲区积压,服务端将下发缓慢警告报文。强烈建议采用“网络接收与业务逻辑分离”的异步队列架构。
注意:按需订阅模式下的端口已全面升级,所有类型数据均使用 181XX 频段,请严格对照列表连接以防验证失败。
协议格式:所有数据包均以 < 开始,> 结束。每次推送均为单条数据记录。字段以 , 分隔。
| 交互环节 | 指令方向 | 格式示例 | 功能与说明 |
|---|---|---|---|
| 1. 登录验证 | C -> S | <DL,用户名,密码> |
TCP 连接建立后首条指令,返回成功方可进行后续操作。 |
| 2. 发送订阅 | C -> S | <DY2,用户名,密码,000001.SZ,600000.SH> |
按需模式适用。断线重连需重新下发订阅。全推用户忽略此步。 |
| 3. 接收数据 | S -> C | <消息ID,带后缀代码,纯代码,时间,字段1...> |
保持接收循环,按数据字典进行字符串分割解析。 |
| 4. 取消订阅 | C -> S | <QXDY2,用户名,密码,000001.SZ> |
停止接收指定标的数据。 |
| ⚠️ 异常推送 | S -> C | <WARN,SLOW,接收缓慢警告> (具体指令视服务端而定) |
接收缓慢警告:当客户端读取 Socket 流过慢导致服务端缓冲区积压时下发。收到此数据代表本地消费性能严重不足,若持续积压可能被服务端强制断开连接。 |
| 接口地址 | 请求方式 | 参数 (JSON Body) | 功能描述 |
|---|---|---|---|
| http://down.l2api.cn:9090/Login | POST | {"userName":"x", "userPwd":"x"} |
HTTP 盘中数据下载授权,获取 Cookie Token。 |
| http://down.l2api.cn:9090/GetData | POST | {"type":"Market", "stock":"000001.SZ"} |
获取标的当日历史切片数据 (自带 GZIP 压缩流)。 |
成交价格 == 0 且 叫卖/叫买序号 != 0。
委托类别(Type) == 10 即为撤单。
import requests import gzip import base64 from io import BytesIO # API 基础 URL BASE_URL = "http://down.l2api.cn:9090" def login(user_name, user_pwd): url = f"{BASE_URL}/Login" payload = {"userName": user_name, "userPwd": user_pwd} response = requests.post(url, json=payload) result = response.json() if result["Code"] == 200 and result["Data"]["code"] == 0: return response.cookies.get('__beetlex_token') return None def get_data_and_save(token, data_type, stock): url = f"{BASE_URL}/GetData" headers = {'Cookie': f'__beetlex_token={token}'} payload = {"type": data_type, "stock": stock} res = requests.post(url, json=payload, headers=headers).json() if res["Code"] == 200: gzip_data = res["Data"]["data"] date_str = res["Data"]["time"] # 解码与解压引擎直送的 Gzip Base64 内存流 compressed = base64.b64decode(gzip_data) with BytesIO(compressed) as bs, gzip.GzipFile(fileobj=bs, mode="rb") as gf: csv_text = gf.read().decode("utf-8-sig").rstrip("\r\n") file_name = f"{date_str}_{data_type}_{stock}.csv" with open(file_name, "w", encoding="utf-8") as f: f.write(csv_text) print(f"[*] 数据极速落盘成功: {file_name}") if __name__ == "__main__": token = login("your_username", "your_password") if token: get_data_and_save(token, "Market", "000001.SZ")
官方提供基于底层 Socket 的完整解决方案,包含网络维活、断线重连、解决 TCP 粘包拆包,以及字符串极速分割组装逻辑。
前往 123云盘 下载 Demo提取码: 8A6f
注:以上为单条快照推送报文。下表从 94131000(时间)开始计算索引 [0],前面的 13810,600531.SH,600531 为外层包头(包含消息ID、带后缀代码、纯代码)。
| 索引 | 字段含义 | 索引 | 字段含义 | 索引 | 字段含义 |
|---|---|---|---|---|---|
| [0] | 时间 (HHMMSSmmm) | [1] | 状态 | [2-6] | 前收盘价 / 开盘价 / 最高价 / 最低价 / 最新价 |
| [7-16] | 申卖价 1-10 档 | [17-26] | 申卖量 1-10 档 | [27-36] | 申买价 1-10 档 |
| [37-46] | 申买量 1-10 档 | [47-49] | 成交笔数/总量/总金额 | [50-51] | 委托买入总量 / 卖出总量 |
| [52-53] | 加权平均委买/卖价 | [54-55] | 涨停价 / 跌停价 | [56-57] | 买入/卖出 总笔数 仅沪市, 深市为0 |
| [58-59] | 买撤笔数 / 买撤数量 沪市 | [60-61] | 卖撤笔数 / 卖撤数量 沪市 |
注:标准的单条委托数据推送。下表从 94128330(时间)开始计算索引 [0],前面的部分为外层包头(包含消息ID、带后缀代码、纯代码)。
| 索引 | 字段名称 | 补充说明 / 枚举值 |
|---|---|---|
| [0] | 时间 | 格式:HHMMSSmmm (如 110747830 代表 11:07:47 830) |
| [1] | 委托号 | 交易所生成的委托流水号 |
| [2] | 委托价格 | 精度一般为 4 位小数(具体视标的而定) |
| [3] | 委托数量 | 报单股数 |
| [4] | 委托类别 | 10:撤单(沪市撤单标记) | 1:市价 | 2:限价 | 3:本方优先 |
| [5] | 委托代码(买卖方向) | 1: B (买入) | 2: S (卖出) |
| [6] | 原始订单号 | 上交所标识订单唯一编号 仅上交所 |
| [7] | 逐笔数据序号 | 仅上交所 |
| [8] | 交易所通道号 | 同一交易日内同一批股票同一个通道 |
注:标准的单条成交数据推送。下表从 94127920(时间)开始计算索引 [0],前面的部分为外层包头(包含消息ID、带后缀代码、纯代码)。
| 索引 | 字段名称 | 补充说明 / 枚举值 |
|---|---|---|
| [0] | 时间 | 格式:HHMMSSmmm |
| [1] | 成交编号 | 交易所成交流水号 |
| [2] | 成交价格 | 深市撤单时此字段必定为 0 |
| [3] | 成交数量 | 撮合股数 |
| [4] | 成交金额 | 总金额 |
| [5] | 买卖方向 | 1: B | 2: S (主动发起方) |
| [6] | 成交类别 | 0: 正常成交 | 1: 撤单状态标记 |
| [7] | 频道代码 | 内部路由通道号,无特殊业务意义 |
| [8] | 叫卖方委托序号 | 被撮合的卖方原始委托流水号 |
| [9] | 叫买方委托序号 | 被撮合的买方原始委托流水号 |