mirror of
https://github.com/microsoft/qlib.git
synced 2026-07-10 14:26:56 +08:00
* update python version * fix: Correct selector handling and add time filtering in storage.py * fix: convert index and columns to list in repr methods * feat: Add Makefile for managing project prerequisites * feat: Add Cython extensions for rolling and expanding operations * resolve install error * fix lint error * fix lint error * fix lint error * fix lint error * fix lint error * update build package * update makefile * update ci yaml * fix docs build error * fix ubuntu install error * fix docs build error * fix install error * fix install error * fix install error * fix install error * fix pylint error * fix pylint error * fix pylint error * fix pylint error * fix pylint error E1123 * fix pylint error R0917 * fix pytest error * fix pytest error * fix pytest error * update code * update code * fix ci error * fix pylint error * fix black error * fix pytest error * fix CI error * fix CI error * add python version to CI * add python version to CI * add python version to CI * fix pylint error * fix pytest general nn error * fix CI error * optimize code * add coments * Extended macos version * remove build package --------- Co-authored-by: Young <afe.young@gmail.com>
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
import os
|
|
import platform
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
from importlib import import_module
|
|
from ruamel.yaml import YAML
|
|
|
|
|
|
DELETE_KEY = "_delete_"
|
|
|
|
|
|
def merge_a_into_b(a: dict, b: dict) -> dict:
|
|
b = b.copy()
|
|
for k, v in a.items():
|
|
if isinstance(v, dict) and k in b:
|
|
v.pop(DELETE_KEY, False)
|
|
b[k] = merge_a_into_b(v, b[k])
|
|
else:
|
|
b[k] = v
|
|
return b
|
|
|
|
|
|
def check_file_exist(filename: str, msg_tmpl: str = 'file "{}" does not exist') -> None:
|
|
if not os.path.isfile(filename):
|
|
raise FileNotFoundError(msg_tmpl.format(filename))
|
|
|
|
|
|
def parse_backtest_config(path: str) -> dict:
|
|
abs_path = os.path.abspath(path)
|
|
check_file_exist(abs_path)
|
|
|
|
file_ext_name = os.path.splitext(abs_path)[1]
|
|
if file_ext_name not in (".py", ".json", ".yaml", ".yml"):
|
|
raise IOError("Only py/yml/yaml/json type are supported now!")
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_config_dir:
|
|
with tempfile.NamedTemporaryFile(dir=tmp_config_dir, suffix=file_ext_name) as tmp_config_file:
|
|
if platform.system() == "Windows":
|
|
tmp_config_file.close()
|
|
|
|
tmp_config_name = os.path.basename(tmp_config_file.name)
|
|
shutil.copyfile(abs_path, tmp_config_file.name)
|
|
|
|
if abs_path.endswith(".py"):
|
|
tmp_module_name = os.path.splitext(tmp_config_name)[0]
|
|
sys.path.insert(0, tmp_config_dir)
|
|
module = import_module(tmp_module_name)
|
|
sys.path.pop(0)
|
|
|
|
config = {k: v for k, v in module.__dict__.items() if not k.startswith("__")}
|
|
|
|
del sys.modules[tmp_module_name]
|
|
else:
|
|
with open(tmp_config_file.name) as input_stream:
|
|
yaml = YAML(typ="safe", pure=True)
|
|
config = yaml.load(input_stream)
|
|
|
|
if "_base_" in config:
|
|
base_file_name = config.pop("_base_")
|
|
if not isinstance(base_file_name, list):
|
|
base_file_name = [base_file_name]
|
|
|
|
for f in base_file_name:
|
|
base_config = parse_backtest_config(os.path.join(os.path.dirname(abs_path), f))
|
|
config = merge_a_into_b(a=config, b=base_config)
|
|
|
|
return config
|
|
|
|
|
|
def _convert_all_list_to_tuple(config: dict) -> dict:
|
|
for k, v in config.items():
|
|
if isinstance(v, list):
|
|
config[k] = tuple(v)
|
|
elif isinstance(v, dict):
|
|
config[k] = _convert_all_list_to_tuple(v)
|
|
return config
|
|
|
|
|
|
def get_backtest_config_fromfile(path: str) -> dict:
|
|
backtest_config = parse_backtest_config(path)
|
|
|
|
exchange_config_default = {
|
|
"open_cost": 0.0005,
|
|
"close_cost": 0.0015,
|
|
"min_cost": 5.0,
|
|
"trade_unit": 100.0,
|
|
"cash_limit": None,
|
|
}
|
|
backtest_config["exchange"] = merge_a_into_b(a=backtest_config["exchange"], b=exchange_config_default)
|
|
backtest_config["exchange"] = _convert_all_list_to_tuple(backtest_config["exchange"])
|
|
|
|
backtest_config_default = {
|
|
"debug_single_stock": None,
|
|
"debug_single_day": None,
|
|
"concurrency": -1,
|
|
"multiplier": 1.0,
|
|
"output_dir": "outputs_backtest/",
|
|
"generate_report": False,
|
|
"data_granularity": "1min",
|
|
}
|
|
backtest_config = merge_a_into_b(a=backtest_config, b=backtest_config_default)
|
|
|
|
return backtest_config
|