diff --git a/vnpy/app/spread_trading/algo.py b/vnpy/app/spread_trading/algo.py index bda5d317..db0aec8f 100644 --- a/vnpy/app/spread_trading/algo.py +++ b/vnpy/app/spread_trading/algo.py @@ -1,6 +1,6 @@ from typing import Any -from vnpy.trader.constant import Direction +from vnpy.trader.constant import Direction, Offset from vnpy.trader.object import (TickData, OrderData, TradeData) from .template import SpreadAlgoTemplate @@ -17,6 +17,7 @@ class SpreadTakerAlgo(SpreadAlgoTemplate): algoid: str, spread: SpreadData, direction: Direction, + offset: Offset, price: float, volume: float, payup: int, @@ -25,8 +26,9 @@ class SpreadTakerAlgo(SpreadAlgoTemplate): ): """""" super().__init__( - algo_engine, algoid, spread, direction, - price, volume, payup, interval, lock + algo_engine, algoid, spread, + direction, offset, price, volume, + payup, interval, lock ) self.cancel_interval: int = 2 diff --git a/vnpy/app/spread_trading/engine.py b/vnpy/app/spread_trading/engine.py index 81e91cf9..aeae2e91 100644 --- a/vnpy/app/spread_trading/engine.py +++ b/vnpy/app/spread_trading/engine.py @@ -425,6 +425,7 @@ class SpreadAlgoEngine: self, spread_name: str, direction: Direction, + offset: Offset, price: float, volume: float, payup: int, @@ -448,6 +449,7 @@ class SpreadAlgoEngine: algoid, spread, direction, + offset, price, volume, payup, @@ -905,6 +907,7 @@ class SpreadStrategyEngine: strategy: SpreadStrategyTemplate, spread_name: str, direction: Direction, + offset: Offset, price: float, volume: float, payup: int, @@ -915,6 +918,7 @@ class SpreadStrategyEngine: algoid = self.spread_engine.start_algo( spread_name, direction, + offset, price, volume, payup, diff --git a/vnpy/app/spread_trading/template.py b/vnpy/app/spread_trading/template.py index c88ef10a..c912be6c 100644 --- a/vnpy/app/spread_trading/template.py +++ b/vnpy/app/spread_trading/template.py @@ -23,11 +23,12 @@ class SpreadAlgoTemplate: algoid: str, spread: SpreadData, direction: Direction, + offset: Offset, price: float, volume: float, payup: int, interval: int, - lock: bool + lock: bool, ): """""" self.algo_engine = algo_engine @@ -36,6 +37,7 @@ class SpreadAlgoTemplate: self.spread: SpreadData = spread self.spread_name: str = spread.name + self.offset: Offset = offset self.direction: Direction = direction self.price: float = price self.volume: float = volume @@ -195,7 +197,12 @@ class SpreadAlgoTemplate: # calculate contract trading volume from coin trading volume if self.spread.is_inverse(vt_symbol): size = self.spread.get_leg_size(vt_symbol) - volume = volume * price / size + + if self.offset == Offset.CLOSE: + leg = self.spread.legs[vt_symbol] + volume = volume * leg.net_pos_price / size + else: + volume = volume * price / size vt_orderids = self.algo_engine.send_order( self, @@ -454,7 +461,8 @@ class SpreadStrategyTemplate: volume: float, payup: int, interval: int, - lock: bool + lock: bool, + offset: Offset ) -> str: """""" if not self.trading: @@ -464,6 +472,7 @@ class SpreadStrategyTemplate: self, self.spread_name, direction, + offset, price, volume, payup, @@ -481,10 +490,14 @@ class SpreadStrategyTemplate: volume: float, payup: int, interval: int, - lock: bool = False + lock: bool = False, + offset: Offset = Offset.NONE ) -> str: """""" - return self.start_algo(Direction.LONG, price, volume, payup, interval, lock) + return self.start_algo( + Direction.LONG, price, volume, + payup, interval, lock, offset + ) def start_short_algo( self, @@ -492,10 +505,14 @@ class SpreadStrategyTemplate: volume: float, payup: int, interval: int, - lock: bool = False + lock: bool = False, + offset: Offset = Offset.NONE ) -> str: """""" - return self.start_algo(Direction.SHORT, price, volume, payup, interval, lock) + return self.start_algo( + Direction.SHORT, price, volume, + payup, interval, lock, offset + ) def stop_algo(self, algoid: str): """""" diff --git a/vnpy/app/spread_trading/ui/widget.py b/vnpy/app/spread_trading/ui/widget.py index 72fa2551..0b512e19 100644 --- a/vnpy/app/spread_trading/ui/widget.py +++ b/vnpy/app/spread_trading/ui/widget.py @@ -4,7 +4,7 @@ Widget for spread trading. from vnpy.event import EventEngine, Event from vnpy.trader.engine import MainEngine -from vnpy.trader.constant import Direction +from vnpy.trader.constant import Direction, Offset from vnpy.trader.ui import QtWidgets, QtCore, QtGui from vnpy.trader.ui.widget import ( BaseMonitor, BaseCell, @@ -169,6 +169,7 @@ class SpreadAlgoMonitor(BaseMonitor): "algoid": {"display": "算法", "cell": BaseCell, "update": False}, "spread_name": {"display": "价差", "cell": BaseCell, "update": False}, "direction": {"display": "方向", "cell": DirectionCell, "update": False}, + "offset": {"display": "开平", "cell": EnumCell, "update": False}, "price": {"display": "价格", "cell": BaseCell, "update": False}, "payup": {"display": "超价", "cell": BaseCell, "update": False}, "volume": {"display": "数量", "cell": BaseCell, "update": False}, @@ -226,6 +227,11 @@ class SpreadAlgoWidget(QtWidgets.QFrame): [Direction.LONG.value, Direction.SHORT.value] ) + self.offset_combo = QtWidgets.QComboBox() + self.offset_combo.addItem( + [Offset.NONE.value, Offset.OPEN.value, Offset.CLOSE.value] + ) + float_validator = QtGui.QDoubleValidator() self.price_line = QtWidgets.QLineEdit() @@ -273,6 +279,7 @@ class SpreadAlgoWidget(QtWidgets.QFrame): form = QtWidgets.QFormLayout() form.addRow("价差", self.name_line) form.addRow("方向", self.direction_combo) + form.addRow("开平", self.offset_combo) form.addRow("价格", self.price_line) form.addRow("数量", self.volume_line) form.addRow("超价", self.payup_line) @@ -298,6 +305,7 @@ class SpreadAlgoWidget(QtWidgets.QFrame): """""" name = self.name_line.text() direction = Direction(self.direction_combo.currentText()) + offset = Offset(self.offset_combo.currentText()) price = float(self.price_line.text()) volume = float(self.volume_line.text()) payup = int(self.payup_line.text()) @@ -310,7 +318,7 @@ class SpreadAlgoWidget(QtWidgets.QFrame): lock = False self.spread_engine.start_algo( - name, direction, price, volume, payup, interval, lock + name, direction, offset, price, volume, payup, interval, lock ) def add_spread(self):