我正在实现一个小的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
>>>

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

考虑到费用,我得出以下公式:
python - 递减范围内的乘积之和-LMLPHP
其中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())

最佳答案

我觉得这个还不错。从aratios

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/

10-10 23:35