Skip to content

Commit

Permalink
pr update
Browse files Browse the repository at this point in the history
  • Loading branch information
Lin-Dongzhao committed Jan 2, 2024
1 parent 8ed7285 commit 4d1da10
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 185 deletions.
13 changes: 6 additions & 7 deletions rqalpha/data/base_data_source/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class BaseDataSource(AbstractDataSource):
INSTRUMENT_TYPE.PUBLIC_FUND,
)

def __init__(self, path, custom_future_info, trading_parameters_update_args):
def __init__(self, path, custom_future_info, update_parameters_end_date=None):
if not os.path.exists(path):
raise RuntimeError('bundle path {} not exist'.format(os.path.abspath(path)))

Expand All @@ -89,8 +89,8 @@ def _p(name):
} # type: Dict[INSTRUMENT_TYPE, AbstractDayBarStore]

self._futures_trading_parameters_store = None
if trading_parameters_update_args:
if update_futures_trading_parameters(path, trading_parameters_update_args):
if update_parameters_end_date:
if update_futures_trading_parameters(path, update_parameters_end_date):
self._futures_trading_parameters_store = FuturesTradingParametersStore(_p("futures_trading_parameters.h5"))
self._future_info_store = FutureInfoStore(_p("future_info.json"), custom_future_info)

Expand All @@ -110,9 +110,7 @@ def _p(name):
))
for ins_type in self.DEFAULT_INS_TYPES:
self.register_instruments_store(InstrumentStore(instruments, ins_type))

if "margin_rate" not in self._future_info_store._default_data[list(self._future_info_store._default_data.keys())[0]]:
self._future_info_store.data_compatible(self._instruments_stores[INSTRUMENT_TYPE.FUTURE])
self._future_info_store.data_compatible(self._instruments_stores[INSTRUMENT_TYPE.FUTURE])
dividend_store = DividendStore(_p('dividends.h5'))
self._dividends = {
INSTRUMENT_TYPE.CS: dividend_store,
Expand Down Expand Up @@ -373,9 +371,10 @@ def get_yield_curve(self, start_date, end_date, tenor=None):
return self._yield_curve.get_yield_curve(start_date, end_date, tenor=tenor)

def get_futures_trading_parameters(self, instrument, dt):
# type: (Instrument, datetime.datetime) -> FuturesTradingParameters
if self._futures_trading_parameters_store:
trading_parameters = self._futures_trading_parameters_store.get_futures_trading_parameters(instrument, dt)
if trading_parameters == None:
if trading_parameters is None:
return self._future_info_store.get_future_info(instrument)
return trading_parameters
else:
Expand Down
158 changes: 88 additions & 70 deletions rqalpha/data/base_data_source/storages.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,38 @@
from copy import copy
from itertools import chain
from contextlib import contextmanager
from typing import Dict, Iterable, Optional
from typing import Dict, Iterable, Optional, NamedTuple

import h5py
import numpy as np
import pandas
from methodtools import lru_cache
import collections

from rqalpha.const import COMMISSION_TYPE, INSTRUMENT_TYPE
from rqalpha.model.instrument import Instrument
from rqalpha.utils.datetime_func import convert_date_to_date_int
from rqalpha.utils.i18n import gettext as _
from rqalpha.utils.logger import system_log

from .storage_interface import (AbstractCalendarStore, AbstractDateSet,
AbstractDayBarStore, AbstractDividendStore,
AbstractInstrumentStore,
AbstractSimpleFactorStore)

class FuturesTradingParameters(NamedTuple):
"""
数据类,用以存储期货交易参数数据
"""
close_commission_ratio: float
close_commission_today_ratio: float
commission_type: str
open_commission_ratio: float
long_margin_ratio: float
short_margin_ratio: float
order_book_id: str = None
underlying_symbol: str = None
tick_size: float = None


class ExchangeTradingCalendarStore(AbstractCalendarStore):
def __init__(self, f):
Expand All @@ -57,18 +71,6 @@ class FutureInfoStore(object):
"by_money": COMMISSION_TYPE.BY_MONEY
}

FuturesInfo = collections.namedtuple("FuturesInfo", [
"order_book_id",
"underlying_symbol",
"close_commission_ratio",
"close_commission_today_ratio",
"commission_type",
"open_commission_ratio",
"long_margin_ratio",
"short_margin_ratio",
"tick_size"
])

def __init__(self, f, custom_future_info):
with open(f, "r") as json_file:
self._default_data = {
Expand All @@ -77,22 +79,22 @@ def __init__(self, f, custom_future_info):
) for item in json.load(json_file)
}
self._custom_data = custom_future_info
self._future_info = {}

def data_compatible(self, futures_instruments_store):
"""
RQAlpha==5.3.5 后, margin_rate调整为从 future_info.json 获取,当用户的 bundle 数据未更新时,调用该函数进行兼容
"""
hard_code = {"TC": 0.05, "ER": 0.05, "WS": 0.05, "RO": 0.05, "ME": 0.06, "WT": 0.05}
for id_or_syms in list(self._default_data.keys()):
if len(id_or_syms) <= 2:
if id_or_syms in hard_code.keys():
self._default_data[id_or_syms]["margin_rate"] = hard_code[id_or_syms]
if "margin_rate" not in self._default_data[list(hard_code.keys())[0]]:
for id_or_syms in list(self._default_data.keys()):
if len(id_or_syms) <= 2:
if id_or_syms in hard_code.keys():
self._default_data[id_or_syms]["margin_rate"] = hard_code[id_or_syms]
else:
order_book_id = futures_instruments_store._instruments[id_or_syms + "88"].trading_code
self._default_data[id_or_syms]["margin_rate"] = futures_instruments_store._instruments[order_book_id].margin_rate
else:
order_book_id = futures_instruments_store._instruments[id_or_syms + "88"].trading_code
self._default_data[id_or_syms]["margin_rate"] = futures_instruments_store._instruments[order_book_id].margin_rate
else:
self._default_data[id_or_syms]["margin_rate"] = futures_instruments_store._instruments[id_or_syms].margin_rate
self._default_data[id_or_syms]["margin_rate"] = futures_instruments_store._instruments[id_or_syms].margin_rate

@classmethod
def _process_future_info_item(cls, item):
Expand All @@ -109,19 +111,34 @@ def get_future_info(self, instrument):
info.update(custom_info)
elif not info:
raise NotImplementedError(_("unsupported future instrument {}").format(order_book_id))
info = self.to_namedtuple(info)
info = self._to_namedtuple(info)
return info

def to_namedtuple(self, info):
def _to_namedtuple(self, info):
if info.get("order_book_id"):
info_data_list = [info["order_book_id"], None]
order_book_id = info['order_book_id']
underlying_symbol = None
else:
info_data_list = [None, info["underlying_symbol"]]
for field in self.FuturesInfo._fields:
if (field in ["order_book_id", "underlying_symbol"]): continue
if (field in ["long_margin_ratio", "short_margin_ratio"]): field = "margin_rate"
info_data_list.append(info[field])
info = self.FuturesInfo._make(info_data_list)
order_book_id = None
underlying_symbol = info['underlying_symbol']
close_commission_ratio = info['close_commission_ratio']
close_commission_today_ratio = info['close_commission_today_ratio']
commission_type = info['commission_type']
open_commission_ratio = info['open_commission_ratio']
long_margin_ratio = info['margin_rate']
short_margin_ratio = info['margin_rate']
tick_size = info['tick_size']
info = FuturesTradingParameters(
close_commission_ratio,
close_commission_today_ratio,
commission_type,
open_commission_ratio,
long_margin_ratio,
short_margin_ratio,
order_book_id,
underlying_symbol,
tick_size
)
return info


Expand Down Expand Up @@ -252,58 +269,59 @@ class FuturesTradingParametersStore(object):
1: COMMISSION_TYPE.BY_VOLUME
}

FuturesTradingParameters = collections.namedtuple("FuturesTradingParameters", [
"order_book_id",
"commission_type",
"long_margin_ratio",
"short_margin_ratio",
"close_commission_ratio",
"close_commission_today_ratio",
"open_commission_ratio"
])

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

def __init__(self, path):
self._path = path
self._order_book_id = None
self.futures_trading_parameters = None
self.arr = None

@lru_cache(1024)
def get_futures_trading_parameters(self, instrument, dt):
# type: (Instrument, datetime.datetime) -> FuturesTradingParameters
dt = convert_date_to_date_int(dt)
if dt < self.FUTURES_TRADING_PARAMETERS_START_DATE:
return None
self._order_book_id = instrument.order_book_id
dt = dt * 1000000
with h5_file(self._path) as h5:
data = h5[self._order_book_id][:]
self.arr = data[data['datetime'] == dt]
if len(self.arr) == 0:
if dt in range(
convert_date_to_date_int(instrument.listed_date),
convert_date_to_date_int(instrument.de_listed_date)
):
raise
order_book_id = instrument.order_book_id
data = self.get_futures_trading_parameters_all_time(order_book_id)
if data is None:
return None
else:
arr = data[data['datetime'] == dt * 1000000]
if len(arr) == 0:
if str(dt) < instrument.listed_date.strftime("%Y%m%d") or str(dt) > instrument.de_listed_date.strftime("%Y%m%d"):
return None
else:
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
self.to_namedtuple()
return self.futures_trading_parameters
futures_trading_parameters = self._to_namedtuple(order_book_id, arr)
return futures_trading_parameters

@lru_cache(1024)
def get_futures_trading_parameters_all_time(self, order_book_id):
with h5_file(self._path) as h5:
try:
data = h5[order_book_id][:]
except KeyError:
return None
return data

def to_namedtuple(self):
parameter_data_list = []
for field in self.FuturesTradingParameters._fields:
if field == "order_book_id":
parameter_data = self._order_book_id
elif field == "commission_type":
parameter_data = self.COMMISSION_TYPE_MAP[int(self.arr[field][0])]
else:
parameter_data = float(self.arr[field][0])
parameter_data_list.append(parameter_data)
self.futures_trading_parameters = self.FuturesTradingParameters._make(parameter_data_list)
def _to_namedtuple(self, order_book_id, arr):
close_commission_ratio = float(arr["close_commission"][0])
close_commission_today_ratio = float(arr['close_commission_today'][0])
commission_type = self.COMMISSION_TYPE_MAP[int(arr['commission_type'][0])]
open_commission_ratio = float(arr['open_commission'][0])
long_margin_ratio = float(arr["long_margin_ratio"][0])
short_margin_ratio = float(arr["short_margin_ratio"][0])

futures_trading_parameters = FuturesTradingParameters(
close_commission_ratio,
close_commission_today_ratio,
commission_type,
open_commission_ratio,
long_margin_ratio,
short_margin_ratio,
order_book_id
)
return futures_trading_parameters


class DividendStore(AbstractDividendStore):
Expand Down
Loading

0 comments on commit 4d1da10

Please sign in to comment.