Python:按天和当前时间戳计算最大利润

标签 python pandas dataframe

我有一个像这样的数据框:

                      close
formated                                                               
2017-01-03 09:30:00   29.9713
2017-01-03 09:31:00   29.0622
2017-01-03 09:32:00   29.0750
2017-01-03 09:33:00   29.0276
2017-01-03 09:34:00   29.0375
...                       ...
2022-08-19 09:30:00  173.5500  
2022-08-19 09:31:00  173.4494
2022-08-19 09:32:00  173.3400
2022-08-19 09:33:00  173.3900
2022-08-19 09:34:00  173.2600

df 包含从 9:30 到 16:00 的每一分钟的价格值。 我希望每天的每一分钟都能获得最大可能的利润。

我目前正在做这样的事情:

df['Profit'] = (df.groupby(pd.Grouper(freq='D'))['close'].transform('max') - df['close']).div(df['close'])

这给出了每行的利润占当天最高值的百分比。
然而,这种方法是有缺陷的,因为它还会根据达到当天最高值之后的时间戳来计算利润百分比。
但我不想要一整天的最大值,而是每天的最大值,仅包含我们当前正在查看的数据帧中的行之后的时间戳。

利润定义为该分钟的值与同一天随后所有分钟内的最大值之间的差值。

所需输出:

                      close     Profit abs.  Profit perc.
formated                                                               
2017-01-03 09:30:00   29.9713   0.0          0.0
2017-01-03 09:31:00   29.0622   0.0128       0.0004404
2017-01-03 09:32:00   29.0750   0.0          0.0
2017-01-03 09:33:00   29.0276   0.0099       0.0003410
2017-01-03 09:34:00   29.0375   0.0          0.0   
...                       ...      ...             ...

请不要使用在 for 循环中迭代数据帧的解决方案,因为这非常慢。

最佳答案

您可以使用 pandas 的 cummax 函数来计算每天的累积最大值。但是,您需要反向应用它。

如果我们每小时这样做一次,为了解释:

>>> example_df
date              price
2020-01-01 00:00  1
2020-01-01 01:00  2
2020-01-01 03:00  1
2020-01-01 04:00  7
2020-01-01 05:00  5
2020-01-01 06:00  2
2020-01-01 07:00  4

>>> example_df.reverse_cummax()
date              price  reverse_cummax
2020-01-01 00:00  1      7
2020-01-01 01:00  2      7
2020-01-01 03:00  1      7
2020-01-01 04:00  7      7
2020-01-01 05:00  5      5
2020-01-01 06:00  2      4
2020-01-01 07:00  4      4

这就是reverse_cummax函数的输出。

我们不能直接使用pandas中的cummax,而且除了反转整个数据帧之外,没有简单的方法可以反转它。我们需要创建一个子函数来反转我们直接感兴趣的“分组依据”数据帧上的列的值,然后在完成后再次反转它们:

def reverse_cummax(df_day):
    return df_day.loc[::-1, "close"].cummax()[::-1]

# This function produces a MultiLevelIndex, but we want our initial index
# back, so we need to drop a level
df["reverse_cummax"] = df.groupby(pd.Grouper(freq='D')).apply(reverse_cummax).droplevel(0)

然后,您可以通过将每个值减去即将到来的每日最大值(reverse_cummax)来获得利润

df["profit abs"] = df["reverse_cummax"] - df["close"]
df["profit percentage"] = df["profit abs"]/df["close"]

已编辑以添加 dermen 建议的改进解决方案

关于Python:按天和当前时间戳计算最大利润,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73979825/

相关文章:

python - 返回无值的数据框

python - 旋转 pandas 数据框后无法读取列

python - 将一个数据帧除以另一个数据帧的问题

arrays - 将 Julia 数据框列从字符串转换为 float

python - 使用Tkinter时,错误: TclError: image "pyimage8" doesn't exist

python - 抓取需要 JavaScript 交互的页面

python - 找到即将到期日期并根据它分配值 - Python 数据框

r - dplyr - 在嵌套列表中按元素汇总

python - 为什么 eval() 找不到该函数?

python - Tkinter 将带参数的函数绑定(bind)到小部件