第1章:订单流中的量化工具开发
说实话,我刚接触订单流的时候,也是两眼一抹黑。看着那些密密麻麻的成交数据,根本不知道从哪下手。后来我慢慢摸索出一套方法——把订单流和量化工具结合起来。今天我就把这套东西拆开了讲给你听。
这一章的内容,说白了就是教你如何用Python把订单流数据变成能用的工具。我会从环境搭建开始,一步步带你写出自己的订单流指标计算函数,最后还能生成交易信号。嗯,咱们开始吧。
1.1 Python环境搭建与数据获取
我个人习惯用Anaconda来管理Python环境。为什么?因为省心。你想想看,搞量化最怕的就是各种库的版本冲突,Anaconda帮你把这事解决了。
核心要点:订单流数据通常来自交易所的Level 2行情接口,我们需要获取逐笔成交数据和订单簿快照。
先搭个干净的环境:
# 创建虚拟环境
conda create -n orderflow python=3.9
# 激活环境
conda activate orderflow
# 安装核心库
pip install pandas numpy matplotlib
pip install websocket-client # 用于实时数据
pip install ccxt # 交易所接口
我在项目中遇到过一个问题——直接用交易所的原始数据,格式乱七八糟的。后来我写了个统一的数据清洗函数,把不同交易所的数据标准化。这里给你看看我的数据获取模板:
import ccxt
import pandas as pd
def get_orderflow_data(symbol='BTC/USDT', limit=1000):
"""
获取订单流原始数据
"""
exchange = ccxt.binance()
# 获取逐笔成交
trades = exchange.fetch_trades(symbol, limit=limit)
df_trades = pd.DataFrame(trades)
# 获取订单簿快照
orderbook = exchange.fetch_order_book(symbol, limit=50)
return df_trades, orderbook
小提示:数据获取时,建议先缓存到本地CSV文件。我一般会保留最近7天的数据,这样回测时不用反复请求接口。
1.2 订单流指标的计算函数
有了原始数据,接下来就是算指标了。订单流里最核心的几个指标,我一个个说。
1. 成交量分布(Volume Profile)
这个指标说白了就是看哪个价格区间成交最多。我习惯用POC(Point of Control)来标记最大成交量位置。
def calculate_volume_profile(df_trades, price_bins=50):
"""
计算成交量分布
"""
# 划分价格区间
price_min = df_trades['price'].min()
price_max = df_trades['price'].max()
bins = np.linspace(price_min, price_max, price_bins)
# 统计每个价格区间的成交量
df_trades['price_bin'] = pd.cut(df_trades['price'], bins)
volume_profile = df_trades.groupby('price_bin')['amount'].sum()
# 找到POC
poc_bin = volume_profile.idxmax()
return volume_profile, poc_bin
2. 买卖压力指标(Delta)
Delta = 主动买盘 - 主动卖盘。正值说明买方强势,负值说明卖方占优。这个指标我用了好几年,说实话,比很多复杂指标都管用。
def calculate_delta(df_trades):
"""
计算买卖压力
"""
# 判断主动买卖方向
df_trades['side'] = df_trades.apply(
lambda x: 'buy' if x['price'] > x['last_price'] else 'sell',
axis=1
)
# 计算累计Delta
buy_volume = df_trades[df_trades['side']=='buy']['amount'].sum()
sell_volume = df_trades[df_trades['side']=='sell']['amount'].sum()
delta = buy_volume - sell_volume
return delta
注意:Delta的计算方式不同交易所可能有差异。我曾经踩过坑——某交易所的主动买卖标记方式跟标准不一样,导致算出来的Delta完全反了。所以一定要先验证数据。
3. 订单簿失衡度(Order Book Imbalance)
这个指标反映的是买卖挂单的力量对比。我一般用这个公式:
def calculate_imbalance(orderbook, depth=10):
"""
计算订单簿失衡度
"""
bids = orderbook['bids'][:depth]
asks = orderbook['asks'][:depth]
bid_volume = sum([bid[1] for bid in bids])
ask_volume = sum([ask[1] for ask in asks])
imbalance = (bid_volume - ask_volume) / (bid_volume + ask_volume)
return imbalance
1.3 订单流可视化工具开发
光有数字不行,得能看出来。我开发了一套可视化工具,把订单流数据变成直观的图表。
先画个成交量分布图:
import matplotlib.pyplot as plt
def plot_volume_profile(volume_profile, poc_bin):
"""
绘制成交量分布图
"""
fig, ax = plt.subplots(figsize=(10, 6))
# 横向柱状图
prices = [interval.mid for interval in volume_profile.index]
volumes = volume_profile.values
ax.barh(prices, volumes, height=0.8, color='steelblue')
# 标记POC
poc_price = poc_bin.mid
poc_volume = volume_profile[poc_bin]
ax.scatter(poc_volume, poc_price, color='red', s=100,
label=f'POC: {poc_price:.2f}')
ax.set_xlabel('成交量')
ax.set_ylabel('价格')
ax.set_title('成交量分布 (Volume Profile)')
ax.legend()
return fig
再画个Delta走势图:
def plot_delta_timeline(df_trades):
"""
绘制Delta时间序列
"""
# 按时间分组计算Delta
df_trades['time'] = pd.to_datetime(df_trades['timestamp'], unit='ms')
df_trades.set_index('time', inplace=True)
# 每分钟累计Delta
delta_minute = df_trades.resample('1min').apply(
lambda x: calculate_delta(x)
)
fig, ax = plt.subplots(figsize=(12, 4))
ax.plot(delta_minute.index, delta_minute.values,
color='darkgreen', linewidth=1.5)
ax.axhline(y=0, color='gray', linestyle='--')
ax.fill_between(delta_minute.index, 0, delta_minute.values,
where=delta_minute.values > 0,
color='green', alpha=0.3)
ax.fill_between(delta_minute.index, 0, delta_minute.values,
where=delta_minute.values < 0,
color='red', alpha=0.3)
ax.set_xlabel('时间')
ax.set_ylabel('Delta')
ax.set_title('买卖压力走势')
return fig
经验之谈:可视化时,颜色选择很重要。我习惯用绿色表示买方力量,红色表示卖方力量。这样一眼就能看出市场倾向。
1.4 自动化交易信号生成
最后一步,也是最关键的一步——把指标变成交易信号。我设计了一套基于订单流的信号生成逻辑。
def generate_orderflow_signals(df_trades, orderbook,
delta_threshold=100,
imbalance_threshold=0.3):
"""
基于订单流生成交易信号
"""
signals = []
# 计算各项指标
volume_profile, poc = calculate_volume_profile(df_trades)
delta = calculate_delta(df_trades)
imbalance = calculate_imbalance(orderbook)
# 信号逻辑
# 1. Delta异常 + 订单簿失衡 -> 强信号
if abs(delta) > delta_threshold and abs(imbalance) > imbalance_threshold:
if delta > 0 and imbalance > 0:
signals.append({
'type': 'BUY',
'strength': 'STRONG',
'reason': '买方主导 + 订单簿失衡偏多'
})
elif delta < 0 and imbalance < 0:
signals.append({
'type': 'SELL',
'strength': 'STRONG',
'reason': '卖方主导 + 订单簿失衡偏空'
})
# 2. 价格接近POC + Delta反转 -> 入场信号
current_price = df_trades['price'].iloc[-1]
poc_price = poc.mid
if abs(current_price - poc_price) / poc_price < 0.01:
if delta > 0 and df_trades['price'].diff().iloc[-5:].mean() > 0:
signals.append({
'type': 'BUY',
'strength': 'MEDIUM',
'reason': '价格接近POC + Delta转正'
})
return signals
核心逻辑:订单流信号的核心是「确认」——用多个指标相互验证。单一指标容易出假信号,但多个指标同时指向同一个方向时,胜率会大幅提升。
我举个例子。有一次BTC在30000附近震荡,Delta持续为负但幅度不大。突然Delta转正且订单簿失衡度超过0.4,同时价格刚好在POC附近。三个信号同时出现,我果断做多,半小时后涨了2%。这就是订单流信号的威力。
知识体系总览
下面这张图是我自己画的,把整个订单流量化工具的开发流程串起来了:
这张图把整个流程串起来了。从数据获取开始,经过清洗、计算指标,再到可视化和信号生成,最后形成交易决策。每一步都环环相扣。
我的建议:刚开始别想着一步到位。先把数据获取和清洗做好,这一步稳了,后面的指标计算才有意义。我见过太多人一上来就搞复杂的信号逻辑,结果数据源就有问题,白忙活一场。
好了,这一章的内容就到这里。代码我都贴出来了,你可以直接复制到自己的环境里跑一跑。记住,订单流量化不是玄学,是实实在在的数据分析。把基础打牢,后面的事情就水到渠成了。