ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

DeepSeek做市商方案:订单簿、存货风险与智能报价闭环

DeepSeek做市商方案:订单簿、存货风险与智能报价闭环 简介一份聚焦 DeepSeek 大模型在证券做市商报价与流动性管理场景中落地的技术方案面向量化做市、金融 AI 与证券系统开发人员系统讲解从市场微观结构解析、存货实时风险计量到智能报价策略的完整闭环。文档共 530 页、52 个大章节内容覆盖行业痛点拆解、报价体系范式转变、流动性指标构建、多源数据资产梳理、行情与交易数据预处理、存货时序建模、市场情绪文本向量化、数据标注体系、训练目标函数设计、模型训练与微调等关键模块尤其覆盖报价合理性、存货风险等级、流动性充足度等标注规范贯通数据到模型的工程化落地路径并配有目录章节跳转和书签大纲便于按需检索和深入研读。资源包仅含 1 个 PDF 文件大小约 15.77MB排版与图表显示完整可稳定查阅。已有 96 人学习下载适合需要建立 AI 驱动做市商报价体系方法论并落地场景化模型的从业者参考。1. DeepSeek做市商方案把报价与存货风险放进同一套闭环做市商的日常纠结在于交易所要求持续双边报价市场一波动刚挂在盘口的单子就可能变成存货。传统规则引擎靠固定价差和人工盯盘高流动性品种报价过宽赚不到钱低流动性品种报价过窄又接回一肚子存货。这份530页的 DeepSeek 做市商方案主线不是“训一个通用大模型”而是把市场微观结构解析、存货风险实时计量、智能报价策略串成闭环先做数据语义化转换再做时序特征与注意力机制风险计量最后落到动态价差和PPO挂单量决策。覆盖数据标准化、标注体系、LoRA/QLoRA微调、蒸馏压缩、TensorRT推理加速的完整链路适合自建做市系统的量化团队和券商IT部门。2. 市场微观结构解析订单簿、成交单、撤单记录的语义化转换做市商模型看到的市场不是K线而是三股离散事件流订单簿快照、逐笔成交、撤单记录。三者问题各不相同——快照是离散的两次快照之间的中间状态丢失逐笔成交部分数据源没有主买主卖方向需要从盘口反推撤单记录最常见的坑是被直接过滤掉但撤单率恰恰是识别虚假流动性的关键信号。文档把这一层定义为“交易数据结构化”核心是把异构原始数据转成统一语义的事件流给后续特征工程与模型推理提供一份干净、可对齐的输入。提示实盘中这一层通常用 Kafka 承接行情源结构化结果以 Parquet 落列式存储回测与实盘共用同一份口径避免“回测用逐笔、实盘用快照”的口径漂移。2.1 原始交易数据的形态分析与结构化原则先看三类原始数据的典型形态。订单簿快照是周期性的交易所按固定间隔推送常见每 100ms 或 500ms 一帧按数据源而定每帧包含买一到买五、卖一到卖五的价格和手数逐笔成交是事件驱动的有成交时间、成交价、成交量但没有统一的买卖方向字段撤单记录同样是事件流描述某一档位的挂单被部分或全部撤销。结构化原则我总结为三条事件对齐快照、成交、撤单统一到同一时间轴时间戳精确到毫秒但不能简单按“同一毫秒归并”需要按交易所消息序号排序状态校准订单簿从快照重建逐笔成交按主动成交方向拆成 taker 视角的买/卖撤单记录用于动态修正订单簿深度全量留痕结构化后的数据不能只保留摘要原始消息序号必须保留用于事后审计和行情回放。这里有个容易踩的坑快照和逐笔成交的时间戳精度不一致时直接 join 会把大量成交挂到错误的盘口上。常见做法是引入消息序号对齐如果某个成交单找不到对应快照帧就按最近一帧快照重建盘口而不是丢弃这条成交。2.2 订单簿数据的语义化转换实现订单簿语义化的第一层不是特征而是把五档快照转成“可计算的盘口状态”。下面这段代码把常用的盘口特征一次性算出来订单簿不平衡度、加权价差、深度比。import numpy as np def order_book_features(snapshot: dict) - dict: bid_prices np.asarray(snapshot[bid_prices], dtypefloat) # 买一到买五 bid_volumes np.asarray(snapshot[bid_volumes], dtypefloat) ask_prices np.asarray(snapshot[ask_prices], dtypefloat) ask_volumes np.asarray(snapshot[ask_volumes], dtypefloat) bid_levels len(bid_prices) ask_levels len(ask_prices) if bid_levels 0 or ask_levels 0: return {} best_bid bid_prices[0] best_ask ask_prices[0] mid_price (best_bid best_ask) / 2.0 # 订单簿不平衡度正值代表买方主导 total_bid_vol bid_volumes.sum() total_ask_vol ask_volumes.sum() imbalance (total_bid_vol - total_ask_vol) / (total_bid_vol total_ask_vol 1e-12) # 加权价差按前n档深度加权的有效价差 depth_weights np.arange(1, min(bid_levels, ask_levels) 1, dtypefloat) depth_weights depth_weights / depth_weights.sum() depth_bid (bid_volumes[:len(depth_weights)] * depth_weights).sum() depth_ask (ask_volumes[:len(depth_weights)] * depth_weights).sum() weighted_spread (best_ask - best_bid) / mid_price 0.01 * (depth_ask - depth_bid) # 深度比买盘前5档总量 / 卖盘前5档总量 depth_ratio (total_bid_vol 1e-12) / (total_ask_vol 1e-12) return { mid_price: mid_price, imb: round(imbalance, 6), weighted_spread: round(weighted_spread, 6), depth_ratio: round(depth_ratio, 6), }代码逻辑订单簿不平衡度imb是盘口方向性的第一信号正值越高意味着买方挂单越厚模型在报卖价时会倾向收紧价差加权价差把前五档深度按距离买卖一档的远近加权避免只用最优档导致价差对厚盘口失真深度比是流动性充裕度的简化代理低于 0.8 时通常意味着卖压集中报价策略应降低卖出挂单量。在语义化层这组特征还需要拼上快照时间戳、标的代码、消息序号组成一条宽表记录。字段结构建议按下面的 schema 落库字段类型说明symbolstring证券代码ts_eventint64事件时间戳毫秒seq_noint64交易所消息序号用于对齐mid_pricefloat64中间价imbfloat64订单簿不平衡度weighted_spreadfloat64加权价差depth_ratiofloat64买卖盘深度比bid_vol0int32买一档量bid_vol1..bid_vol4 以此类推2.3 成交单与撤单记录的语义化转换成交单语义化的关键动作是判定主买主卖taker side。常见做法是拿成交价与当前盘口比较成交价大于等于卖一价记为主动买小于等于买一价记为主动卖如果成交价落在买卖价之间则用上一笔成交相对中间价的移动方向辅助判定。def process_trades_and_cancels(trades: list, cancels: list, ask_price: float, bid_price: float): buy_vol 0.0 sell_vol 0.0 for t in trades: if t[price] ask_price: buy_vol t[volume] elif t[price] bid_price: sell_vol t[volume] else: # mid_direction 是上游根据最近一笔成交相对中间价的方向标记的 1/-1 if t[mid_direction] 0: buy_vol t[volume] else: sell_vol t[volume] total_placed sum(c[placed_volume] for c in cancels) total_cancelled sum(c[cancelled_volume] for c in cancels) cancel_ratio total_cancelled / (total_placed 1e-12) return { buy_volume: buy_vol, sell_volume: sell_vol, cancel_ratio: round(cancel_ratio, 6), }撤单率这个特征容易踩坑。撤单率高不一定代表流动性差也可能是大资金在试探盘口。做市商模型通常会再叠加一个时间约束只看 30 秒窗口内撤单率超过 40% 且成交同步萎缩的场景才判定为虚假流动性高撤单率叠加高成交量更可能是高频对手方在抢单对报价策略的参考价值完全不同。这个区分在特征工程阶段就要做不要等模型自己去悟。2.4 质量校验与性能优化结构化数据上线前要做质量校验我一般加四类检查价格档位单调性买一价必须小于买二价、成交价是否落在买卖价合理范围内、消息序号是否连续跳号说明丢行情、撤单量是否小于等于当时挂单量。任何异常要在 Kafka 消费端按标的熔断避免脏数据污染模型输入。性能方面单标的行情处理延迟要求严格。常见优化是订单簿不平衡度和撤单率做成增量计算只在快照更新和撤单事件到达时重算受影响字段而不是每帧全量重算。单节点每秒处理十万级行情快照在主流配置下并不难难点在数据对齐消息序号一旦有缺口整个时间窗口的特征都要标记为不可信而不是填一个默认值继续算。3. 存货风险精准计量从时序特征工程到注意力机制存货风险的计量链路是“两段式”结构上段是手写规则和时序特征工程保证可解释和低延迟下段才是 DeepSeek 大模型参与的注意力权重分配解决多因子动态加权的问题。两段之间由滑动窗口衔接。3.1 存货时序特征工程持仓量、持仓成本、持仓时长做市商的持仓方向可能是多头也可能是空头持仓成本必须按方向分开计算不能只算一个均价。实际落地的计算类是下面这个样子class InventoryTracker: def __init__(self, symbol: str): self.symbol symbol self.position 0.0 self.long_qty 0.0 self.long_cost 0.0 # 多头持仓总成本 self.short_qty 0.0 self.short_cost 0.0 # 空头累计开仓资金 self.open_time 0.0 def update(self, price: float, qty: float, direction: str): # direction: buy 买入, sell 卖出 if direction buy: if self.position 0: # 先平空头 cover min(qty, -self.position) self.short_qty - cover self.short_cost - cover * price leftover qty - cover if leftover 0: self.long_qty leftover self.long_cost leftover * price else: self.long_qty qty self.long_cost qty * price else: # sell if self.position 0: # 先平多头 reduce min(qty, self.position) self.long_qty - reduce self.long_cost - reduce * price leftover qty - reduce if leftover 0: self.short_qty leftover self.short_cost leftover * price else: self.short_qty qty self.short_cost qty * price self.position self.long_qty - self.short_qty这段代码是存货成本更新的核心。两个细节要注意一是平仓和开仓要拆开处理方向转换时空头和多头不能混在一个池子里算二是成本更新必须用移动加权法不能用简单算术平均否则方向转换时持仓成本会被严重扭曲。持仓时长在每次 update 时同步更新单位用秒超过设定阈值比如 600 秒的部分要单独拆出来作为压力信号这部分信号是后续注意力机制里“持仓时长因子”的原始输入。3.2 滑动窗口设计长度与更新频率的量化选择滑动窗口有四个关键参数窗口长度、更新频率、衰减函数、对齐方式。窗口长度直接决定风险计量的灵敏度太长会把大幅波动平滑掉太短会把日内噪声当成趋势。参数取值影响窗口长度60s / 300s / 600s60s 灵敏但噪声大600s 稳定但风险响应慢更新频率50ms / 250ms50ms 适合高波动标的CPU 开销高衰减函数线性 / 指数指数衰减更贴近市场记忆效应对齐方式按消息序号防丢失按时间戳对齐在行情跳变时不可靠选型上分标的配置比全局统一更合理。高波动小盘股窗口长度建议 60 秒更新频率 250 毫秒大盘蓝筹可以放到 300 秒窗口因为订单簿结构更稳定短窗口只会增加无效报警。窗口数据要做到增量维护新数据进来时用 O(1) 复杂度更新统计量避免每帧从全量滚动窗口重新聚合。3.3 基于注意力机制的风险因子权重分配时序特征工程做完后进入 DeepSeek 模型的注意力层。风险因子包括市场波动率、订单簿不平衡度、存货偏离度、持仓时长压力、宏观舆情向量等。注意力机制起的作用是给每个因子动态分配权重——不同市场状态下主导风险的因子完全不一样。下面是用 NumPy 手写单头注意力的简化实现逻辑与 Transformer 中的 attention 一致def factor_attention(factor_matrix: np.ndarray, market_state: np.ndarray) - np.ndarray: # factor_matrix: [n_factors, feature_dim] 每个因子一行 # market_state: [feature_dim] 当前市场状态向量 feature_dim factor_matrix.shape[1] query market_state W_q # 生成查询向量 keys factor_matrix W_k # 生成每个因子的键向量 scores np.dot(keys, query) / np.sqrt(feature_dim) weights np.exp(scores) / np.exp(scores).sum() return weights # 权重向量shape[n_factors]这里的W_q、W_k是微调阶段学到的参数。实际工程直接用 PyTorch 实现即可原理一致。权重输出有双重用途一是给下游存货风险打分模型作为输入二是做注意力权重可视化满足风控对模型决策路径可追溯的要求。权重异常比如市场暴跌时权重仍集中在舆情因子上说明模型需要重新校验这是生产环境里很有价值的监控信号。3.4 风险预警阈值的自适应校准静态阈值在波动率突变的环境里会失效波动放大时静态阈值会频繁误报波动收敛时又会漏报。自适应校准用已实现波动率和 EWMA 实时调整阈值def calibrate_threshold(vol_series: np.ndarray, base_threshold: float, alpha0.94): ewma_vol np.zeros_like(vol_series) ewma_vol[0] vol_series[0] for i in range(1, len(vol_series)): ewma_vol[i] alpha * ewma_vol[i - 1] (1 - alpha) * vol_series[i] vol_ratio vol_series / (ewma_vol 1e-12) return base_threshold * (0.7 0.6 * np.clip(vol_ratio, 0, 2.5))核心在vol_ratio当前波动率与平滑基线的比值低于 1阈值收紧提高灵敏度高于 1阈值放宽容忍更大的风险波动。但自适应不能无限放大必须保留硬上限极端行情下硬上限兜底比任何自适应权重都可靠。兜底触发时的动作是强制切换到应急报价模式冻结挂单量并扩大价差。4. 智能报价策略响应闭环动态价差、挂单量分配与模型压缩风险计量模型输出的是“当前存货风险状态”真正落到交易所的是报价。报价闭环分三层动态价差模型决定价格PPO 挂单量算法决定数量模型服务层保证推理延迟与并发。4.1 动态价差模型融合存货成本与市场流动性价差不是固定值而是存货成本、市场波动、流动性深度三者的函数。常见做法是spread_target base_spread k1 * inventory_risk k2 * volatility k3 * (1 - depth_ratio) bid mid_price - 0.5 * spread_target ask mid_price 0.5 * spread_target其中base_spread是覆盖交易成本的最小价差inventory_risk由第三章的风险计量模型输出volatility是当前波动率depth_ratio是订单簿深度比k1、k2、k3在模型微调阶段训练。完整计算逻辑如下def compute_quote(mid_price: float, inventory_risk: float, volatility: float, depth_ratio: float, base_spread: float) - dict: k1, k2, k3 2.0, 0.8, 0.5 spread_target base_spread k1 * inventory_risk k2 * volatility k3 * (1 - depth_ratio) # 价差下限保护不能低于交易所最小报价单位 spread_target max(spread_target, 2 * tick_size) bid mid_price - 0.5 * spread_target ask mid_price 0.5 * spread_target return {bid: round(bid, 4), ask: round(ask, 4), spread: round(spread_target, 4)}参数k12.0表示存货风险每上升 1 个标准差报价价差扩大 2 个基点k30.5表示深度比从 1 掉到 0.5 时价差额外扩大 0.25 个基点。系数在实盘前用历史行情回放校准实盘后用在线数据滚动更新。价差模型输出的价格不是直接下单价还要经过交易所最小报价单位tick size的取整和交易所规则校验。4.2 挂单量决策深度强化学习与 PPO价差模型只决定价格挂单量分配用深度强化学习。问题建模为 MDP状态是订单簿不平衡度、存货风险、市场波动率、当前挂单量动作是各档位挂单量的连续值奖励函数是价差收益减去存货风险惩罚。策略网络用 PPO 训练训练循环的核心骨架def ppo_update(actor, critic, buffer, optimizer, eps0.2): states buffer[states] # 状态张量 actions buffer[actions] old_probs buffer[log_probs] advantages buffer[advantages] for _ in range(3): _, new_probs actor(states, actions) ratio torch.exp(new_probs - old_probs) clipped torch.clamp(ratio, 1 - eps, 1 eps) * advantages actor_loss -torch.min(ratio * advantages, clipped).mean() optimizer.zero_grad() actor_loss.backward() optimizer.step()eps0.2是 PPO 默认的裁剪幅度控制每次更新的步长防止一次更新把策略推得太远。PPO 在这里的优势是多品种共享策略不同标的的状态分布差异很大但共享策略网络可以学到“高风险状态下减小挂单量”的通用逻辑再通过微调适配个别品种的成交偏好。挂单量输出范围受交易所单笔申报上限约束这个约束在动作层就要用 tanh 或 clip 限定而不是在奖励函数里做软惩罚。4.3 模型层落地LoRA/QLoRA微调与蒸馏压缩深层次的大模型在做市商场景不能整权重微调版本迭代成本太高回滚也麻烦。方案里落的是 LoRA 和 QLoRA参数LoRA 建议值说明r16秩越低越省显存低于 8 效果下降明显alpha32缩放因子alpha/r 通常取 2dropout0.05防止小样本过拟合target_modulesq_proj, v_proj仅适配注意力投影矩阵量化位宽4bit (QLoRA)NF4 量化显存占用压到三分之一以下QLoRA 把预训练权重做成 4bit NF4 格式缓存反向传播只更新低秩适配器。蒸馏阶段把教师模型知识迁移到小模型用 KL 散度做蒸馏损失输出层用温度参数柔化概率分布def distill_loss(student_logits, teacher_logits, temperature3.0): soft_teacher torch.softmax(teacher_logits / temperature, dim-1) log_soft_student torch.log_softmax(student_logits / temperature, dim-1) kl (soft_teacher * (soft_teacher.log() - log_soft_student)).sum(-1).mean() return temperature * temperature * kl蒸馏温度取 3 通常比 1 效果好因为软标签携带了类间关系信息最后还要与真实标签的交叉熵按 0.5:0.5 加权避免模型只学教师不学真值。4.4 推理加速与缓存TensorRT/ONNX与热点股票识别大模型微调后的服务化依赖推理引擎。常见流程是 PyTorch → ONNX → TensorRT Engine再做 INT8 量化# 导入ONNX python -c import torch; m torch.load(model.pt); d torch.randn(1, 128); torch.onnx.export(m, d, model.onnx, opset_version17) # 构建TensorRT引擎 trtexec --onnxmodel.onnx --saveEnginemodel_int8.engine --int8 --fp16trtexec是 TensorRT 自带的引擎构建工具--int8 --fp16同时开启两档精度优化在常见显卡上能把单次推理耗时压到毫秒级。缓存策略上热点股票的报价请求频率极高本地内存缓存命中率能到 80% 以上。热点识别用报价频率的 EWMA 排序每 5 秒更新一次热榜热点股票走进程内缓存冷门标的走 Redis 缓存数据老化时间分别设 50ms 和 500ms既保证热点标的毫秒级响应又控制冷门标的的缓存穿透。5. 训练与生产验证时序滑窗划分、评估指标与版本回滚5.1 时序滑窗划分与多目标损失函数训练集划分必须用时序滑窗法禁止随机打散。做市商数据是强时序相关的随机切分会把未来信息泄漏到训练集。滑窗参数建议训练窗口 5 天验证窗口 1 天步长 1 天既保证样本量充分又模拟“前知后不知”的实盘口径。def temporal_split(events, train_days5, val_days1, step_days1): dates sorted(set(events[date])) for i in range(0, len(dates) - train_days - val_days 1, step_days): train events[events[date].isin(dates[i:i train_days])] val events[events[date].isin(dates[i train_days:i train_days val_days])] yield train, val损失函数要融合报价收益与存货风险不能只回归报价价差。常见写法是loss lambda_price * MSE(预测价差, 真实价差) lambda_risk * 存货波动率惩罚两类损失的反向梯度必须分开打印训练曲线避免收益项把风险项完全压制。5.2 微调效果评估报价准确率、存货波动率、流动性覆盖率三个核心评估指标各有口径指标定义告警阈值报价准确率报价落在最优买卖价之间且被市场成交的比例低于 60% 触发告警存货波动率日内持仓净值的标准差超过 2% 触发告警流动性覆盖率有效报价时间占比低于 90% 触发告警评估时注意报价准确率的统计口径是“按盘口最优价成交”还是“按模型中价成交”两者差异巨大。生产环境按前者统计因为做市商业务赚的是真实成交的钱不是模型认为合理的钱。注意力权重可视化在生产里同样有价值模型失控前往往先出现注意力权重异常集中。5.3 模型版本管理与生产告警版本管理要支撑“秒级回滚”。每个模型版本打上唯一标签例如dsmm_v20260126_lora16_q4发布后先跑 30 分钟模拟盘评分通过才能进生产。生产监控指标包括报价偏差模型报价与市场共识价的偏离度和风险计量误差预测 VaR 与回测 VaR 的偏差任一指标连续 5 分钟超阈值自动切回上一个稳定版本而不是在线上热修。版本切换时旧模型缓存预热 60 秒这期间报价服务保持只读不重算避免切换窗口产生额外延迟未成交的挂单同步撤销并重新报价。告警分级上报价偏差超过 0.5 个基点、撤单率连续 10 秒高于 60%、大模型推理 P99 延迟超过 50ms都要进入独立告警通道。P99 延迟告警的检查间隔不低于 5 秒避免瞬时抖动造成告警风暴真正要盯的是“连续三个检查周期都超限”的趋势而不是单点尖峰。本文还有配套的精品资源点击获取
返回列表