[Mod] add send/cancel order function of algo engine
This commit is contained in:
parent
f94144b704
commit
be9142e878
@ -21,12 +21,13 @@ class SpreadTakerAlgo(SpreadAlgoTemplate):
|
|||||||
price: float,
|
price: float,
|
||||||
volume: float,
|
volume: float,
|
||||||
payup: int,
|
payup: int,
|
||||||
interval: int
|
interval: int,
|
||||||
|
lock: bool
|
||||||
):
|
):
|
||||||
""""""
|
""""""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
algo_engine, algoid, spread, direction,
|
algo_engine, algoid, spread, direction,
|
||||||
price, volume, payup, interval
|
price, volume, payup, interval, lock
|
||||||
)
|
)
|
||||||
|
|
||||||
self.cancel_interval: int = 2
|
self.cancel_interval: int = 2
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import List, Dict
|
from typing import List, Dict, Set
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
|
||||||
@ -13,7 +13,8 @@ from vnpy.trader.object import (
|
|||||||
TickData, ContractData, LogData,
|
TickData, ContractData, LogData,
|
||||||
SubscribeRequest, OrderRequest, CancelRequest
|
SubscribeRequest, OrderRequest, CancelRequest
|
||||||
)
|
)
|
||||||
from vnpy.trader.constant import Direction
|
from vnpy.trader.constant import Direction, Offset, OrderType
|
||||||
|
from vnpy.trader.converter import OffsetConverter, PositionHolding
|
||||||
|
|
||||||
from .base import (
|
from .base import (
|
||||||
LegData, SpreadData,
|
LegData, SpreadData,
|
||||||
@ -242,6 +243,11 @@ class SpreadAlgoEngine:
|
|||||||
self.symbol_algo_map: dict[str: SpreadAlgoTemplate] = defaultdict(list)
|
self.symbol_algo_map: dict[str: SpreadAlgoTemplate] = defaultdict(list)
|
||||||
|
|
||||||
self.algo_count: int = 0
|
self.algo_count: int = 0
|
||||||
|
self.vt_tradeids: Set = set()
|
||||||
|
|
||||||
|
self.offset_converter: OffsetConverter = OffsetConverter(
|
||||||
|
self.main_engine
|
||||||
|
)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
""""""
|
""""""
|
||||||
@ -254,9 +260,11 @@ class SpreadAlgoEngine:
|
|||||||
self.event_engine.register(EVENT_TICK, self.process_tick_event)
|
self.event_engine.register(EVENT_TICK, self.process_tick_event)
|
||||||
self.event_engine.register(EVENT_ORDER, self.process_order_event)
|
self.event_engine.register(EVENT_ORDER, self.process_order_event)
|
||||||
self.event_engine.register(EVENT_TRADE, self.process_trade_event)
|
self.event_engine.register(EVENT_TRADE, self.process_trade_event)
|
||||||
|
self.event_engine.register(EVENT_POSITION, self.process_position_event)
|
||||||
self.event_engine.register(EVENT_TIMER, self.process_timer_event)
|
self.event_engine.register(EVENT_TIMER, self.process_timer_event)
|
||||||
self.event_engine.register(
|
self.event_engine.register(
|
||||||
EVENT_SPREAD_DATA, self.process_spread_event)
|
EVENT_SPREAD_DATA, self.process_spread_event
|
||||||
|
)
|
||||||
|
|
||||||
def process_spread_event(self, event: Event):
|
def process_spread_event(self, event: Event):
|
||||||
""""""
|
""""""
|
||||||
@ -280,6 +288,9 @@ class SpreadAlgoEngine:
|
|||||||
def process_order_event(self, event: Event):
|
def process_order_event(self, event: Event):
|
||||||
""""""
|
""""""
|
||||||
order = event.data
|
order = event.data
|
||||||
|
|
||||||
|
self.offset_converter.update_order(order)
|
||||||
|
|
||||||
algo = self.order_algo_map.get(order.vt_orderid, None)
|
algo = self.order_algo_map.get(order.vt_orderid, None)
|
||||||
if algo and algo.is_active():
|
if algo and algo.is_active():
|
||||||
algo.update_order(order)
|
algo.update_order(order)
|
||||||
@ -287,10 +298,24 @@ class SpreadAlgoEngine:
|
|||||||
def process_trade_event(self, event: Event):
|
def process_trade_event(self, event: Event):
|
||||||
""""""
|
""""""
|
||||||
trade = event.data
|
trade = event.data
|
||||||
|
|
||||||
|
# Filter duplicate trade push
|
||||||
|
if trade.vt_tradeid in self.vt_tradeids:
|
||||||
|
return
|
||||||
|
self.vt_tradeids.add(trade.vt_tradeid)
|
||||||
|
|
||||||
|
self.offset_converter.update_trade(trade)
|
||||||
|
|
||||||
algo = self.order_algo_map.get(trade.vt_orderid, None)
|
algo = self.order_algo_map.get(trade.vt_orderid, None)
|
||||||
if algo and algo.is_active():
|
if algo and algo.is_active():
|
||||||
algo.update_trade(trade)
|
algo.update_trade(trade)
|
||||||
|
|
||||||
|
def process_position_event(self, event: Event):
|
||||||
|
""""""
|
||||||
|
position = event.data
|
||||||
|
|
||||||
|
self.offset_converter.update_position(position)
|
||||||
|
|
||||||
def process_timer_event(self, event: Event):
|
def process_timer_event(self, event: Event):
|
||||||
""""""
|
""""""
|
||||||
buf = list(self.algos.values())
|
buf = list(self.algos.values())
|
||||||
@ -372,13 +397,71 @@ class SpreadAlgoEngine:
|
|||||||
price: float,
|
price: float,
|
||||||
volume: float,
|
volume: float,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
|
lock: bool
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
""""""
|
""""""
|
||||||
pass
|
holding = self.offset_converter.get_position_holding(vt_symbol)
|
||||||
|
contract = self.main_engine.get_contract(vt_symbol)
|
||||||
|
|
||||||
|
if direction == Direction.LONG:
|
||||||
|
available = holding.short_pos - holding.short_pos_frozen
|
||||||
|
else:
|
||||||
|
available = holding.long_pos - holding.long_pos_frozen
|
||||||
|
|
||||||
|
# If no position to close, just open new
|
||||||
|
if not available:
|
||||||
|
offset = Offset.OPEN
|
||||||
|
# If enougth position to close, just close old
|
||||||
|
elif volume < available:
|
||||||
|
offset = Offset.CLOSE
|
||||||
|
# Otherwise, just close existing position
|
||||||
|
else:
|
||||||
|
volume = available
|
||||||
|
offset = Offset.CLOSE
|
||||||
|
|
||||||
|
original_req = OrderRequest(
|
||||||
|
contract.symbol,
|
||||||
|
contract.exchange,
|
||||||
|
direction,
|
||||||
|
offset,
|
||||||
|
OrderType.LIMIT,
|
||||||
|
price,
|
||||||
|
volume
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert with offset converter
|
||||||
|
req_list = self.offset_converter.convert_order_request(
|
||||||
|
original_req, lock)
|
||||||
|
|
||||||
|
# Send Orders
|
||||||
|
vt_orderids = []
|
||||||
|
|
||||||
|
for req in req_list:
|
||||||
|
vt_orderid = self.main_engine.send_order(
|
||||||
|
req, contract.gateway_name)
|
||||||
|
|
||||||
|
# Check if sending order successful
|
||||||
|
if not vt_orderid:
|
||||||
|
continue
|
||||||
|
|
||||||
|
vt_orderids.append(vt_orderid)
|
||||||
|
|
||||||
|
self.offset_converter.update_order_request(req, vt_orderid)
|
||||||
|
|
||||||
|
# Save relationship between orderid and algo.
|
||||||
|
self.order_algo_map[vt_orderid] = algo
|
||||||
|
|
||||||
|
return vt_orderids
|
||||||
|
|
||||||
def cancel_order(self, algo: SpreadAlgoTemplate, vt_orderid: str) -> None:
|
def cancel_order(self, algo: SpreadAlgoTemplate, vt_orderid: str) -> None:
|
||||||
""""""
|
""""""
|
||||||
pass
|
order = self.main_engine.get_order(vt_orderid)
|
||||||
|
if not order:
|
||||||
|
self.write_algo_log(algo, "撤单失败,找不到委托{}".format(vt_orderid))
|
||||||
|
return
|
||||||
|
|
||||||
|
req = order.create_cancel_request()
|
||||||
|
self.main_engine.cancel_order(req, order.gateway_name)
|
||||||
|
|
||||||
def get_tick(self, vt_symbol: str) -> TickData:
|
def get_tick(self, vt_symbol: str) -> TickData:
|
||||||
""""""
|
""""""
|
||||||
|
@ -25,7 +25,8 @@ class SpreadAlgoTemplate:
|
|||||||
price: float,
|
price: float,
|
||||||
volume: float,
|
volume: float,
|
||||||
payup: int,
|
payup: int,
|
||||||
interval: int
|
interval: int,
|
||||||
|
lock: bool
|
||||||
):
|
):
|
||||||
""""""
|
""""""
|
||||||
self.algo_engine = algo_engine
|
self.algo_engine = algo_engine
|
||||||
@ -39,6 +40,7 @@ class SpreadAlgoTemplate:
|
|||||||
self.volume: float = volume
|
self.volume: float = volume
|
||||||
self.payup: int = payup
|
self.payup: int = payup
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
|
self.lock = lock
|
||||||
|
|
||||||
if direction == Direction.LONG:
|
if direction == Direction.LONG:
|
||||||
self.target = volume
|
self.target = volume
|
||||||
@ -166,6 +168,7 @@ class SpreadAlgoTemplate:
|
|||||||
price,
|
price,
|
||||||
volume,
|
volume,
|
||||||
direction,
|
direction,
|
||||||
|
self.lock
|
||||||
)
|
)
|
||||||
|
|
||||||
self.leg_orders[vt_symbol].extend(vt_orderids)
|
self.leg_orders[vt_symbol].extend(vt_orderids)
|
||||||
|
@ -227,6 +227,11 @@ class SpreadAlgoDialog(QtWidgets.QDialog):
|
|||||||
button_start = QtWidgets.QPushButton("启动")
|
button_start = QtWidgets.QPushButton("启动")
|
||||||
button_start.clicked.connect(self.start_algo)
|
button_start.clicked.connect(self.start_algo)
|
||||||
|
|
||||||
|
self.lock_combo = QtWidgets.QComboBox()
|
||||||
|
self.lock_combo.addItems(
|
||||||
|
["否", "是"]
|
||||||
|
)
|
||||||
|
|
||||||
form = QtWidgets.QFormLayout()
|
form = QtWidgets.QFormLayout()
|
||||||
form.addRow("价差", self.name_line)
|
form.addRow("价差", self.name_line)
|
||||||
form.addRow("方向", self.direction_combo)
|
form.addRow("方向", self.direction_combo)
|
||||||
@ -234,6 +239,7 @@ class SpreadAlgoDialog(QtWidgets.QDialog):
|
|||||||
form.addRow("数量", self.volume_line)
|
form.addRow("数量", self.volume_line)
|
||||||
form.addRow("超价", self.payup_line)
|
form.addRow("超价", self.payup_line)
|
||||||
form.addRow("间隔", self.interval_line)
|
form.addRow("间隔", self.interval_line)
|
||||||
|
form.addRow("锁仓", self.lock_line)
|
||||||
form.addRow(button_start)
|
form.addRow(button_start)
|
||||||
|
|
||||||
self.setLayout(form)
|
self.setLayout(form)
|
||||||
@ -247,8 +253,14 @@ class SpreadAlgoDialog(QtWidgets.QDialog):
|
|||||||
payup = int(self.payup_line.text())
|
payup = int(self.payup_line.text())
|
||||||
interval = int(self.interval_line.text())
|
interval = int(self.interval_line.text())
|
||||||
|
|
||||||
|
lock_str = self.lock_combo.currentText()
|
||||||
|
if lock_str == "是":
|
||||||
|
lock = True
|
||||||
|
else:
|
||||||
|
lock = False
|
||||||
|
|
||||||
self.spread_engine.start_algo(
|
self.spread_engine.start_algo(
|
||||||
name, direction, price, volume, payup, interval
|
name, direction, price, volume, payup, interval, lock
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user