本人笨笨,几百年没写blog了实在是学了忘忘了学,知识点又杂,大概零零碎碎写一点点,没有售后(。),反正比一上来就默认你啥都知道好(一点点而已)(大佬请跳过,看这个纯属浪费您时间,本人废话很多。千万不要抄!我真的很菜就是记录一下自己的思路而已!!欢迎大家提出BUG!!土下座!!!
1.影响因子选择
当然得借鉴别人论文,我又没学过金融知识,所以整理了26个影响因子。(想起来再补上表
进行了如下处理:
1.1.填充空缺值
只有汇率是每天都有的好吗?其他的一个月一次的就直接用上一个非空数据。每一季度的直接取平均值或者扔了吧,本来就只能预测几天而已。
Dataframe=Dataframe.fillna(value=None, method='ffill')
#检查一下是否都是非空了
Dataframe.info()
1.2. pearson系数分析
检查两个变量之间变化趋势的方向以及程度,值范围-1到+1,0表示两个变量不相关,正值表示正相关,负值表示负相关,值越大相关性越强。常规操作,本来只是按照流程走,却发现后面问题好大。
Dataframe.corr()
2.预测方法一——VAR
读了n篇论文都是用VAR,那咱也来。
首先要知道VAR针对的是什么样的数据,https://zhuanlan.zhihu.com/p/87116384如此写到:
“向量自回归模型是针对多元时间序列数据,向量自回归模型采用了一种更为灵活的时序建模策略:给定多元时间序列数据为 ,则对于任意第 t 个时间间隔,存在如下的线性表达式
其中,表示向量自回归模型的系数矩阵; ϵt 可视为高斯噪声……”
(好了,已经看不懂了,但是问题应该不大,due赶不完了)
2.1多元时间序列
https://juejin.cn/post/6844903687567966216#heading-1说得简洁明了,就是一元的只有时间一个影响因素影响目标变量,但是多元有很多个因素,这些因素既会被时间影响,也会影响目标变量。所以,理论上,VAR确实很合适的样子。
2.2 白噪声检验Ljung-Box检验
该检验用来检查序列是否为随机序列,如果是随机序列,那它们的值之间没有任何关系。使用LB检验来检验序列是否为白噪声,原假设为在延迟期数内序列之间相互独立。这也是一个常规套路操作的样子。直接上代码吧:
from statsmodels.tsa.stattools import adfuller
import statsmodels.api as sm
white_noise=[]
##
for name in data_drop_Date:
df=data_drop_Date[name]
## 白噪声检验Ljung-Box检验
## 该检验用来检查序列是否为随机序列,如果是随机序列,那它们的值之间没有任何关系
## 使用LB检验来检验序列是否为白噪声,原假设为在延迟期数内序列之间相互独立。
lags = [4,8,16,32]
LB = sm.stats.diagnostic.acorr_ljungbox(df,lags = lags,return_df = True)
print(name+"的检验结果:\n",LB)
if(LB['lb_pvalue'].all()<0.05):
print(name+' is not white noise')
else:
white_noise.append(name)
## 如果P值小于0.05,说明序列之间不独立,不是白噪声
print(white_noise)
我这里结果还好,没有白噪声。
2.3序列的单位根检验ADF
常规操作.
not_stable_list_orgin=[]
not_stable_list_after=[]
stable_df=pd.DataFrame()
## 序列的单位根检验,即检验序列的平稳性
for name in data_drop_Date:
df=data_drop_Date[name]
dftest = adfuller(df,autolag='BIC')
dfoutput = pd.Series(dftest[0:4], index=['adf','p-value','usedlag','Number of Observations Used'])
print(name+"单位根检验结果:\n",dfoutput)
if(dfoutput['p-value']>=0.05):
not_stable_list_orgin.append(name)
else:
stable_df[name]=df
for name in not_stable_list_orgin:
## 对X1进行一阶差分后的序列进行检验
df=data_drop_Date[name]
X1diff = df.diff().dropna()
dftest = adfuller(X1diff,autolag='BIC')
dfoutput = pd.Series(dftest[0:4], index=['adf','p-value','usedlag','Number of Observations Used'])
print(name+"一阶差分单位根检验结果:\n",dfoutput)
if(dfoutput['p-value']>0.05 ):
not_stable_list_after.append(name)
else:
print(name)
fig = plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(111)
df.plot(ax=ax1)
X1diff.plot(ax=ax1)
plt.show()
stable_df[name]=X1diff
print(not_stable_list_orgin)
print(not_stable_list_after)
print(stable_df)
就是先做单位根检验,不平稳的数据一阶差分,然后 混~合~在~一~起~。但是做了一阶差分肯定要少一个数据,干脆去掉第一行。
2.4 确定滞后项阶数
首先照抄了该链接的思路https://www.frisk.today/post/267267077.html#VAR-%E6%A8%A1%E5%9E%8B%E7%9A%84%E6%9E%84%E5%BB%BA
from statsmodels.tsa.vector_ar.var_model import VAR
mod = VAR(endog=stable_df,dates=pd.date_range('2021/9/2','2022/9/24',freq='D'))
# 估计最优滞后项系数
lag_order = mod.select_order()
# 输出结果
print(lag_order.summary())
然后呢:.select_order() 处 leading minor of the array is not positive definite
去搜索没什么结果只有乱葬岗(。)
I found an explanation: "Fitting high dimensional VARs is not a goal of statsmodels at the present. Some other approach such as a ridge penalty might help you. I don't think there is anything that we can do here."
就是影响因子太多了,不适合。
呵。
呵呵。
1.2的Pearson系数还是不得不用的,我只选取的abs()>0.5的数据保留。
结果是出来了,但是……
大佬说得好啊:“0阶就退化模型呗。建立个普通的回归模型”
我好像看到有说ridge penalty
行吧。
3.预测方法——普通版
高深的不好用那就把所有的基础线性回归用一个遍。sklearn库是真的非常好用啊!12个模型来一遍。
BUT!!模型不能不调参(人不能,但至少不应该
使用GridSearchCV搜索,先用官网的SVM案例测试了一下,可行。但是自己写就频频报错。问题有
1.不适合调参的,如linear regression。我们可以通过这个函数看一下,官网全是英文懒得看……
print(clf.get_params())
2.遍历时报错 local variable 'GridSearchCV' referenced before assignment
大佬有云https://blog.csdn.net/sinat_40304087/article/details/115701595
大意时说我重复调用,但诡异的是,重复的是 ‘GridSearchCV' (那不然呢那不然呢)
然后就发现了,因为我用if代替match(3.6还没有QAQ),我在上一个elif后面的搜索方法中又一次写了这个:
from sklearn.model_selection import GridSearchCV
也就是本来是global,一下子变成private了
(未完不知道有没有待续)
2023.3.7
确定没有后续了,测试结果就是VAR在外界影响特别大的情况下不太适合使用,正确率50%都不到,测试的这段时间美元加息了n次.......其实还有很多的影响啦,包括每个季度月初(如3月前几天都会有一小部分的下降,因为要结算),后面全面通关啦等等......对于其他大佬的论文,只能说在一切稳定的时间段进行一个短期的预测还是可以的,有些东西确实有一些滞后影响,但是只能说这些因素与汇率之间有一定的关联罢了,就像被打了会觉得痛一样,有关系,但是预测什么时候被打做不到。
后期稍微改了一丢丢方向,用了蒙特卡罗做一个风险的警示,多因素这一点被完全丢掉了,如果有需要,这个是链接:EllyNo5/Estimating-VaR-of-CNY-USD-with-Monte-Carlo-Simulation: It's aims to measure the relative risk aspects of the CNY/USD foreign exchange market and test if calculating value at risk with Monte Carlo simulation will still have a better performance in the environment of rapid market movement. (github.com)
纯英文,要看的话辛苦各位了。匆匆忙忙写的东西,如果有不足还请指正。自认为除了汇率之外的东西用VAR可以套用这个思路,不会错的,就是效果不好说喽~