滚动OLS回归和ValueError:值的长度与索引的长度不匹配

时间:2019-05-07 12:23:01

标签: python pandas dataframe regression

假设我的股票价格为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个前向收益在经过粗略的观察后非常合适。情节看起来像这样:

enter image description here

鉴于这些是我看过的高风险股票,它们在过去几个月中被谋杀,即使能够返还0%的股票实际上也是赢家,所以我的结论是,这值得一看在进行交易时。

无论如何希望有一天能对某人有所帮助。

0 个答案:

没有答案