首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >乘积超过递减幅度之和

乘积超过递减幅度之和
EN

Stack Overflow用户
提问于 2018-08-01 19:05:03
回答 1查看 133关注 0票数 3

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

  • 一只熊猫的数据,里面有收盘价
  • 潘达斯系列的布尔人代表购买信号
  • 潘达斯的一系列代表出售信号的布尔人
  • 浮动资金,代表交易费用占初始资本的百分比。

这就是数据的样子:

代码语言:javascript
运行
复制
>>> 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
>>> 

代码语言:javascript
运行
复制
>>> 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是一笔买卖交易的回报。

这可以很容易地使用向量化的实现来实现:

代码语言:javascript
运行
复制
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的回答,解决方案是执行一个“累积产品”对反向系列的比率。这给了我以下解决方案:

代码语言:javascript
运行
复制
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())
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-01 19:51:24

这个没那么糟,我不认为。从像ratios这样的

代码语言:javascript
运行
复制
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

我们(在这里我们只专注于“新”第二任期):

代码语言:javascript
运行
复制
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)))

代码语言:javascript
运行
复制
def vectorized(rs):
    rev = 1 + rs.iloc[2:].iloc[::-1]
    return rev.cumprod().sum()

也就是说,我们所要做的就是从头到尾,把累积积的总和反方向取下来。

这给了我:

代码语言:javascript
运行
复制
In [109]: manual(ratios)
Out[109]: 3.07017466956023

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

(我不太担心我们应该使用2还是1作为补偿,还是加入f因子--这些都是很容易改变的。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51640628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档