-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Migrate backtest logic from NT #1263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| self._order = order_list[0] | ||
|
|
||
|
|
||
| class SAOEIntStrategy(SAOEStrategy): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between this and SAOEStrategy? Why do we need another class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SAOEStrategy is the strategy that maintains SAOEState internally (by SAOEStateAdapter). SAOEIntStrategy is a subclass of SAOEStrategy, but it contains interpreters. For now, SAOEIntStrategy is the only implementation of SAOEStrategy but I think it is useful to leave this two-level structure for future scalability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to explain that in docstring.
|
@lihuoran Will there be a related internal PR in neutrader? |
qlib/rl/data/pickle_styled.py
Outdated
| def _drop_stock_id(df: pd.DataFrame) -> pd.DataFrame: | ||
| return df.reset_index().drop(columns=["instrument"]).set_index(["datetime"]) | ||
|
|
||
| self.today = _drop_stock_id(fetch_features(stock_id, date)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it will be better to add more docs about the reason that today and yesterday are different with its base IntradayProcessedData.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NTIntradayProcessedData's base is BaseIntradayProcessedData, not IntradayProcessedData. Both NTIntradayProcessedData and IntradayProcessedData are implementations of BaseIntradayProcessedData and that is why they have different data formats.
qlib/rl/utils/env_wrapper.py
Outdated
| raise NotImplementedError("Render is not implemented in EnvWrapper.") | ||
|
|
||
|
|
||
| class CollectDataEnvWrapper: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it necessary to create a new class?
Will it be simpler to create a superclass of EnvWrapper if we want to simplify the interface further?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| """ | ||
|
|
||
| def __init__(self, data_dir: Path, max_step: int, data_ticks: int, data_dim: int) -> None: | ||
| def __init__(self, max_step: int, data_ticks: int, data_dim: int, data_dir: Path = None) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all implementations related to data_dir is coupled with the specific data format for that specific case.
So it should not be a general class as a part of the framework.
So it should be redesigned after the data interface is well-designed.
We could leave a TODO here in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO left.
| warnings.filterwarnings("ignore", category=RuntimeWarning) | ||
|
|
||
| path = sys.argv[1] | ||
| backtest(get_backtest_config_fromfile(path)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test or script to run the code (maybe just a script in internal nuetrader)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we have it now.
qlib/rl/data/pickle_styled.py
Outdated
| return f"{self.__class__.__name__}({self.today}, {self.yesterday})" | ||
|
|
||
|
|
||
| class NTIntradayProcessedData(BaseIntradayProcessedData): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be put into another file, because it's not pickle_styled. See the headers of this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure how should we re-organize related structures. If we need to move NTIntradayProcessedData to a separate file, where should we put NTIntradayProcessedData and load_intraday_processed_data()?
qlib/rl/data/pickle_styled.py
Outdated
| ) -> BaseIntradayProcessedData: | ||
| from qlib.rl.data.integration import dataset # pylint: disable=C0415 | ||
|
|
||
| if dataset is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. This should be separated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| if self._policy is not None: | ||
| self._policy.eval() | ||
|
|
||
| def set_env(self, env: BaseEnvWrapper) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BaseEnvWrapper is for aligning the interface of Executor to RL Environment.
It is weird to rely on BaseEnvWrapper when running backtesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Backtest migration * Minor bug fix in test * Reorganize file to avoid loop import * Fix test SAOE bug * Remove unnecessary names * Resolve PR comments; remove private classes; * Fix CI error * Resolve PR comments * Refactor data interfaces * Remove convert_instance_config and change config * Pylint issue * Pylint issue * Fix tempfile warning * Resolve PR comments * Add more comments

Description
Migrate experiment backtest logic from NT.
Motivation and Context
How Has This Been Tested?
pytest qlib/tests/test_all_pipeline.pyunder upper directory ofqlib.Screenshots of Test Results (if appropriate):
Types of changes