rqalpha 源码--配置 Mod 扩展

本文详细解析了模组配置的加载与初始化过程,包括如何根据配置文件动态加载和配置模组,以及模组的优先级排序和启动配置。通过具体实例展示了配置如何影响环境属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一步将 config 里面关于 mod 的配置进行加载和配置开启。

mod 配置格式

在这里插入图片描述

通过 mod_handle 将当前的 env 进行关联

mod_handler.set_env(env)

mod_handle 可以理解为一个管理配置的封装类,首先第一步做的就是将自身的 _env 将当前环境中的 env 关联起来,拿到该 env 的config, 对自己所管理的 mod 们进行配置。
根据上一小节的图例,可以知道:
enable 决定这个这个扩展是否被启用;
lib: 要导入的模块名
priority: 模块的优先级(最后存入的是一个排序的字典)

在执行到 load_mod() 的时候,一是能拿到本身的配置,更新入用户输入配置;
二是将 真正的 Mod 类导入。

相关源码: mod/init.py

    def set_env(self, environment):
        self._env = environment
        config = environment.config

        for mod_name in config.mod.__dict__:
            mod_config = getattr(config.mod, mod_name)
            # enable 决定这个扩展是否被启用
            if not mod_config.enabled:
                continue
            # 将启用的扩展加到 _mod_list 中
            self._mod_list.append((mod_name, mod_config))

        for idx, (mod_name, user_mod_config) in enumerate(self._mod_list):
            if hasattr(user_mod_config, 'lib'):
                # 扩展中需要导入的模块名
                lib_name = user_mod_config.lib
            elif mod_name in SYSTEM_MOD_LIST:
                lib_name = "rqalpha.mod.rqalpha_mod_" + mod_name
            else:
                lib_name = "rqalpha_mod_" + mod_name
            system_log.debug(_(u"loading mod {}").format(lib_name))
            # 根据配置导入 mod 库
            mod_module = import_mod(lib_name)
            # 不能导入的 从 mod_list 中删除
            if mod_module is None:
                del self._mod_list[idx]
                return
            # 在每个被导入的模块中执行 load_mod()
            mod = mod_module.load_mod()
            # __config__ 是写在 __init__ 文件中的默认配置
            mod_config = RqAttrDict(copy.deepcopy(getattr(mod_module, "__config__", {})))
            # 将用户输入配置更新到 mod 配置中
            mod_config.update(user_mod_config)
            setattr(config.mod, mod_name, mod_config)
            self._mod_list[idx] = (mod_name, mod_config)
            self._mod_dict[mod_name] = mod

        # 在 mod_list 里面按照优先级排序
        self._mod_list.sort(key=lambda item: getattr(item[1], "priority", 100))
        environment.mod_dict = self._mod_dict

开启配置

在主程序中的代码段:

mod_handler.start_up()

在 ModHandle 中的代码段:

def start_up(self):
    for mod_name, mod_config in self._mod_list:
        # 开启配置 改变 env 属性
        self._mod_dict[mod_name].start_up(self._env, mod_config)

举个例子,在我们的用户配置里面,我们对 simulatiom 这个扩展的配置如下:
在这里插入图片描述
程序运行最终会执行到 mod/simulation/mod.py 中, Simulation 类的 start_up()
通过执行 start_up,为 env 配置了相关的扩展部件。感觉这种设计很灵活。

    def start_up(self, env, mod_config):
        # 根据 mod_config 配置去改变 env 相应的属性
        mod_config.matching_type = self.parse_matching_type(mod_config.matching_type)
        if mod_config.commission_multiplier < 0:
            raise patch_user_exc(ValueError(_(u"invalid commission multiplier value: value range is [0, +∞)")))
        if env.config.base.margin_multiplier <= 0:
            raise patch_user_exc(ValueError(_(u"invalid margin multiplier value: value range is (0, +∞]")))

        if env.config.base.frequency == "tick":
            mod_config.volume_limit = False
            if mod_config.matching_type not in [
                MATCHING_TYPE.NEXT_TICK_LAST,
                MATCHING_TYPE.NEXT_TICK_BEST_OWN,
                MATCHING_TYPE.NEXT_TICK_BEST_COUNTERPARTY,
            ]:
                raise RuntimeError(_("Not supported matching type {}").format(mod_config.matching_type))
        else:
            if mod_config.matching_type not in [
                MATCHING_TYPE.NEXT_BAR_OPEN,
                MATCHING_TYPE.CURRENT_BAR_CLOSE,
            ]:
                raise RuntimeError(_("Not supported matching type {}").format(mod_config.matching_type))

        if mod_config.signal:
            env.set_broker(SignalBroker(env, mod_config))
        else:
            # 设置了模拟券商代理
            env.set_broker(SimulationBroker(env, mod_config))
        # 设置了时间源
        event_source = SimulationEventSource(env, env.config.base.account_list)
        env.set_event_source(event_source)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值