From 04b1f65477230330fe3126a627a0c1bfee3be5c6 Mon Sep 17 00:00:00 2001 From: "Don.Lin" <142398161+Lin-Dongzhao@users.noreply.github.com> Date: Fri, 22 Mar 2024 11:52:31 +0800 Subject: [PATCH] Rqsdk 735 (#858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修改期货交割时trading_pnl计算问题 * data update * 新增auto_update_bundle单元测试 * 若auto_update_bundle_path文件夹未创建,则自动创建路径 * 期货交割价格根据配置选择close或settlement * 测试用例新增期货交割后的仓位、总权益验证 * pr update --- .github/workflows/test.yml | 2 +- rqalpha/data/bundle.py | 2 + .../position_model.py | 6 ++ rqalpha/utils/testing/fixtures.py | 2 +- tests/outs/test_f_delivery.pkl | Bin 0 -> 11335 bytes tests/test_f_delivery.py | 42 ++++++++++ .../test_auto_update_bundle/__init__.py | 7 ++ .../mock_data/mock_open_auction_info.pkl | Bin 0 -> 90484 bytes .../test_auto_update_bundle_mixin.py | 75 ++++++++++++++++++ 9 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 tests/outs/test_f_delivery.pkl create mode 100644 tests/test_f_delivery.py create mode 100644 tests/unittest/test_data/test_auto_update_bundle/__init__.py create mode 100644 tests/unittest/test_data/test_auto_update_bundle/mock_data/mock_open_auction_info.pkl create mode 100644 tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5a3879ae8..895bb7fcd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] steps: # Checks out a copy of your repository on the ubuntu-latest machine - uses: actions/checkout@v2 diff --git a/rqalpha/data/bundle.py b/rqalpha/data/bundle.py index 4903c8cb6..d69239df1 100644 --- a/rqalpha/data/bundle.py +++ b/rqalpha/data/bundle.py @@ -633,6 +633,8 @@ def update_futures_trading_parameters(path, end_date): class AutomaticUpdateBundle(object): def __init__(self, path, filename, rqdata_api, fields, end_date): # type: (str, str, Callable, List[str], datetime.date) -> None + if not os.path.exists(path): + os.makedirs(path) self._file = os.path.join(path, filename) self._trading_dates = None self._filename = filename diff --git a/rqalpha/mod/rqalpha_mod_sys_accounts/position_model.py b/rqalpha/mod/rqalpha_mod_sys_accounts/position_model.py index ba97624f0..ddd69c16a 100644 --- a/rqalpha/mod/rqalpha_mod_sys_accounts/position_model.py +++ b/rqalpha/mod/rqalpha_mod_sys_accounts/position_model.py @@ -318,6 +318,12 @@ def settlement(self, trading_date): user_system_log.warn(_(u"{order_book_id} is expired, close all positions by system").format( order_book_id=self._order_book_id )) + account = self._env.get_account(self._order_book_id) + side = SIDE.SELL if self.direction == POSITION_DIRECTION.LONG else SIDE.BUY + trade = Trade.__from_create__( + None, self.last_price, self._quantity, side, POSITION_EFFECT.CLOSE, self._order_book_id + ) + self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=None)) self._quantity = self._old_quantity = 0 return delta_cash diff --git a/rqalpha/utils/testing/fixtures.py b/rqalpha/utils/testing/fixtures.py index a818bc733..aa8d1ab76 100644 --- a/rqalpha/utils/testing/fixtures.py +++ b/rqalpha/utils/testing/fixtures.py @@ -26,7 +26,7 @@ def init_fixture(self): from rqalpha.environment import Environment super(EnvironmentFixture, self).init_fixture() - self.env = Environment(RqAttrDict(self.env_config)) + self.env = Environment(RqAttrDict(self.env_config), False) @contextmanager def mock_env_method(self, name, mock_method): diff --git a/tests/outs/test_f_delivery.pkl b/tests/outs/test_f_delivery.pkl new file mode 100644 index 0000000000000000000000000000000000000000..64d540ee7c2c4926ad517b263c700d8f207dbc1b GIT binary patch literal 11335 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 literal 0 HcmV?d00001 diff --git a/tests/test_f_delivery.py b/tests/test_f_delivery.py new file mode 100644 index 000000000..c53224662 --- /dev/null +++ b/tests/test_f_delivery.py @@ -0,0 +1,42 @@ +import datetime + +def init(context): + context.f1 = "IH2402" + context.f2 = "IC2402" + context.fired = False + + +def handle_bar(context, bar_dict): + if not context.fired: + buy_open(context.f1, 3) + sell_open(context.f2, 3) + context.fired = True + if bar_dict._dt.date() == datetime.date(2024, 2, 19): + context.cash_before_delivery = context.portfolio.cash + context.daily_pnl = context.portfolio.daily_pnl + if bar_dict._dt.date() == datetime.date(2024, 2, 20): + assert get_position(context.f1).quantity == 0 + assert get_position(context.f2).quantity == 0 + assert abs(context.portfolio.cash - (((2363 * 300) + (5105.6 * 200)) * 0.12 * 3 + context.cash_before_delivery + context.daily_pnl)) < 0.0000001 + assert context.portfolio.total_value == context.portfolio.cash + + +__config__ = { + "base": { + "start_date": "2024-02-05", + "end_date": "2024-02-20", + "frequency": "1d", + "accounts": { + "future": 10000000, + }, + }, + "extra": { + "log_level": "error", + }, + "mod": { + "sys_progress": { + "enabled":True, + "show": True, + }, + }, +} \ No newline at end of file diff --git a/tests/unittest/test_data/test_auto_update_bundle/__init__.py b/tests/unittest/test_data/test_auto_update_bundle/__init__.py new file mode 100644 index 000000000..8f6432114 --- /dev/null +++ b/tests/unittest/test_data/test_auto_update_bundle/__init__.py @@ -0,0 +1,7 @@ +import os + + +def load_tests(loader, standard_tests, pattern): + this_dir = os.path.dirname(__file__) + standard_tests.addTests(loader.discover(start_dir=this_dir, pattern=pattern)) + return standard_tests \ No newline at end of file diff --git a/tests/unittest/test_data/test_auto_update_bundle/mock_data/mock_open_auction_info.pkl b/tests/unittest/test_data/test_auto_update_bundle/mock_data/mock_open_auction_info.pkl new file mode 100644 index 0000000000000000000000000000000000000000..0f61c58a6c3e1b6f7434273efdcbcd85a5e1e0e2 GIT binary patch literal 90484 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 literal 0 HcmV?d00001 diff --git a/tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py b/tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py new file mode 100644 index 000000000..817cd74a1 --- /dev/null +++ b/tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# 版权所有 2019 深圳米筐科技有限公司(下称“米筐科技”) +# +# 除非遵守当前许可,否则不得使用本软件。 +# +# * 非商业用途(非商业用途指个人出于非商业目的使用本软件,或者高校、研究所等非营利机构出于教育、科研等目的使用本软件): +# 遵守 Apache License 2.0(下称“Apache 2.0 许可”),您可以在以下位置获得 Apache 2.0 许可的副本:http://www.apache.org/licenses/LICENSE-2.0。 +# 除非法律有要求或以书面形式达成协议,否则本软件分发时需保持当前许可“原样”不变,且不得附加任何条件。 +# +# * 商业用途(商业用途指个人出于任何商业目的使用本软件,或者法人或其他组织出于任何目的使用本软件): +# 未经米筐科技授权,任何个人不得出于任何商业目的使用本软件(包括但不限于向第三方提供、销售、出租、出借、转让本软件、本软件的衍生产品、引用或借鉴了本软件功能或源代码的产品或服务),任何法人或其他组织不得出于任何目的使用本软件,否则米筐科技有权追究相应的知识产权侵权责任。 +# 在此前提下,对本软件的使用同样需要遵守 Apache 2.0 许可,Apache 2.0 许可与本许可冲突之处,以本许可为准。 +# 详细的授权流程,请联系 public@ricequant.com 获取。 + +import os +import datetime +import pickle +import tempfile + +from rqalpha.utils.testing import DataProxyFixture, RQAlphaTestCase +from rqalpha.data.bundle import AutomaticUpdateBundle +from rqalpha.data.trading_dates_mixin import TradingDatesMixin + + +class AutomaticUpdateBundleTestCase(DataProxyFixture, RQAlphaTestCase): + def __init__(self, *args, **kwargs): + super(AutomaticUpdateBundleTestCase, self).__init__(*args, **kwargs) + self._path = tempfile.TemporaryDirectory().name + + def init_fixture(self): + super(AutomaticUpdateBundleTestCase, self).init_fixture() + self._auto_update_bundle_module = AutomaticUpdateBundle( + path=self._path, + filename="open_auction_volume.h5", + rqdata_api=self._mock_get_open_auction_info, + fields=['volume'], + end_date=datetime.date(2024, 2, 28), + ) + trading_dates_mixin = TradingDatesMixin(self.base_data_source.get_trading_calendars()) + self.base_data_source.batch_get_trading_date = trading_dates_mixin.batch_get_trading_date + self.base_data_source.get_next_trading_date = trading_dates_mixin.get_next_trading_date + + def _mock_get_open_auction_info(self, order_book_id, *args, **kwargs): + df = pickle.loads(open( + os.path.join(os.path.dirname(__file__), "mock_data/mock_open_auction_info.pkl"), "rb" + ).read()) + df = df.loc[order_book_id].reset_index() + df['order_book_id'] = order_book_id + df = df.set_index(["order_book_id", "datetime"]) + return df + + def _mock_get_open_auction_volume(self, instrument, dt): + # type: (Instrument, datetime.date) -> float + data = self._auto_update_bundle_module.get_data(instrument, dt) + if data is None: + volume = 0 + else: + volume = 0 if len(data) == 0 else data['volume'] + return volume + + def test_auto_update_bundle(self): + s_volume = self._mock_get_open_auction_volume(self.env.get_instrument("000001.XSHE"), datetime.date(2023, 12, 28)) + f_volume = self._mock_get_open_auction_volume(self.env.get_instrument("A2401"), datetime.date(2023, 12, 28)) + assert os.path.exists(os.path.join(self._path, "open_auction_volume.h5")) == True + + pickle_data = pickle.loads(open( + os.path.join(os.path.dirname(__file__), "mock_data/mock_open_auction_info.pkl"), "rb" + ).read()) + + s_df = pickle_data.loc["000001.XSHE"] + assert s_volume == s_df[s_df.index.date == datetime.date(2023, 12, 28)].volume[0] + f_df = pickle_data.loc['A2401'] + # 期货由于有夜盘,open_auction_info 的时间为前一个交易日的晚上,即从 pickle 文件中获取时,date 应该提前一个交易日 + assert f_volume == f_df[f_df.index.date == datetime.date(2023, 12, 27)].volume[0] +