在波谲云诡的股票市场中,投资者常面临何时买入、何时卖出以实现收益最大化的核心难题,这类“股票问题”因其决策的时序性和状态依赖性,成为动态规划(Dynamic Programming, DP)的经典应用场景,动态规划通过将复杂问题分解为相互重叠的子问题,并存储子问题的解以避免重复计算,为股票交易中的多阶段决策提供了系统化的优化工具。
股票问题的动态规划建模
股票问题的核心在于寻找一个最优的交易策略,使得在给定的交易规则下(如最多完成k笔交易、 cooldown 间隔等)实现收益最大化,动态规划建模通常包含以下关键要素:
-
状态定义 (State Definition)
这是动态规划的核心,我们需要定义能够描述当前决策环境的关键变量,对于股票问题,常见状态包括:dp[i][j][0]:表示在第i天,已经进行了j笔交易,并且当前不持有股票时的最大收益。dp[i][j][1]:表示在第i天,已经进行了j笔交易,并且当前持有股票时的最大收益。i代表时间(天数),j代表交易次数(买入算一次交易),0或1代表是否持有股票。
-
状态转移方程 (State Transition)
这是动态规划的“灵魂”,它描述了如何从子问题的解推导出当前问题的解。- 不持有股票 (
dp[i][j][0]):
这可能是因为前一天就不持有,今天也没操作;或者昨天持有,今天卖出了(完成一笔交易)。
dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1] + prices[i])
(卖出时,交易次数j增加1,收益增加prices[i]) - 持有股票 (
dp[i][j][1]):
这可能是因为前一天就持有,今天也没操作;或者昨天不持有,今天买入了(消耗一次交易机会)。
dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j][0] - prices[i])
(买入时,交易次数j不变,收益减少prices[i],因为花费了现金)
- 不持有股票 (
-
初始条件 (Initialization)
这是求解的起点。dp[0][j][0] = 0:第0天(未开始交易),不持有股票,收益为0。dp[0][j][1] = -infinity(或一个非常小的负数):第0天不可能持有股票(除非允许透支,但通常不允许)。dp[i][0][0] = 0:在任何一天,如果一笔交易都没做(j=0),不持有股票,收益为0。dp[i][0][1] = -infinity:一笔交易都没做,不可能持有股票。
-
目标状态 (Target State)
我们要求的是在最后一天 (n-1),完成最多k笔交易(或不超过k笔),且不持有股票时的最大收益:
max(dp[n-1][j][0])forjfrom0tok
经典股票问题的动态规划解法
动态规划的魅力在于其灵活性,能够轻松应对各种交易约束:
-
无限次交易(Best Time to Buy and Sell Stock II)
- 特点:可以无限次买卖,求最大利润。
- DP解法:此时交易次数
j不再是关键约束,可以简化状态为dp[i][0]和dp[i][1]。dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
- 优化:可进一步空间优化为两个变量,核心思想是只要相邻两天价格上涨就累加利润(等价于多次低买高卖)。
-
最多一次交易(Best Time to Buy and Sell Stock)
- 特点:只能完成一笔买卖(一次买入一次卖出),求最大利润。
- DP解法:
j的取值只能是0或1。dp[i][1][0] = max(dp[i-1][1][0], dp[i-1][1][1] + prices[i])(卖出)dp[i][1][1] = max(dp[i-1][1][1], dp[i-1][0][0] - prices[i])(买入,从j=0转移到j=1)dp[i][0][0] = 0,dp[i][0][1] = -inf
- 优化:可简化为记录最低买入成本和最大利润,动态规划框架清晰展示了状态如何随时间演化。
-
最多k次交易(Best Time to Buy and Sell Stock IV)
- 特点:限制最多完成
k笔交易(每笔交易包含一次买入和一次卖出),求最大利润,这是最通用的模型。 - DP解法:完全使用上述三状态模型
dp[i][j][0/1]。- 遍历天数
i从0到n-1。 - 遍历交易次数
j从1到k。 - 按状态转移方程更新。
- 遍历天数
- 注意:当
k非常大(如k >= n/2)时,问题退化为无限次交易,需特殊处理以避免不必要的计算。
- 特点:限制最多完成
-
含冷冻期/手续费(Best Time to Buy and Sell Stock with Cooldown / Transaction Fee)
- 特点:卖出后第二天不能买入(冷冻期),或每次交易需支付手续费。
- DP解法(冷冻期):在状态转移中增加约束。
- 不持有股票可能是冷冻期结束后的状态,需引入新状态或调整转移方程。
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])(正常卖出)
dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i])(买入需在冷冻期结束后,即i-2天不持有)
- 不持有股票可能是冷冻期结束后的状态,需引入新状态或调整转移方程。
- DP解法(手续费):在卖出时减去手续费
fee。
dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j-1][1] + prices[i] - fee)
动态规划在股票问题中的优势与局限
-
优势:
- 系统性:提供清晰的框架,将复杂的决策过程分解为可管理的状态和转移。
- 最优性保证:在满足问题约束条件下,能找到全局最优解(或最优值)。
- 灵活性:通过调整状态定义和转移方程,能适应各种复杂的交易规则(如交易次数限制、冷冻期、手续费、T+1等)。
- 避免贪婪陷阱:贪婪算法在股票问题中常常失效(如局部最优不等于全局最优),动态规划通过考虑所有可能路径确保最优。
-
局限:
- 维度诅咒:当交易次数上限
k很大,或者考虑更多状态维度(如持仓数量、不同股票)时,状态空间急剧膨胀,计算量和内存消耗巨大。 - 预测依赖:模型依赖于未来的价格序列(
prices[i]),实际应用中,未来价格未知,动态规划主要用于事后分析或已知未来价格序列的优化问题(如算法竞赛题),在实际交易中,需结合预测模型或滚动优化策略。 - 模型简化:实际市场比模型复杂得多(如交易滑点、市场冲击、情绪影响等),动态规划模型需要大量简化。
- 维度诅咒:当交易次数上限
动态规划为解决股票交易中的多阶段最优决策问题提供了强大而优雅的数学工具,通过精确定义状态、构建状态转移方程并设置合理的初始条件,我们能够系统化地求解在多种交易约束下的最大收益问题,从简单的无限次交易到复杂的带冷冻期和交易次数限制的场景,动态规划框架展现出其普适性和适应性。
必须清醒认识到,经典动态规划模型
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权,未经许可,不得转载。
