DeepSeek驱动做市商智能报价:微观结构解析与存货风险控制

DeepSeek驱动做市商智能报价:微观结构解析与存货风险控制 简介PDF资源《DeepSeek证券做市商报价与流动性管理方案基于市场微观结构解析、存货实时风险精准计量与智能报价策略》共530页面向量化研究员、做市交易员与金融AI从业者系统解决做市商报价体系从传统规则向AI驱动转变中的痛点与落地路径。全卷共52个大章节以单个PDF文件封装体积15.77MB支持目录书签跳转与章节快速定位文字、图表显示完整正常。内容从业务痛点与AI赋能机遇切入依次涵盖多源数据资产梳理、行情与交易数据结构化、存货动态建模、市场情绪文本向量化、数据标注与质量校验、场景仿真增强、时序滑窗数据划分、多目标损失函数设计、金融领域预训练与指令微调等模块形成从数据到决策的完整闭环。已有96人学习下载适合需要结合市场微观结构与存货实时风险控制来构建智能报价策略的中高级从业者参考。1. 做市商为什么需要 DeepSeek报价义务、存货风险与智能报价的落地链条做市商报价系统最容易走偏的地方是把 DeepSeek 当成会报价的模型直接喂行情让它写价格。真实落地时模型只占整条链路最后一小段前面是市场微观结构解析出来的特征流中间是存货实时风险计量给出的约束最后才是智能报价策略在约束里选参数。判断一套方案能不能上线先看这三段有没有闭环而不是看模型回答是否漂亮。标题里 530 页的方案价值同样在这个顺序里落到生产环境至少要回答三个问题——行情特征怎么算、库存风险怎么衡量、报出去的价怎么既满足做市义务又不养大亏损。这里按这条链路给一套可复现的实现先把微观结构指标算成特征再把 DeepSeek API 接进风险计量与报价策略两个环节最后给出参数、常见坑位和上线前验证。适合量化交易系统、行情工程与风险控制方向的从业者前提是让 DeepSeek 只输出参数增量不直接写买卖价格。2. 市场微观结构解析把订单簿变成 DeepSeek 能吃的特征流做市报价依赖的是微观结构不是日线级别的大盘数据。订单簿快照与逐笔成交流是两张最核心的表所有后续计算都从这两份数据出发。我一般会先把字段口径定死再写模型否则第 4 章的报价公式和第 3 章的库存指标对不齐DeepSeek 拿到手的特征就会带符号错误。2.1 订单簿快照与逐笔成交的字段口径Level-2 十档快照加上逐笔成交trade prints是标准输入。关键口径有两个时间戳要区分交易所撮合时间与本地网关接收时间前者用于多路行情对齐后者用于计算行情时延并判断策略是否来得及反应成交记录里的主动方向字段buy/sell不是每个数据源都给缺失时可以用最新成交价相对上一笔成交价的方向做 tick 规则的近似推断。字段归一化之后才能真正被公式引用否则每换一个行情源就要改一遍特征代码。字段类型口径说明后续用途ts_exchangeint64交易所撮合时间纳秒多路行情对齐ts_recvint64本地网关接收时间纳秒时延监控bid_px[0..9] / bid_qty[0..9]float64买一到买十档价格与数量价差、深度、OBIask_px[0..9] / ask_qty[0..9]float64卖一到卖十档价格与数量价差、深度、OBIlast_px / last_qtyfloat64最近一笔成交价与量有效价差、成交压力sidestring主动成交方向buy/sell买卖压力识别字段表里bid_px与ask_px的顺序必须约定清楚买档按价格从高到低卖档按价格从低到高。很多特征算错不是公式问题而是拿到的档位顺序反了导致 OBI 正负颠倒。逐笔成交的side字段如果源数据没给用 last_px 与上一笔 last_px 的比较推断只对明显 tick 跳变有效集合竞价期间的记录要单独过滤。2.2 三个必算的微观结构指标价差、订单簿不平衡、深度梯度特征选择的原则是浓缩市场状态给下游判断用而不是把十档行情原样塞给模型。我常用的指标族有三个相对价差衡量当前交易成本有效价差反映实际成交相对中间价的偏离是逆向选择压力的代理变量订单簿不平衡OBI反映短时间内的买卖压力方向。再补一个深度梯度用来识别盘口是均匀分布还是集中在头部。import numpy as np def microstructure_features(bids, asks, last_price, mid_prev, top_n3, levels10): # bids: 按价格从高到低的 (price, qty)asks: 按价格从低到高 mid (bids[0][0] asks[0][0]) / 2.0 quoted (asks[0][0] - bids[0][0]) / mid if mid 0 else 0.0 eff 2.0 * abs(last_price - mid_prev) / mid_prev if mid_prev 0 else 0.0 w np.arange(1, top_n 1, dtypefloat) w w[::-1] / w.sum() # 越靠近盘口的档位权重越大 bid_vol sum(q * w[i] for i, (_, q) in enumerate(bids[:top_n])) ask_vol sum(q * w[i] for i, (_, q) in enumerate(asks[:top_n])) obi (bid_vol - ask_vol) / (bid_vol ask_vol 1e-12) depth np.cumsum([bids[i][1] asks[i][1] for i in range(levels)]) x np.arange(1, levels 1) slope np.polyfit(x, np.log(depth 1e-9), 1)[0] # 深度梯度 return {mid: mid, quoted_spread: quoted, effective_spread: eff, obi: obi, depth_slope: slope}OBI 用前三档加权而不是直接十档求和是因为近盘口挂单对下一笔成交方向的影响最大权重按档位线性衰减避免某一档挂巨额单把指标带偏。深度斜率用 log 累计深度回归正斜率表示越往深处盘口越厚负斜率表示流动性集中在头部、下方承接不足。effective_spread的有效性依赖mid_prev的准确性如果行情源有断档mid_prev 要从快照缓存里取最近一帧的值不能用 0 填充。2.3 实时特征管道的最小实现实时性要求指标计算不能等收盘后批处理。一个可行做法是流式更新每收到一帧快照就调用一次特征函数再用指数加权把序列平滑后输出给下游。这样做的好处是参数少、行为可预期行情突变时特征能在几个快照内跟上而单笔异常挂单不会让特征反复跳变。class FeatureStream: def __init__(self, decay0.9, top_n3, levels10): self.decay decay self.top_n top_n self.levels levels self.mean {} def update(self, snap): f microstructure_features( snap[bids], snap[asks], snap[last_px], self.mean.get(mid, snap[last_px]), self.top_n, self.levels) for k, v in f.items(): self.mean[k] self.decay * self.mean.get(k, v) (1 - self.decay) * v return fdecay0.9意味着每个新快照有 10% 的权重特征半衰期约为 6~7 帧如果快照频率是 100ms则特征大约记住 700ms 的市场状态。做市场景里这个尺度刚好比单帧噪声长又比分钟级指标灵敏。高频期货或逐笔报价流可以加大 decay 到 0.95如果系统里还同时维护了分钟级波动率记得把两套时间尺度的输出分开存储不要混进同一个特征向量。2.4 DeepSeek 接入与本地部署的取舍DeepSeek 在这个方案里不是行情引擎而是把特征与风险指标转成策略参数的中介。接入方式分两种官方 API 或者本地部署。我一般先测 API 的 p95 时延因为做市报价对延迟敏感模型返回超过 500ms 就可能错过一个报价周期。API 调用要设计成无状态单轮不传历史对话上下文只在 prompt 里拼当前特征这样既避免计数膨胀也不会撞上对话长度上限一类会话级限制。import requests import json def call_deepseek(prompt, api_key, base_urlhttps://api.deepseek.com/chat/completions, modeldeepseek-chat, temperature0.3, timeout8): # 无状态调用不传 history避免上下文膨胀和会话超限报错 resp requests.post( urlbase_url, headers{Authorization: fBearer {api_key}, Content-Type: application/json}, json{ model: model, messages: [{role: user, content: prompt}], response_format: {type: json_object}, temperature: temperature, max_tokens: 400, }, timeouttimeout, ) resp.raise_for_status() content resp.json()[choices][0][message][content] return json.loads(content)response_format指定成 json_object 后模型会尽量输出合法 JSON但解析失败仍要兜底。temperature建议 0.2~0.3报价场景不需要创造性需要的是同一输入下输出稳定。model名称以你在开放平台创建的实际模型名为准别把聊天客户端的模型名直接抄进生产配置。提示遇到request extension preparation failed之类的网关报错先把请求体精简到 model、messages、response_format 三个字段再试多数情况是客户端或代理把请求扩展字段包装坏了与模型本身无关。注意团队里用 vscode 或 codex 接入 DeepSeek 调试 prompt 很顺手但生产链路不要走交互式通道必须走 API 或本地部署否则一次对话重试就会打穿报价节流。3. 存货实时风险精准计量从库存 VaR 到压力情景生成存货风险是做市策略与普通高频策略最大的分水岭。散户或自营策略可以不关心持仓太久做市商不行——报价义务要求双边挂单天然会把库存推离零点。如果风险计量环节反应慢智能报价再聪明也只是在有缺陷的约束里绕圈。3.1 存货风险的三个维度平均成本法只回答这批复牌赚了多少回答不了这些货要多久出完、出完要付出多少滑点。存货风险要拆成三个维度看数量维度是净头寸的绝对值与方向波动维度是存货市值对价格波动的敏感度流动性维度是期望清仓时长由持仓量除以你愿意贡献的成交量占比得出。三个维度缺一不可只有数量没有波动算不出风险金额只有波动没有流动性算不出风控动作的紧迫程度。3.2 实时指标族与阈值表实时计量我习惯用三个指标构成一个状态机库存 VaR 给出风险金额期望清仓时长给出时间压力二者组合映射到低中高三个风险等级。库存 VaR 采用参数法用特征流里的 1 分钟波动率按分钟数开方外推期望清仓时长用最近 30 分钟的每分钟平均成交量乘以参与率做分母。参与率要根据交易所做市义务和撤单限制调整股票和期货差异很大。风险等级判定条件报价动作LOWVaR 1% 净资产 且 T_lq 15 分钟维持基准参数MEDVaR 占 1%~3% 或 T_lq 15~60 分钟报价朝持仓反方向偏移缩短 THIGHVaR 3% 或 T_lq 60 分钟暂停单边报价进入降级模式import numpy as np def inventory_risk(position, nav, sigma_min, t_minutes, minute_vol, participation0.1, z1.645): # position: 净库存(股)正数为多头sigma_min: 1分钟波动率 var abs(position) * sigma_min * np.sqrt(t_minutes) * z liq_time abs(position) / (minute_vol * participation 1e-12) var_ratio var / (nav if nav 0 else 1.0) if var_ratio 0.01 and liq_time 15: level LOW elif var_ratio 0.03 or liq_time 60: level MED else: level HIGH return {var: var, var_ratio: var_ratio, liq_time_min: liq_time, level: level}这里t_minutes取你愿意承担的风险持有期通常与第 4 章报价模型里的 T 一致保持两个模块信念统一。z1.645对应 95% 单尾置信度如果风控要求更严可以换成 2.32699%。波动率输入要用 EWMA 平滑后的 1 分钟收益波动率不能用日线波动率除以交易时间片——后者在行情突变时反应太慢等到 VaR 越过阈值库存早就打穿了。注意participation不要设成 1.0那等于假设你可以在不影响市场的前提下瞬间清仓。常见做法是 0.1~0.2即你愿意贡献全市场每分钟成交量的一到两成来缩减库存。3.3 用 DeepSeek 生成压力情景并校验3.3.1 Prompt 设计要点存货压力情景生成是 DeepSeek 在风控侧比较实用的点让模型基于当前库存、波动率和新闻标题产出未来一小时内可能出现的恶劣价格路径类型与幅度再把这个定性输出交给内部的随机过程去模拟。关键是不能让模型自由发挥必须限定输出为固定 schema 的 JSON。def build_stress_prompt(position, sigma_min, headlines): news | .join(headlines[:5]) return ( 你是证券做市商的存货压力分析师。当前净库存(股) str(position) f1分钟波动率{sigma_min:.6f}近期新闻 news 。给出3个对当前存货最不利的价格路径情景输出JSON {scenarios:[{name:...,path_type:adverse/flash_crash/flat, expected_move_pct:0.0,duration_min:10,trigger:...}]}。只输出JSON。 )path_type限死在三个枚举值里expected_move_pct要求是百分比数值而不是自然语言描述这样下游可以直接按幅度参数化价格路径。新闻标题最多取 5 条超过之后信息增益急剧下降而 token 成本仍在涨。duration_min给出情景持续时长用来和第 3.2 节的期望清仓时长对比如果清仓需要 40 分钟而最恶劣情景持续 20 分钟说明还在可承受范围如果反过来就要直接触发降级。3.3.2 返回校验与兜底模型返回后不能直接信。第一步json.loads解析第二步校验 schema 字段是否齐全且类型正确第三步检查expected_move_pct是否落在合理区间比如 ±30% 以内是合理超过就先丢弃。任何一步失败就整体丢弃本次输出沿用上一轮有效参数绝对不能用半截数据继续往下传。提示不要要求 DeepSeek 直接输出完整价格序列。模型生成的是定性情景与幅度价格路径由内部随机过程按这些约束模拟否则单一情景的序列会被当成必然路径回测和实盘的假设就全拧了。4. 智能报价策略报价宽度、报价偏移与 LLM 参数自适应报价策略要同时处理两个目标一方面满足做市义务保证双边持续报价另一方面控制存货风险避免库存单向越滚越大。这两个目标天然冲突处理方式是分层解耦基准模型负责把风险和波动翻译成报价DeepSeek 只在参数层做小幅调整。4.1 分层报价引擎我采用三层结构信号层负责维护特征流与风险指标状态策略层运行一个基准报价模型并接收 DeepSeek 输出的参数增量执行层负责最小变动价位取整、交易所限价规则、报价节流与撤单重挂。约束的传递方向是单向的信号层给策略层输入策略层给执行层输出执行层永远不允许反过来改策略参数。LLM 只允许作用在策略层的参数上不允许直接生成价格这条边界要写死在架构注释里。4.2 基于 Avellaneda-Stoikov 的基准报价模型常见的做法是用 Avellaneda-Stoikov 框架做基准保留价格在中间价基础上减去存货惩罚项半价差由风险厌恶系数、波动率和盘口流动性共同决定。长期库存多头时保留价格下移买价和卖价同时下移结果是买成交减少、卖成交增加把库存压回零点附近。import math def avellaneda_stoikov(mid, q, gamma, sigma, horizon_t, kappa, tick): # q0 表示多头库存保留价格向下偏移以促进减仓 reserve mid - q * gamma * sigma * sigma * horizon_t half (1.0 / gamma) * math.log(1.0 gamma / kappa) 0.5 * sigma * sigma * horizon_t bid math.floor((reserve - half) / tick) * tick ask math.ceil((reserve half) / tick) * tick return bid, ask参数含义建议初始值调参方向gamma风险厌恶系数1e-5~1e-4按库存单位归一库存风险等级升高时上调kappa盘口流动性参数近 5 分钟平均深度 / 平均价差盘口变薄时下调sigma1 分钟波动率特征流 EWMA 输出盘中自适应horizon_t报价有效期分钟5~30清仓时长紧张时缩短gamma的量纲敏感度最高如果按股数直接算gamma 必须放到 1e-5 量级否则gamma * kappa太大导致ln(1 gamma/kappa)失去区分度。kappa的常见标定方法是拿最近 5 分钟盘口深度均值除以平均价差代表市场愿意在多大价格范围内吸收多少量。4.3 DeepSeek 融入策略的参数自适应DeepSeek 在这个环节的任务是把特征、风险等级与新闻标题综合成一个参数增量。输入要紧凑一个 JSON 特征对象、风险等级字符串加最多 5 条新闻标题。输出固定为三个增量d_gamma、d_horizon、d_skew每个限制在 [-0.5, 0.5] 内。这样即便模型判断完全错误参数偏离也只有 50%不会立刻把报价打到极端位置。def adapt_params(features, risk, headlines, base): prompt ( 你是做市报价参数调整器。输入特征 json.dumps(features, ensure_asciiFalse) 风险等级 risk 新闻 | .join(headlines[:5]) 。输出JSON参数增量范围在[-0.5,0.5] {d_gamma:0.0,d_horizon:0.0,d_skew:0.0}。只输出JSON。 ) out call_deepseek(prompt, api_keyAPI_KEY, temperature0.2) d_gamma max(-0.5, min(0.5, float(out.get(d_gamma, 0.0)))) d_horizon max(-0.5, min(0.5, float(out.get(d_horizon, 0.0)))) d_skew max(-0.5, min(0.5, float(out.get(d_skew, 0.0)))) return { gamma: base[gamma] * (1.0 d_gamma), horizon_t: base[horizon_t] * (1.0 d_horizon), skew_shift: d_skew * base[skew_max], }参数的 clamp 要在合成之前做而不是合成之后。如果模型输出里某个字段缺失out.get取默认 0整个请求就算部分失败也仍然返回一份可用的基线参数。skew_max是报价偏移的上限值按最小变动价位的倍数设定比如不超过 5 个 tick。风险等级是 HIGH 时直接跳过 LLM 调用返回基线因为压力场景下模型延迟会进一步放大系统风险。提示参数合成后必须再过一次预交易风控买价低于最新价上限、卖价高于最新价下限、买卖价差不小于一个最小变动价位。LLM 参数增量不允许绕过这层检查这层代码永远由风控团队维护。5. 上线前的三个验证撮合回测、输出稳定性、降级开关做市策略的回测不能只回放价格序列因为挂单是否成交取决于后续订单流穿过你价格的方式。这里给三个上线前必须跑通的验证每个都对应一类常见的实盘事故。5.1 用历史快照重建撮合环境回放历史 Level-2 快照与逐笔成交每帧快照生成一组报价然后看后续逐笔成交是否穿过该报价。队列位置保守假设为 0.5即你的挂单排在队列中间只有一半的穿过量能成交超过 0.5 秒的报价认为已经撤掉或过期避免用一整天的旧报价去撮合几小时后的成交。def replay_fill(quotes, prints, queue_pos0.5, ttl0.5): fills {} for q in quotes: for p in prints: if p.ts q.ts or p.ts q.ts ttl: continue if p.side SELL and p.px q.ask: fills[q.id] q.ask * p.qty * queue_pos break if p.side BUY and p.px q.bid: fills[q.id] q.bid * p.qty * queue_pos break return fills回测输出里要重点盯两个量报价成交率成交笔数除以报价生命周期内被穿过的次数和库存漂移每个交易时段的期末净头寸标准差。如果成交率异常高说明报价过于贴近对手方价格价差没收够如果库存漂移持续单向放大说明 LLM 的 sk_ew 增量在系统性助长某一方向而不是回归中间位置。5.2 输出稳定性检查抽取同一份输入连跑 50 次统计五个指标非法 JSON 率、五个参数增量的标准差、离群值比例增量离 0 超过 0.5 的比例、p95 响应时延、最大响应时延。非法率超过 2% 或 p95 超过 800ms就应该切熔断。会话类报错在日志里出现时基本可以断定有人把聊天客户端接到了生产链路做市调用必须是无状态单轮。5.3 降级开关与归因验证降级条件设三条连续 3 次调用失败或解析失败风险等级为 HIGHp95 时延超标持续 30 秒。任一条件成立就切到基线参数报价同时强制报价偏移归零、报价宽度乘以 1.5 安全系数。降级判断周期固定 1 秒连续失败计数在 30 秒内没有新触发就自动清零。最后把回测成交率、库存漂移和 LLM 参数增量打到同一张日志表做参数增量对成交率的归因分析这样每次改 prompt 或调温度参数都能快速看出改动是在优化系统还是在增加激进程度。本文还有配套的精品资源点击获取