Skip to content

Commit

Permalink
Merge 25260b7 into 8718fa2
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhou-JiaJun committed May 30, 2023
2 parents 8718fa2 + 25260b7 commit df6a794
Show file tree
Hide file tree
Showing 19 changed files with 473 additions and 196 deletions.
56 changes: 56 additions & 0 deletions docs/source/api/base_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,56 @@ after_trading - 盘后
交易接口
=================

OrderStyle - 订单类型
------------------------------------------------------

该类型可供后续下单接口中 price_or_style 参数使用

.. module:: rqalpha.model.order

.. _order_style:

.. autoclass:: MarketOrder

.. code-block:: python
order_shares("000001.XSHE", amount=100, price_or_style=MarketOrder())
市价单

.. autoclass:: LimitOrder

:param float limit_price: 价格

.. code-block:: python
order_shares("000001.XSHE", amount=100, price_or_style=LimitOrder(10))
限价单

.. autoclass:: TWAPOrder

:param int start_min: 分钟起始时间
:param int end_min: 分钟结束时间

.. code-block:: python
order_shares("000001.XSHE", amount=100, price_or_style=TWAPOrder(931, 945))
算法时间加权价格订单

.. autoclass:: VWAPOrder

:param int start_min: 分钟起始时间
:param int end_min: 分钟结束时间

.. code-block:: python
order_shares("000001.XSHE", amount=100, price_or_style=VWAPOrder(931, 945))
算法成交量加权价格订单

.. module:: rqalpha.api

submit_order - 自由参数下单「通用」
Expand Down Expand Up @@ -651,6 +701,8 @@ Order - 订单
------------------------------------------------------
.. module:: rqalpha.model.order

.. _order:

.. autoclass:: Order
:members:
:show-inheritance:
Expand Down Expand Up @@ -878,6 +930,10 @@ ORDER_TYPE - 订单类型
限价单

.. py:attribute:: ALGO
算法单


ORDER_STATUS - 订单状态
------------------------------------------------------
Expand Down
145 changes: 106 additions & 39 deletions rqalpha/apis/api_abstract.py

Large diffs are not rendered by default.

44 changes: 29 additions & 15 deletions rqalpha/apis/api_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,40 @@ def assure_order_book_id(id_or_ins):
return assure_instrument(id_or_ins).order_book_id


def cal_style(price, style):
if price is None and style is None:
def cal_style(price, style, price_or_style=None):
if price_or_style is None:
if price:
price_or_style = price
if style:
price_or_style = style

if price_or_style is None:
return MarketOrder()

if style is not None:
if not isinstance(style, OrderStyle):
raise RuntimeError
return style
if not isinstance(price_or_style, (int, float, OrderStyle)):
raise RQInvalidArgument(f"price or style or price_or_style type no support. {price_or_style}")

if isinstance(price, OrderStyle):
# 为了 order_xxx('RB1710', 10, MarketOrder()) 这种写法
if isinstance(price, LimitOrder):
if np.isnan(price.get_limit_price()):
raise RQInvalidArgument(_(u"Limit order price should not be nan."))
return price
if isinstance(price_or_style, OrderStyle):
return price_or_style

if np.isnan(price):
raise RQInvalidArgument(_(u"Limit order price should not be nan."))
return LimitOrder(price_or_style)

return LimitOrder(price)

def calc_open_close_style(price, style, price_or_style):
if isinstance(price_or_style, tuple):
_length = len(price_or_style)
if _length == 0:
o, c = None, None
elif _length == 1:
o, c = price_or_style[0], price_or_style[0]
else:
o, c = price_or_style[0], price_or_style[1]
open_style = cal_style(price, style, o)
close_style = cal_style(price, style, c)
else:
open_style = cal_style(price, style, price_or_style)
close_style = open_style
return open_style, close_style


@export_as_api
Expand Down
6 changes: 6 additions & 0 deletions rqalpha/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ class MATCHING_TYPE(CustomEnum):
class ORDER_TYPE(CustomEnum):
MARKET = "MARKET"
LIMIT = "LIMIT"
ALGO = "ALGO"


class ALGO(CustomEnum):
TWAP = "TWAP"
VWAP = "VWAP"


# noinspection PyPep8Naming
Expand Down
3 changes: 3 additions & 0 deletions rqalpha/data/base_data_source/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,6 @@ def get_merge_ticks(self, order_book_id_list, trading_date, last_dt=None):

def history_ticks(self, instrument, count, dt):
raise NotImplementedError

def get_algo_bar(self, id_or_ins, start_min, end_min, dt):
raise NotImplementedError("open source rqalpha not support algo order")
22 changes: 18 additions & 4 deletions rqalpha/data/data_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# 详细的授权流程,请联系 public@ricequant.com 获取。

from datetime import datetime, date
from typing import Union, List, Sequence, Optional
from typing import Union, List, Sequence, Optional, Tuple

import six
import numpy as np
Expand All @@ -28,6 +28,7 @@
from rqalpha.model.bar import BarObject, NANDict, PartialBarObject
from rqalpha.model.tick import TickObject
from rqalpha.model.instrument import Instrument
from rqalpha.model.order import TWAPOrder, VWAPOrder, ALGO_ORDER_STYLES
from rqalpha.utils.functools import lru_cache
from rqalpha.utils.datetime_func import convert_int_to_datetime, convert_date_to_int
from rqalpha.utils.typing import DateLike, StrOrIter
Expand Down Expand Up @@ -130,9 +131,9 @@ def get_prev_close(self, order_book_id, dt):

@lru_cache(10240)
def _get_prev_settlement(self, instrument, dt):
prev_trading_date = self.get_previous_trading_date(dt)
bar = self._data_source.history_bars(instrument, 1, '1d', 'settlement', prev_trading_date,
skip_suspended=False, adjust_orig=dt)
bar = self._data_source.history_bars(
instrument, 1, '1d', fields='prev_settlement', dt=dt, skip_suspended=False, adjust_orig=dt
)
if bar is None or len(bar) == 0:
return np.nan
return bar[0]
Expand Down Expand Up @@ -303,3 +304,16 @@ def get_trading_period(self, sym_or_ids, default_trading_period=None):
def is_night_trading(self, sym_or_ids):
# type: (StrOrIter) -> bool
return any((instrument.trade_at_night for instrument in self.instruments(sym_or_ids)))

def get_algo_bar(self, id_or_ins, order_style, dt):
# type: (Union[str, Instrument], Union[*ALGO_ORDER_STYLES], datetime) -> Tuple[float, int]
if not isinstance(order_style, ALGO_ORDER_STYLES):
raise RuntimeError("get_algo_bar only support VWAPOrder and TWAPOrder")
if not isinstance(id_or_ins, Instrument):
id_or_ins = self.instrument(id_or_ins)
if id_or_ins is None:
return np.nan, 0
bar = self._data_source.get_algo_bar(id_or_ins, order_style.start_min, order_style.end_min, dt)
return (bar[order_style.TYPE], bar["volume"]) if bar else (np.nan, 0)


5 changes: 5 additions & 0 deletions rqalpha/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ def is_st_stock(self, order_book_id, dates):
# type: (str, Sequence[DateLike]) -> Sequence[bool]
raise NotImplementedError

def get_algo_bar(self, id_or_ins, start_min, end_min, dt):
# type: (Union[str, Instrument], int, int, datetime) -> Optional[numpy.void]
# 格式: (date, VWAP, TWAP, volume) -> 案例 (20200102, 16.79877183, 16.83271429, 144356044)
raise NotImplementedError


class AbstractBroker(with_metaclass(abc.ABCMeta)):
"""
Expand Down
42 changes: 20 additions & 22 deletions rqalpha/mod/rqalpha_mod_sys_accounts/api/api_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
from __future__ import division
from typing import Union, Optional, List

import numpy as np

from rqalpha.api import export_as_api
from rqalpha.apis.api_base import assure_instrument
from rqalpha.apis.api_abstract import order, order_to, buy_open, buy_close, sell_open, sell_close
from rqalpha.apis.api_base import cal_style
from rqalpha.apis.api_rqdatac import futures
from rqalpha.environment import Environment
from rqalpha.model.order import Order, LimitOrder, OrderStyle
from rqalpha.model.order import Order, LimitOrder, OrderStyle, ALGO_ORDER_STYLES
from rqalpha.const import SIDE, POSITION_EFFECT, ORDER_TYPE, RUN_TYPE, INSTRUMENT_TYPE, POSITION_DIRECTION
from rqalpha.model.instrument import Instrument
from rqalpha.portfolio.position import Position
Expand All @@ -35,8 +37,7 @@
from rqalpha.utils.arg_checker import apply_rules, verify_that


__all__ = [
]
__all__ = []


def _submit_order(id_or_ins, amount, side, position_effect, style):
Expand All @@ -50,9 +51,8 @@ def _submit_order(id_or_ins, amount, side, position_effect, style):
u"Order Creation Failed: 0 order quantity, order_book_id={order_book_id}"
).format(order_book_id=order_book_id))
return None
if isinstance(style, LimitOrder) and style.get_limit_price() <= 0:
raise RQInvalidArgument(_(u"Limit order price should be positive"))

if isinstance(style, LimitOrder) and np.isnan(style.get_limit_price()):
raise RQInvalidArgument(_(u"Limit order price should not be nan."))

if env.config.base.run_type != RUN_TYPE.BACKTEST and instrument.type == INSTRUMENT_TYPE.FUTURE:
if "88" in order_book_id:
Expand Down Expand Up @@ -121,8 +121,6 @@ def _submit_order(id_or_ins, amount, side, position_effect, style):
)

for o in orders:
if o.type == ORDER_TYPE.MARKET:
o.set_frozen_price(price)
if env.can_submit_order(o):
env.broker.submit_order(o)
else:
Expand Down Expand Up @@ -176,37 +174,37 @@ def _order(order_book_id, quantity, style, target):


@order.register(INSTRUMENT_TYPE.FUTURE)
def future_order(order_book_id, quantity, price=None, style=None):
# type: (Union[str, Instrument], int, Optional[float], Optional[OrderStyle]) -> List[Order]
return _order(order_book_id, quantity, cal_style(price, style), False)
def future_order(order_book_id, quantity, price=None, style=None, price_or_style=None):
# type: (Union[str, Instrument], int, Optional[float], Optional[OrderStyle], Optional[Union[float, OrderStyle]]) -> List[Order]
return _order(order_book_id, quantity, cal_style(price, style, price_or_style), False)


@order_to.register(INSTRUMENT_TYPE.FUTURE)
def future_order_to(order_book_id, quantity, price=None, style=None):
# type: (Union[str, Instrument], int, Optional[float], Optional[OrderStyle]) -> List[Order]
return _order(order_book_id, quantity, cal_style(price, style), True)
def future_order_to(order_book_id, quantity, price=None, style=None, price_or_style=None):
# type: (Union[str, Instrument], int, Optional[float], Optional[OrderStyle], Optional[Union[float, OrderStyle]]) -> List[Order]
return _order(order_book_id, quantity, cal_style(price, style, price_or_style), True)


@buy_open.register(INSTRUMENT_TYPE.FUTURE)
def future_buy_open(id_or_ins, amount, price=None, style=None):
return _submit_order(id_or_ins, amount, SIDE.BUY, POSITION_EFFECT.OPEN, cal_style(price, style))
def future_buy_open(id_or_ins, amount, price=None, style=None, price_or_style=None):
return _submit_order(id_or_ins, amount, SIDE.BUY, POSITION_EFFECT.OPEN, cal_style(price, style, price_or_style))


@buy_close.register(INSTRUMENT_TYPE.FUTURE)
def future_buy_close(id_or_ins, amount, price=None, style=None, close_today=False):
def future_buy_close(id_or_ins, amount, price=None, style=None, close_today=False, price_or_style=None):
position_effect = POSITION_EFFECT.CLOSE_TODAY if close_today else POSITION_EFFECT.CLOSE
return _submit_order(id_or_ins, amount, SIDE.BUY, position_effect, cal_style(price, style))
return _submit_order(id_or_ins, amount, SIDE.BUY, position_effect, cal_style(price, style, price_or_style))


@sell_open.register(INSTRUMENT_TYPE.FUTURE)
def future_sell_open(id_or_ins, amount, price=None, style=None):
return _submit_order(id_or_ins, amount, SIDE.SELL, POSITION_EFFECT.OPEN, cal_style(price, style))
def future_sell_open(id_or_ins, amount, price=None, style=None, price_or_style=None):
return _submit_order(id_or_ins, amount, SIDE.SELL, POSITION_EFFECT.OPEN, cal_style(price, style, price_or_style))


@sell_close.register(INSTRUMENT_TYPE.FUTURE)
def future_sell_close(id_or_ins, amount, price=None, style=None, close_today=False):
def future_sell_close(id_or_ins, amount, price=None, style=None, close_today=False, price_or_style=None):
position_effect = POSITION_EFFECT.CLOSE_TODAY if close_today else POSITION_EFFECT.CLOSE
return _submit_order(id_or_ins, amount, SIDE.SELL, position_effect, cal_style(price, style))
return _submit_order(id_or_ins, amount, SIDE.SELL, position_effect, cal_style(price, style, price_or_style))


@export_as_api
Expand Down

0 comments on commit df6a794

Please sign in to comment.