百天计划之第26天,关于“qlib智能量化,财富自由与个人成长”。
8月重点是基于qlib智能量化框架,搭建量化投资平台。
昨天我们已经把数据准备及指标准备好了,今天可以正式进入回测。
但今天我们用qlib来做传统基于“规则”的回测,而不是一上来就搞机器学习模型预测,这是9月份的工作。
01 qlib的回测
qlib的回测是基于pred_score的,就是说每天给所有的股票打分,持有分数高的。
qlib所有策略的基类:qlib.strategy.base.BaseStrategy
基类里有三个实现,显然qlib有考虑对“强化学习”环境的支持:
策略的核心是实现如下这个函数:genreate_trade_decision。
@abstractmethod def generate_trade_decision( self, execute_result: list = None, ) -> Union[BaseTradeDecision, Generator[Any, Any, BaseTradeDecision]]: """Generate trade decision in each trading bar
这里可以类比传统像backtrader里的strategy里的on_bar函数。
无论是向量化计算,还是事件驱动,on_bar里实现策略,就是计算当天的指标,然后确实是买入还是卖出,只是传统量化框架会直接调用执行器exccutor去下订单,qlib仅是生成订单列表,后续统一执行。
qlib做了分离,只计算信号,后面统一来执行。
这里看似循环了两轮,但符合机器学习批量计算的逻辑,量化与智能量化就统一成了一个范式,而且代码更加解耦。策略只管生成交易信号,与执行器没有任何关系,外部要如何使用这些信号,与策略无关。
02 强化学习的策略基类
class RLStrategy(BaseStrategy, metaclass=ABCMeta): """RL-based strategy""" def __init__( self, policy, outer_trade_decision: BaseTradeDecision = None, level_infra: LevelInfrastructure = None, common_infra: CommonInfrastructure = None, **kwargs, ) -> None:
强化学习的策略基数,在原有BaseStrategy的基础上, 多了一个参数policy。
class RLIntStrategy(RLStrategy, metaclass=ABCMeta): """(RL)-based (Strategy) with (Int)erpreter""" def __init__( self, policy, state_interpreter: dict | StateInterpreter, action_interpreter: dict | ActionInterpreter,
RLIntStrategy在RLStrategy的基础,又多了两个参数:一个状态解决器,另一个是行为解释器——这里只需要先有个印象,我们讲强化学习的时候会详细说明。
有了这两个解释器:
def generate_trade_decision(self, execute_result: list = None) -> BaseTradeDecision: _interpret_state = self.state_interpreter.interpret(execute_result=execute_result) _action = self.policy.step(_interpret_state) _trade_decision = self.action_interpreter.interpret(action=_action) return _trade_decision
强化学习根据当前的状态,就可以生成交易决策。
所以,强化学习仅需要配置好这两种解释器即可。
这个解释器也是基类,在原代码的如下位置:
真正的代码实现都在contrib/strategy下:
这里文档有点旧了,所以说能看代码尽量看代码。
“规则策略”:
这里实现了一些基类,但没有可用的策略。
规则策略一般可以这么抽象:
1、买入信号,比如20日动量>0.02。
2、卖出信号,比如20日动量<0。
3、排序信号,20日动量从大到小。
使用的策略类似topK,它是子集(买入信号+已持仓-买入信号)进行排序。
可以在pred_score里把其余的股票过滤掉即可(已持仓这个需要执行器判断)。
比如2020-01-01,买入信号大于2%的只有2支,那么,pred_score在这一天只有这两支有信号即可。
“信号策略”,目前有TopK, EnhancedIndexingStrategy
信号策略基类,扩展了几个参数:signal(pred_score), model, dataset。
class BaseSignalStrategy(BaseStrategy): def __init__( self, *, signal: Union[Signal, Tuple[BaseModel, Dataset], List, Dict, Text, pd.Series, pd.DataFrame] = None, model=None, dataset=None, risk_degree: float = 0.95,
这里示例里用得最多的是topK策略,基于权重的是基于signal给标的直接按仓位比重调仓,而当前代码里实现的是“指数增强”策略。
我们重点关注一下topK。
小结:
qlib的回测代码是比较结构化的,但不太适合传统规则量化,可以考虑自己实现——简单改造一下topK即可。
最近文章: