Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 递减范围上的乘积之和_Python_Pandas_Math_Vectorization - Fatal编程技术网

Python 递减范围上的乘积之和

Python 递减范围上的乘积之和,python,pandas,math,vectorization,Python,Pandas,Math,Vectorization,我正在实现一个小型Python应用程序来衡量交易策略的回报。计算回报的函数接受以下输入: 包含收盘价的熊猫数据框 代表买入信号的一系列布尔值 熊猫的一系列布尔字母代表卖出信号 代表交易费用占初始资本百分比的浮动 这就是数据的样子: >>> df.head() open high low close volume date 2015-01-02 5.34 5.3

我正在实现一个小型Python应用程序来衡量交易策略的回报。计算回报的函数接受以下输入:

  • 包含收盘价的熊猫数据框
  • 代表买入信号的一系列布尔值
  • 熊猫的一系列布尔字母代表卖出信号
  • 代表交易费用占初始资本百分比的浮动
这就是数据的样子:

>>> df.head()
            open  high   low  close  volume
date                                       
2015-01-02  5.34  5.37  5.11   5.21  108469
2015-01-05  5.21  5.26  4.85   4.87  160089
2015-01-06  4.87  4.87  4.55   4.57  316501
2015-01-07  4.63  4.75  4.60   4.67  151117
2015-01-08  4.69  4.89  4.69   4.81  159294
>>> 


在不考虑费用的情况下,这是计算比率的公式:

其中,
C
是初始资本,
ri
是一次买入/卖出交易的回报

这可以使用矢量化实现轻松实现:

buy_sell = df[(buy==True)|(sell==True)]
prices = buy_sell.close
diffs = prices - prices.shift()
ratios = diffs / prices.shift()
return ((ratios + 1).product(axis=0))

当考虑到费用时,我得出以下公式:

其中
f
是交易费

这可以很容易地使用循环来实现,但是有没有一种方法可以通过矢量化实现来实现呢

我不是一个数学专家,但也许依赖于求和指数的乘积可以防止这种情况发生?我试着在网上查找这处房产,但似乎什么也找不到。也许我没有正确地表述这个问题,因为我缺乏专业术语

如果您对此有任何想法,我们将不胜感激:)


编辑 根据DSM的回答,解决方案是对反转的比率序列执行“累积乘积”。这为我提供了以下解决方案:

def compute_return(df, buy, sell, fees=0.):

    # Bunch of verifications operation performed on data

    buy_sell = df[(buy==True)|(sell==True)]
    prices = buy_sell.close
    diffs = prices - prices.shift()
    ratios = diffs / prices.shift()

    cum_prod = (ratios + 1)[1:][::-1].cumprod()

    return ((1 - fees) * (ratios + 1).product(axis=0) - fees * cum_prod.sum())

我不认为这件很糟糕。从一个
比率
类似

In [95]: ratios
Out[95]: 
date
2015-01-02         NaN
2015-01-05   -0.065259
2015-01-06   -0.061602
2015-01-07    0.021882
2015-01-08    0.029979
Name: close, dtype: float64
我们有(这里我们只关注“新”的第二任期):

也就是说,我们所需要做的就是,从一开始到另一开始,按相反的方向取累积积的和

这给了我:

In [109]: manual(ratios)
Out[109]: 3.07017466956023

In [110]: vectorized(ratios)
Out[110]: 3.07017466956023

(我没有太在意我们是否应该使用2或1作为偏移量,或者加入
f
因子——这些都是很容易的变化。)

你能为这个问题添加一些数据和预期结果吗?这是勾号数据吗?时间成分是什么?如果您将前几行发布为text@sundance为什么时间成分很重要?无论是计算每周回报还是每日回报,都需要添加数据结构的屏幕截图。数据每天都被索引,但就像@RafaelC提到的,时间成分甚至数据本身都不是很重要,更多的是关于向量化这样一个公式的可行性。在这里使用for循环更好。嗯,我明白了。。。我不知道
cumprod()
方法,但它似乎很好地解决了我的问题!作为一个Pandas方法,我想它的实现是矢量化的?
def manual(rs):
    return sum(np.prod([1+rs.iloc[j] for j in range(i, len(rs))]) 
               for i in range(2, len(rs)))
def vectorized(rs):
    rev = 1 + rs.iloc[2:].iloc[::-1]
    return rev.cumprod().sum()
In [109]: manual(ratios)
Out[109]: 3.07017466956023

In [110]: vectorized(ratios)
Out[110]: 3.07017466956023