mirror of
https://github.com/microsoft/qlib.git
synced 2026-07-12 15:26:54 +08:00
* Intermediate version * Fix yaml template & Successfully run rolling * Be compatible with benchmark * Get same results with previous linear model * Black formatting * Update black * Update the placeholder mechanism * Update CI * Update CI * Upgrade Black * Fix CI and simplify code * Fix CI * Move the data processing caching mechanism into utils. * Adjusting DDG-DA * Organize import
90 lines
3.5 KiB
Python
90 lines
3.5 KiB
Python
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
# pylint: skip-file
|
|
# flake8: noqa
|
|
|
|
import yaml
|
|
import copy
|
|
import os
|
|
|
|
|
|
class TunerConfigManager:
|
|
def __init__(self, config_path):
|
|
if not config_path:
|
|
raise ValueError("Config path is invalid.")
|
|
self.config_path = config_path
|
|
|
|
with open(config_path) as fp:
|
|
config = yaml.safe_load(fp)
|
|
self.config = copy.deepcopy(config)
|
|
|
|
self.pipeline_ex_config = PipelineExperimentConfig(config.get("experiment", dict()), self)
|
|
self.pipeline_config = config.get("tuner_pipeline", list())
|
|
self.optim_config = OptimizationConfig(config.get("optimization_criteria", dict()), self)
|
|
|
|
self.time_config = config.get("time_period", dict())
|
|
self.data_config = config.get("data", dict())
|
|
self.backtest_config = config.get("backtest", dict())
|
|
self.qlib_client_config = config.get("qlib_client", dict())
|
|
|
|
|
|
class PipelineExperimentConfig:
|
|
def __init__(self, config, TUNER_CONFIG_MANAGER):
|
|
"""
|
|
:param config: The config dict for tuner experiment
|
|
:param TUNER_CONFIG_MANAGER: The tuner config manager
|
|
"""
|
|
self.name = config.get("name", "tuner_experiment")
|
|
# The dir of the config
|
|
self.global_dir = config.get("dir", os.path.dirname(TUNER_CONFIG_MANAGER.config_path))
|
|
# The dir of the result of tuner experiment
|
|
self.tuner_ex_dir = config.get("tuner_ex_dir", os.path.join(self.global_dir, self.name))
|
|
if not os.path.exists(self.tuner_ex_dir):
|
|
os.makedirs(self.tuner_ex_dir)
|
|
# The dir of the results of all estimator experiments
|
|
self.estimator_ex_dir = config.get("estimator_ex_dir", os.path.join(self.tuner_ex_dir, "estimator_experiment"))
|
|
if not os.path.exists(self.estimator_ex_dir):
|
|
os.makedirs(self.estimator_ex_dir)
|
|
# Get the tuner type
|
|
self.tuner_module_path = config.get("tuner_module_path", "qlib.contrib.tuner.tuner")
|
|
self.tuner_class = config.get("tuner_class", "QLibTuner")
|
|
# Save the tuner experiment for further view
|
|
tuner_ex_config_path = os.path.join(self.tuner_ex_dir, "tuner_config.yaml")
|
|
with open(tuner_ex_config_path, "w") as fp:
|
|
yaml.dump(TUNER_CONFIG_MANAGER.config, fp)
|
|
|
|
|
|
class OptimizationConfig:
|
|
def __init__(self, config, TUNER_CONFIG_MANAGER):
|
|
self.report_type = config.get("report_type", "pred_long")
|
|
if self.report_type not in [
|
|
"pred_long",
|
|
"pred_long_short",
|
|
"pred_short",
|
|
"excess_return_without_cost",
|
|
"excess_return_with_cost",
|
|
"model",
|
|
]:
|
|
raise ValueError(
|
|
"report_type should be one of pred_long, pred_long_short, pred_short, excess_return_without_cost, excess_return_with_cost and model"
|
|
)
|
|
|
|
self.report_factor = config.get("report_factor", "information_ratio")
|
|
if self.report_factor not in [
|
|
"annualized_return",
|
|
"information_ratio",
|
|
"max_drawdown",
|
|
"mean",
|
|
"std",
|
|
"model_score",
|
|
"model_pearsonr",
|
|
]:
|
|
raise ValueError(
|
|
"report_factor should be one of annualized_return, information_ratio, max_drawdown, mean, std, model_pearsonr and model_score"
|
|
)
|
|
|
|
self.optim_type = config.get("optim_type", "max")
|
|
if self.optim_type not in ["min", "max", "correlation"]:
|
|
raise ValueError("optim_type should be min, max or correlation")
|