statsmdels.tsa 模块中的 VAR 类。
import warnings
warnings.filterwarnings("ignore")
学习
# encoding: gbkimport pandas as pd
import numpy as np
import arrow
import re
import matplotlib.pyplot as plt
import time
# 统计包# from scipy import statsimport statsmodels.api as sm
import statsmodels.stats.diagnostic
'''黄金建模专用脚本'''# 伦敦金万德获取代码# w_wsd_data = vba_wsd("SPTAUUSDOZ.IDC","close","2016-01-01","2019-01-11", "TradingCalendar=SHFE", w_wsd_codes, w_wsd_fields, w_wsd_times, w_wsd_errorid)# 上期黄金获取代码# w_wsd_data = vba_wsd("AU1606.SHF,AU1612.SHF,AU1706.SHF,AU1712.SHF,AU1806.SHF,AU1812.SHF,AU1906.SHF","close","2016-01-01","2019-01-11", "TradingCalendar=SHFE", w_wsd_codes, w_wsd_fields, w_wsd_times, w_wsd_errorid)# 上期黄金成交量获取代码# w_wsd_data = vba_wsd("AU1606.SHF,AU1612.SHF,AU1706.SHF,AU1712.SHF,AU1806.SHF,AU1812.SHF,AU1906.SHF","volume","2016-01-01","2019-01-11", "TradingCalendar=SHFE", w_wsd_codes, w_wsd_fields, w_wsd_times, w_wsd_errorid)# 常量# 文件名
shfeDataFileName = 'shfeAu20160101_20190111.csv'
shfeIndexDataFileName = 'SHFEAuIndex.csv'
xauUsdDataFileName = 'xauusd20160101_20190111.csv'
forexCNYUSDFileName = 'CNYUSDforex.csv'# 综合月
adjMonthDict = {'5月':5, '11月':11}
# 合约顺序
ctrOrderList = ['AU1606.SHF','AU1612.SHF','AU1706.SHF','AU1712.SHF','AU1806.SHF','AU1812.SHF','AU1906.SHF']
volOrderList = ['AU1606.VOL','AU1612.VOL','AU1706.VOL','AU1712.VOL','AU1806.VOL','AU1812.VOL','AU1906.VOL']
# 列名
dateTimeName = 'DateTime'
indexPriceName = 'indexPrice'
xauusdPriceName = 'CLOSE'# 先处理数据# 品种指数编制:参照中信建投期货的主力合约换月规则,拼接数据classshfeFuturesIndexGenerate():
def__init__(self,dataFileName=str(),ctrOrder=ctrOrderList,volOrder=volOrderList):
self.data = pd.read_csv(dataFileName,encoding='gbk')
self.ctrOrderList = ctrOrder
self.volOrderList = volOrder
defdataCombine(self):
# 按合约顺序提取和拼接数据
catIndexData = {dateTimeName:[],indexPriceName:[]}
# 根据价格列名进行循环
j = 0for i inrange(len(ctrOrderList)):
# # 按照合约顺序开始抓合约价格数据和日期数据# tempdata = self.data.loc[:,[dateTimeName,self.ctrOrderList[i]]]# 目前处理的是合约名字
tempCatName = self.ctrOrderList[i]
tempVolName = self.volOrderList[i]
# 获得当前合约的交割月
settleMonth = int(re.sub("\D","",tempCatName)[-2:])
# 获得当前合约的年份
settleYear = float(re.sub("\D","",tempCatName))/100
settleYear = round(settleYear)
# 日期循环whileTrue:
# 抓日期和价格
tempDate = self.data[dateTimeName][j]
tempPrice = self.data[tempCatName][j]
# 抓日期的月份
tempDateMonth = arrow.get(tempDate).month
# 抓日期的年份
tempDateYear = int(str(arrow.get(tempDate).year)[-2:])
# 对月份和年份进行判断,看是否要换月if tempDateMonth >= settleMonth:
if tempDateYear >= settleYear:
break# 对月份进行判断,看是否需要加权if tempDateMonth == adjMonthDict['5月'] or tempDateMonth == adjMonthDict['11月']:
# 目前合约的价格和成交量
tempPrice1 = tempPrice
tempVol1 = self.data[tempVolName][j]
# 抓下一个合约的价格和成交量
catName2 = self.ctrOrderList[i + 1]
volName2 = self.volOrderList[i + 1]
tempPrice2 = self.data[catName2][j]
tempVol2 = self.data[volName2][j]
# 合成加权平均价格
weight1 = tempVol1 / (tempVol1 + tempVol2)
weight2 = tempVol2 / (tempVol1 + tempVol2)
tempPrice = tempPrice1 * weight1 + tempPrice2 * weight2
tempPrice = round(tempPrice,2)
# 先插入价格
catIndexData[indexPriceName].append(tempPrice)
# 最后加入日期
tempDate = time.strptime(tempDate,'%Y/%m/%d')
tempDate = time.strftime('%Y/%m/%d',tempDate)
catIndexData[dateTimeName].append(tempDate)
# 行数递增
j += 1if j == self.data.shape[0]:
break
catIndexData = pd.DataFrame(catIndexData)
return catIndexData
defgetNewDateFile(self):
data = self.dataCombine()
data.to_csv('SHFEAuIndex.csv',index=False)
# 然后开始建模classgetVarModel():
# def __init__(self, shfeAuIndexFileName=shfeIndexDataFileName, xauusdFileName=xauUsdDataFileName, inSampleStart='2016-1-4',inSampleEnd='2018-9-28'):def__init__(self, shfeAuIndexFileName=shfeIndexDataFileName, xauusdFileName=xauUsdDataFileName,
inSampleStart='2018-1-1',inSampleEnd='2018-9-28'):
self.shfeIndexData = pd.read_csv(shfeAuIndexFileName)
self.xauusdData = pd.read_csv(xauusdFileName)
self.forexData = pd.read_csv(forexCNYUSDFileName)
# 处理数据,用日期做index
self.shfeIndexData[dateTimeName] = pd.to_datetime(self.shfeIndexData[dateTimeName])
self.shfeIndexData = self.shfeIndexData.set_index(dateTimeName)
self.xauusdData[dateTimeName] = pd.to_datetime(self.xauusdData[dateTimeName])
self.xauusdData = self.xauusdData.set_index(dateTimeName)
self.forexData[dateTimeName] = pd.to_datetime(self.forexData[dateTimeName])
self.forexData = self.forexData.set_index(dateTimeName)
# 样本内数据,构造Series类型数据
self.shfeIndexInSampleData = self.shfeIndexData[inSampleStart:inSampleEnd]
self.shfeIndexInSampleData = pd.Series(self.shfeIndexInSampleData[indexPriceName],
index=self.shfeIndexInSampleData.index)
self.xauusdDataInSampleData = self.xauusdData[inSampleStart:inSampleEnd]
self.xauusdDataInSampleData = pd.Series(self.xauusdDataInSampleData[xauusdPriceName],
index=self.xauusdDataInSampleData.index)
self.forexDataInSampleData = self.forexData[inSampleStart:inSampleEnd]
self.forexDataInSampleData = pd.Series(self.forexDataInSampleData['OPEN'],
index=self.forexDataInSampleData.index)
# 样本个数
self.sampleNum = self.shfeIndexInSampleData.shape[0]
# 价格走势图defprice_trend_draw(self):
# 处理数据,化为人民币和1g# changeXAUUSD = np.array(self.xauusdDataInSampleData) / 28.3495 * 6.78
font1 = {'size':23}
changeXAUUSD = np.multiply(np.array(self.xauusdDataInSampleData) / 28.3495 , np.array(self.forexDataInSampleData))
changeXAUUSD = np.round(changeXAUUSD,2)
shfeXAU = np.array(self.shfeIndexInSampleData)
# 算相关系数,一定要是pd.Series类型数据才可以
correlation = round(pd.Series(shfeXAU).corr(pd.Series(changeXAUUSD)),6)
# print(changeXAUUSD)
fig = plt.figure(figsize=(12,8))
plt.plot(changeXAUUSD,'r',label='XAU USD')
plt.plot(shfeXAU,'g',label='SHFE XAU')
plt.title('Correlation: ' + str(correlation),font1)
plt.grid(True)
plt.axis('tight')
plt.legend(loc=0,prop=font1)
plt.ylabel('Price',font1)
plt.show()
# plt.plot()# 对数一阶差分处理deflogdiff(self,data):
logData = np.log(data)
logDiffData = np.diff(logData)
return logDiffData
# 数据稳定性检验defadftest(self,data,maxlags):
adfResult = sm.tsa.stattools.adfuller(data,maxlags)
output = pd.DataFrame(index=['Test Statistic Value', "p-value", "Lags Used", "Number of Observations Used",
此代码用于禁止显示 Python 脚本中的警告。警告模块提供了一种将警告作为异常处理或临时过滤它们的方法。在这种情况下,通过添加一个简单的过滤器,使用 filterpolice 函数忽略所有警告
这个错误信息显示了在VAR模型中使用的数据类型出现问题。具体而言,错误信息中提到了Pandas数据类型被转换成了Numpy对象类型,而这通常是由于数据中存在类型不一致的问题导致的。建议检查数据的类型是否一致,如果有类型不一致的情况,需要进行类型转换以确保数据的一致性。另外,也可以尝试使用 `np.asarray()`函数将数据强制转换为Numpy数组,以避免数据类型问题。
## 确保数据框架中的数据类型适合于 VAR 建模。数据应该是数字的,最好是平稳的。
它指示由于将对象数据类型传递给 statsmodel 中的 VAR ()函数而导致的 ValueError,该函数只接受数值数据类型。在将其传递给 VAR ()函数之前,应该确保熊猫 DataFrame 中的所有列都是数值数据类型。可以使用 df.dtypes 方法检查 DataFrame 中列的数据类型。
根据您提供的信息,似乎 "开盘价","最高价","最低价"这些列的数据类型是"object",但这些列应该是数值型数据。可以使用 `pandas.to_numeric()` 函数将它们转换为数值类型。例如:
`df["开盘价"] = pd.to_numeric(df["开盘价"]) df["最高价"] = pd.to_numeric(df["最高价"]) df["最低价"] = pd.to_numeric(df["最低价"])`
# 研究意义
该代码从多个文件中读取数据,将它们组合成一个数据框架,转换数据类型,并拟合一个 VAR 模型来分析影响期货波动性的因素。模型结果和方差分解图表明,波动性主要受其自身过去价值(70%)的影响,其次是工业增加值(20%)和 M2货币供应量(10%)。
错误消息表明,对于最大值函数,存在一个零大小的数组,该数组没有标识。这个错误发生在 statsmodel 包的 add _ Trends 函数中,该函数由 get _ var _ endog 函数调用,而 get _ var _ endog 函数又由 var _ model 类的 fit 函数调用。
第二个错误 "ValueError: zero-size array to reduction operation maximum which has no identity" 通常是由于出现了空的数组或维度为 0 的数组导致的。可能的解决方法包括:
try:
exchanges.append(df_exchange[df_exchange["年份"] == int(year)]["美元(人民币元/100美元)"].values[0])
except:
exchanges.append(np.NaN)
try:
in_.append(df_in[df_in["时间"] == year + "年"]["年度工业增加值"].values[0])
except:
in_.append(np.NaN)
try:
M2.append(df_M2[df_M2["月度标识"] == month]["货币和准货币(M2)"].values[0])
except:
M2.append(np.NaN)
这段代码中,三个try/except块的作用是从三个数据框(df_exchange,df_in和df_M2)中提取对应的数值,并将其附加到名为exchanges、in_和M2的列表中。如果无法提取数值,这些代码会将np.NaN添加到列表中。
使用try/except块的原因是防止由于数据缺失或其他错误而导致程序崩溃。当出现错误时,程序不会停止,而是跳过该块并继续执行后面的代码。
增删表
这段代码的作用是从 `df_M2`中筛选出月份为 `month`的行,并提取"货币和准货币(M2)"列的值加入到 `M2`列表中。如果筛选的结果为空(即找不到对应月份的行),则加入 `NaN`值到 `M2`列表中。
> df_M2 = df_M2.loc[:,["月度标识","货币和准货币(M2)"]]
这行代码是在 Pandas 中从数据框 `df_M2` 中选取了两列,即"月度标识"和"货币和准货币(M2)",并且重新赋值给了数据框 `df_M2`。
`:,:` 代表选择所有行, `["月度标识","货币和准货币(M2)"]` 代表选择名为"月度标识"和"货币和准货币(M2)"的两列数据。