mirror of
https://github.com/microsoft/qlib.git
synced 2026-07-07 13:00:58 +08:00
@@ -31,7 +31,7 @@ rtn & earning in the Account
|
||||
class AccumulatedInfo:
|
||||
"""
|
||||
accumulated trading info, including accumulated return/cost/turnover
|
||||
AccumulatedInfo should be shared accross different levels
|
||||
AccumulatedInfo should be shared across different levels
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@@ -199,7 +199,7 @@ class Account:
|
||||
|
||||
# if stock is sold out, no stock price information in Position, then we should update account first, then update current position
|
||||
# if stock is bought, there is no stock in current position, update current, then update account
|
||||
# The cost will be substracted from the cash at last. So the trading logic can ignore the cost calculation
|
||||
# The cost will be subtracted from the cash at last. So the trading logic can ignore the cost calculation
|
||||
if order.direction == Order.SELL:
|
||||
# sell stock
|
||||
self._update_state_from_order(order, trade_val, cost, trade_price)
|
||||
@@ -378,7 +378,7 @@ class Account:
|
||||
)
|
||||
|
||||
def get_portfolio_metrics(self):
|
||||
"""get the history portfolio_metrics and postions instance"""
|
||||
"""get the history portfolio_metrics and positions instance"""
|
||||
if self.is_port_metr_enabled():
|
||||
_portfolio_metrics = self.portfolio_metrics.generate_portfolio_metrics_dataframe()
|
||||
_positions = self.get_hist_positions()
|
||||
|
||||
@@ -13,7 +13,7 @@ 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
|
||||
"""backtest function for the interaction of the outermost strategy and executor in the nested decision execution
|
||||
|
||||
please refer to the docs of `collect_data_loop`
|
||||
|
||||
|
||||
@@ -505,8 +505,8 @@ class BaseTradeDecision:
|
||||
`inner_trade_decision` will be changed **inplaced**.
|
||||
|
||||
Motivation of the `mod_inner_decision`
|
||||
- Leave a hook for outer decision to affact the decision generated by the inner strategy
|
||||
- e.g. the outmost strategy generate a time range for trading. But the upper layer can only affact the
|
||||
- Leave a hook for outer decision to affect the decision generated by the inner strategy
|
||||
- e.g. the outmost strategy generate a time range for trading. But the upper layer can only affect the
|
||||
nearest layer in the original design. With `mod_inner_decision`, the decision can passed through multiple
|
||||
layers
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class Exchange:
|
||||
Necessary fields:
|
||||
$close is for calculating the total value at end of each day.
|
||||
Optional fields:
|
||||
$volume is only necessary when we limit the trade amount or caculate PA(vwap) indicator
|
||||
$volume is only necessary when we limit the trade amount or calculate PA(vwap) indicator
|
||||
$vwap is only necessary when we use the $vwap price as the deal price
|
||||
$factor is for rounding to the trading unit
|
||||
limit_sell will be set to False by default(False indicates we can sell this
|
||||
@@ -505,7 +505,7 @@ class Exchange:
|
||||
Note: some future information is used in this function
|
||||
Parameter:
|
||||
target_position : dict { stock_id : amount }
|
||||
current_postion : dict { stock_id : amount}
|
||||
current_position : dict { stock_id : amount}
|
||||
trade_unit : trade_unit
|
||||
down sample : for amount 321 and trade_unit 100, deal_amount is 300
|
||||
deal order on trade_date
|
||||
|
||||
@@ -41,7 +41,7 @@ class BaseExecutor:
|
||||
Parameters
|
||||
----------
|
||||
time_per_step : str
|
||||
trade time per trading step, used for genreate the trade calendar
|
||||
trade time per trading step, used for generate the trade calendar
|
||||
show_indicator: bool, optional
|
||||
whether to show indicators, :
|
||||
- 'pa', the price advantage
|
||||
@@ -369,12 +369,12 @@ class NestedExecutor(BaseExecutor):
|
||||
self.inner_strategy.reset(level_infra=sub_level_infra, outer_trade_decision=trade_decision)
|
||||
|
||||
def _update_trade_decision(self, trade_decision: BaseTradeDecision) -> BaseTradeDecision:
|
||||
# outter strategy have chance to update decision each iterator
|
||||
# outer strategy have chance to update decision each iterator
|
||||
updated_trade_decision = trade_decision.update(self.inner_executor.trade_calendar)
|
||||
if updated_trade_decision is not None:
|
||||
trade_decision = updated_trade_decision
|
||||
# NEW UPDATE
|
||||
# create a hook for inner strategy to update outter decision
|
||||
# create a hook for inner strategy to update outer decision
|
||||
self.inner_strategy.alter_outer_trade_decision(trade_decision)
|
||||
return trade_decision
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ class BaseOrderIndicator:
|
||||
indicators : List[BaseOrderIndicator]
|
||||
the list of all inner indicators.
|
||||
metrics : Union[str, List[str]]
|
||||
all metrics needs ot be sumed.
|
||||
all metrics needs to be sumed.
|
||||
fill_value : float, optional
|
||||
fill np.NaN with value. By default None.
|
||||
"""
|
||||
|
||||
@@ -152,7 +152,7 @@ class BasePosition:
|
||||
"""
|
||||
generate stock weight dict {stock_id : value weight of stock in the position}
|
||||
it is meaningful in the beginning or the end of each trade step
|
||||
- During execution of each trading step, the weight may be not consistant with the portfolio value
|
||||
- During execution of each trading step, the weight may be not consistent with the portfolio value
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
@@ -39,7 +39,7 @@ def get_benchmark_weight(
|
||||
if not path:
|
||||
path = Path(C.dpm.get_data_uri(freq)).expanduser() / "raw" / "AIndexMembers" / "weights.csv"
|
||||
# TODO: the storage of weights should be implemented in a more elegent way
|
||||
# TODO: The benchmark is not consistant with the filename in instruments.
|
||||
# TODO: The benchmark is not consistent with the filename in instruments.
|
||||
bench_weight_df = pd.read_csv(path, usecols=["code", "date", "index", "weight"])
|
||||
bench_weight_df = bench_weight_df[bench_weight_df["index"] == bench]
|
||||
bench_weight_df["date"] = pd.to_datetime(bench_weight_df["date"])
|
||||
|
||||
@@ -73,7 +73,7 @@ class PortfolioMetrics:
|
||||
self.init_bench(freq=freq, benchmark_config=benchmark_config)
|
||||
|
||||
def init_vars(self):
|
||||
self.accounts = OrderedDict() # account postion value for each trade time
|
||||
self.accounts = OrderedDict() # account position value for each trade time
|
||||
self.returns = OrderedDict() # daily return rate for each trade time
|
||||
self.total_turnovers = OrderedDict() # total turnover for each trade time
|
||||
self.turnovers = OrderedDict() # turnover for each trade time
|
||||
@@ -236,7 +236,7 @@ class Indicator:
|
||||
"""
|
||||
`Indicator` is implemented in a aggregate way.
|
||||
All the metrics are calculated aggregately.
|
||||
All the metrics are calculated for a seperated stock and in a specific step on a specific level.
|
||||
All the metrics are calculated for a separated stock and in a specific step on a specific level.
|
||||
|
||||
| indicator | desc. |
|
||||
|--------------+--------------------------------------------------------------|
|
||||
|
||||
@@ -93,7 +93,7 @@ class TradeCalendarManager:
|
||||
|
||||
About the endpoints:
|
||||
- Qlib uses the closed interval in time-series data selection, which has the same performance as pandas.Series.loc
|
||||
# - The returned right endpoints should minus 1 seconds becasue of the closed interval representation in Qlib.
|
||||
# - The returned right endpoints should minus 1 seconds because of the closed interval representation in Qlib.
|
||||
# Note: Qlib supports up to minutely decision execution, so 1 seconds is less than any trading time interval.
|
||||
|
||||
Parameters
|
||||
|
||||
Reference in New Issue
Block a user