This step will config inside on mod configuration to load and configure the open.
mod configuration format
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:
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)