NSLog(@"hello world");
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from matplotlib import pylab as plt
import math
group1 = ['300460', '002619', '603809','000426','002600','000008','002217','300652','600505','002078']
group2 =['603533','603928','600693','603811','300613','300621','000988','600839','300502','000933','600685','002907','002922',
'600284','601998','000505','600726','000591','002798','601127']
group3 = ['300697', '300035', '603322','601229','002681','002121','600615','600367','002695','002301','300130','603920','300325',
'300468','002061','002897','002014','000628','300034','002023','002199','000882','000401','002598','300558','600691',
'300392','601901','300353','002077']
# IF_IH_IC = ['IF','IH','IC'] # 三大期货指数
# IF_IH = ['IF','IH']
# IF_IC = ['IF','IC']
# IH_IC = ['IH','IC']
IF = 'IF'
IH = 'IH'
IC = 'IC'
# 定义函数:得到投资组合x从时间start到时间end的日收益率序列(x:group start:20190101, end:20190401)
def get_returndaily(x,start,end):
#:step1:先用交易日日历得到从时间start到时间end的交易日日期
from CAL.PyCAL import *
data=DataAPI.TradeCalGet(exchangeCD=u"XSHG",beginDate=str(start),endDate=str(end),field=['calendarDate','isOpen'])
# DataAPI.TradeCalGet即交易所交易日历函数
data = data[data['isOpen'] == 1]
date= map(lambda x: x[0:4]+x[5:7]+x[8:10], data['calendarDate'].values.tolist())
# 从时间start到时间end的每个交易日日期,得到后存为列表date
# step2:调用投资组合x每只股票每个交易日的市值以及收盘价
returndaily=np.zeros(len(date)-1)
for i in range(len(date)-1): # 即 i=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11...]为了从date列表里面依次定位取第几个日子
inf1=DataAPI.MktEqudAdjGet(tradeDate=date[i],ticker=x,field=u"ticker,closePrice").set_index('ticker') # 前一个交易日的收盘价
inf2=DataAPI.MktEqudAdjGet(tradeDate=date[i+1],ticker=x,field=u"ticker,marketValue,closePrice").set_index('ticker') # 当前交易日的收盘价和市值
# 将以上两个表横向合并成一张有股票代码、市值、上个交易日收盘价和当前交易日收盘价组成的表Return
Return=pd.concat([inf2,inf1],axis=1)
# print date[i+1]
# print Return
# step3:计算每只股票收益率和市值加权的权重以及两者的乘积
# 每只股票权重不等
"""
Return.columns=['Weight','Return','WReturn'] # 改下表的列名称(就是第一行的字段),下面分别计算各列数据
Return['Weight']=Return['Weight']/Return['Weight'].sum() # 按市值在该组总市值占比分配权重
Return['Return']=Return['Return']/Return['WReturn']-1 # 即定义出三者逻辑运算关系
Return['WReturn']=Return['Weight']*Return['Return'] # 同上,这个WReturn即我们需要的个股日收益率表
returndaily[i]=Return['WReturn'].sum() # 按日依次汇总得出组合的日收益率表returndaily
# Return['Return']=Return['Return']/Return['Return']-1 # 即定义出三者逻辑运算关系
"""
# 每只股票等权重
Return.columns=['Weight','Return','WReturn']
Return['Weight'] = 1.0
Return['Return']=Return['Return']/Return['WReturn']-1 # 即定义出三者逻辑运算关系
Return['WReturn']=Return['Weight']*Return['Return'] # 同上,这个WReturn即我们需要的个股日收益率表
returndaily[i]=Return['WReturn'].sum()
return returndaily
# 定义函数:得到期货指数y从时间start到时间end的日收益率序列(y:IF,IH,IC start:20190101, end:20190401)
def get_returnfutures_daily(y,start,end):
# step1:先用交易日日历得到从时间start到时间end的交易日日期
from CAL.PyCAL import *
data=DataAPI.TradeCalGet(exchangeCD=u"XSHG",beginDate=str(start),endDate=str(end),field=['calendarDate','isOpen'])
data = data[data['isOpen'] == 1]
date= map(lambda x: x[0:4]+x[5:7]+x[8:10], data['calendarDate'].values.tolist())
# step2:调用指数y收盘价用来计算收益率
returndaily=np.zeros(len(date)-1)
for i in range(len(date)-1): # 即 i=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11...]为了从date列表里面依次定位取第几个日子
# inf1= DataAPI.MktFutdGet(tradeDate=date[i],ticker=y,field=u"ticker,closePrice",pandas="1").set_index('ticker')
# inf2= DataAPI.MktFutdGet(tradeDate=date[i+1],ticker=y,field=u"ticker,openInt,closePrice",pandas="1").set_index('ticker') # 这两个返回空值,有时间再研究
inf1 = DataAPI.MktMFutdGet(tradeDate=date[i],mainCon=u"1",contractMark=u"",contractObject=y,field=u"ticker,closePrice",pandas="1").set_index('ticker')
inf2 = DataAPI.MktMFutdGet(tradeDate=date[i+1],mainCon=u"1",contractMark=u"",contractObject=y,field=u"ticker,openInt,closePrice",pandas="1").set_index('ticker')
Return=pd.concat([inf2,inf1],axis=1)
# step3:计算每种期货指数收益率和持仓量加权的权重以及两者的乘积
# 如果对冲指数包含多个期货指数
if type(y) is list:
Return.columns=['Weight','Return','WReturn'] # 改下表的列名称(就是第一行的字段),下面分别计算各列数据
Return['Weight']=Return['Weight']/Return['Weight'].sum() # 按市值在该组总市值占比分配权重
Return['Return']=Return['Return']/Return['WReturn']-1 # 即定义出三者逻辑运算关系
Return['WReturn']=Return['Weight']*Return['Return'] # 同上,这个WReturn即我们需要的个股日收益率表
returndaily[i]=Return['WReturn'].sum() # 按日依次汇总得出组合的日收益率表returndaily
# 如果只用一种期货指数对冲
else:
Return.columns = ['Weight','Return','WReturn']
# Return['Weight'] = 1.0/(len(date)-1) # 等权
Return['Return'] = Return['Return']/Return['WReturn']-1
# Return['WReturn'] = Return['Weight']*Return['Return']
returndaily[i] = Return['Return'].sum()
return returndaily
# 定义函数:填充ndarray中的nan值
def fill_ndarray(t1):
nan_num = np.count_nonzero(t1==t1)
if nan_num != 0: # 不为0,说明当前这一列中有nan
temp_not_nan=t1[t1==t1] # 当前不为nan的array
# 选中当前为nan的位置,把值赋值为该列除nan以外的数的均值
t1[np.isnan(t1)] = temp_not_nan.mean()
return t1
# 股票组合收益率
group1_ret = get_returndaily(group1,20190101,20190401)
group2_ret = get_returndaily(group2,20190101,20190401)
group3_ret = get_returndaily(group3,20190101,20190401)
print group3_ret
print "*"*100
# 各个指数收益率
# IF_IH_IC_ret = get_returnfutures_daily(IF_IH_IC,20190101,20190401) # 三大指数
# IF_IH_ret = get_returnfutures_daily(IF_IH,20190101,20190401)
# IF_IC_ret = get_returnfutures_daily(IF_IC,20190101,20190401)
# IH_IC_ret = get_returnfutures_daily(IH_IC,20190101,20190401)
IF_ret = get_returnfutures_daily(IF,20190101,20190401)
IF_ret = fill_ndarray(IF_ret)
IH_ret = get_returnfutures_daily(IH,20190101,20190401)
IH_ret = fill_ndarray(IH_ret)
IC_ret = get_returnfutures_daily(IC,20190101,20190401)
IC_ret = fill_ndarray(IC_ret)
print IC_ret
print type(IC_ret)
# 定义相关系数函数
def corr(stock_list): # stock_list:股票组合收益率
# 期货收益率序列
# IF_IH_IC_series = pd.Series(IF_IH_IC_ret)
# IF_IH_series = pd.Series(IF_IH_ret)
# IF_IC_series = pd.Series(IF_IC_ret)
# IH_IC_series = pd.Series(IH_IC_ret)
IF_ret_series = pd.Series(IF_ret)
IH_ret_series = pd.Series(IH_ret)
IC_ret_series = pd.Series(IC_ret)
# 股票收益率序列
stock_group = pd.Series(stock_list)
# 计算相关系数,保留四位小数
# corr_IF_IH_IC = round(stock_group.corr(IF_IH_IC_series), 4)
# corr_IF_IH = round(stock_group.corr(IF_IH_series), 4)
# corr_IF_IC = round(stock_group.corr(IF_IC_series), 4)
# corr_IH_IC = round(stock_group.corr(IH_IC_series), 4)
corr_IF = round(stock_group.corr(IF_ret_series), 4)
corr_IH = round(stock_group.corr(IH_ret_series), 4)
corr_IC = round(stock_group.corr(IC_ret_series), 4)
# 绘制散点图
# plt.scatter(stock_list, IF_IH_IC_ret)
# plt.title('corr_IF_IH_IC :' + str(corr_IF_IH_IC), fontproperties='SimHei')
# print('corr_IF_IH_IC :', corr_IF_IH_IC)
# plt.show()
# plt.scatter(stock_list, IF_IH_ret)
# plt.title('corr_IF_IH :' + str(corr_IF_IH), fontproperties='SimHei')
# print('corr_IF_IH :', corr_IF_IH)
# plt.show()
# plt.scatter(stock_list, IF_IC_ret)
# plt.title('corr_IF_IC :' + str(corr_IF_IC), fontproperties='SimHei')
# print('corr_IF_IC :', corr_IF_IC)
# plt.show()
# plt.scatter(stock_list, IH_IC_ret)
# plt.title('corr_IH_IC :' + str(corr_IH_IC), fontproperties='SimHei')
# print('corr_IH_IC :', corr_IH_IC)
# plt.show()
plt.scatter(stock_list, IF_ret)
plt.title('corr_IF :' + str(corr_IF), fontproperties='SimHei')
print('corr_IF :', corr_IF)
plt.show()
plt.scatter(stock_list, IH_ret)
plt.title('corr_IH :' + str(corr_IH), fontproperties='SimHei')
print('corr_IH :', corr_IH)
plt.show()
plt.scatter(stock_list, IC_ret)
plt.title('corr_IC :' + str(corr_IC), fontproperties='SimHei')
print('corr_IC :', corr_IC)
plt.show()
return corr_IF,corr_IH,corr_IC
group1_corr = corr(group1_ret) # 组合的各种相关系数
group2_corr = corr(group2_ret)
group3_corr = corr(group3_ret)
print group1_corr
print "*"*100
print group2_corr
print "*"*100
print group3_corr
# 结论:有结果可知,三组股票均与IC的相关性最高。当然了,在与指数池做相关性分析时,发现:第二组用IH\IC混合对冲较好,由于相对复杂,时间关系,这里不深入研究,日后再探讨。
# 下面是求贝塔的过程
cov_mat = np.cov(group3_ret,IC_ret)
print cov_mat
# 协方差
cov = cov_mat[1,1]
print 'cov(group3_ret,IC_ret) =', cov
print "var =", IC_ret.var() # 方差
# 得出贝塔
B=cov/IC_ret.var()
print 'β =', B
# 期指总市值
def matketValue(y, date):
inf = DataAPI.MktMFutdGet(tradeDate=date,mainCon=u"1",contractMark=u"",contractObject=y,field=u"ticker,closePrice",pandas="1").set_index('ticker')
closeprice = inf.values
tol_index_equd = closeprice * 300
return tol_index_equd
# 股票组合总市值(废弃)
# def group_matketValue(group, date):
# group_equd = 0
# for stock in group:
# equd=DataAPI.MktEqudAdjGet(tradeDate=date,ticker=stock,field=u"ticker,marketValue").set_index('ticker')
# equd = equd["marketValue"].values
# # print equd
# group_equd += equd
# return group_equd
Vs = len(group3)*1000000
Vf = matketValue(IC, '20190401')
print 'Vs=', Vs # 股票组合市值
print 'Vf=', Vf # 一手期指市值
N = B*Vs/Vf # 期指对冲的手数
print 'N=', N