假设我的股票价格为df
,看起来像这样:
Date Stock A
2019-05-06 07:59:59.999 0.028213
2019-05-06 08:59:59.999 0.028389
2019-05-06 09:59:59.999 0.028242
2019-05-06 10:59:59.999 0.028744
2019-05-06 11:59:59.999 0.028826
2019-05-06 12:59:59.999 0.028949
2019-05-06 13:59:59.999 0.028886
2019-05-06 14:59:59.999 0.028863
2019-05-06 15:59:59.999 0.029398
Name: Stock A, Length: 1000, dtype: float64
我要为每只股票执行的操作是使用pyfinance
中的ols.PandasRollingOLS(y, X, window=n)
计算一个预测值,然后计算当前价格与该预测值有多少标准差,然后绘制该图相对于某些远期收益,即未来n天中的库存上涨或下跌多少,基本上是.shift(-n)
。听起来很简单,但我知道如何让自己越来越陷于困境。
运行滚动回归的代码如下,并且工作正常,所以这不是问题:
X = df['Time']
y = df['Stock A']
model = ols.PandasRollingOLS(y, X, window=250)
prediction = model._predicted
Prediction
然后返回751个数组,每个数组中的最终数字是我要使用的数字。因此,对于我来说,要返回每个数据点的预测值列表,我必须做[i[-1] for i in prediction]
,然后再给我[...0.02862762374502103, 0.028612066422311653, 0.028596879968127514, 0.028582598374502034, 0.02856930540239047, 0.028553991394421267, 0.02854553854980154, 0.028536955824703027, 0.028531125290838216, 0.028522397768924877, 0.02851387212749102, 0.028514959521912523]
。
我首先要做的是能够创建一个新列,例如df['Diff']
,该列计算当前价格与预测价格之间的差,然后除以滚动的100标准差。
我的代码将类似于df['Diff'] = (df['Stock A'] - [i[-1] for i in prediction]) / df['Stock A'].rolling(100).std()
但是,这会产生TypeError: unsupported operand type(s) for /: 'generator' and 'float'
作为错误,并且当我尝试在没有标准偏差位的情况下相互减去一个ValueError: operands could not be broadcast together with shapes (1000,) (751,)
。
由于价格数据的长度为1000个数据点,并且只有751个预测,因此我理解为什么会出错。
最后,我想要的是2列,一列用于计算当前价格与预测价格之间的差,除以滚动标准差,而第二列则用于计算远期回报百分比,即df['returns'] = df['Stock A'].diff(-100)/df['Stock A']
:>
Date Diff Returns
2019-05-02 07:59:59.999 0.68213 -0.91
2019-05-02 08:59:59.999 0.68389 -0.91
2019-05-02 09:59:59.999 0.68452 -0.92
2019-05-02 10:59:59.999 0.69642 -0.92
2019-05-02 11:59:59.999 0.71459 -0.94
2019-05-02 12:59:59.999 0.73697 -0.96
2019-05-02 13:59:59.999 0.75624 -0.97
2019-05-02 14:59:59.999 0.78542 -0.98
2019-05-02 15:59:59.999 1.20543 -1.25
一旦我可以正确使用一只股票,我将循环遍历其余股票。真的很感谢任何帮助,欢呼。
编辑:
所以我要做的是,由于两组数据的长度未命中,因此我写了一篇文章,将price列缩小了。我现在所拥有的是这样:
X = data['Time']
y = data['Stock A']
model = ols.PandasRollingOLS(y, X, window=250)
prediction = model._predicted
data['returns'] = (data['Stock A'].shift(-150)-data['Stock A'])/data['Stock A']
data['Stock A'] = data['Stock A'].iloc[-751:]
data['Stock A'].dropna(inplace=True)
data['diff'] = (data['Stock A'] - [i[-1] for i in prediction])/data['Stock A'].rolling(250).std()
这基本上可以满足我的要求,但是我现在遇到的问题是,数据不是从数据点250开始的,而是从497开始的,所以它立即切掉了我的数据点的一半。
如果任何人都可以快速看到我在做什么,那太好了,如果不担心的话,看来我将不得不放弃这一点。干杯
EDIT 2.0:
对不起,删除NA是造成此问题的原因,所以我现在在计算中指定df
的长度,所以我的最终代码是这个,再次感谢您的帮助:
X = data['Time']
y = data['Stock A']
model = ols.PandasRollingOLS(y, X, window=250)
prediction = model._predicted
data['returns'] = (data['Stock A'].shift(-150)-data['Stock A'])/data['Stock A']
data['diff'] = (data['Stock A'].iloc[-751:] - [i[-1] for i in prediction])/data['Stock A'].rolling(250).std()
回应布拉德的评论:
因此,首先,我实际上是从csv文件中获取我的股票数据(144只股票),因此您必须从某个位置获取数据,但是一旦有了,这就是我正在做的事情。
我想绘制/绘制每只股票的实际值和预测值之间的标准差,以相同的方式计算z得分,然后将其与远期收益相对应,因此在将来假设有100个数据点,百分比是多少区别。我想看看价格是否离它的预测相差无几,随着时间的推移,它是否真的产生了赢家。
因此,我计算了标准差和远期收益,可以说是在300点窗口中进行回归,在400点窗口中进行收益,然后对于每只股票,我将这些数据附加到df
中,按差异对它进行排序,然后将除最极端的数据点以外的所有数据点都放在一边,因为只有在某些东西超出正常范围时,我才会进行交易。
df = []
data['Time'] = range(0, 0+ len(data))
for stock in stocks:
X = data['Time']
y = data[stock]
model = ols.PandasRollingOLS(y, X, window=300)
prediction = model._predicted
data['returns'] = (data[stock].shift(-400) - data[stock]) / data[stock]
lngth = (1000-300)+1 # the length the data needs to be to match the prediction array, otherwise you encounter an annoying error
data['diff'] = (data[stock].iloc[-lngth:] - [i[-1] for i in prediction]) / data[stock].rolling(300).std()
df.append(data[['diff', 'returns']])
df = pd.concat(df, axis=0)
df.dropna(inplace=True)
df.reset_index(inplace=True)
df = df.drop(['Date'], axis=1)
df.sort_values('diff', inplace=True)
size = len(df) * 0.001
size = size.__round__()
df = df.drop(df.index[size:-size])
if len(df) > 0:
X = df['diff'].values.reshape(-1,1)
y = df['returns'].values.reshape(-1,1)
model = LinearRegression()
model.fit(X,y)
return model.score(X,y)
您可以使用这些参数,但我一直在寻找的组合非常合适,并且300个回归窗口,400个前向收益在经过粗略的观察后非常合适。情节看起来像这样:
鉴于这些是我看过的高风险股票,它们在过去几个月中被谋杀,即使能够返还0%的股票实际上也是赢家,所以我的结论是,这值得一看在进行交易时。
无论如何希望有一天能对某人有所帮助。