Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Fq模拟盘选股系统和回测

在上一次的文章中,我谈到了要用Dagster来构建智能选股系统,这篇文章就是上一篇文章的延续,来说说如何用Dagster来构建模拟盘和回测系统。

上一篇文章中的示例代码只能称为是伪代码,是不能运行的,只是用来表达我的想法,所以这一篇文章,我会把上一篇文章中的伪代码变成可运行的代码。

在这之前,先重复说明我的观点。在Fq中所说的选股,并不是说选出来的股票让你直接梭哈的,Fq所说的选股只是用来发现市场的交易机会。

我们通过某一种策略来选出某一类股票,某一类股票聚合一起形成一个股票池,同时我们这个选股策略也会做为一个模拟盘来观测,我们需要关注每一个这样的选股策略在近期是否有赚钱效应,有赚钱效应的地方,就是我们要参与交易的地方。

可能和大家所说的策略和回测有所不同,所以有必要再来解释一下,以免误导读者。

可能有很多参与者,想通过回测来证明策略是不是有效。但是我的观点并不是这样的,我认为一个策略是不是有效,是和时间周期相关的,也就是说,不同的时间周期,同一个策略,它的表现是不一样的。

比如,一个策略在2015年表现很好,但是2016年表现很差,那么这个策略在2016年就不应该被采用,但是到了2017年这个策略又有效了。在从回测的角度来观察它,那么你觉得他是好策略和坏策略呢。市场上绝大多数策略都可能表现为这种情况。

所以在Fq中的目标是我们要衡量策略在本周本月他是否有赚钱效应,如果你有100个策略被观测,在近期有赚钱效应的策略,他们所形成的股票池,才是我们近期要参与交易的标的。

上面是一个总的指导思想,接下来我们就是要把他变成落地的系统。

今天用一个例子来阐述系统的设计

第一个,我们用五连阳的动量策略,先做一个MVP(最小可用产品),先让整个流程运行起来,以后只要按这个流程来开发更多的策略就可以了。

如图,five_yang_strategy是dagster的一个asset,我们把每个策略设计成一个asset。five_yang_stock_pool也是dagster的一个asset,他依赖five_yang_strategy,当five_yang_strategy产生数据的时候,five_yang_stock_pool会接收到数据,并生成关于这个策略的股票池。

five_yang_strategy的输入是全市场的股票,输出是五连阳的股票池。当然在以后开发的策略,他的输入也可以是其他策略生成的股票池,这样我们就实现了上一篇文章(https://mp.weixin.qq.com/s/5iHm-Cg8Va9JrDCLmHpCwQ)所说的,股票标的在策略之间的传递,构成一个流动的股票池链条。

所有作为模拟盘的策略assets被放在这个目录中:

freshquant/dagster/assets/sim/

比如:

freshquant/dagster/assets/sim/five_yang_strategy.py
@dg.asset(
    description="五连阳动量策略",
)
def five_yang_strategy():
    # 具体逻辑省略
    pass
@dg.asset(
    description="五连阳动量策略股票池",
    deps=["five_yang_strategy"],
)
def five_yang_stock_pool(five_yang_strategy):
    # 具体逻辑省略
    pass

然后我们用dagster的sensor来触发他们每天的自动更新。他们的定义在这里:

freshquant/dagster/sensors/five_yang_sensor.py
@asset_sensor(
    asset_key=AssetKey("five_yang_strategy"),
    job=five_yang_stock_pool_job,
    name="five_yang_strategy_sensor",
    description="监控five_yang_strategy资产的更新,并触发five_yang_stock_pool的执行,生成五连阳的股票池",
)
def five_yang_strategy_sensor(context, event):
    """
    监控five_yang_strategy资产的更新,并触发five_yang_stock_pool的执行

    当five_yang_strategy资产更新时,立即触发five_yang_stock_pool的执行,
    确保股票池数据始终与策略结果保持同步。
    """
    # 当five_yang_strategy资产更新时,触发five_yang_stock_pool的执行
    return RunRequest(run_key=None)

以上我们就完成了一个策略模拟盘的开发,他会在每天盘后数据下载完成后,自动执行。

每个策略的运行就是模拟盘,我们可以在dagster的面板中参考他们的执行日志。

现在只是MVP,信息暂时比较简单,以后需要把输出信息做的更丰富一些。

另外我们在模拟策略的设计上,把公共的部分抽取做成一个基类BaseStrategy。

freshquant/sim/base_strategy/main.py
class BaseStrategy(ABC):
    """
    交易策略基类

    提供通用的账户管理、订单执行、技术指标计算等功能,
    可作为各种具体策略的父类,实现代码复用。
    """
    pass
freshquant/sim/five_yang_strategy/main.py

那么具体的实现类,只要实现should_buy和should_sell方法即可,就可以完成一个策略的开发。

class FiveYangStrategy(BaseStrategy):
    def __init__(self, init_cash=1000000, lot_size=3000, nodatabase=True):
        pass

    def should_buy(self, hist_data, current_idx):
        # 返回True表示买入,False表示不买
        return True

    def should_sell(self, pos: QA_Position, hist_data: pd.DataFrame, current_idx):
        # 返回True表示卖出,False表示不卖
        return True

回测系统

虽然我觉得回测不能作为策略是否有效的判断标准,但是回测还是很有必要的,因为回测可以让我们看到策略在历史上的表现。

我们的回测不需要一定依赖某个框架,当前我选择了使用backtrader来做回测。

前面的模拟盘我们是基于QA的QIFIAccount来做的,以后我们可以以QIFIAccount为基础来评估模拟盘的表现。

但是这样的策略不能直接在backtrader中使用,为了让backtrader中也能回测基于QIFIAccount的策略,我们采用了一个适配器模式,也就是开发一个通用的适配器,此适配器可以适配我们的模拟盘策略,让他能在backtrader中使用。

freshquant/backtest/backtrader/base/backtrader_adapter.py
class BacktraderStrategyAdapter(bt.Strategy):
    """
    BaseStrategy到Backtrader的通用适配器类

    这个适配器类继承自backtrader.Strategy,可以适配任何BaseStrategy的子类,
    将backtrader的回测框架与BaseStrategy的交易逻辑连接起来。
    """
    pass

同时我们再实现一个BackTraderRunner类,来负责回测的运行。

freshquant/backtest/backtrader/base/backtrader_runner.py

这样所有的策略只要简化成这样就能直接在backtrader中运行回测,只要按这个模式来写策略,就可以很方便地和backtrader集成。

class FiveYangStrategyTester(BacktraderTester):

    def __init__(self):
        self.strategy_class = FiveYangStrategy


if __name__ == "__main__":
    run_tester(FiveYangStrategyTester())

如果以后要用其他的回测框架,那么我们也可以用这种模式来开发一个其他框架的适配器,这样就可以很方便地切换回测框架了。

如下所示,我们运行这个脚本来回测这个为MVP做的模拟策略。

python freshquant/backtest/backtrader/five_yang_strategy/main.py

这次更新的意义在于,我们完成了策略的模拟盘和回测系统,以后只要按照这个模式来开发策略,就可以很方便地实现策略的模拟盘和回测了。

再强调一次,这次更新也只是一个MVP,以后会继续完善,包括回测系统,以及策略的可视化等。