一、前言
Tick数据是期货市场最精细的数据,记录了每一笔成交的价格、数量和时间。相比K线数据,Tick数据能够揭示更多市场微观结构信息,是高频交易和精细化分析的基础。
本文将介绍:
- Tick数据的概念与结构
- 如何获取和处理Tick数据
- Tick数据分析方法
- 基于Tick的交易策略
二、为什么选择天勤量化(TqSdk)
在众多期货量化工具中,**天勤量化(TqSdk)**是目前国内最受欢迎的开源期货量化框架之一:
| 特点 | 说明 |
|---|---|
| 完全免费 | 开源免费,无需付费即可获取实时行情 |
| 数据全面 | 支持国内所有期货交易所的实时行情和历史数据 |
| 上手简单 | 几行Python代码即可获取数据 |
| 文档完善 | 官方文档详细,示例代码丰富 |
安装方法:
bash
pip install tqsdk
三、Tick数据基础
3.1 什么是Tick数据
| 概念 | 说明 |
|---|---|
| Tick | 每次行情变动产生的一条记录 |
| 频率 | 约500毫秒推送一次(交易所限制) |
| 内容 | 价格、成交量、买卖盘口等 |
| 用途 | 高频分析、微观结构研究 |
3.2 Tick数据字段
| 字段 | 说明 |
|---|---|
| datetime | 时间戳 |
| last_price | 最新价 |
| volume | 累计成交量 |
| amount | 累计成交额 |
| open_interest | 持仓量 |
| bid_price1 | 买一价 |
| bid_volume1 | 买一量 |
| ask_price1 | 卖一价 |
| ask_volume1 | 卖一量 |
3.3 Tick vs K线
| 对比项 | Tick数据 | K线数据 |
|---|---|---|
| 精度 | 毫秒级 | 秒/分钟级 |
| 数据量 | 大 | 小 |
| 信息量 | 丰富 | 压缩 |
| 适用场景 | 高频、微观分析 | 趋势、技术分析 |
| 处理难度 | 高 | 低 |
四、获取Tick数据
4.1 实时Tick数据
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:获取期货实时Tick数据
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth
from datetime import datetime
api = TqApi(auth=TqAuth("快期账户", "快期密码"))
SYMBOL = "SHFE.rb2510"
quote = api.get_quote(SYMBOL)
print("=" * 70)
print(f"Tick数据实时监控 - {SYMBOL}")
print("=" * 70)
print(f"{'时间':<15} {'最新价':<10} {'成交量':<10} {'买一':<10} {'卖一':<10} {'持仓':<10}")
print("-" * 70)
last_volume = 0
tick_count = 0
while tick_count < 100: # 收集100个Tick
api.wait_update()
if api.is_changing(quote, "last_price"):
now = datetime.now().strftime("%H:%M:%S.%f")[:-3]
# 计算本次成交量
tick_volume = quote.volume - last_volume if last_volume > 0 else 0
last_volume = quote.volume
print(f"{now:<15} {quote.last_price:<10.0f} {tick_volume:<10} "
f"{quote.bid_price1:<10.0f} {quote.ask_price1:<10.0f} {quote.open_interest:<10.0f}")
tick_count += 1
api.close()
4.2 Tick数据收集器
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:Tick数据收集器
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth
from datetime import datetime
import pandas as pd
import time
api = TqApi(auth=TqAuth("快期账户", "快期密码"))
SYMBOL = "SHFE.rb2510"
quote = api.get_quote(SYMBOL)
print("=" * 60)
print(f"Tick数据收集器 - {SYMBOL}")
print("=" * 60)
# 存储Tick数据
tick_data = []
last_volume = 0
collect_seconds = 60 # 收集60秒
start_time = time.time()
while time.time() - start_time < collect_seconds:
api.wait_update()
if api.is_changing(quote):
tick_volume = quote.volume - last_volume if last_volume > 0 else 0
last_volume = quote.volume
tick = {
"datetime": datetime.now(),
"last_price": quote.last_price,
"tick_volume": tick_volume,
"bid_price1": quote.bid_price1,
"bid_volume1": quote.bid_volume1,
"ask_price1": quote.ask_price1,
"ask_volume1": quote.ask_volume1,
"open_interest": quote.open_interest,
}
tick_data.append(tick)
print(f"\r收集中... {len(tick_data)} ticks", end="")
# 转换为DataFrame
df = pd.DataFrame(tick_data)
print(f"\n\n收集完成!共 {len(df)} 条Tick数据")
print("\n数据预览:")
print(df.head(10))
# 保存到CSV
filename = f"tick_{SYMBOL.replace('.', '_')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
df.to_csv(filename, index=False)
print(f"\n数据已保存: {filename}")
api.close()
五、Tick数据分析
5.1 成交量分析
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:Tick数据成交量分析
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth
from datetime import datetime
from collections import deque
api = TqApi(auth=TqAuth("快期账户", "快期密码"))
SYMBOL = "SHFE.rb2510"
quote = api.get_quote(SYMBOL)
print("=" * 60)
print("Tick成交量分析")
print("=" * 60)
# 使用滑动窗口统计
WINDOW_SIZE = 50 # 50个Tick的窗口
tick_volumes = deque(maxlen=WINDOW_SIZE)
tick_prices = deque(maxlen=WINDOW_SIZE)
last_volume = 0
last_price = 0
# 统计变量
buy_volume = 0 # 主买量
sell_volume = 0 # 主卖量
while True:
api.wait_update()
if api.is_changing(quote, "last_price"):
# 计算本Tick成交量
tick_vol = quote.volume - last_volume if last_volume > 0 else 0
price_change = quote.last_price - last_price if last_price > 0 else 0
last_volume = quote.volume
last_price = quote.last_price
if tick_vol > 0:
tick_volumes.append(tick_vol)
tick_prices.append(quote.last_price)
# 判断主买主卖(简化:价格上涨为主买,下跌为主卖)
if price_change > 0:
buy_volume += tick_vol
elif price_change < 0:
sell_volume += tick_vol
# 统计
if len(tick_volumes) >= 10:
avg_vol = sum(tick_volumes) / len(tick_volumes)
max_vol = max(tick_volumes)
total_vol = sum(tick_volumes)
# 大单判断(超过平均3倍)
is_big_order = tick_vol > avg_vol * 3
# 买卖力量对比
total_bs = buy_volume + sell_volume
buy_ratio = buy_volume / total_bs * 100 if total_bs > 0 else 50
big_mark = " ★大单★" if is_big_order else ""
print(f"\r价格={quote.last_price:.0f} 本笔={tick_vol:>5} "
f"均量={avg_vol:>5.0f} 最大={max_vol:>5} "
f"买/卖={buy_ratio:>5.1f}%{big_mark} ", end="")
5.2 盘口分析
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:盘口数据分析
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth
from datetime import datetime
from collections import deque
api = TqApi(auth=TqAuth("快期账户", "快期密码"))
SYMBOL = "SHFE.rb2510"
quote = api.get_quote(SYMBOL)
print("=" * 70)
print("盘口分析")
print("=" * 70)
# 盘口历史
bid_history = deque(maxlen=100)
ask_history = deque(maxlen=100)
spread_history = deque(maxlen=100)
while True:
api.wait_update()
if api.is_changing(quote):
bid1 = quote.bid_price1
ask1 = quote.ask_price1
bid_vol = quote.bid_volume1
ask_vol = quote.ask_volume1
# 计算买卖盘口比
total_vol = bid_vol + ask_vol
bid_ratio = bid_vol / total_vol * 100 if total_vol > 0 else 50
# 价差
spread = ask1 - bid1
spread_history.append(spread)
# 盘口失衡度
imbalance = (bid_vol - ask_vol) / (bid_vol + ask_vol) if total_vol > 0 else 0
# 统计
avg_spread = sum(spread_history) / len(spread_history) if spread_history else 0
# 判断盘口状态
if imbalance > 0.3:
status = "买盘强势"
elif imbalance < -0.3:
status = "卖盘强势"
else:
status = "均衡"
print(f"\r买一={bid1:.0f}({bid_vol:>5}) | 卖一={ask1:.0f}({ask_vol:>5}) "
f"价差={spread:.1f}(均{avg_spread:.1f}) 失衡={imbalance:+.2f} [{status}] ", end="")
5.3 成交速度分析
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:成交速度分析
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth
from datetime import datetime
import time
api = TqApi(auth=TqAuth("快期账户", "快期密码"))
SYMBOL = "SHFE.rb2510"
quote = api.get_quote(SYMBOL)
print("=" * 60)
print("成交速度分析")
print("=" * 60)
# 统计周期(秒)
PERIOD = 5
last_volume = 0
period_start = time.time()
period_volume = 0
tick_count = 0
# 历史记录
speed_history = []
while True:
api.wait_update()
if api.is_changing(quote, "volume"):
tick_vol = quote.volume - last_volume if last_volume > 0 else 0
last_volume = quote.volume
period_volume += tick_vol
tick_count += 1
# 每个周期统计
elapsed = time.time() - period_start
if elapsed >= PERIOD:
speed = period_volume / elapsed # 手/秒
speed_history.append(speed)
# 与历史对比
if len(speed_history) > 1:
avg_speed = sum(speed_history) / len(speed_history)
speed_ratio = speed / avg_speed if avg_speed > 0 else 1
if speed_ratio > 1.5:
status = "🔥 成交加速"
elif speed_ratio < 0.5:
status = "❄️ 成交减速"
else:
status = "📊 正常"
print(f"\n[{datetime.now().strftime('%H:%M:%S')}] "
f"速度={speed:.1f}手/秒 均速={avg_speed:.1f} "
f"比值={speed_ratio:.2f}x {status}")
# 重置
period_start = time.time()
period_volume = 0
tick_count = 0
六、基于Tick的交易策略
6.1 大单跟踪策略
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:大单跟踪策略
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth, TqSim
from tqsdk.lib import TargetPosTask
from collections import deque
from datetime import datetime
# ============ 策略参数 ============
SYMBOL = "SHFE.rb2510"
BIG_ORDER_THRESHOLD = 50 # 大单阈值(手)
FOLLOW_SECONDS = 30 # 跟随时间窗口(秒)
MIN_BIG_ORDERS = 3 # 最少大单数量
LOTS = 1
# ============ 初始化 ============
api = TqApi(TqSim(init_balance=500000), auth=TqAuth("快期账户", "快期密码"))
quote = api.get_quote(SYMBOL)
position = api.get_position(SYMBOL)
target_pos = TargetPosTask(api, SYMBOL)
print("=" * 60)
print("大单跟踪策略")
print("=" * 60)
print(f"大单阈值: {BIG_ORDER_THRESHOLD}手")
print(f"跟随窗口: {FOLLOW_SECONDS}秒")
print("-" * 60)
# 大单记录
big_orders = deque() # (timestamp, volume, direction)
last_volume = 0
last_price = 0
current_pos = 0
while True:
api.wait_update()
if api.is_changing(quote, "last_price"):
tick_vol = quote.volume - last_volume if last_volume > 0 else 0
price_change = quote.last_price - last_price if last_price > 0 else 0
last_volume = quote.volume
last_price = quote.last_price
now = datetime.now()
# 检测大单
if tick_vol >= BIG_ORDER_THRESHOLD:
direction = 1 if price_change >= 0 else -1
big_orders.append((now, tick_vol, direction))
print(f"\n[大单] {'买' if direction > 0 else '卖'} {tick_vol}手 @ {quote.last_price:.0f}")
# 清理过期大单
while big_orders and (now - big_orders[0][0]).seconds > FOLLOW_SECONDS:
big_orders.popleft()
# 统计窗口内大单
if len(big_orders) >= MIN_BIG_ORDERS:
buy_volume = sum(v for t, v, d in big_orders if d > 0)
sell_volume = sum(v for t, v, d in big_orders if d < 0)
# 判断信号
net_direction = 0
if buy_volume > sell_volume * 1.5:
net_direction = 1
elif sell_volume > buy_volume * 1.5:
net_direction = -1
# 执行交易
current_pos = position.pos_long - position.pos_short
if net_direction != 0 and current_pos != net_direction * LOTS:
target_pos.set_target_volume(net_direction * LOTS)
print(f"\n[跟随] {'做多' if net_direction > 0 else '做空'} "
f"买单={buy_volume} 卖单={sell_volume}")
# 无信号时平仓
elif len(big_orders) == 0 and current_pos != 0:
target_pos.set_target_volume(0)
print("\n[平仓] 大单信号消失")
print(f"\r价格={quote.last_price:.0f} 大单数={len(big_orders)} "
f"持仓={position.pos_long - position.pos_short} ", end="")
七、Tick数据存储
7.1 保存到数据库
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:Tick数据存储到SQLite
说明:本代码仅供学习参考
"""
import sqlite3
from datetime import datetime
def create_tick_table(conn, symbol):
"""创建Tick数据表"""
table_name = symbol.replace(".", "_")
cursor = conn.cursor()
cursor.execute(f"""
CREATE TABLE IF NOT EXISTS {table_name} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
datetime TEXT,
last_price REAL,
volume INTEGER,
bid_price1 REAL,
ask_price1 REAL,
open_interest INTEGER
)
""")
conn.commit()
return table_name
def save_tick(conn, table_name, tick_data):
"""保存Tick数据"""
cursor = conn.cursor()
cursor.execute(f"""
INSERT INTO {table_name}
(datetime, last_price, volume, bid_price1, ask_price1, open_interest)
VALUES (?, ?, ?, ?, ?, ?)
""", (
tick_data["datetime"],
tick_data["last_price"],
tick_data["volume"],
tick_data["bid_price1"],
tick_data["ask_price1"],
tick_data["open_interest"],
))
conn.commit()
# 使用示例
# conn = sqlite3.connect("tick_data.db")
# table = create_tick_table(conn, "SHFE.rb2510")
# save_tick(conn, table, tick_data)
八、总结
| 要点 | 内容 |
|---|---|
| Tick定义 | 每次行情变动的记录 |
| 更新频率 | 约500毫秒 |
| 核心字段 | 价格、成交量、盘口 |
| 分析维度 | 成交量、盘口、速度 |
| 适用策略 | 大单跟踪、盘口分析 |
| 数据存储 | CSV、SQLite |
免责声明:本文仅供学习交流使用,不构成任何投资建议。期货交易有风险,入市需谨慎。
更多资源: