如何用Pandas在时间/价值序列中寻找最优买卖点(含最短持有期)
解决思路与Pandas实现方案
核心目标
在给定最短持有期的约束下,找到买入点和卖出点,使得卖出价值 - 买入价值最大化(适配数据中存在的升值、非线性折旧场景)。
步骤1:数据准备
先确保数据集按时间顺序排序,示例如下:
import pandas as pd # 模拟你的折旧数据集(替换为实际数据) data = { "月份": ["2020-01", "2020-02", "2020-03", "2020-04", "2020-05", "2020-06"], "价值": [1000, 950, 980, 920, 1050, 1000] } df = pd.DataFrame(data) # 转换为时间格式并排序 df["月份"] = pd.to_datetime(df["月份"]) df = df.sort_values("月份").reset_index(drop=True)
步骤2:计算最优买卖点
根据数据集规模选择对应方法:
方法1:双重循环(适合小数据集)
直接遍历所有符合最短持有期的买卖组合,筛选收益最大值:
min_hold_period = 2 # 设置最短持有期(单位:月) max_profit = -float("inf") best_buy_idx = None best_sell_idx = None for i in range(len(df)): # 卖出点必须在买入点至少min_hold_period个月之后 for j in range(i + min_hold_period, len(df)): profit = df.loc[j, "价值"] - df.loc[i, "价值"] if profit > max_profit: max_profit = profit best_buy_idx = i best_sell_idx = j # 输出结果 if best_buy_idx is not None: print(f"最优买入点:{df.loc[best_buy_idx, '月份'].strftime('%Y-%m')},价值{df.loc[best_buy_idx, '价值']}") print(f"最优卖出点:{df.loc[best_sell_idx, '月份'].strftime('%Y-%m')},价值{df.loc[best_sell_idx, '价值']}") print(f"最大收益:{max_profit}") else: print("没有符合最短持有期的买卖组合")
方法2:向量化计算(适合大数据集)
用Numpy矩阵操作替代循环,提升效率:
import numpy as np min_hold_period = 2 # 提取价值数组并生成收益矩阵 values = df["价值"].values profit_matrix = values - values[:, None] # 创建掩码:仅保留符合最短持有期的买卖组合 mask = np.triu(np.ones_like(profit_matrix), k=min_hold_period) profit_matrix = np.where(mask == 1, profit_matrix, -float("inf")) # 筛选最大收益对应的点位 max_profit = profit_matrix.max() if max_profit == -float("inf"): print("没有符合最短持有期的买卖组合") else: best_buy_idx, best_sell_idx = np.unravel_index(profit_matrix.argmax(), profit_matrix.shape) print(f"最优买入点:{df.loc[best_buy_idx, '月份'].strftime('%Y-%m')},价值{df.loc[best_buy_idx, '价值']}") print(f"最优卖出点:{df.loc[best_sell_idx, '月份'].strftime('%Y-%m')},价值{df.loc[best_sell_idx, '价值']}") print(f"最大收益:{max_profit}")
步骤3:特殊场景处理
- 若所有符合条件的组合收益均为负,可选择不交易,或筛选损失最小的组合(将收益计算改为
df.loc[i, "价值"] - df.loc[j, "价值"]后找最小值) - 若数据集长度小于
最短持有期 + 1,直接提示无可用组合
内容的提问来源于stack exchange,提问作者Daniel Becker
相关产品推荐
相关产品推荐

