Skip to content

Commit

Permalink
期货历史交易参数迁移至mod-ricequant-data (#882)
Browse files Browse the repository at this point in the history
* 修复增量回测出错问题

* in development

* futures_trading_parameters迁移至mod-ricequant-data

* update requirements

* update

* future_info数值调整,需更新

---------

Co-authored-by: Cuizi7 <Cuizi7@users.noreply.github.com>
  • Loading branch information
Lin-Dongzhao and Cuizi7 committed May 14, 2024
1 parent 5bc7ba8 commit 02e57aa
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 323 deletions.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ simplejson >=3.10.0
dill ==0.2.5
PyYAML >=3.12
tabulate
rqrisk >=1.0.8
rqrisk >=1.0.9
h5py
matplotlib >=1.5.1 ; python_version >= '3.6'
matplotlib >=1.5.1,<=3.0.3 ; python_version == '3.5'
filelock
37 changes: 6 additions & 31 deletions rqalpha/data/base_data_source/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,21 @@
import pandas as pd
import six
from rqalpha.utils.i18n import gettext as _
from rqalpha.const import INSTRUMENT_TYPE, TRADING_CALENDAR_TYPE, DEFAULT_ACCOUNT_TYPE
from rqalpha.const import INSTRUMENT_TYPE, TRADING_CALENDAR_TYPE
from rqalpha.interface import AbstractDataSource
from rqalpha.model.instrument import Instrument
from rqalpha.utils.datetime_func import (convert_date_to_int, convert_int_to_date, convert_int_to_datetime)
from rqalpha.utils.exception import RQInvalidArgument, RQDatacVersionTooLow
from rqalpha.utils.exception import RQInvalidArgument
from rqalpha.utils.functools import lru_cache
from rqalpha.utils.typing import DateLike
from rqalpha.environment import Environment
from rqalpha.data.bundle import update_futures_trading_parameters
from rqalpha.utils.logger import user_system_log
from rqalpha.data.base_data_source.adjust import FIELDS_REQUIRE_ADJUSTMENT, adjust_bars
from rqalpha.data.base_data_source.storage_interface import (AbstractCalendarStore, AbstractDateSet,
AbstractDayBarStore, AbstractDividendStore,
AbstractInstrumentStore)
from rqalpha.data.base_data_source.storages import (DateSet, DayBarStore, DividendStore,
ExchangeTradingCalendarStore, FutureDayBarStore,
FutureInfoStore, FuturesTradingParametersStore,InstrumentStore,
FutureInfoStore,InstrumentStore,
ShareTransformationStore, SimpleFactorStore,
YieldCurveStore, FuturesTradingParameters)

Expand Down Expand Up @@ -72,8 +70,7 @@ class BaseDataSource(AbstractDataSource):
INSTRUMENT_TYPE.PUBLIC_FUND,
)

def __init__(self, path, custom_future_info, futures_time_series_trading_parameters=False, end_date=None):
# type: (str, dict, bool, date) -> None
def __init__(self, path: str, custom_future_info: dict, *args, **kwargs) -> None:
if not os.path.exists(path):
raise RuntimeError('bundle path {} not exist'.format(os.path.abspath(path)))

Expand All @@ -89,7 +86,6 @@ def _p(name):
INSTRUMENT_TYPE.LOF: funds_day_bar_store
} # type: Dict[INSTRUMENT_TYPE, AbstractDayBarStore]

self._futures_trading_parameters_store = None
self._future_info_store = FutureInfoStore(_p("future_info.json"), custom_future_info)

self._instruments_stores = {} # type: Dict[INSTRUMENT_TYPE, AbstractInstrumentStore]
Expand Down Expand Up @@ -133,20 +129,6 @@ def _p(name):
self._suspend_days = [DateSet(_p('suspended_days.h5'))] # type: List[AbstractDateSet]
self._st_stock_days = DateSet(_p('st_stock_days.h5'))

if futures_time_series_trading_parameters:
try:
import rqdatac
except ImportError:
user_system_log.warn(_("RQDatac is not installed, \"config.base.futures_time_series_trading_parameters\" will be disabled."))
else:
try:
update_futures_trading_parameters(path, end_date)
except (rqdatac.share.errors.PermissionDenied, RQDatacVersionTooLow):
user_system_log.warn(_("RQDatac does not have permission to obtain futures histrical trading parameters, \"config.base.futures_time_series_trading_parameters\" will be disabled."))
else:
file = os.path.join(path, "futures_trading_parameters.h5")
self._futures_trading_parameters_store = FuturesTradingParametersStore(file, custom_future_info)

def register_day_bar_store(self, instrument_type, store):
# type: (INSTRUMENT_TYPE, AbstractDayBarStore) -> None
self._day_bars[instrument_type] = store
Expand Down Expand Up @@ -382,15 +364,8 @@ def get_yield_curve(self, start_date, end_date, tenor=None):
return self._yield_curve.get_yield_curve(start_date, end_date, tenor=tenor)

@lru_cache(1024)
def get_futures_trading_parameters(self, instrument, dt):
# type: (Instrument, datetime.date) -> FuturesTradingParameters
if self._futures_trading_parameters_store:
trading_parameters = self._futures_trading_parameters_store.get_futures_trading_parameters(instrument, dt)
if trading_parameters is None:
return self._future_info_store.get_future_info(instrument.order_book_id, instrument.underlying_symbol)
return trading_parameters
else:
return self._future_info_store.get_future_info(instrument.order_book_id, instrument.underlying_symbol)
def get_futures_trading_parameters(self, instrument: Instrument, dt: datetime.date) -> FuturesTradingParameters:
return self._future_info_store.get_future_info(instrument.order_book_id, instrument.underlying_symbol)

def get_merge_ticks(self, order_book_id_list, trading_date, last_dt=None):
raise NotImplementedError
Expand Down
68 changes: 1 addition & 67 deletions rqalpha/data/base_data_source/storages.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self, f, custom_future_info):
}
self._custom_data = custom_future_info
if "margin_rate" not in self._default_data[next(iter(self._default_data))]:
raise RuntimeError(_("Your bundle data is too old, please use 'rqalpha update-bundle' or 'rqalpha download-bundle' to update it to lastest before using"))
raise RuntimeError(_("The bundle data you are using is too old, please update it to lastest before using"))

@classmethod
def _process_future_info_item(cls, item):
Expand Down Expand Up @@ -247,72 +247,6 @@ class FutureDayBarStore(DayBarStore):
DEFAULT_DTYPE = np.dtype(DayBarStore.DEFAULT_DTYPE.descr + [("open_interest", '<f8')])


class FuturesTradingParametersStore(object):
COMMISSION_TYPE_MAP = {
0: COMMISSION_TYPE.BY_MONEY,
1: COMMISSION_TYPE.BY_VOLUME
}

# 历史期货交易参数的数据在2010年4月之后才有
FUTURES_TRADING_PARAMETERS_START_DATE = 20100401

def __init__(self, path, custom_future_info):
self._path = path
self._custom_data = custom_future_info

def get_futures_trading_parameters(self, instrument, dt):
# type: (Instrument, datetime.date) -> FuturesTradingParameters or None
dt = convert_date_to_date_int(dt)
if dt < self.FUTURES_TRADING_PARAMETERS_START_DATE:
return None
order_book_id = instrument.order_book_id
underlying_symbol = instrument.underlying_symbol
data = self.get_futures_trading_parameters_all_time(order_book_id)
if data is None:
return None
else:
arr = data[data['datetime'] == dt]
if len(arr) == 0:
if dt >= convert_date_to_date_int(instrument.listed_date) and dt <= convert_date_to_date_int(instrument.de_listed_date):
user_system_log.info("Historical futures trading parameters are abnormal, the lastst parameters will be used for calculations.\nPlease contract RiceQuant to repair: 0755-26569969")
return None
custom_info = self._custom_data.get(order_book_id) or self._custom_data.get(underlying_symbol)
if custom_info:
arr[0] = self.set_custom_info(arr[0], custom_info)
futures_trading_parameters = self._to_namedtuple(arr[0])
return futures_trading_parameters

@lru_cache(1024)
def get_futures_trading_parameters_all_time(self, order_book_id):
# type: (str) -> numpy.ndarray or None
with h5_file(self._path) as h5:
try:
data = h5[order_book_id][:]
except KeyError:
return None
return data

def set_custom_info(self, arr, custom_info):
for field in custom_info:
if field == "commission_type":
if custom_info[field] == COMMISSION_TYPE.BY_MONEY:
value = 0
elif custom_info[field] == COMMISSION_TYPE.BY_VOLUME:
value = 1
else:
value = custom_info[field]
arr[field] = value
return arr

def _to_namedtuple(self, arr):
# type: (numpy.void) -> FuturesTradingParameters
dic = dict(zip(arr.dtype.names, arr))
del dic['datetime']
dic["commission_type"] = self.COMMISSION_TYPE_MAP[dic['commission_type']]
futures_trading_parameters = FuturesTradingParameters(**dic)
return futures_trading_parameters


class DividendStore(AbstractDividendStore):
def __init__(self, path):
self._path = path
Expand Down

0 comments on commit 02e57aa

Please sign in to comment.