It use default param freq='day' for create Account obj in Backtest.
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 48.7k
- Forks
- 7.7k
- PR merge metrics
- No merged PRs in 30d
Description
🐛 Bug Description
I only have 60min freq data.
When I try to backtest with 60min. It report can't find day data.
So I look into the stack, and found the reason that it use default param freq='day' for create Account obj.
I hope you could add a 'freq' in backtest config, and convert it into Account obj.
To Reproduce
Steps to reproduce the behavior:
user code
freq = '60min'
# backtest and analysis
with R.start(experiment_name="backtest_analysis"):
recorder = R.get_recorder(recorder_id=rid, experiment_name="train_model")
model = recorder.load_object("trained_model")
# prediction
recorder = R.get_recorder()
ba_rid = recorder.id
sr = SignalRecord(model, dataset, recorder)
sr.generate()
# backtest & analysis
par = PortAnaRecord(recorder, port_analysis_config, freq, freq)
par.generate()
framework code
class PortAnaRecord(ACRecordTemp):
def _generate(self, **kwargs):
# custom strategy and get backtest
portfolio_metric_dict, indicator_dict = normal_backtest(
executor=self.executor_config, strategy=self.strategy_config, **self.backtest_config
)
def backtest(
start_time: Union[pd.Timestamp, str],
end_time: Union[pd.Timestamp, str],
strategy: Union[str, dict, object, Path],
executor: Union[str, dict, object, Path],
benchmark: str = "SH000300",
account: Union[float, int, dict] = 1e9,
exchange_kwargs: dict = {},
pos_type: str = "Position",
) -> Tuple[PORT_METRIC, INDICATOR_METRIC]:
trade_strategy, trade_executor = get_strategy_executor(
start_time,
end_time,
strategy,
executor,
benchmark,
account,
exchange_kwargs,
pos_type=pos_type,
)
return backtest_loop(start_time, end_time, trade_strategy, trade_executor)
def get_strategy_executor(
start_time: Union[pd.Timestamp, str],
end_time: Union[pd.Timestamp, str],
strategy: Union[str, dict, object, Path],
executor: Union[str, dict, object, Path],
benchmark: Optional[str] = "SH000300",
account: Union[float, int, dict] = 1e9,
exchange_kwargs: dict = {},
pos_type: str = "Position",
) -> Tuple[BaseStrategy, BaseExecutor]:
# NOTE:
# - for avoiding recursive import
# - typing annotations is not reliable
from ..strategy.base import BaseStrategy # pylint: disable=C0415
from .executor import BaseExecutor # pylint: disable=C0415
trade_account = create_account_instance(
start_time=start_time,
end_time=end_time,
benchmark=benchmark,
account=account,
pos_type=pos_type,
)
def create_account_instance(
start_time: Union[pd.Timestamp, str],
end_time: Union[pd.Timestamp, str],
benchmark: Optional[str],
account: Union[float, int, dict],
pos_type: str = "Position",
) -> Account:
return Account(
init_cash=init_cash,
position_dict=position_dict,
pos_type=pos_type,
benchmark_config=(
{}
if benchmark is None
else {
"benchmark": benchmark,
"start_time": start_time,
"end_time": end_time,
}
),
)
class Account:
def __init__(
self,
init_cash: float = 1e9,
position_dict: dict = {},
freq: str = "day",
benchmark_config: dict = {},
pos_type: str = "Position",
port_metr_enabled: bool = True,
) -> None:
There exists param 'freq' in the Account init method.
But I can't change it from outer.
Expected Behavior
I hope you could add a 'freq' in backtest config, and convert it into Account obj.
Screenshot
Environment
Note: User could run cd scripts && python collect_info.py all under project directory to get system information
and paste them here directly.
- Qlib version:
- Python version:
- OS (
Windows,Linux,MacOS): - Commit number (optional, please provide it if you are using the dev version):
Additional Notes
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with PortAnaRecord._generate, normal_backtest, and get_strategy_executor, then follow create_account_instance into Account.init. Trace how the backtest frequency is available at the call site and verify that it reaches the Account instance instead of the default day frequency. Done means 60min backtests no longer require day data and the existing daily path remains usable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100