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

adapting strategies to latest interfaces.

This commit is contained in:
Young
2021-06-28 07:30:34 +00:00
committed by you-n-g
parent c907d8deb4
commit 72c9593aa7
9 changed files with 70 additions and 19 deletions

View File

@@ -10,6 +10,8 @@ from tqdm.auto import tqdm
def backtest_loop(start_time, end_time, trade_strategy: BaseStrategy, trade_executor: BaseExecutor):
"""backtest funciton for the interaction of the outermost strategy and executor in the nested decision execution
please refer to the docs of `collect_data_loop`
Returns
-------
report: Report
@@ -28,8 +30,11 @@ def collect_data_loop(start_time, end_time, trade_strategy: BaseStrategy, trade_
----------
start_time : pd.Timestamp|str
closed start time for backtest
**NOTE**: This will be applied to the outmost executor's calendar.
end_time : pd.Timestamp|str
closed end time for backtest
**NOTE**: This will be applied to the outmost executor's calendar.
E.g. Executor[day](Executor[1min]), setting `end_time == 20XX0301` will include all the minutes on 20XX0301
trade_strategy : BaseStrategy
the outermost portfolio strategy
trade_executor : BaseExecutor

View File

@@ -3,6 +3,8 @@ import warnings
import pandas as pd
from typing import Union
from qlib.backtest.report import Indicator
from .order import Order, BaseTradeDecision
from .exchange import Exchange
from .utils import TradeCalendarManager, CommonInfrastructure, LevelInfrastructure
@@ -174,7 +176,7 @@ class BaseExecutor:
else:
raise ValueError("generate_report should be True if you want to generate report")
def get_trade_indicator(self):
def get_trade_indicator(self) -> Indicator:
"""get the trade indicator instance, which has pa/pos/ffr info."""
return self.trade_account.indicator
@@ -279,7 +281,7 @@ class NestedExecutor(BaseExecutor):
trade_decision = updated_trade_decision
# NEW UPDATE
# create a hook for inner strategy to update outter decision
self.inner_strategy.alter_decision(trade_decision)
self.inner_strategy.alter_outer_trade_decision(trade_decision)
_inner_trade_decision = self.inner_strategy.generate_trade_decision(_inner_execute_result)
@@ -287,7 +289,7 @@ class NestedExecutor(BaseExecutor):
_inner_execute_result = yield from self.inner_executor.collect_data(trade_decision=_inner_trade_decision)
execute_result.extend(_inner_execute_result)
inner_order_indicators.append(self.inner_executor.get_trade_indicator().get_order_indicator)
inner_order_indicators.append(self.inner_executor.get_trade_indicator().get_order_indicator())
if hasattr(self, "trade_account"):
trade_step = self.trade_calendar.get_trade_step()

View File

@@ -56,7 +56,7 @@ class BaseTradeDecision:
2. After a period of time, the decision are updated and become available
3. The inner strategy try to get the decision and start to execute the decision according to `get_range_limit`
Case 2:
1. The strategy is available at the start of the interval
1. The outer strategy's decision is available at the start of the interval
2. Same as `case 1.3`
"""
def __init__(self, strategy: BaseStrategy):
@@ -133,14 +133,19 @@ class TradeDecisionWO(BaseTradeDecision):
def get_range_limit(self) -> Tuple[int, int]:
if self.idx_range is None:
# Default to get full index
return 0, self.strategy.trade_calendar.get_trade_len() - 1
raise NotImplementedError(f"The decision didn't provide an index range")
return self.idx_range
def get_decision(self) -> List[object]:
return self.order_list
def __repr__(self) -> str:
return f"strategy: {self.strategy}; idx_range: {self.idx_range}; order_list[{len(self.order_list)}]"
# TODO: the orders below need to be discussed ------------------------------------
# - The classes below are designed for Case 1
# - However, Case 1 can't take `order_pool` as the an argument as the constructor function
class TradeDecisionWithOrderPool:
"""trade decision that made by strategy"""

View File

@@ -395,11 +395,9 @@ class Indicator:
)
)
@property
def get_order_indicator(self):
return self.order_indicator
@property
def get_trade_indicator(self):
return self.trade_indicator

View File

@@ -103,6 +103,9 @@ class TradeCalendarManager:
"""Get the start_time and end_time for trading"""
return self.start_time, self.end_time
def __repr__(self) -> str:
return f"{self.start_time}[{self.start_index}]~{self.end_time}[{self.end_index}]: [{self.trade_step}/{self.trade_len}]"
class BaseInfrastructure:
def __init__(self, **kwargs):