核心内容摘要
西施乘鲤谣:一段穿越时空的爱恋,一段无声的告白
声明本文为个人学习笔记仅供技术交流不构成任何投资建议。
前言在期货量化这条路上我已经走了整整二十年。
数据可视化是量化交易中不可或缺的一环——好的图表能帮助我们更直观地理解行情、分析策略、展示结果。
今天这篇文章我来分享一下Python期货数据可视化的实践经验包括常用的图表类型和代码实现。
常用可视化库库特点适用场景matplotlib基础、灵活静态图表plotly交互式网页展示mplfinance专业K线金融图表本文主要使用matplotlib和mplfinance。
安装pipinstallmatplotlib mplfinance pandas numpy
获取数据首先获取期货数据fromtqsdkimportTqApi,TqAuthimportpandasaspd apiTqApi(authTqAuth(账户,密码))# 获取K线数据symbolSHFE.rb2505klinesapi.get_kline_serial(symbol,60*60,
# 1小时K线api.wait_update()# 转为DataFramedfklines.to_dataframe()df[datetime]pd.to_datetime(df[datetime])dfdf.set_index(datetime)print(df.tail())api.close()
K线图绑制
1 使用mplfinance绑制专业K线importmplfinanceasmpfimportpandasaspd# 准备数据需要特定列名df_ohlcdf[[open,high,low,close,volume]].copy()df_ohlc.columns[Open,High,Low,Close,Volume]# 绑制K线图mpf.plot(df_ohlc.tail(
,# 最近100根K线typecandle,# 蜡烛图stylecharles,# 样式title螺纹钢 RB2505 1小时K线,ylabel价格,volumeTrue,# 显示成交量figsize(14,
)
2 添加均线# 计算均线df_ohlc[MA5]df_ohlc[Close].rolling(
.mean()df_ohlc[MA20]df_ohlc[Close].rolling(
.mean()# 添加均线到图表ap[mpf.make_addplot(df_ohlc[MA5].tail(
,colorblue,width
,mpf.make_addplot(df_ohlc[MA20].tail(
,colororange,width
,]mpf.plot(df_ohlc.tail(
,typecandle,stylecharles,title螺纹钢 K线 均线,addplotap,volumeTrue,figsize(14,
)
3 添加布林带# 计算布林带period20df_ohlc[MA20]df_ohlc[Close].rolling(period).mean()df_ohlc[STD]df_ohlc[Close].rolling(period).std()df_ohlc[Upper]df_ohlc[MA20]2*df_ohlc[STD]df_ohlc[Lower]df_ohlc[MA20]-2*df_ohlc[STD]# 绑制ap[mpf.make_addplot(df_ohlc[MA20].tail(
,colorblue),mpf.make_addplot(df_ohlc[Upper].tail(
,colorgray,linestyle--),mpf.make_addplot(df_ohlc[Lower].tail(
,colorgray,linestyle--),]mpf.plot(df_ohlc.tail(
,typecandle,addplotap,title布林带指标,figsize(14,
)
策略回测结果可视化
1 资金曲线importmatplotlib.pyplotaspltimportnumpyasnp# 模拟资金曲线数据np.random.seed(
returnsnp.random.randn(
*
02# 模拟日收益equity100000*(1returns).cumprod()# 绘制资金曲线plt.figure(figsize(12,
)plt.plot(equity,colorblue,linewidth
1.
plt.fill_between(range(len(equity)),equity,alpha
0.
plt.title(策略资金曲线,fontsize
plt.xlabel(交易日)plt.ylabel(账户权益)plt.grid(True,alpha
0.
plt.tight_layout()plt.show()
2 回撤曲线defcalc_drawdown(equity):计算回撤peaknp.maximum.accumulate(equity)drawdown(equity-peak)/peakreturndrawdown drawdowncalc_drawdown(equity)# 绘制回撤曲线fig,axesplt.subplots(2,1,figsize(12,
,sharexTrue)# 资金曲线axes[0].plot(equity,colorblue)axes[0].set_title(资金曲线)axes[0].set_ylabel(账户权益)axes[0].grid(True,alpha
0.
# 回撤曲线axes[1].fill_between(range(len(drawdown)),drawdown,colorred,alpha
0.
axes[1].set_title(回撤曲线)axes[1].set_xlabel(交易日)axes[1].set_ylabel(回撤比例)axes[1].grid(True,alpha
0.
plt.tight_layout()plt.show()
3 收益分布# 计算日收益率daily_returnsnp.diff(equity)/equity[:-1]# 绘制收益分布fig,axesplt.subplots(1,2,figsize(14,
)# 直方图axes[0].hist(daily_returns,bins50,colorblue,alpha
7,edgecolorblack)axes[0].axvline(x0,colorred,linestyle--)axes[0].set_title(日收益分布)axes[0].set_xlabel(日收益率)axes[0].set_ylabel(频次)# 累计分布sorted_returnsnp.sort(daily_returns)cumulativenp.arange(1,len(sorted_returns)
/len(sorted_returns)axes[1].plot(sorted_returns,cumulative)axes[1].axhline(y
5,colorred,linestyle--,alpha
0.
axes[1].set_title(累计分布)axes[1].set_xlabel(日收益率)axes[1].set_ylabel(累计概率)plt.tight_layout()plt.show()
交易信号可视化
1 在K线图上标记买卖点importmatplotlib.pyplotaspltimportmatplotlib.datesasmdates# 准备数据df_plotdf.tail(
.copy()df_plot[MA5]df_plot[close].rolling(
.mean()df_plot[MA20]df_plot[close].rolling(
.mean()# 生成信号df_plot[signal]0df_plot.loc[df_plot[MA5]df_plot[MA20],signal]1df_plot.loc[df_plot[MA5]df_plot[MA20],signal]-1df_plot[signal_change]df_plot[signal].diff()# 买卖点buy_signalsdf_plot[df_plot[signal_change]2]sell_signalsdf_plot[df_plot[signal_change]-2]# 绑图fig,axplt.subplots(figsize(14,
)ax.plot(df_plot.index,df_plot[close],label收盘价,colorblack,linewidth
ax.plot(df_plot.index,df_plot[MA5],labelMA5,colorblue,linewidth
ax.plot(df_plot.index,df_plot[MA20],labelMA20,colororange,linewidth
# 标记买卖点ax.scatter(buy_signals.index,buy_signals[close],marker^,colorred,s100,label买入,zorder
ax.scatter(sell_signals.index,sell_signals[close],markerv,colorgreen,s100,label卖出,zorder
ax.set_title(交易信号标记)ax.set_xlabel(时间)ax.set_ylabel(价格)ax.legend()ax.grid(True,alpha
0.
plt.xticks(rotation
plt.tight_layout()plt.show()
多图组合展示
1 完整的策略分析面板importmatplotlib.pyplotaspltimportmatplotlib.gridspecasgridspec figplt.figure(figsize(16,
)gsgridspec.GridSpec(3,2,height_ratios[2,1,1])#
K线图 均线ax1fig.add_subplot(gs[0,:])ax
plot(df_plot.index,df_plot[close],label收盘价)ax
plot(df_plot.index,df_plot[MA5],labelMA
ax
plot(df_plot.index,df_plot[MA20],labelMA
ax
set_title(价格走势与均线)ax
legend()ax
grid(True,alpha
0.
#
成交量ax2fig.add_subplot(gs[1,0])colors[redifcoelsegreenforc,oinzip(df_plot[close],df_plot[open])]ax
bar(range(len(df_plot)),df_plot[volume],colorcolors,alpha
0.
ax
set_title(成交量)ax
set_ylabel(成交量)#
资金曲线ax3fig.add_subplot(gs[1,1])ax
plot(equity,colorblue)ax
fill_between(range(len(equity)),equity,alpha
0.
ax
set_title(资金曲线)ax
set_ylabel(权益)#
回撤ax4fig.add_subplot(gs[2,0])ax
fill_between(range(len(drawdown)),drawdown,colorred,alpha
0.
ax
set_title(回撤)ax
set_ylabel(回撤比例)#
收益分布ax5fig.add_subplot(gs[2,1])ax
hist(daily_returns,bins30,colorblue,alpha
0.
ax
axvline(x0,colorred,linestyle--)ax
set_title(日收益分布)plt.tight_layout()plt.show()
保存图表# 保存为PNGplt.savefig(strategy_report.png,dpi150,bbox_inchestight)# 保存为PDF适合打印plt.savefig(strategy_report.pdf,bbox_inchestight)# 使用mplfinance保存mpf.plot(df_ohlc.tail(
,typecandle,stylecharles,savefigkline_chart.png)
实用技巧
1 设置中文字体importmatplotlib.pyplotasplt# Windowsplt.rcParams[font.sans-serif][SimHei]plt.rcParams[axes.unicode_minus]False# Mac# plt.rcParams[font.sans-serif] [Arial Unicode MS]
2 自定义样式# 使用内置样式plt.style.use(seaborn-darkgrid)# 或自定义plt.rcParams.update({figure.facecolor:white,axes.facecolor:white,axes.grid:True,grid.alpha:
3,font.size:10,})
3 交互式图表Plotlyimportplotly.graph_objectsasgofromplotly.subplotsimportmake_subplots# 创建K线图figmake_subplots(rows2,cols1,shared_xaxesTrue,vertical_spacing
03,row_heights[
7,
3])# K线fig.add_trace(go.Candlestick(xdf_plot.index,opendf_plot[open],highdf_plot[high],lowdf_plot[low],closedf_plot[close],nameK线),row1,col
# 成交量fig.add_trace(go.Bar(xdf_plot.index,ydf_plot[volume],name成交量),row2,col
fig.update_layout(title交互式K线图,xaxis_rangeslider_visibleFalse)fig.show()
十、