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)"的两列数据。