[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,
|
||||
volume: float,
|
||||
payup: int,
|
||||
interval: int
|
||||
interval: int,
|
||||
lock: bool
|
||||
):
|
||||
""""""
|
||||
super().__init__(
|
||||
algo_engine, algoid, spread, direction,
|
||||
price, volume, payup, interval
|
||||
price, volume, payup, interval, lock
|
||||
)
|
||||
|
||||
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 copy import copy
|
||||
|
||||
@ -13,7 +13,8 @@ from vnpy.trader.object import (
|
||||
TickData, ContractData, LogData,
|
||||
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 (
|
||||
LegData, SpreadData,
|
||||
@ -242,6 +243,11 @@ class SpreadAlgoEngine:
|
||||
self.symbol_algo_map: dict[str: SpreadAlgoTemplate] = defaultdict(list)
|
||||
|
||||
self.algo_count: int = 0
|
||||
self.vt_tradeids: Set = set()
|
||||
|
||||
self.offset_converter: OffsetConverter = OffsetConverter(
|
||||
self.main_engine
|
||||
)
|
||||
|
||||
def start(self):
|
||||
""""""
|
||||
@ -254,9 +260,11 @@ class SpreadAlgoEngine:
|
||||
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_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_SPREAD_DATA, self.process_spread_event)
|
||||
EVENT_SPREAD_DATA, self.process_spread_event
|
||||
)
|
||||
|
||||
def process_spread_event(self, event: Event):
|
||||
""""""
|
||||
@ -280,6 +288,9 @@ class SpreadAlgoEngine:
|
||||
def process_order_event(self, event: Event):
|
||||
""""""
|
||||
order = event.data
|
||||
|
||||
self.offset_converter.update_order(order)
|
||||
|
||||
algo = self.order_algo_map.get(order.vt_orderid, None)
|
||||
if algo and algo.is_active():
|
||||
algo.update_order(order)
|
||||
@ -287,10 +298,24 @@ class SpreadAlgoEngine:
|
||||
def process_trade_event(self, event: Event):
|
||||
""""""
|
||||
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)
|
||||
if algo and algo.is_active():
|
||||
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):
|
||||
""""""
|
||||
buf = list(self.algos.values())
|
||||
@ -372,13 +397,71 @@ class SpreadAlgoEngine:
|
||||
price: float,
|
||||
volume: float,
|
||||
direction: Direction,
|
||||
lock: bool
|
||||
) -> 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:
|
||||
""""""
|
||||
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:
|
||||
""""""
|
||||
|
@ -25,7 +25,8 @@ class SpreadAlgoTemplate:
|
||||
price: float,
|
||||
volume: float,
|
||||
payup: int,
|
||||
interval: int
|
||||
interval: int,
|
||||
lock: bool
|
||||
):
|
||||
""""""
|
||||
self.algo_engine = algo_engine
|
||||
@ -39,6 +40,7 @@ class SpreadAlgoTemplate:
|
||||
self.volume: float = volume
|
||||
self.payup: int = payup
|
||||
self.interval = interval
|
||||
self.lock = lock
|
||||
|
||||
if direction == Direction.LONG:
|
||||
self.target = volume
|
||||
@ -166,6 +168,7 @@ class SpreadAlgoTemplate:
|
||||
price,
|
||||
volume,
|
||||
direction,
|
||||
self.lock
|
||||
)
|
||||
|
||||
self.leg_orders[vt_symbol].extend(vt_orderids)
|
||||
|
@ -227,6 +227,11 @@ class SpreadAlgoDialog(QtWidgets.QDialog):
|
||||
button_start = QtWidgets.QPushButton("启动")
|
||||
button_start.clicked.connect(self.start_algo)
|
||||
|
||||
self.lock_combo = QtWidgets.QComboBox()
|
||||
self.lock_combo.addItems(
|
||||
["否", "是"]
|
||||
)
|
||||
|
||||
form = QtWidgets.QFormLayout()
|
||||
form.addRow("价差", self.name_line)
|
||||
form.addRow("方向", self.direction_combo)
|
||||
@ -234,6 +239,7 @@ class SpreadAlgoDialog(QtWidgets.QDialog):
|
||||
form.addRow("数量", self.volume_line)
|
||||
form.addRow("超价", self.payup_line)
|
||||
form.addRow("间隔", self.interval_line)
|
||||
form.addRow("锁仓", self.lock_line)
|
||||
form.addRow(button_start)
|
||||
|
||||
self.setLayout(form)
|
||||
@ -247,8 +253,14 @@ class SpreadAlgoDialog(QtWidgets.QDialog):
|
||||
payup = int(self.payup_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(
|
||||
name, direction, price, volume, payup, interval
|
||||
name, direction, price, volume, payup, interval, lock
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user