一、前言

数据可视化是量化交易的重要工具,可以帮助我们直观理解市场、分析策略表现。本文将介绍如何使用Python对期货数据和策略绩效进行可视化展示。

本文将介绍:

  • K线图绘制
  • 技术指标可视化
  • 资金曲线展示
  • 交易信号标注

二、为什么选择天勤量化(TqSdk)

TqSdk数据格式便于可视化:

功能 说明
DataFrame格式 直接用于绑定
完整数据 OHLCV齐全
实时更新 动态图表

安装方法

pip install tqsdk matplotlib

三、K线图绘制

3.1 基础K线图

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:基础K线图绘制
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime
import pandas as pd

api = TqApi(auth=TqAuth("快期账户", "快期密码"))

SYMBOL = "SHFE.rb2510"
klines = api.get_kline_serial(SYMBOL, 3600, 100)

api.wait_update()

# 数据准备
df = klines.copy()
df['datetime'] = pd.to_datetime(df['datetime'])
df = df[df['close'] > 0].tail(50)

print("=" * 50)
print("K线图绑定")
print("=" * 50)

# 绑定K线图
fig, ax = plt.subplots(figsize=(14, 7))

# 计算涨跌
df['color'] = df.apply(lambda x: 'red' if x['close'] >= x['open'] else 'green', axis=1)

# 绘制K线
for idx, row in df.iterrows():
    color = row['color']
    # 实体
    ax.bar(row['datetime'], abs(row['close'] - row['open']), 
           bottom=min(row['open'], row['close']), 
           color=color, width=0.03, edgecolor=color)
    # 影线
    ax.vlines(row['datetime'], row['low'], row['high'], color=color, linewidth=1)

ax.set_xlabel('时间')
ax.set_ylabel('价格')
ax.set_title(f'{SYMBOL} K线图')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('kline_chart.png', dpi=100)
print("K线图已保存: kline_chart.png")

api.close()

3.2 带成交量K线图

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:K线图+成交量
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd

api = TqApi(auth=TqAuth("快期账户", "快期密码"))

SYMBOL = "SHFE.rb2510"
klines = api.get_kline_serial(SYMBOL, 3600, 100)

api.wait_update()

df = klines.copy()
df['datetime'] = pd.to_datetime(df['datetime'])
df = df[df['close'] > 0].tail(50)

# 创建子图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 9), height_ratios=[3, 1], sharex=True)

# K线图
for idx, row in df.iterrows():
    color = 'red' if row['close'] >= row['open'] else 'green'
    ax1.bar(row['datetime'], abs(row['close'] - row['open']), 
            bottom=min(row['open'], row['close']), 
            color=color, width=0.03, edgecolor=color)
    ax1.vlines(row['datetime'], row['low'], row['high'], color=color, linewidth=1)

ax1.set_ylabel('价格')
ax1.set_title(f'{SYMBOL} K线图')
ax1.grid(True, alpha=0.3)

# 成交量图
colors = ['red' if c >= o else 'green' for c, o in zip(df['close'], df['open'])]
ax2.bar(df['datetime'], df['volume'], color=colors, width=0.03, alpha=0.7)
ax2.set_ylabel('成交量')
ax2.set_xlabel('时间')
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
ax2.grid(True, alpha=0.3)

plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('kline_volume.png', dpi=100)
print("K线+成交量图已保存: kline_volume.png")

api.close()

四、技术指标可视化

4.1 均线叠加

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:K线+均线图
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth
from tqsdk.tafunc import ma
import matplotlib.pyplot as plt
import pandas as pd

api = TqApi(auth=TqAuth("快期账户", "快期密码"))

SYMBOL = "SHFE.rb2510"
klines = api.get_kline_serial(SYMBOL, 3600, 100)

api.wait_update()

df = klines.copy()
df['datetime'] = pd.to_datetime(df['datetime'])
df = df[df['close'] > 0]

# 计算均线
df['ma5'] = ma(df['close'], 5)
df['ma10'] = ma(df['close'], 10)
df['ma20'] = ma(df['close'], 20)

df = df.tail(50)

# 绑定
fig, ax = plt.subplots(figsize=(14, 7))

# K线
for idx, row in df.iterrows():
    color = 'red' if row['close'] >= row['open'] else 'green'
    ax.bar(row['datetime'], abs(row['close'] - row['open']), 
           bottom=min(row['open'], row['close']), 
           color=color, width=0.03, edgecolor=color, alpha=0.7)
    ax.vlines(row['datetime'], row['low'], row['high'], color=color, linewidth=1)

# 均线
ax.plot(df['datetime'], df['ma5'], label='MA5', color='orange', linewidth=1.5)
ax.plot(df['datetime'], df['ma10'], label='MA10', color='blue', linewidth=1.5)
ax.plot(df['datetime'], df['ma20'], label='MA20', color='purple', linewidth=1.5)

ax.legend(loc='upper left')
ax.set_title(f'{SYMBOL} K线+均线')
ax.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('kline_ma.png', dpi=100)
print("均线图已保存: kline_ma.png")

api.close()

4.2 MACD指标图

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:MACD指标可视化
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth
from tqsdk.tafunc import macd
import matplotlib.pyplot as plt
import pandas as pd

api = TqApi(auth=TqAuth("快期账户", "快期密码"))

SYMBOL = "SHFE.rb2510"
klines = api.get_kline_serial(SYMBOL, 3600, 100)

api.wait_update()

df = klines.copy()
df['datetime'] = pd.to_datetime(df['datetime'])
df = df[df['close'] > 0]

# 计算MACD
diff, dea, macd_bar = macd(df['close'], 12, 26, 9)
df['diff'] = diff
df['dea'] = dea
df['macd'] = macd_bar

df = df.tail(50)

# 创建子图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 9), height_ratios=[2, 1], sharex=True)

# K线图
for idx, row in df.iterrows():
    color = 'red' if row['close'] >= row['open'] else 'green'
    ax1.bar(row['datetime'], abs(row['close'] - row['open']), 
            bottom=min(row['open'], row['close']), 
            color=color, width=0.03, edgecolor=color)
    ax1.vlines(row['datetime'], row['low'], row['high'], color=color, linewidth=1)

ax1.set_title(f'{SYMBOL} MACD指标')
ax1.grid(True, alpha=0.3)

# MACD图
colors = ['red' if m >= 0 else 'green' for m in df['macd']]
ax2.bar(df['datetime'], df['macd'], color=colors, width=0.03, alpha=0.7)
ax2.plot(df['datetime'], df['diff'], label='DIFF', color='orange', linewidth=1.5)
ax2.plot(df['datetime'], df['dea'], label='DEA', color='blue', linewidth=1.5)
ax2.axhline(y=0, color='gray', linestyle='--', linewidth=0.5)
ax2.legend(loc='upper left')
ax2.set_ylabel('MACD')
ax2.grid(True, alpha=0.3)

plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('macd_chart.png', dpi=100)
print("MACD图已保存: macd_chart.png")

api.close()

五、策略绩效可视化

5.1 资金曲线

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:资金曲线可视化
说明:本代码仅供学习参考
"""

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 模拟资金曲线数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=180, freq='D')
returns = np.random.normal(0.001, 0.02, 180)
equity = 200000 * (1 + returns).cumprod()

df = pd.DataFrame({'date': dates, 'equity': equity})

# 计算回撤
df['peak'] = df['equity'].cummax()
df['drawdown'] = (df['equity'] - df['peak']) / df['peak']

# 创建图表
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8), height_ratios=[2, 1], sharex=True)

# 资金曲线
ax1.plot(df['date'], df['equity'], color='blue', linewidth=1.5, label='账户权益')
ax1.plot(df['date'], df['peak'], color='green', linestyle='--', linewidth=1, alpha=0.5, label='历史最高')
ax1.fill_between(df['date'], df['equity'], df['peak'], alpha=0.1, color='red')

ax1.set_ylabel('权益')
ax1.set_title('策略资金曲线')
ax1.legend(loc='upper left')
ax1.grid(True, alpha=0.3)

# 添加绩效指标
total_return = (equity[-1] - 200000) / 200000
max_dd = df['drawdown'].min()
ax1.text(0.02, 0.95, f'总收益: {total_return:.2%}\n最大回撤: {max_dd:.2%}', 
         transform=ax1.transAxes, fontsize=10, verticalalignment='top',
         bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

# 回撤图
ax2.fill_between(df['date'], df['drawdown'], 0, color='red', alpha=0.5)
ax2.set_ylabel('回撤')
ax2.set_xlabel('日期')
ax2.set_ylim(df['drawdown'].min() * 1.1, 0.01)
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('equity_curve.png', dpi=100)
print("资金曲线图已保存: equity_curve.png")

5.2 交易信号标注

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:交易信号标注
说明:本代码仅供学习参考
"""

from tqsdk import TqApi, TqAuth
from tqsdk.tafunc import ma
import matplotlib.pyplot as plt
import pandas as pd

api = TqApi(auth=TqAuth("快期账户", "快期密码"))

SYMBOL = "SHFE.rb2510"
klines = api.get_kline_serial(SYMBOL, 3600, 100)

api.wait_update()

df = klines.copy()
df['datetime'] = pd.to_datetime(df['datetime'])
df = df[df['close'] > 0]

# 计算均线
df['ma5'] = ma(df['close'], 5)
df['ma20'] = ma(df['close'], 20)

# 生成信号
df['signal'] = 0
df.loc[df['ma5'] > df['ma20'], 'signal'] = 1
df.loc[df['ma5'] < df['ma20'], 'signal'] = -1

# 找交叉点
df['signal_change'] = df['signal'].diff()
buy_signals = df[df['signal_change'] == 2]
sell_signals = df[df['signal_change'] == -2]

df = df.tail(60)
buy_signals = buy_signals[buy_signals['datetime'].isin(df['datetime'])]
sell_signals = sell_signals[sell_signals['datetime'].isin(df['datetime'])]

# 绑定
fig, ax = plt.subplots(figsize=(14, 7))

# K线
for idx, row in df.iterrows():
    color = 'red' if row['close'] >= row['open'] else 'green'
    ax.bar(row['datetime'], abs(row['close'] - row['open']), 
           bottom=min(row['open'], row['close']), 
           color=color, width=0.03, edgecolor=color, alpha=0.5)
    ax.vlines(row['datetime'], row['low'], row['high'], color=color, linewidth=1)

# 均线
ax.plot(df['datetime'], df['ma5'], label='MA5', color='orange', linewidth=1.5)
ax.plot(df['datetime'], df['ma20'], label='MA20', color='blue', linewidth=1.5)

# 买入信号
ax.scatter(buy_signals['datetime'], buy_signals['low'] * 0.998, 
           marker='^', color='red', s=100, label='买入', zorder=5)

# 卖出信号
ax.scatter(sell_signals['datetime'], sell_signals['high'] * 1.002, 
           marker='v', color='green', s=100, label='卖出', zorder=5)

ax.legend(loc='upper left')
ax.set_title(f'{SYMBOL} 交易信号图')
ax.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('signal_chart.png', dpi=100)
print("信号图已保存: signal_chart.png")

api.close()

六、总结

图表类型 用途
K线图 展示价格走势
指标图 分析技术指标
资金曲线 评估策略表现
信号图 检验交易逻辑

可视化速查

# K线绑定
ax.bar(dt, height, bottom=low, color=color)
ax.vlines(dt, low, high, color=color)

# 均线叠加
ax.plot(df['datetime'], df['ma'], label='MA')

# 信号标注
ax.scatter(dt, price, marker='^', color='red')

# 保存图表
plt.savefig('chart.png', dpi=100)

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

更多资源

  • 天勤量化官网:https://www.shinnytech.com
  • GitHub开源地址:https://github.com/shinnytech/tqsdk-python
  • 官方文档:https://doc.shinnytech.com/tqsdk/latest
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐