【发布时间】:2016-10-19 08:54:14
【问题描述】:
我正在为包含价格数据的DataFrame 中的每一行计算DataFrame 的损益金额。
逻辑如下:
- 我们在当前时间段买入/卖出资产。
- 我们持有
holding_period的资产。 - 如果在持有期间价格超过
take_profit,则以该价格退出获利。 - 如果在持有期间,价格超过
stop_loss,则以该价格退出亏损。 - 看到的第一个
take_profit或stop_loss级别决定了我们是盈利还是亏损退出。 - 如果既没有达到止盈,也没有达到止损,则在持有期最后一个价位退出。
我实现它的方式是使用pandas.rolling_apply,它将提供的函数应用到DataFrame 中每个系列的滚动窗口。
鉴于rolling_apply为DataFrame中的每一行列组合调用一个函数,这是一个严重的瓶颈。
我想知道是否有更好的方法可以使用其他 pandas/numpy 功能来实现这一点?
这是当前的实现:
def potential_pnl(prices, side, periods, take_profit=np.nan, stop_loss=np.nan):
# set sign depending on direction of price movement required by BUY/SELL
if side == Side.SELL:
take_profit *= -1
else:
stop_loss *= -1
def period_potential_pnl(window):
# enter at the first price, rest of the window are possible exit prices
entry_price = window[0]
exit_prices = window[1:]
take_profit_price = entry_price + take_profit
stop_loss_price = entry_price + stop_loss
# calculate array of bools showing where take_profit/stop_loss is reached
if side == Side.BUY:
filtered = exit_prices[ (exit_prices >= take_profit_price) |
(exit_prices <= stop_loss_price) ]
else:
filtered = exit_prices[ (exit_prices <= take_profit_price) |
(exit_prices >= stop_loss_price) ]
# if neither take_profit/stop_loss is reached, exit at the last price
# otherwise exit at the first price which exceeds take_profit/stop_loss
if len(filtered) == 0:
exit_price = exit_prices[-1]
else:
exit_price = filtered[0]
exit_pnl = exit_price - entry_price
if side == Side.SELL:
exit_pnl *= -1
return exit_pnl
# apply `period_potential_pnl` onto the dataframe
pnl = pd.rolling_apply(prices, periods + 1, period_potential_pnl)
# shift back by periods so the exit pnl is lined up with the entry price
pnl = pnl.shift(-periods)[:-periods]
return pnl
我尝试过的事情:
我最初使用pandas.rolling_max 和pandas.rolling_min 来确定是否到达take_profit 或stop_loss。
我在使用这种方法时遇到的问题有两个:
- 您不能将最高价格用作
take_profit的退出价格,因为take_profit很可能以较低的价格达到;无法实时知道持有期的最长期限。 - 您无法确定首先到达
take_profit或stop_loss中的哪一个。
问题:
有没有更有效的方法来计算每个时期的损益?
【问题讨论】:
标签: python numpy pandas machine-learning