rqalpha source code - Extended configuration Mod

This step will config inside on mod configuration to load and configure the open.

mod configuration format

Here Insert Picture Description

The current env by associating mod_handle

mod_handler.set_env(env)

mod_handle can be understood as a package class management configuration, The first step is to do their own _env will be associated with the current environment env up, get the config of the env, on their own mod managed configuration.
According to legend the previous section, you can know:
enable this extension to decide whether this is enabled;
lib: to import the module name
priority (last deposit is a sort of dictionary) module: priority

When performing the load_mod (), one can get its own configuration, update the user input configuration;
the second is introduced to the real class Mod.

Related Source: MOD / the 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

Open configuration

In the main code segment:

mod_handler.start_up()

In ModHandle code segment:

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)

For example, the configuration in which our customers, we configure simulatiom this extension is as follows:
Here Insert Picture Description
run eventually perform a mod / simulation / mod.py in, start_up (Simulation and the like)
by performing START_UP configured related to env the extension member. I feel this design is very flexible.

    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)

Guess you like

Origin blog.csdn.net/Enjolras_fuu/article/details/94851684
Recommended