1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-06 04:20:57 +08:00

Add multi horizon task generator

This commit is contained in:
Young
2021-10-28 00:01:19 +08:00
parent 5fa56703ae
commit 31e9d529de
2 changed files with 64 additions and 5 deletions

View File

@@ -152,8 +152,11 @@ def init_from_yaml_conf(conf_path, **kwargs):
:param conf_path: A path to the qlib config in yml format
"""
with open(conf_path) as f:
config = yaml.safe_load(f)
if conf_path is None:
config = {}
else:
with open(conf_path) as f:
config = yaml.safe_load(f)
config.update(kwargs)
default_conf = config.pop("default_conf", "client")
init(default_conf, **config)
@@ -216,7 +219,7 @@ def auto_init(**kwargs):
.. code-block:: yaml
conf_type: ref
qlib_cfg: '<shared_yaml_config_path>'
qlib_cfg: '<shared_yaml_config_path>' # this could be null reference no config from other files
# following configs in `qlib_cfg_update` is project=specific
qlib_cfg_update:
exp_manager:
@@ -259,8 +262,8 @@ def auto_init(**kwargs):
# - There is a shared configure file and you don't want to edit it inplace.
# - The shared configure may be updated later and you don't want to copy it.
# - You have some customized config.
qlib_conf_path = conf["qlib_cfg"]
qlib_conf_update = conf.get("qlib_cfg_update")
qlib_conf_path = conf.get("qlib_cfg", None)
qlib_conf_update = conf.get("qlib_cfg_update", {})
init_from_yaml_conf(qlib_conf_path, **qlib_conf_update, **kwargs)
logger = get_module_logger("Initialization")
logger.info(f"Auto load project config: {conf_pp}")

View File

@@ -112,6 +112,9 @@ def handler_mod(task: dict, rolling_gen):
except KeyError:
# Maybe dataset do not have handler, then do nothing.
pass
except TypeError:
# May be the handler is a string. `"handler.pkl"["kwargs"]` will raise TypeError
pass
class RollingGen(TaskGen):
@@ -259,3 +262,56 @@ class RollingGen(TaskGen):
# Update the following rolling
res.extend(self.gen_following_tasks(t, test_end))
return res
class MultiHorizonGenBase(TaskGen):
def __init__(self, horizon: List[int] = [5], label_leak_n=2):
"""
This task generator tries to genrate tasks for different horizons based on an existing task
Parameters
----------
horizon : List[int]
the possible horizons of the tasks
label_leak_n : int
How many future days it will take to get complete label after the day making prediction
For example:
- User make prediction on day `T`(after getting the close price on `T`)
- The label is the return of buying stock on `T + 1` and selling it on `T + 2`
- the `label_leak_n` will be 2 (e.g. two days of information is leaked to leverage this sample)
"""
self.horizon = list(horizon)
self.label_leak_n = label_leak_n
self.ta = TimeAdjuster()
self.test_key = "test"
@abc.abstractmethod
def set_horizon(self, task: dict, hr: int):
"""
This method is designed to change the task **in place**
Parameters
----------
task : dict
Qlib's task
hr : int
the horizon of task
"""
def generate(self, task: dict):
res = []
for hr in self.horizon:
# Add horizon
t = copy.deepcopy(task)
self.set_horizon(t, hr)
# adjust segment
segments = self.ta.align_seg(t["dataset"]["kwargs"]["segments"])
test_start = min(t for t in segments[self.test_key] if t is not None)
for k in list(segments.keys()):
if k != self.test_key:
segments[k] = self.ta.truncate(segments[k], test_start, hr + self.label_leak_n)
t["dataset"]["kwargs"]["segments"] = segments
res.append(t)
return res