Skip to content

Commit f59cfe5

Browse files
authored
Fix account shared bug (#791)
* Fix account shared bug * fix bug in nested executor
1 parent 1ecdfd4 commit f59cfe5

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

qlib/backtest/executor.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def __init__(
118118
self.dealt_order_amount = defaultdict(float)
119119
self.deal_day = None
120120

121-
def reset_common_infra(self, common_infra):
121+
def reset_common_infra(self, common_infra, copy_trade_account=False):
122122
"""
123123
reset infrastructure for trading
124124
- reset trade_account
@@ -129,9 +129,14 @@ def reset_common_infra(self, common_infra):
129129
self.common_infra.update(common_infra)
130130

131131
if common_infra.has("trade_account"):
132-
# NOTE: there is a trick in the code.
133-
# shallow copy is used instead of deepcopy. So positions are shared
134-
self.trade_account: Account = copy.copy(common_infra.get("trade_account"))
132+
if copy_trade_account:
133+
# NOTE: there is a trick in the code.
134+
# shallow copy is used instead of deepcopy.
135+
# 1. So positions are shared
136+
# 2. Others are not shared, so each level has it own metrics (portfolio and trading metrics)
137+
self.trade_account: Account = copy.copy(common_infra.get("trade_account"))
138+
else:
139+
self.trade_account = common_infra.get("trade_account")
135140
self.trade_account.reset(freq=self.time_per_step, port_metr_enabled=self.generate_portfolio_metrics)
136141

137142
@property
@@ -342,14 +347,18 @@ def __init__(
342347
**kwargs,
343348
)
344349

345-
def reset_common_infra(self, common_infra):
350+
def reset_common_infra(self, common_infra, copy_trade_account=False):
346351
"""
347352
reset infrastructure for trading
348353
- reset inner_strategyand inner_executor common infra
349354
"""
350-
super(NestedExecutor, self).reset_common_infra(common_infra)
355+
# NOTE: please refer to the docs of BaseExecutor.reset_common_infra for the meaning of `copy_trade_account`
356+
357+
# The first level follow the `copy_trade_account` from the upper level
358+
super(NestedExecutor, self).reset_common_infra(common_infra, copy_trade_account=copy_trade_account)
351359

352-
self.inner_executor.reset_common_infra(common_infra)
360+
# The lower level have to copy the trade_account
361+
self.inner_executor.reset_common_infra(common_infra, copy_trade_account=True)
353362
self.inner_strategy.reset_common_infra(common_infra)
354363

355364
def _init_sub_trading(self, trade_decision):

0 commit comments

Comments
 (0)