rqalpha source - load configuration

Profiles

yaml

version: 0.1.1

# 白名单,设置可以直接在策略代码中指定哪些模块的配置项目
whitelist: [base, extra, validator, mod]

base:
  # 可以指定回测的唯一ID,用户区分多次回测的结果
  run_id: 9999
  # 数据源所存储的文件路径
  data_bundle_path: data/bundle/
  # 启动的策略文件路径
  strategy_file: strategies/macd.py
  # 回测起始日期
  start_date: 2005-06-01
  # 回测结束日期(如果是实盘,则忽略该配置)
  end_date: 2050-01-01
  # 股票起始资金,默认为0
  stock_starting_cash: 1000000
  # 期货起始资金,默认为0
  future_starting_cash: 1000000
  # 设置策略类型,目前支持 `stock` (股票策略)、`future` (期货策略)及 `stock_future` (混合策略)
  strategy_type: stock
  # 运行类型,`b` 为回测,`p` 为模拟交易, `r` 为实盘交易。
  run_type: b
  # 目前支持 `1d` (日线回测) 和 `1m` (分钟线回测),如果要进行分钟线,请注意是否拥有对应的数据源,目前开源版本是不提供对应的数据源的。
  frequency: 1d
  # 启用的回测引擎,目前支持 `current_bar` (当前Bar收盘价撮合) 和 `next_bar` (下一个Bar开盘价撮合)
  matching_type: next_bar
  # Benchmark,如果不设置,默认没有基准参照。
  benchmark: ~
  # 设置滑点
  slippage: 0
  # 设置手续费乘数,默认为1
  commission_multiplier: 1
  # 设置保证金乘数,默认为1
  margin_multiplier: 1
  # 在模拟交易和实盘交易中,RQAlpha支持策略的pause && resume,该选项表示开启 resume 功能
  resume_mode: false
  # 在模拟交易和实盘交易中,RQAlpha支持策略的pause && resume,该选项表示开启 persist 功能呢,
  # 其会在每个bar结束对进行策略的持仓、账户信息,用户的代码上线文等内容进行持久化
  persist: false
  persist_mode: real_time
  # 选择是否开启自动处理, 默认不开启
  handle_split: false
  account_list: [2]
  securities: 0

extra:
  # 选择日期的输出等级,有 `verbose` | `info` | `warning` | `error` 等选项,您可以通过设置 `verbose` 来查看最详细的日志,
  # 或者设置 `error` 只查看错误级别的日志输出
  log_level: info
  user_system_log_disabled: false
  # 在回测结束后,选择是否查看图形化的收益曲线
  context_vars: ~
  # force_run_init_when_pt_resume: 在PT的resume模式时,是否强制执行用户init。主要用于用户改代码。
  force_run_init_when_pt_resume: false
  # enable_profiler: 是否启动性能分析
  enable_profiler: false
  is_hold: false
  locale: zh_Hans_CN

validator:
  # cash_return_by_stock_delisted: 开启该项,当持仓股票退市时,按照退市价格返还现金
  cash_return_by_stock_delisted: false
  # close_amount: 在执行order_value操作时,进行实际下单数量的校验和scale,默认开启
  close_amount: true
  # bar_limit: 在处于涨跌停时,无法买进/卖出,默认开启
  bar_limit: true


mod:
  # 回测 / 模拟交易 支持 Mod
  simulation:
    lib: 'mod.simulation'
    enabled: true
    priority: 100
  # 技术分析API
  funcat_api:
    lib: 'mod.funcat'
    enabled: false
    priority: 200
  # 开启该选项,可以在命令行查看回测进度
  progress:
    lib: 'mod.progress'
    enabled: false
    priority: 400
  # 接收实时行情运行
  simple_stock_realtime_trade:
    lib: 'mod.realtime'
    persist_path: "./persist/strategy/"
    fps: 3
    enabled: false
    priority: 500
  # 渐进式输出运行结果
  progressive_output_csv:
    lib: 'mod.progressive_output_csv'
    enabled: false
    output_path: "./"
    priority: 600
  risk_manager:
    lib: 'mod.risk_manager'
    enabled: true
    priority: 700
    # available_cash: 查可用资金是否充足,默认开启
    available_cash: true
    # available_position: 检查可平仓位是否充足,默认开启
    available_position: true
  analyser:
    priority: 100
    enabled: true
    lib: 'mod.analyser'
    record: true
    output_file: data/result/output_file
    plot: data/result/plot
    plot_save_file: data/result/plot_save_file
    report_save_path: data/result/

json

No demo here.

Load configuration

import os
import codecs
import json
import pprint

import yaml

from utils.i18n import gettext


def load_config(config_path, loader=yaml.Loader):
    """
    在项目启动时去加载配置
    :param config_path: 配置路径
    :param loader: 配置加载器
    :return:
    """
    if config_path is None:
        return dict()
    if not os.path.exists(config_path):  # 判断路径是否真实存在
        raise RuntimeError(gettext(u"config.yml not found in {config_path}").format(config_path))
    if ".json" in config_path:  # 如果是 .json 格式的配置
        # codecs 模块是专门用来做编码转换的
        with codecs.open(config_path, encoding="utf-8") as f:
            json_config = f.read()
        config = json.loads(json_config)
    else:
        with codecs.open(config_path, encoding="utf-8") as stream:
            config = yaml.load(stream, loader)
    return config


if __name__ == '__main__':
    config = load_config(config_path='config.yml')
    print(pprint.pformat(config))

Convert an object dictionary

The conversion dictionary object, you can use Call

class RqAttrDict(object):
    """
    将字典类型转换为对象 这样就可以用 . 来操作 字典的键值
    """
    def __init__(self, d=None):
        # 一个对象的 __dict__ 魔法方法包含了其全部属性值
        self.__dict__ = d if d is not None else dict()

        #  迭代字典中的嵌套字典 仍然赋值为嵌套字典对象的格式
        #  因为在 py2 里面 dict.items() 返回的是数组 six.iteritems() 返回的是生成器
        #  但是在 py3 里面 dict.items() 也是返回生成器
        for k, v in list(six.iteritems(self.__dict__)):
            if isinstance(v, dict):
                self.__dict__[k] = RqAttrDict(v)

    def __repr__(self):
        # __str__ 会覆盖 __repr__
        return pprint.pformat(self.__dict__)

    def __iter__(self):
        # 返回迭代器本身或者是其他可迭代的对象的实例 实现了委托迭代
        # 然后去调用该对象的 __next__ 方法
        return self.__dict__.__iter__()

    def update(self, other):
        # 递归更新字典
        RqAttrDict._update_dict_recursive(self, other)

    def items(self):
        # 返回生成器对象
        return six.iteritems(self.__dict__)

    iteritems = items

    @staticmethod
    def _update_dict_recursive(target, other):
        # 使用 other 去更新 target
        if isinstance(other, RqAttrDict):
            other = other.__dict__
        if isinstance(target, RqAttrDict):
            target = target.__dict__

        for k, v in six.iteritems(other):
            if isinstance(v, collections.Mapping):  # 如果他的值仍然是个字典 为甚不用 dict 二是用 collections.Mapping
                r = RqAttrDict._update_dict_recursive(target.get(k, {}), v)
                target[k] = r
            else:
                target[k] = other[k]
        return target

    def convert_to_dict(self):
        # 将对象转换为 字典
        result_dict = dict()
        for k, v in list(six.iteritems(self.__dict__)):
            if isinstance(v, RqAttrDict):
                v = v.convert_to_dict()
            result_dict[k] = v
        return result_dict

This completes the configuration work before the start.

The relevant code:

Guess you like

Origin blog.csdn.net/Enjolras_fuu/article/details/94838872