Closed linchunquan closed 5 months ago
首先,step()
时,所处的环境是根据历史股票数据构建出来的股票交易环境
可以先了解一下 env 相关的东西,获取的 next_state 是环境给出的。这里是第二天股票的 state,是客观的事实,不是预测出来的,这里有什么问题吗?
问题很严重也很明显:今天只能看到昨天股票的高、开、低、收价格及成交量。你当前的代码逻辑,在T日的step结束时,把T+1的股价作为下一步的状态了,这相当于在T+1日的step里,agent已经提前感知了T+1日的股价,这就是未来函数产生的原因。
我认为T日获得T+1股价其实对算法(train)来说是没有用的,因为每天只操作一次并且T+1日的操作其实T日就已经给出了,T+1日其实是给T+2日的action。 我的问题是在T+1日时,trade的算法是怎么操作的,action的产生是否与当日(T+1)的状态相关,train和trade的机制是一样的吗? 我记得action应该是随机概率的生成,然后给定方向,根据reward调整。
现实当中T日怎能获得T+1股价的股价呢?这就叫做未来函数,是错误。train和trade的业务模型需要保持一致,如果train期间应用了带未来函数的方法训练,实盘trade是不可能成功的。
首先,
step()
时,所处的环境是根据历史股票数据构建出来的股票交易环境 可以先了解一下 env 相关的东西,获取的 next_state 是环境给出的。这里是第二天股票的 state,是客观的事实,不是预测出来的,这里有什么问题吗?
你在step里更新date的时机不对。我们理一理你的代码逻辑:在dayT-1,step结束后通过getenv返回了环境e,然后Agent根据e确定action1并提交给env,env处理action1,执行交易股票等操作,之后进入dayT,通过getenv返回新的环境e+1。
但在这个过程中,env处理action时使用的close收盘价格等一系列指标已经在dayT-1交给Agent了。等于是Agent在已知dayT的所有情况下做出了action1并立即处理了。所以收敛速度十分快速。当把day+1的指令放到处理action之前就能发现模型不再收敛。希望作者复现一下。
这里附上原始代码: ` begin_cash = self.cash_on_hand assert min(self.holdings) >= 0
#### 使用dayT的数据开始处理action #####
assert_value = np.dot(self.holdings, self.closings)
self.account_information["cash"].append(begin_cash)
self.account_information["asset_value"].append(assert_value)
self.account_information["total_assets"].append(begin_cash + assert_value)
reward = self.get_reward()
self.account_information["reward"].append(reward)
transactions = self.get_transactions(actions)
######一些省略的action处理代码############
#### action处理结束, 进入day T+1 #####
self.date_index += 1 ###<---至少这一句应该放到处理action之前执行,因为不可能在已知dayT的全部状态的情况下操作dayT
state = (
[coh] + list(holdings_updated) + self.get_date_vector(self.date_index)
)
self.state_memory.append(state)
#### 返回 day T+1的状态 #####
return state, reward, False, {}`
顺便再附上我修改前后的模型收敛情况, 这是不做任何修改的收敛情况: 可以看到20多轮就能在训练集上收敛出不错的结果
而这是将day+1提前到处理action之前的结果 在30多轮后在训练集上依旧看不到明显的收敛
我又用第三方平台跑了一下训练出来的模型, 这个模型大概在5800x+3080的平台上训练了两个小时. 总之是效果一言难尽. 没有使用任何未来数据的情况下训练和执行的. 训练集是11年到21年, 测试集是过去一年到现在. 具体看图吧, 虽然强化学习每次执行结果不一样, 但是都会收敛到-30~-40%的样子, 这已经是我跑10次里最好的一次了
下面的是跑20年7月到21年7月的结果, 模型在训练集上表现出了在你的测试集上的效果, 我认为可以初步排除我自己的回测代码写错的问题
好的,数据集和我用的一样,我也跑一下,试试。
但在这个过程中,env处理action时使用的close收盘价格等一系列指标已经在dayT-1交给Agent了。等于是Agent在已知dayT的所有情况下做出了action1并立即处理了
强化学习的相关机制和原理,暂时先关闭这个 Issue
FinRL的各种例子都有未来函数的问题,你的代码里也把这部分错误逻辑copy过来了。详见
注意啊,date_index应该是要在state更新之后才能递增,因为在T日,只能看到T-1日的股价。去除未来函数之后,再看看你的算法是否还·有效果吧 :)