使用Windpy和Python进行金融数据分析
一、windpy+python初步想法
Wind有python接口,可以导出相关的金融数据,特别适用于要导出大量数据,或者想看不同区间的数据的情况,特别是有定期更新数据的需求时,用python解决比excel更方便。
所以研究了一下Windpy的应用,现在这样的应用教程还是比较少的,希望能从基础的数据导出出发,用python完成进一步的数据再处理、数据分析、数据可视化的完整的金融数据的分析。
现在是第一篇,主要完成了分析一只或多只指数在分析区间内的涨跌幅走势(折现图)、各区间段内的涨跌幅、最大回撤、年化夏普比率对比表格
二、思路和代码展示
(一)导入相关的库
1.一开始的时候遇到了好多问题,比如显示中文乱码、字体、中文字体下坐标轴负数的负号显示问题等,下面的代码就一下子都解决了。
# 设置输出格式为utf8
# -*- coding: utf-8 -*-
import io
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding="utf8")
import time
# 调用wind接口
from WindPy import w
# 调用需要的各种库
import pandas as pd
import numpy as np
import datetime
from dateutil.parser import parse
from datetime import datetime
from datetime import timedelta
from dateutil.relativedelta import relativedelta
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
plt.rcParams['font.sans-serif'] = ['SimHei'] #设计字体为黑体
plt.rcParams['axes.unicode_minus'] = False #解决中文字体下坐标轴负数的负号显示问题
plt.rcParams['figure.figsize'] = (9, 5) #统一图片大小
import seaborn as sns
pd.set_option('display.max_columns',None)
w.start()
w.isconnected()
(二)制作基础的数据表
包括列名为指数简称、各行为日期区间内的涨跌幅
def get_ClosePrice_increase(
IndexCode, # 要分析的指数列表
StartDate, # 开始日期'20190301'
EndDate, # 截止日期'20191231'
long_x = 10, # 图片的尺寸设置,默认是10,可以改
short_y = 6, # 图片的尺寸设置,默认是6,可以改
need_to_show=True
):
error_code, IndexName = w.wss(IndexCode, "sec_name",usedf=True)
IndexName_list = IndexName['SEC_NAME'].to_list()
True_StartDate = (parse(StartDate) - relativedelta(days=1)).strftime('%Y%m%d')
error_code, ClosePrice = w.wsd(IndexCode, "close", True_StartDate, EndDate, "",usedf=True) #导出区间内收盘价
col=IndexName_list
ClosePrice.columns=col
ClosePrice_increase = ((ClosePrice - ClosePrice.iloc[0,:]) / ClosePrice.iloc[0,:])*100 #区间涨跌幅计算
ClosePrice_increase = ClosePrice_increase.iloc[1:,:]
print(ClosePrice_increase)
运行结果如下:
上证指数 沪深300
2019-03-01 1.803877 2.189585
2019-03-04 2.945361 3.399322
2019-03-05 3.852247 3.996405
2019-03-06 5.479355 4.870590
2019-03-07 5.626205 3.801181
... ... ...
2024-02-23 2.173689 -4.895355
2024-02-26 1.226415 -5.886890
2024-02-27 2.534106 -4.757844
2024-02-28 0.574596 -5.971338
2024-02-29 2.523583 -4.177493
[1214 rows x 2 columns]
(三)画指数收益率的对比图(只有一只的话就是指数的走势图)
plt.rcParams['figure.figsize'] = (long_x, short_y)
x = ClosePrice_increase.index
for index,IndexName in enumerate(IndexName_list):
y = ClosePrice_increase[IndexName_list[index]]
plt.plot(x, y,label=IndexName_list[index],
color=color_list[index], linestyle='-', markersize=5)
# 设置X,Y轴标签
plt.ylabel('区间涨跌幅:%',fontsize = 14,loc="top")
# 设置图例
plt.legend(loc='upper right')
# 设置图片标题并保存
fig_name = '图 ' + IndexName_list[0] +'等指数涨跌幅对比_' + StartDate + '-' + EndDate +'.png'
plt.savefig(fig_name, bbox_inches='tight')
plt.legend(loc='upper right')
# plt.show()
图片输出结果如下:
(四)做各个区间段的涨跌幅、最大回撤、年化夏普比等指标的对比表格
1.定义各个区间段
# 区间段定义
YearBeginning = EndDate[:4] + '0101'
SixMonthBefore = (parse(EndDate) - relativedelta(months=6)+ relativedelta(days=1)).strftime('%Y%m%d') #6个月前
OneYearBefore = (parse(EndDate) - relativedelta(years=1)+ relativedelta(days=1)).strftime('%Y%m%d') #1年前
TwoYearBefore = (parse(EndDate) - relativedelta(years=2)+ relativedelta(days=1)).strftime('%Y%m%d') #2年前
ThreeYearBefore = (parse(EndDate) - relativedelta(years=3)+ relativedelta(days=1)).strftime('%Y%m%d') #3年前
FiveYearBefore = (parse(EndDate) - relativedelta(years=5)+ relativedelta(days=1)).strftime('%Y%m%d') #5年前
TenYearBefore = (parse(EndDate) - relativedelta(years=10)+ relativedelta(days=1)).strftime('%Y%m%d') #10年前
error_code, basedate = w.wss(IndexCode.split(',')[0], "basedate", usedf=True) #基准指数基日以来的日期
basedate = basedate.iloc[0,0].strftime('%Y%m%d')
error_code, launchdate = w.wss(IndexCode.split(',')[0], "launchdate", usedf=True) #基准指数发布以来的日期
launchdate = launchdate.iloc[0,0].strftime('%Y%m%d')
date_list = [YearBeginning, SixMonthBefore, OneYearBefore, TwoYearBefore, ThreeYearBefore, FiveYearBefore, TenYearBefore,basedate,launchdate]
Time_list = ['今年以来','近6个月','近一年','近两年','近三年','近五年','近十年','基日以来','发布以来']
2.区间段的指标导出
windpy导出数据的突出特点就是导出数据的时候不同指标对应的代码差别较大,所以很难对不同性质的指标都用for循环一下子就写出来,需要根据不同指标的wind公式的特征针对性的改,但是整体的思路是一致的,就以用的最多的区间涨跌幅、最大回撤、年化夏普比率为例子做展示:
(1)区间涨跌幅和区间最大回撤数据对比
Indicators_list = ['pct_chg_per','risk_maxdownside']
Indicators_name = ['区间涨跌幅:%','区间最大回撤:%']
for index,Indicators in enumerate(Indicators_list):
index_data_all = pd.DataFrame()
error_code, index_name = w.wss(IndexCode, "sec_name",usedf=True)
index_data_all.index = IndexCode.split(',')
index_data_all['指数简称'] = index_name['SEC_NAME']
for index2,date in enumerate(date_list):
Code = "startDate=" + date + ";endDate=" + EndDate
error_code, index_data = w.wss(IndexCode,Indicators,Code,usedf=True) #导出所需的相关指标
index_data.columns = [Time_list[index2]]
index_data_all = pd.concat([index_data_all,index_data],axis=1)
index_data_all = index_data_all.round(2)
# 导出表格为csv
csv_name = '指数' + Indicators_name[index][:-2] + '对比.csv'
index_data_all.to_csv(csv_name,encoding='utf-8-sig')
注意!
基日和发布日都是以指数列表的第一个指数为基准的,因为对比分析要保证区间段一致。
结果如下:
①指数区间涨跌幅对比
指数简称 | 今年以来 | 近6个月 | 近一年 | 近两年 | 近三年 | 近五年 | 近十年 | 基日以来 | 发布以来 | |
000001.SH | 上证指数 | 1.35 | -3.85 | -8.06 | -12.91 | -14.08 | 2.52 | 46.63 | 2915.17 | 2170.46 |
000300.SH | 沪深300 | 2.48 | -7.23 | -13.6 | -23.26 | -34.12 | -4.18 | 61.36 | 167.09 | 167.09 |
②指数区间最大回撤对比
指数简称 | 今年以来 | 近6个月 | 近一年 | 近两年 | 近三年 | 近五年 | 近十年 | 基日以来 | 发布以来 | |
000001.SH | 上证指数 | -8.93 | -14.95 | -20.41 | -22.55 | -27.27 | -27.27 | -52.3 | -78.27 | -78.27 |
000300.SH | 沪深300 | -6.1 | -17.39 | -23.6 | -31.17 | -41.68 | -45.25 | -46.7 | -72.3 | -72.3 |
(2)区间年化夏普比率数据对比
Indicators_list = ['sharpe']
Indicators_name = ['Sharpe(年化)']
for index,Indicators in enumerate(Indicators_list):
index_data_all = pd.DataFrame()
error_code, index_name = w.wss(IndexCode, "sec_name",usedf=True)
index_data_all.index = IndexCode.split(',')
index_data_all['指数简称'] = index_name['SEC_NAME']
for index2,date in enumerate(date_list):
Code = "startDate=" + date + ";endDate=" + EndDate + ';period=2;returnType=1;yield=1'
error_code, index_data = w.wss(IndexCode,Indicators,Code,usedf=True) #导出所需的相关指标
index_data.columns = [Time_list[index2]]
index_data_all = pd.concat([index_data_all,index_data],axis=1)
index_data_all = index_data_all.round(2)
# 导出表格为csv
csv_name = '指数' + Indicators_name[index] + '对比.csv'
index_data_all.to_csv(csv_name,encoding='utf-8-sig')
结果如下:
①指数Sharpe(年化)对比
指数简称 | 今年以来 | 近6个月 | 近一年 | 近两年 | 近三年 | 近五年 | 近十年 | 基日以来 | 发布以来 | |
000001.SH | 上证指数 | 0.35 | -0.53 | -0.75 | -0.5 | -0.41 | -0.01 | 0.23 | 0.4 | 0.39 |
000300.SH | 沪深300 | 0.58 | -1.01 | -1.06 | -0.77 | -0.88 | -0.07 | 0.28 |
(五)函数调用
IndexCode = "000001.SH,000300.SH" #把需要着重显示的放在第一个,就是红色
StartDate = '20190301'
EndDate = '20240229'
color_list = ['r','b'] #颜色列表元素数量应与IndexCode中的指数数量一致
get_ClosePrice_increase(IndexCode,StartDate,EndDate)
三、总结
以上就是一个简单的windpy导出数据,用python做数据处理和可视化的应用实例,其实还可以进一步做优化,比如把数据对比也做一个可视化展示,做个对比柱状图之类的,需要的话可以画出来~
之后还将持续优化、更新,还有其他的分析实例也将再发出来~
作者:瓜瓜南南