【期货量化进阶】期货Tick数据分析与应用:高频数据入门(TqSdk完整教程)

一、前言

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

免责声明:本文仅供学习交流使用,不构成任何投资建议。期货交易有风险,入市需谨慎。

更多资源

相关推荐
爱吃羊的老虎2 小时前
Streamlit:快速创建应用界面,无需了解 Web 开发
前端·python
小杨同学492 小时前
C 语言实战:堆内存存储字符串 + 多种递归方案计算字符串长度
数据库·后端·算法
YangYang9YangYan2 小时前
2026中专财务专业学数据分析指南
数据挖掘·数据分析
君义_noip2 小时前
【模板:字符串哈希】信息学奥赛一本通 1455:【例题1】Oulipo
算法·哈希算法·信息学奥赛·csp-s
只想要搞钱2 小时前
python 学习记录--1(开发工具,链接数据库mysql)
python·学习
星浩AI2 小时前
深入理解 LlamaIndex:RAG 框架核心概念与实践
人工智能·后端·python
fengfuyao9852 小时前
基于Matlab的压缩感知梯度投影重构算法实现方案
算法·matlab·重构
python开发笔记2 小时前
can(6) canopen python库使用
服务器·网络·python