第三节:价差与滑点——做市商的利润与成本
做市商靠什么赚钱?说白了,就是买卖价差。但赚到的钱,往往会被滑点吃掉一部分。今天咱们就聊聊这两个核心概念。
一、买卖价差:做市商的饭碗
买卖价差(Bid-Ask Spread),就是买一价和卖一价之间的差值。举个例子:
买一价:10.00 元
卖一价:10.02 元
价差:0.02 元
你作为做市商,在10.00元买入,10.02元卖出。每成交一个单位,你就赚0.02元。这就是你的利润来源。
我在项目中遇到过一种情况:有些新手做市商喜欢把价差设得很小,以为这样能吸引更多订单。结果呢?交易量是上去了,但利润薄得像纸片,稍微来一波行情就亏回去了。
价差的计算公式很简单:
价差 = 卖一价 - 买一价
相对价差 = 价差 / 中间价 × 100%
我个人习惯用相对价差来衡量市场流动性。比如:
| 市场 | 买一价 | 卖一价 | 价差 | 相对价差 |
|---|---|---|---|---|
| BTC/USDT | 50000.00 | 50000.10 | 0.10 | 0.0002% |
| 小币种A | 1.00 | 1.05 | 0.05 | 4.88% |
看到没?比特币的价差只有万分之二,而小币种接近5%。这就是流动性的差距。
核心要点:价差越小,市场流动性越好。做市商在流动性好的市场里,虽然单笔利润薄,但可以靠高频交易来积累收益。
二、滑点:做市商的隐形杀手
滑点(Slippage),就是你预期成交的价格和实际成交价格之间的差异。为什么会发生滑点?
滑点产生的原因主要有三个:
- 订单簿深度不足——你挂的买单太大,把价格推高了
- 市场波动剧烈——在你下单到成交的瞬间,价格已经变了
- 网络延迟——你的订单到达交易所时,行情已经更新了
我曾经吃过一次大亏。有一次做市某个小币种,我挂了一笔5000 USDT的买单。当时买一价是2.00元,我以为能全部成交在这个价位。结果呢?因为订单簿太薄,我的单子一路吃到了2.05元才全部成交。滑点高达2.5%,这笔交易直接亏掉了当天的利润。
滑点的计算方式:
滑点 = (实际成交均价 - 预期价格) / 预期价格 × 100%
举个例子:
预期价格:10.00 元
实际成交均价:10.03 元
滑点 = (10.03 - 10.00) / 10.00 × 100% = 0.3%
注意:滑点对做市商来说是双向的。你买入时可能产生正滑点(买贵了),卖出时也可能产生负滑点(卖便宜了)。两者都会侵蚀你的利润。
三、流动性对价差的影响
流动性,说白了就是市场里有多少人在买卖。流动性越好,价差越小。为什么?
你想想看,在一个有1000个买家和1000个卖家的市场里,竞争激烈,大家只能把价差压得很小才能抢到订单。反过来,一个只有10个买家和10个卖家的市场,随便挂个单都能成交,谁愿意把价差缩小?
流动性对价差的影响可以用一个公式来量化:
价差 ∝ 1 / 流动性
也就是说,流动性翻倍,价差减半。我在实际项目中验证过这个规律:
| 交易对 | 日均交易量 | 平均价差 | 流动性等级 |
|---|---|---|---|
| BTC/USDT | 100亿 | 0.01% | 极高 |
| ETH/USDT | 30亿 | 0.03% | 高 |
| 主流币种 | 1亿 | 0.1% | 中等 |
| 小币种 | 100万 | 1% | 低 |
嗯,这里要注意:流动性不是一成不变的。我记得有一次做市某个币种,白天流动性很好,价差只有0.05%。到了晚上,交易量骤降,价差直接飙到0.3%。所以做市商必须根据时间动态调整策略。
实战建议:我一般会在流动性好的时段加大做市力度,在流动性差的时段缩小挂单量或者干脆暂停。你可以用历史数据统计出每个交易对在不同时间段的平均价差,然后制定相应的策略。
四、如何计算和监控价差与滑点
在实际做市系统中,你需要实时计算这两个指标。下面是我常用的Python代码:
import pandas as pd
import numpy as np
def calculate_spread(bid_price, ask_price):
"""计算绝对价差和相对价差"""
spread = ask_price - bid_price
mid_price = (bid_price + ask_price) / 2
relative_spread = spread / mid_price * 100
return spread, relative_spread
def calculate_slippage(order_book, order_size, side='buy'):
"""计算预期滑点"""
total_cost = 0
filled_quantity = 0
if side == 'buy':
levels = order_book['asks']
else:
levels = order_book['bids']
for price, quantity in levels:
if filled_quantity + quantity >= order_size:
need = order_size - filled_quantity
total_cost += price * need
filled_quantity = order_size
break
else:
total_cost += price * quantity
filled_quantity += quantity
avg_price = total_cost / filled_quantity
expected_price = levels[0][0] # 最优价格
slippage = (avg_price - expected_price) / expected_price * 100
return slippage, avg_price
# 使用示例
order_book = {
'bids': [(10.00, 100), (9.99, 200), (9.98, 300)],
'asks': [(10.02, 100), (10.03, 200), (10.04, 300)]
}
spread, rel_spread = calculate_spread(10.00, 10.02)
print(f"价差: {spread:.4f}, 相对价差: {rel_spread:.2f}%")
slippage, avg_price = calculate_slippage(order_book, 250, 'buy')
print(f"滑点: {slippage:.2f}%, 平均成交价: {avg_price:.4f}")
这段代码我用了好几年,基本没出过问题。不过要注意,实际生产环境中订单簿是实时变化的,你需要用WebSocket订阅行情数据,而不是用静态数据。
总结一下:价差是你的利润来源,滑点是你的成本。做市商的核心能力,就是在控制滑点的前提下,尽可能多地赚取价差。流动性是影响这两者的关键因素,你必须时刻关注市场深度和波动情况。
下一节我们会聊到订单簿的构建和维护,这是做市商策略的基础设施。到时候我会分享一些我在搭建订单簿系统时踩过的坑,希望对你有帮助。