Skip to content

Commit

Permalink
Merge pull request ricequant#825 from ricequant/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Zhou-JiaJun authored Nov 29, 2023
2 parents 0fd8f89 + adc0d31 commit 3fd540e
Show file tree
Hide file tree
Showing 19 changed files with 94 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
# Checks out a copy of your repository on the ubuntu-latest machine
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Cache bundle
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
CHANGELOG
==================

5.3.3
==================
- 修复平今数量的计算异常

5.3.2
==================
- 修复导出的分析报告出现乱码的异常

5.3.1
==================
- 新增检查基准上市时段是否满足回测时间范围
- 修复分钟回测中挂单在非交易时间内被拒单的异常

5.3.0
==================
- 策略参数配置 extra 下 新增 log_file 用于将日志输出到文件
- 修复期货分钟回测open_auction拿到的最新价有误(signal模式)

5.2.1
==================
- 修复期货分钟回测open_auction拿到的最新价有误
Expand Down
2 changes: 2 additions & 0 deletions rqalpha/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ extra:
is_hold: false
locale: ~
logger: []
# 日志输出文件
log_file: ~
2 changes: 1 addition & 1 deletion rqalpha/data/bar_dict_price_board.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self):

def _get_bar(self, order_book_id):
if ExecutionContext.phase() == EXECUTION_PHASE.OPEN_AUCTION:
return self._env.data_proxy.get_open_auction_bar(order_book_id, self._env.calendar_dt)
return self._env.data_proxy.get_open_auction_bar(order_book_id, self._env.trading_dt)
return self._env.get_bar(order_book_id)

def get_last_price(self, order_book_id):
Expand Down
4 changes: 2 additions & 2 deletions rqalpha/data/bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ def __call__(self, *args, **kwargs):
yield self._step


STOCK_FIELDS = ['open', 'close', 'high', 'low', 'limit_up', 'limit_down', 'volume', 'total_turnover']
INDEX_FIELDS = ['open', 'close', 'high', 'low', 'volume', 'total_turnover']
STOCK_FIELDS = ['open', 'close', 'high', 'low', 'prev_close', 'limit_up', 'limit_down', 'volume', 'total_turnover']
INDEX_FIELDS = ['open', 'close', 'high', 'low', 'prev_close', 'volume', 'total_turnover']
FUTURES_FIELDS = STOCK_FIELDS + ['settlement', 'prev_settlement', 'open_interest']
FUND_FIELDS = STOCK_FIELDS

Expand Down
4 changes: 4 additions & 0 deletions rqalpha/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,7 @@ def set_loggers(config):

for logger_name, level in extra_config.logger:
getattr(logger, logger_name).level = getattr(logbook, level.upper())

if extra_config.log_file:
logbook.FileHandler(filename=extra_config.log_file, mode="a").push_application()

8 changes: 5 additions & 3 deletions rqalpha/mod/rqalpha_mod_sys_accounts/position_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,11 @@ def pnl(self):
# type: () -> float
return super(FuturePosition, self).pnl * self.contract_multiplier

def calc_close_today_amount(self, trade_amount):
close_today_amount = trade_amount - self.old_quantity
return max(close_today_amount, 0)
def calc_close_today_amount(self, trade_amount, position_effect):
if position_effect == POSITION_EFFECT.CLOSE_TODAY:
return trade_amount if trade_amount <= self.today_quantity else self.today_quantity
else:
return max(trade_amount - self._old_quantity, 0)

def apply_trade(self, trade):
if trade.position_effect == POSITION_EFFECT.CLOSE_TODAY:
Expand Down
12 changes: 10 additions & 2 deletions rqalpha/mod/rqalpha_mod_sys_analyser/mod.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,18 @@ def get_benchmark_daily_returns(self):

def _subscribe_events(self, event):
if self._benchmark:
_s = self._env.config.base.start_date
_e = self._env.config.base.end_date
for order_book_id, weight in self._benchmark:
if self._env.data_proxy.instrument(order_book_id) is None:
ins = self._env.data_proxy.instrument(order_book_id)
if ins is None:
raise RuntimeError(
_("benchmark not exists, please entry correct order_book_id").format(order_book_id)
_("benchmark {} not exists, please entry correct order_book_id").format(order_book_id)
)
if ins.listed_date.date() > _s or ins.de_listed_date.date() <= _e:
raise RuntimeError(
_("benchmark {} listed date {} > backtest start date {} or de_listed date {} <= backtest end "
"date {}").format(order_book_id, ins.listed_date.date(), _s, ins.de_listed_date.date(), _e)
)

self._env.event_bus.add_listener(EVENT.TRADE, self._collect_trade)
Expand Down
14 changes: 5 additions & 9 deletions rqalpha/mod/rqalpha_mod_sys_analyser/report/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from typing import Dict, Optional

import numpy
import pandas
from collections import ChainMap
from pandas import Series, DataFrame

Expand Down Expand Up @@ -152,16 +153,11 @@ def generate_report(result_dict, output_path):
df["date"] = df["date"].apply(lambda x: x.strftime("%Y-%m-%d"))
df = df.set_index("date")

csv_txt = StringIO()
try:
csv_txt.write(df.to_csv(encoding='utf-8', lineterminator='\n'))
except TypeError as e:
if pandas.__version__ >= '1.5.0':
df.to_csv("{}/{}.csv".format(output_path, name), encoding='utf-8-sig', lineterminator='\n')
else:
# pandas 1.5.0 以下是 line_terminator
csv_txt.write(df.to_csv(encoding='utf-8', line_terminator='\n'))

with open(os.path.join(output_path, "{}.csv".format(name)), 'w') as csvfile:
csvfile.write(csv_txt.getvalue())

df.to_csv("{}/{}.csv".format(output_path, name), encoding='utf-8-sig', line_terminator='\n')

if __name__ == "__main__":
import pickle
Expand Down
15 changes: 9 additions & 6 deletions rqalpha/mod/rqalpha_mod_sys_simulation/matcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,12 @@ def match(self, account, order, open_auction):
elif isinstance(order.style, ALGO_ORDER_STYLES):
reason = _(u"Order Cancelled: {order_book_id} bar no volume").format(order_book_id=order.order_book_id)
else:
reason = _(u"Order Cancelled: current bar [{order_book_id}] miss market data.").format(
order_book_id=order.order_book_id)
order.mark_rejected(reason)
# 撮合的时候无行情数据也不需要撤单,等到有行情再撮合
reason = None
# reason = _(u"Order Cancelled: current bar [{order_book_id}] miss market data.").format(
# order_book_id=order.order_book_id)
if reason:
order.mark_rejected(reason)
return

price_board = self._env.price_board
Expand Down Expand Up @@ -186,7 +189,7 @@ def match(self, account, order, open_auction):
else:
fill = order.unfilled_quantity

ct_amount = account.calc_close_today_amount(order_book_id, fill, order.position_direction)
ct_amount = account.calc_close_today_amount(order_book_id, fill, order.position_direction, order.position_effect)

if open_auction:
price = deal_price
Expand Down Expand Up @@ -429,7 +432,7 @@ def match(self, account, order, open_auction): # type: (Account, Order, bool) -
fill = order.unfilled_quantity

# 平今的数量
ct_amount = account.calc_close_today_amount(order_book_id, fill, order.position_direction)
ct_amount = account.calc_close_today_amount(order_book_id, fill, order.position_direction, order.position_effect)

# 对价格进行滑点处理
if instrument.during_call_auction(self._env.calendar_dt):
Expand Down Expand Up @@ -579,7 +582,7 @@ def match(self, account, order, open_auction):
else:
fill = min(order.unfilled_quantity, amount)

ct_amount = account.calc_close_today_amount(order_book_id, fill, order.position_direction)
ct_amount = account.calc_close_today_amount(order_book_id, fill, order.position_direction, order.position_effect)

trade = Trade.__from_create__(
order_id=order.order_id,
Expand Down
2 changes: 1 addition & 1 deletion rqalpha/mod/rqalpha_mod_sys_simulation/signal_broker.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def _match(self, account, order):
))
return

ct_amount = account.calc_close_today_amount(order_book_id, order.quantity, order.position_direction)
ct_amount = account.calc_close_today_amount(order_book_id, order.quantity, order.position_direction, order.position_effect)
trade_price = self._slippage_decider.get_trade_price(order, deal_price)
trade = Trade.__from_create__(
order_id=order.order_id,
Expand Down
14 changes: 6 additions & 8 deletions rqalpha/mod/rqalpha_mod_sys_simulation/simulation_broker.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def submit_order(self, order):
order.active()
self._env.event_bus.publish_event(Event(EVENT.ORDER_CREATION_PASS, account=account, order=order))
if self._match_immediately:
self._match(self._env.calendar_dt)
self._match()

def cancel_order(self, order):
account = self._env.get_account(order.order_book_id)
Expand Down Expand Up @@ -158,19 +158,17 @@ def pre_settlement(self, __):
def on_bar(self, event):
for matcher in self._matchers.values():
matcher.update(event)
self._match(event.calendar_dt)
self._match()

def on_tick(self, event):
tick = event.tick
self._get_matcher(tick.order_book_id).update(event)
self._match(event.calendar_dt, tick.order_book_id)
self._match(tick.order_book_id)

def _match(self, dt, order_book_id=None):
def _match(self, order_book_id=None):
# 撮合未完成的订单,若指定标的时只撮合指定的标的的订单
order_filter = lambda a_and_o: (not a_and_o[1].is_final()) and (True if order_book_id is None else a_and_o[1].order_book_id == order_book_id)
# + 需要在交易时段内
open_order_filter = lambda a_and_o: order_filter(a_and_o) and self._env.data_proxy.instrument(a_and_o[1].order_book_id).during_continuous_auction(dt.time())
for account, order in filter(open_order_filter, self._open_orders):
order_filter = lambda a_and_o: not (a_and_o[1].is_final() or (order_book_id and a_and_o[1].order_book_id != order_book_id))
for account, order in filter(order_filter, self._open_orders):
self._get_matcher(order.order_book_id).match(account, order, open_auction=False)
for account, order in filter(order_filter, self._open_auction_orders):
self._get_matcher(order.order_book_id).match(account, order, open_auction=True)
Expand Down
4 changes: 2 additions & 2 deletions rqalpha/portfolio/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ def get_position(self, order_book_id: str, direction: POSITION_DIRECTION = POSIT
except KeyError:
return Position(order_book_id, direction)

def calc_close_today_amount(self, order_book_id, trade_amount, position_direction):
return self._get_or_create_pos(order_book_id, position_direction).calc_close_today_amount(trade_amount)
def calc_close_today_amount(self, order_book_id, trade_amount, position_direction, position_effect):
return self._get_or_create_pos(order_book_id, position_direction).calc_close_today_amount(trade_amount, position_effect)

@property
def type(self):
Expand Down
2 changes: 1 addition & 1 deletion rqalpha/portfolio/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def settlement(self, trading_date):
def update_last_price(self, price):
self._last_price = price

def calc_close_today_amount(self, trade_amount):
def calc_close_today_amount(self, trade_amount, position_effect):
return 0

@property
Expand Down
Binary file modified rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.mo
Binary file not shown.
7 changes: 5 additions & 2 deletions rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,11 @@ msgstr "Bundle日线数据不完整,请及时更新bundle"
msgid "good bundle's day bar"
msgstr "Bundle日线数据良好"

msgid "benchmark not exists, please entry correct order_book_id"
msgstr "当前使用的基准合约信息不存在,请输入正确的合约"
msgid "benchmark {} not exists, please entry correct order_book_id"
msgstr "基准标的({})信息不存在,请输入正确的标的代码"

msgid "benchmark {} listed date {} > backtest start date {} or de_listed date {} <= backtest end date {}"
msgstr "基准标的({})上市日期({})晚于回测起始日期({})或退市日期({})早于回测结束日期({})"

#: rqalpha/cmds/bundle.py:105
msgid ""
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

[metadata]
name = rqalpha
version = 5.2.1
version = 5.3.3

[versioneer]
VCS = git
Expand Down
21 changes: 21 additions & 0 deletions tests/api_tests/mod/sys_simulation/test_signal_broker.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"frequency": "1d",
"accounts": {
"stock": 1000000,
"future": 1000000
}
},
"extra": {
Expand Down Expand Up @@ -53,3 +54,23 @@ def handle_bar(context, bar_dict):
assert get_position(stock).avg_price == price

return locals()


def test_signal_open_auction():

def init(context):
context.fixed = True

def open_auction(context, bar_dict):
if context.fixed:
order_shares("000001.XSHE", 1000)
buy_open("AU1512", 1)
pos = get_position("000001.XSHE")
assert pos.quantity == 1000
assert pos.avg_price == 18.0
pos = get_position("AU1512")
assert pos.quantity == 1
assert pos.avg_price == 242.2
context.fixed = False

return locals()
Binary file modified tests/outs/test_f_mean_reverting.pkl
Binary file not shown.

0 comments on commit 3fd540e

Please sign in to comment.