Skip to content

4.9 做市系统

一句话总结:没有做市的预测市场=空市场——流动性是市场的生命线。

📊 学习进度

  • 状态:⬜ 未开始
  • 上次实时更新:2026-07-03
  • 预计时长:4-5 小时
  • 已完成:0/3 个模块
  • 在整体流程中的位置:预测市场实战·第 6 阶段

📍 本章定位

  • 服务方案:方案 3(核心 90%)
  • 学习方式:🔥 推荐
  • 在流程中的作用:提供市场流动性
  • 核心知识点:做市策略、价差管理、库存控制、尾盘处理
  • 预计时长:4-5 小时
  • 完成后能做什么:能搭建基础做市系统

人机分工

环节谁做重要度说明
做市策略设计🧑 人⭐⭐⭐⭐⭐基于金融知识
策略实现🤖 AI⭐⭐⭐⭐AI 生成代码
参数调优🤖 AI + 🧑 人⭐⭐⭐⭐AI 回测,人决策
风控监控🤖 AI⭐⭐⭐⭐AI 实时监控

1. 做市系统概述

1.1 什么是做市

做市(Market Making)是指做市商同时挂出买单和卖单,为市场提供流动性,并通过买卖价差获利的行为。在预测市场中,做市商是市场的"润滑剂",没有做市商,市场就会变成"死盘"。

1.2 为什么预测市场需要做市

没有做市有做市
买卖价差大(>10%)价差小(<2%)
大单无法成交大单可拆分成交
价格波动剧烈价格相对稳定
用户体验差用户体验好
市场变成死盘市场活跃

1.3 做市系统架构


2. 五种做市策略详解

2.1 策略总览

策略功能触发时机核心参数
初始化做市创建初始流动性市场创建时初始价格、初始深度
盘中做市维持盘口深度交易进行中深度、波动率、风险敞口、动态价差
信息实时变动策略根据新信息调整价格有新信息时AI 信号、价格调整幅度
尾盘策略防止尾盘失真接近结算时价格收敛策略
对冲策略控制风险敞口库存单边积累时对冲比例、对冲标的

2.2 初始化做市

初始化做市是在市场创建时,为市场提供初始流动性。

核心逻辑

typescript
interface InitMarketMakingParams {
  eventId: string;
  initialPrice: number;    // 初始价格,如 0.50
  initialDepth: number;    // 初始深度,如 $1000
  spread: number;          // 初始价差,如 0.02 (2%)
  levels: number;          // 挂单层数,如 5
}

function initializeMarketMaking(params: InitMarketMakingParams): Order[] {
  const orders: Order[] = [];
  const { initialPrice, initialDepth, spread, levels } = params;
  
  const depthPerLevel = initialDepth / levels;
  
  for (let i = 0; i < levels; i++) {
    const offset = i * spread;
    
    // 买单:价格递减
    orders.push({
      side: 'YES',
      orderType: 'LIMIT',
      price: initialPrice - spread / 2 - offset,
      quantity: depthPerLevel / (initialPrice - spread / 2 - offset)
    });
    
    // 卖单:价格递增
    orders.push({
      side: 'NO',
      orderType: 'LIMIT',
      price: initialPrice + spread / 2 + offset,
      quantity: depthPerLevel / (1 - initialPrice - spread / 2 - offset)
    });
  }
  
  return orders;
}

2.3 盘中做市

盘中做市是做市系统的核心,负责在交易进行中维持盘口深度。

维度低值时的策略高值时的策略
深度增加挂单量减少挂单量
波动率收窄价差扩大价差
风险敞口减少单边持仓对冲
动态价差提高做市收益降低做市风险

盘中做市核心算法

typescript
class MarketMaker {
  private position: number = 0;  // YES 库存(正=多,负=空)
  private maxPosition: number = 1000;  // 最大库存
  
  /**
   * 计算做市报价
   */
  calculateQuotes(
    midPrice: number,
    volatility: number,
    depth: number,
    inventory: number
  ): { bid: number; ask: number; bidSize: number; askSize: number } {
    // 1. 基础价差 = 波动率 * 系数
    const baseSpread = volatility * 0.5;
    
    // 2. 库存调整:库存偏多时降低买价,偏空时提高卖价
    const inventorySkew = inventory / this.maxPosition * 0.02;
    
    // 3. 深度调整:深度不足时扩大挂单量
    const depthMultiplier = Math.max(1, 1000 / depth);
    
    // 4. 计算买卖价格
    const bid = midPrice - baseSpread / 2 - inventorySkew;
    const ask = midPrice + baseSpread / 2 - inventorySkew;
    
    // 5. 计算挂单量
    const baseSize = 100 * depthMultiplier;
    const bidSize = inventory > 0 ? baseSize * 0.8 : baseSize * 1.2;
    const askSize = inventory < 0 ? baseSize * 0.8 : baseSize * 1.2;
    
    return { bid, ask, bidSize, askSize };
  }
  
  /**
   * 更新库存
   */
  updatePosition(trade: Trade): void {
    if (trade.side === 'YES') {
      // 做市商卖出 YES,库存减少
      this.position -= trade.quantity;
    } else {
      // 做市商买入 YES,库存增加
      this.position += trade.quantity;
    }
  }
}

2.4 信息实时变动策略

当有新信息(如新闻、数据发布)影响事件概率时,做市商需要快速调整价格。

AI 信号处理

typescript
interface InfoSignal {
  source: string;       // 信息来源
  content: string;      // 信息内容
  impact: number;       // 预估影响 (-1 到 1)
  confidence: number;   // 置信度 (0 到 1)
  timestamp: number;
}

function adjustPriceForInfo(
  currentPrice: number,
  signal: InfoSignal
): number {
  // 影响幅度 = 信号影响 * 置信度 * 最大调整幅度
  const adjustment = signal.impact * signal.confidence * 0.1;
  
  // 限制单次最大调整
  const maxAdjustment = 0.05;
  const clampedAdjustment = Math.max(-maxAdjustment, Math.min(maxAdjustment, adjustment));
  
  // 新价格
  const newPrice = Math.max(0.01, Math.min(0.99, currentPrice + clampedAdjustment));
  
  return newPrice;
}

2.5 尾盘策略

接近结算时间时,做市商需要调整策略,防止价格失真。

尾盘策略参数

距离结算时间价差挂单量说明
> 1 小时正常正常标准做市
30 分钟 - 1 小时收窄 50%减少 30%降低风险
10 - 30 分钟收窄 80%减少 60%高度谨慎
< 10 分钟最小最小极度谨慎
< 1 分钟停止停止等待结算

2.6 对冲策略

当库存单边积累时,做市商需要对冲风险。

typescript
interface HedgeParams {
  currentPosition: number;   // 当前 YES 库存
  maxPosition: number;       // 最大允许库存
  hedgeRatio: number;        // 对冲比例 (0-1)
  hedgeTarget: string;       // 对冲标的(其他市场/永续合约)
}

function calculateHedge(params: HedgeParams): number {
  const { currentPosition, maxPosition, hedgeRatio } = params;
  
  // 库存偏移度
  const positionRatio = Math.abs(currentPosition) / maxPosition;
  
  // 需要对冲的数量
  const hedgeQuantity = Math.abs(currentPosition) * hedgeRatio * positionRatio;
  
  return hedgeQuantity;
}

3. 做市商必须解决的问题

问题不解决的后果解决方案
盘口厚度不够大单无法成交动态挂单量
滑点过大用户体验差限价单优先
价差不合理套利者薅羊毛动态价差
尾盘失真结算价格不准确尾盘策略
库存单边积累做市商爆仓对冲策略
风险敞口不可控系统性风险风控阈值

4. 风险管理

4.1 风控指标

指标阈值说明动作
单边库存< 30% 最大库存控制方向风险超过则停止同向挂单
总风险敞口< 50% 资金控制总风险超过则对冲
单笔亏损< 1% 资金控制单笔风险超过则暂停
日亏损< 5% 资金控制日风险超过则停止做市
连续亏损< 3 次控制情绪风险超过则检查策略

4.2 风控实现

typescript
class RiskManager {
  private maxPosition: number;
  private maxDailyLoss: number;
  private consecutiveLosses: number = 0;
  
  constructor(config: RiskConfig) {
    this.maxPosition = config.maxPosition;
    this.maxDailyLoss = config.maxDailyLoss;
  }
  
  /**
   * 检查是否允许做市
   */
  canMakeMarket(position: number, dailyPnl: number): boolean {
    // 检查库存限制
    if (Math.abs(position) > this.maxPosition * 0.3) {
      console.warn('Position limit reached');
      return false;
    }
    
    // 检查日亏损限制
    if (dailyPnl < -this.maxDailyLoss) {
      console.warn('Daily loss limit reached');
      return false;
    }
    
    // 检查连续亏损
    if (this.consecutiveLosses >= 3) {
      console.warn('Consecutive loss limit reached');
      return false;
    }
    
    return true;
  }
  
  /**
   * 更新连续亏损计数
   */
  updateConsecutiveLosses(pnl: number): void {
    if (pnl < 0) {
      this.consecutiveLosses++;
    } else {
      this.consecutiveLosses = 0;
    }
  }
}

4.3 风控流程图


5. 做市收益分析

5.1 收益模型

收益公式

做市利润 = 价差收益 + 手续费返还 - 交易手续费 - 库存损失

价差收益 = 成交量 × 平均价差 × 50%(双边)
手续费返还 = 成交量 × 0.15%(做市商返还)
交易手续费 = 成交量 × 0.3%(做市商费率)
库存损失 = 库存 × 价格变动 × 方向

5.2 收益估算

参数保守估计正常估计乐观估计
日交易量$10,000$50,000$200,000
平均价差1%2%3%
价差收益/日$50$500$3,000
手续费/日$30$150$600
库存损失/日$20$100$400
净收益/日$100$750$4,000
月收益$3,000$22,500$120,000

注意:以上为理论估算,实际收益受市场条件、策略参数、竞争环境等因素影响。


6. 做市系统接口

6.1 核心接口

typescript
// 做市引擎接口
interface IMarketMakingEngine {
  // 初始化做市
  initialize(params: InitMarketMakingParams): Promise<void>;
  
  // 启动做市
  start(): Promise<void>;
  
  // 停止做市
  stop(): Promise<void>;
  
  // 更新参数
  updateParams(params: Partial<MarketMakingParams>): void;
  
  // 获取当前状态
  getStatus(): MarketMakingStatus;
  
  // 获取收益报告
  getPerformanceReport(): PerformanceReport;
}

// 做市状态
interface MarketMakingStatus {
  isRunning: boolean;
  currentPosition: number;
  dailyPnl: number;
  totalPnl: number;
  activeOrders: number;
  lastUpdate: number;
}

// 收益报告
interface PerformanceReport {
  totalTrades: number;
  totalVolume: number;
  averageSpread: number;
  winRate: number;
  sharpeRatio: number;
  maxDrawdown: number;
}

6.2 配置接口

typescript
interface MarketMakingConfig {
  // 基础参数
  spread: number;              // 基础价差
  depth: number;               // 基础深度
  levels: number;              // 挂单层数
  
  // 风控参数
  maxPosition: number;         // 最大库存
  maxDailyLoss: number;        // 最大日亏损
  maxConsecutiveLosses: number; // 最大连续亏损
  
  // 动态调整
  volatilityMultiplier: number; // 波动率系数
  inventorySkew: number;       // 库存偏移系数
  
  // 尾盘参数
  tailStartMinutes: number;    // 尾盘开始时间
  tailSpreadMultiplier: number; // 尾盘价差系数
}

7. OPC 做市策略

7.1 轻量做市方案

作为 OPC,不需要复杂的做市系统。推荐轻量方案:

阶段策略复杂度预期收益
MVP固定价差挂单$100-500/月
P1动态价差+库存管理$500-2,000/月
P2AI 信号+自动调参$2,000-10,000/月

7.2 做市启动清单

  • [ ] 准备做市资金(建议 $5,000+)
  • [ ] 部署做市合约
  • [ ] 配置做市参数
  • [ ] 测试网验证
  • [ ] 主网小额测试
  • [ ] 监控系统搭建
  • [ ] 逐步增加资金

8. 做市策略进阶

8.1 Avellaneda-Stoikov 模型

AS 模型是学术界最常用的做市定价模型,核心思想是根据库存风险动态调整价差:

最优价差 = γ × σ² × (T - t) + (2/γ) × ln(1 + γ/κ)

其中:
γ = 风险厌恶系数(越大越保守)
σ = 波动率
T - t = 剩余时间
κ = 订单到达率

AS 模型实现

typescript
class ASMarketMaker {
  private gamma: number;  // 风险厌恶系数
  private kappa: number;  // 订单到达率
  
  constructor(gamma: number = 0.1, kappa: number = 1.5) {
    this.gamma = gamma;
    this.kappa = kappa;
  }
  
  /**
   * 计算最优报价
   */
  calculateOptimalQuotes(
    midPrice: number,
    inventory: number,
    volatility: number,
    timeToExpiry: number  // 距离结算的秒数
  ): { bid: number; ask: number; spread: number } {
    // 库存风险调整
    const inventoryPenalty = inventory * this.gamma * volatility * volatility * timeToExpiry;
    
    // 最优中间价 = 中间价 - 库存惩罚
    const optimalMid = midPrice - inventoryPenalty;
    
    // 最优价差
    const optimalSpread = this.gamma * volatility * volatility * timeToExpiry 
      + (2 / this.gamma) * Math.log(1 + this.gamma / this.kappa);
    
    return {
      bid: optimalMid - optimalSpread / 2,
      ask: optimalMid + optimalSpread / 2,
      spread: optimalSpread
    };
  }
}

8.2 多市场做市策略

当同时为多个事件市场做市时,需要考虑跨市场相关性:

typescript
class MultiMarketMaker {
  private markets: Map<string, MarketState> = new Map();
  private correlationMatrix: number[][] = [];
  
  /**
   * 跨市场风险对冲
   * 当两个相关事件的库存方向相反时,可以降低风险
   */
  calculateCrossMarketHedge(
    marketA: string,
    marketB: string
  ): number {
    const correlation = this.getCorrelation(marketA, marketB);
    const inventoryA = this.markets.get(marketA)!.inventory;
    const inventoryB = this.markets.get(marketB)!.inventory;
    
    // 如果两个市场正相关且库存方向相反,可以部分对冲
    if (correlation > 0.5 && inventoryA * inventoryB < 0) {
      return Math.min(Math.abs(inventoryA), Math.abs(inventoryB)) * correlation * 0.5;
    }
    
    return 0;
  }
  
  /**
   * 动态分配做市资金
   * 高交易量市场分配更多资金
   */
  allocateCapital(totalCapital: number): Map<string, number> {
    const allocation = new Map<string, number>();
    let totalVolume = 0;
    
    for (const [id, state] of this.markets) {
      totalVolume += state.volume24h;
    }
    
    for (const [id, state] of this.markets) {
      const ratio = state.volume24h / totalVolume;
      allocation.set(id, totalCapital * ratio);
    }
    
    return allocation;
  }
}

8.3 做市回测框架

在上线前必须对做市策略进行历史数据回测:

typescript
interface BacktestResult {
  totalPnl: number;
  sharpeRatio: number;
  maxDrawdown: number;
  winRate: number;
  averageHoldingTime: number;
  totalTrades: number;
}

class MarketMakingBacktester {
  async run(
    strategy: MarketMakingStrategy,
    historicalData: TradeData[],
    initialCapital: number
  ): Promise<BacktestResult> {
    let capital = initialCapital;
    let position = 0;
    const trades: Trade[] = [];
    const equityCurve: number[] = [];
    
    for (const snapshot of historicalData) {
      // 1. 计算报价
      const quotes = strategy.calculateQuotes(snapshot);
      
      // 2. 模拟成交
      const fills = this.simulateFills(quotes, snapshot);
      
      // 3. 更新状态
      for (const fill of fills) {
        position += fill.side === 'BUY' ? fill.quantity : -fill.quantity;
        capital -= fill.quantity * fill.price * (fill.side === 'BUY' ? 1 : -1);
        trades.push(fill);
      }
      
      equityCurve.push(capital + position * snapshot.midPrice);
    }
    
    return this.calculateMetrics(equityCurve, trades);
  }
}

9. 常见问题

问题原因解决方案
做市亏损策略参数不当回测+调优
流动性突然消失做市商停机冗余做市商
价格被操控做市商被夹对冲+风控
库存单边积累趋势市场动态对冲
Gas 费过高频繁调仓批处理+减少频率
竞争激烈其他做市商差异化策略

9. 下一步

完成做市系统后,进入 阶段 7:数据中台

8.4 做市策略参数调优指南

做市策略的效果高度依赖参数设置。以下是经过实战验证的参数调优方法:

参数敏感度分析

参数低值效果高值效果推荐范围敏感度
gamma(风险厌恶)激进,高收益高风险保守,低收益低风险0.05-0.2
kappa(订单到达率)价差大,成交少价差小,成交多1.0-2.0
maxPosition允许大库存限制严格资金的 20-40%
spreadMultiplier价差小,风险高价差大,收益低0.8-1.5

参数调优回测框架

typescript
class ParameterOptimizer {
  /**
   * 网格搜索最优参数
   */
  async gridSearch(
    historicalData: TradeData[],
    paramRanges: ParamRanges
  ): Promise<OptimalParams> {
    const results: BacktestResult[] = [];
    
    // 遍历参数组合
    for (const gamma of paramRanges.gamma) {
      for (const kappa of paramRanges.kappa) {
        for (const maxPos of paramRanges.maxPosition) {
          const strategy = new ASMarketMaker(gamma, kappa, maxPos);
          const result = await this.backtest(strategy, historicalData);
          
          results.push({
            params: { gamma, kappa, maxPosition: maxPos },
            sharpeRatio: result.sharpeRatio,
            totalPnl: result.totalPnl,
            maxDrawdown: result.maxDrawdown
          });
        }
      }
    }
    
    // 选择夏普比率最高的参数
    const optimal = results.sort((a, b) => b.sharpeRatio - a.sharpeRatio)[0];
    
    return {
      params: optimal.params,
      metrics: {
        sharpeRatio: optimal.sharpeRatio,
        totalPnl: optimal.totalPnl,
        maxDrawdown: optimal.maxDrawdown
      }
    };
  }
  
  /**
   * 参数稳定性检验
   * 确保最优参数在不同时间段都表现良好
   */
  async walkForwardAnalysis(
    historicalData: TradeData[],
    windowSize: number = 30 // 30 天窗口
  ): Promise<WalkForwardResult> {
    const results: WindowResult[] = [];
    
    for (let i = 0; i < historicalData.length - windowSize; i += windowSize) {
      const trainData = historicalData.slice(i, i + windowSize);
      const testData = historicalData.slice(i + windowSize, i + windowSize * 2);
      
      // 在训练集上优化参数
      const optimalParams = await this.gridSearch(trainData, this.defaultRanges());
      
      // 在测试集上验证
      const testResult = await this.backtest(
        new ASMarketMaker(optimalParams.gamma, optimalParams.kappa),
        testData
      );
      
      results.push({
        window: i / windowSize,
        trainSharpe: optimalParams.metrics.sharpeRatio,
        testSharpe: testResult.sharpeRatio
      });
    }
    
    return {
      avgTrainSharpe: average(results.map(r => r.trainSharpe)),
      avgTestSharpe: average(results.map(r => r.testSharpe)),
      degradation: 1 - average(results.map(r => r.testSharpe)) / 
                      average(results.map(r => r.trainSharpe))
    };
  }
}

8.5 做市监控看板设计

做市系统需要实时监控以下关键指标:

typescript
// 做市监控看板数据结构
interface MarketMakingDashboard {
  // 实时状态
  status: {
    isRunning: boolean;
    uptime: number;           // 运行时长
    activeOrders: number;     // 活跃挂单数
    activeMarkets: number;    // 做市市场数
  };
  
  // 收益指标
  performance: {
    dailyPnl: number;         // 日收益
    weeklyPnl: number;        // 周收益
    monthlyPnl: number;       // 月收益
    totalPnl: number;         // 总收益
    sharpeRatio: number;      // 夏普比率
    maxDrawdown: number;      // 最大回撤
  };
  
  // 风险指标
  risk: {
    currentPosition: number;  // 当前库存
    maxPosition: number;      // 最大库存
    positionUtilization: number; // 库存利用率
    dailyLoss: number;        // 日亏损
    consecutiveLosses: number; // 连续亏损次数
  };
  
  // 做市效率
  efficiency: {
    averageSpread: number;    // 平均价差
    fillRate: number;         // 成交率
    cancelRate: number;       // 撤单率
    makerVolume: number;      // 做市成交量
    takerVolume: number;      // Taker 成交量
  };
}
看板区域指标刷新频率告警条件
实时状态运行状态、活跃订单1s停机即告警
收益曲线日/周/月收益1min日亏损 >5%
库存监控库存量、利用率5s利用率 >80%
风险面板最大回撤、连续亏损1min回撤 >10%
效率面板价差、成交率30s成交率 <30%

8.6 做市策略常见陷阱

陷阱表现后果避免方法
过度自信忽视风控,加大仓位巨额亏损严格遵守风控阈值
追涨杀跌价格变动时调整价差亏损加速使用 AS 模型自动调整
忽视尾盘结算前不做特殊处理尾盘失真启用尾盘策略
单一市场只做一个市场风险集中多市场分散
忽视 Gas频繁调仓成本过高批处理+减少频率

做市风控 Checklist

typescript
// 做市前检查清单
const preMarketChecklist = [
  { check: '做市资金到位', required: true },
  { check: '风控参数配置', required: true },
  { check: '监控系统就绪', required: true },
  { check: '应急暂停测试', required: true },
  { check: 'Gas 费预算', required: false },
  { check: '备用 RPC 节点', required: false },
];

function validateChecklist(items: ChecklistItem[]): boolean {
  return items
    .filter(item => item.required)
    .every(item => item.completed);
}

8.7 做市策略回测最佳实践

做市策略回测是验证策略有效性的关键步骤。以下是回测最佳实践:

typescript
// 做市回测数据结构
interface BacktestConfig {
  startDate: Date;
  endDate: Date;
  initialCapital: number;
  tradingFee: number;        // 交易手续费
  slippageModel: 'fixed' | 'proportional'; // 滑点模型
  gasCostPerTrade: number;   // 每笔交易 Gas 成本
}

// 回测结果指标
interface BacktestMetrics {
  totalReturn: number;       // 总收益率
  annualizedReturn: number;  // 年化收益率
  sharpeRatio: number;       // 夏普比率
  maxDrawdown: number;       // 最大回撤
  winRate: number;           // 胜率
  avgHoldingTime: number;    // 平均持仓时间
  totalTrades: number;       // 总交易次数
  profitFactor: number;      // 盈亏比
}

// 回测执行器
class BacktestRunner {
  async run(
    strategy: MarketMakingStrategy,
    config: BacktestConfig
  ): Promise<BacktestMetrics> {
    // 1. 加载历史数据
    const historicalData = await this.loadData(config);
    
    // 2. 初始化策略
    strategy.initialize(config.initialCapital);
    
    // 3. 逐个时间点模拟
    for (const snapshot of historicalData) {
      const quotes = strategy.calculateQuotes(snapshot);
      const fills = this.simulateFills(quotes, snapshot, config);
      strategy.updateState(fills);
    }
    
    // 4. 计算指标
    return this.calculateMetrics(strategy);
  }
}

回测注意事项

注意事项说明处理方式
前视偏差使用未来数据严格时间顺序
幸存者偏差只看成功案例包含失败事件
滑点模型过于乐观使用保守滑点
交易成本忽略 Gas 费包含所有成本
流动性假设假设无限深度限制最大成交量

参考与延伸

[11] Backtrader(2025)— Python 回测框架

[12] QuantConnect(2025)— 云端量化回测平台

[1] Hummingbot(2025)— 开源做市机器人

[2] Avellaneda-Stoikov Model(2025)— 做市定价模型

[3] Quantitative Trading(2025)— 量化做市策略

[4] DeFi Market Making(2025)— DeFi 做市指南

[5] Risk Management in Trading(2025)— 交易风险管理

[6] Avellaneda & Stoikov. "High-Frequency Trading in a Limit Order Book"(2008)— AS 做市模型原始论文

[7] Cartea, Jaimungal & Penalva. "Algorithmic and High-Frequency Trading"(2015)— 算法做市学术专著

[8] Wintermute(2025)— 专业做市商参考

[9] Jump Crypto(2025)— 加密做市商参考

[10] Guéant, O. "The Financial Mathematics of Market Liquidity"(2016)— 流动性数学模型

OPC 超级个体实战指南