python - 递减范围内的乘积之和

标签 python pandas math vectorization

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

  • 包含收盘价的 Pandas 数据框
  • 代表买入信号的 Pandas 系列 bool 值
  • 代表卖出信号的 Pandas 系列 bool 值
  • 代表交易费用占初始资本百分比的 float

这是数据的样子:

>>> 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
>>> 

>>> buy.head()
2015-01-02     True
2015-01-05    False
2015-01-06    False
2015-01-07    False
2015-01-08    False
dtype: bool
>>>

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

其中 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))

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

enter image description here

其中 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

我们有(这里我们只关注“新的”第二个任期):

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

(我没有太在意担心我们应该使用 2 还是 1 作为此处的偏移量,或者放入 f 因子——这些都是简单的更改。)

关于python - 递减范围内的乘积之和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51640628/

相关文章:

python - celery ,postgresql -> 配置后端

python - 如何自定义 Django Rest Framework 序列化器输出?

python - 更有效地使用 itertools.groupby()

python - Geoviews:与英国等值区域图重叠的 map 图 block 无法完全对齐

c# - 根据点对划分一个矩形

javascript - 掌握了 90% 的 JavaScript 代码 - 无法理解其余部分

python - zlib.错误 : Error -5 while decompressing data: incomplete or truncated stream in Python

Pandas 按日期时间分组

python - Pandas agg 根据数据类型定义指标

.net - 在冒重复的风险之前,您可以随机生成多少次 GUID? (。网)