[Add]SniperAlgo and IcebergAlgo

This commit is contained in:
vn.py 2019-04-07 22:14:04 +08:00
parent 4472e026c9
commit 2f674f2019
7 changed files with 269 additions and 17 deletions

View File

@ -0,0 +1,137 @@
from vnpy.trader.constant import Offset, Direction
from vnpy.trader.object import TradeData, OrderData, TickData
from vnpy.trader.engine import BaseEngine
from vnpy.app.algo_trading import AlgoTemplate
class IcebergAlgo(AlgoTemplate):
""""""
display_name = "Iceberg 冰山"
default_setting = {
"vt_symbol": "",
"direction": [Direction.LONG.value, Direction.SHORT.value],
"price": 0.0,
"volume": 0.0,
"display_volume": 0.0,
"interval": 0,
"offset": [
Offset.NONE.value,
Offset.OPEN.value,
Offset.CLOSE.value,
Offset.CLOSETODAY.value,
Offset.CLOSEYESTERDAY.value
]
}
variables = [
"traded",
"timer_count",
"vt_orderid"
]
def __init__(
self,
algo_engine: BaseEngine,
algo_name: str,
setting: dict
):
""""""
super().__init__(algo_engine, algo_name, setting)
# Parameters
self.vt_symbol = setting["vt_symbol"]
self.direction = Direction(setting["direction"])
self.price = setting["price"]
self.volume = setting["volume"]
self.display_volume = setting["display_volume"]
self.interval = setting["interval"]
self.offset = Offset(setting["offset"])
# Variables
self.timer_count = 0
self.vt_orderid = ""
self.traded = 0
self.last_tick = None
self.subscribe(self.vt_symbol)
self.put_parameters_event()
self.put_variables_event()
def on_stop(self):
""""""
self.write_log("停止算法")
def on_tick(self, tick: TickData):
""""""
self.last_tick = tick
def on_order(self, order: OrderData):
""""""
msg = f"委托号:{order.vt_orderid},委托状态:{order.status.value}"
self.write_log(msg)
if not order.is_active():
self.vt_orderid = ""
self.put_variables_event()
def on_trade(self, trade: TradeData):
""""""
self.traded += trade.volume
if self.traded >= self.volume:
self.write_log(f"已交易数量:{self.traded},总数量:{self.volume}")
self.stop()
else:
self.put_variables_event()
def on_timer(self):
""""""
self.timer_count += 1
if self.timer_count < self.interval:
self.put_variables_event()
return
self.timer_count = 0
contract = self.get_contract(self.vt_symbol)
if not contract:
return
# If order already finished, just send new order
if not self.vt_orderid:
order_volume = self.volume - self.traded
order_volume = min(order_volume, self.display_volume)
if self.direction == Direction.LONG:
self.vt_orderid = self.buy(
self.vt_symbol,
self.price,
order_volume,
offset=self.offset
)
else:
self.vt_orderid = self.sell(
self.vt_symbol,
self.price,
order_volume,
offset=self.offset
)
# Otherwise check for cancel
else:
if self.direction == Direction.LONG:
if self.last_tick.ask_price_1 <= self.price:
self.cancel_order(self.vt_orderid)
self.vt_orderid = ""
self.write_log(u"最新Tick卖一价低于买入委托价格之前委托可能丢失强制撤单")
else:
if self.last_tick.bid_price_1 >= self.price:
self.cancel_order(self.vt_orderid)
self.vt_orderid = ""
self.write_log(u"最新Tick买一价高于卖出委托价格之前委托可能丢失强制撤单")
self.put_variables_event()

View File

@ -0,0 +1,101 @@
from vnpy.trader.constant import Offset, Direction
from vnpy.trader.object import TradeData, OrderData, TickData
from vnpy.trader.engine import BaseEngine
from vnpy.app.algo_trading import AlgoTemplate
class SniperAlgo(AlgoTemplate):
""""""
display_name = "Sniper 狙击手"
default_setting = {
"vt_symbol": "",
"direction": [Direction.LONG.value, Direction.SHORT.value],
"price": 0.0,
"volume": 0.0,
"offset": [
Offset.NONE.value,
Offset.OPEN.value,
Offset.CLOSE.value,
Offset.CLOSETODAY.value,
Offset.CLOSEYESTERDAY.value
]
}
variables = [
"traded",
"vt_orderid"
]
def __init__(
self,
algo_engine: BaseEngine,
algo_name: str,
setting: dict
):
""""""
super().__init__(algo_engine, algo_name, setting)
# Parameters
self.vt_symbol = setting["vt_symbol"]
self.direction = Direction(setting["direction"])
self.price = setting["price"]
self.volume = setting["volume"]
self.offset = Offset(setting["offset"])
# Variables
self.vt_orderid = ""
self.traded = 0
self.subscribe(self.vt_symbol)
self.put_parameters_event()
self.put_variables_event()
def on_tick(self, tick: TickData):
""""""
if self.vt_orderid:
self.cancel_all()
return
if self.direction == Direction.LONG:
if tick.ask_price_1 <= self.price:
order_volume = self.volume - self.traded
order_volume = min(order_volume, tick.ask_volume_1)
self.vt_orderid = self.buy(
self.vt_symbol,
self.price,
order_volume,
offset=self.offset
)
else:
if tick.bid_price_1 >= self.price:
order_volume = self.volume - self.traded
order_volume = min(order_volume, tick.bid_volume_1)
self.vt_orderid = self.sell(
self.vt_symbol,
self.price,
order_volume,
offset=self.offset
)
self.put_variables_event()
def on_order(self, order: OrderData):
""""""
if not order.is_active():
self.vt_orderid = ""
self.put_variables_event()
def on_trade(self, trade: TradeData):
""""""
self.traded += trade.volume
if self.traded >= self.volume:
self.write_log(f"已交易数量:{self.traded},总数量:{self.volume}")
self.stop()
else:
self.put_variables_event()

View File

@ -26,6 +26,13 @@ class TwapAlgo(AlgoTemplate):
] ]
} }
variables = [
"traded",
"order_volume",
"timer_count",
"total_count"
]
def __init__( def __init__(
self, self,
algo_engine: BaseEngine, algo_engine: BaseEngine,
@ -50,13 +57,6 @@ class TwapAlgo(AlgoTemplate):
self.total_count = 0 self.total_count = 0
self.traded = 0 self.traded = 0
self.variables.extend([
"traded",
"order_volume",
"timer_count",
"total_count"
])
self.subscribe(self.vt_symbol) self.subscribe(self.vt_symbol)
self.put_parameters_event() self.put_parameters_event()
self.put_variables_event() self.put_variables_event()
@ -66,6 +66,7 @@ class TwapAlgo(AlgoTemplate):
self.traded += trade.volume self.traded += trade.volume
if self.traded >= self.volume: if self.traded >= self.volume:
self.write_log(f"已交易数量:{self.traded},总数量:{self.volume}")
self.stop() self.stop()
else: else:
self.put_variables_event() self.put_variables_event()
@ -98,15 +99,7 @@ class TwapAlgo(AlgoTemplate):
if tick.ask_price_1 <= self.price: if tick.ask_price_1 <= self.price:
self.buy(self.vt_symbol, self.price, self.buy(self.vt_symbol, self.price,
order_volume, offset=self.offset) order_volume, offset=self.offset)
self.write_log(
f"委托买入{self.vt_symbol}{order_volume}@{self.price}")
else: else:
if tick.bid_price_1 >= self.price: if tick.bid_price_1 >= self.price:
self.sell(self.vt_symbol, self.price, self.sell(self.vt_symbol, self.price,
order_volume, offset=self.offset) order_volume, offset=self.offset)
self.write_log(
f"委托卖出{self.vt_symbol}{order_volume}@{self.price}")
def get_default_setting(self):
""""""
return self.default_setting

View File

@ -44,8 +44,16 @@ class AlgoEngine(BaseEngine):
def load_algo_template(self): def load_algo_template(self):
"""""" """"""
from .algos.twap_algo import TwapAlgo from .algos.twap_algo import TwapAlgo
from .algos.iceberg_algo import IcebergAlgo
from .algos.sniper_algo import SniperAlgo
self.algo_templates[TwapAlgo.__name__] = TwapAlgo self.add_algo_template(TwapAlgo)
self.add_algo_template(IcebergAlgo)
self.add_algo_template(SniperAlgo)
def add_algo_template(self, template: AlgoTemplate):
""""""
self.algo_templates[template.__name__] = template
def load_algo_setting(self): def load_algo_setting(self):
"""""" """"""

View File

@ -96,6 +96,8 @@ class AlgoTemplate:
self.on_stop() self.on_stop()
self.put_variables_event() self.put_variables_event()
self.write_log("停止算法")
def subscribe(self, vt_symbol): def subscribe(self, vt_symbol):
"""""" """"""
self.algo_engine.subscribe(self, vt_symbol) self.algo_engine.subscribe(self, vt_symbol)
@ -109,6 +111,9 @@ class AlgoTemplate:
offset: Offset = Offset.NONE offset: Offset = Offset.NONE
): ):
"""""" """"""
msg = f"委托买入{vt_symbol}{volume}@{price}"
self.write_log(msg)
return self.algo_engine.send_order( return self.algo_engine.send_order(
self, self,
vt_symbol, vt_symbol,
@ -128,6 +133,9 @@ class AlgoTemplate:
offset: Offset = Offset.NONE offset: Offset = Offset.NONE
): ):
"""""" """"""
msg = f"委托卖出{vt_symbol}{volume}@{price}"
self.write_log(msg)
return self.algo_engine.send_order( return self.algo_engine.send_order(
self, self,
vt_symbol, vt_symbol,

View File

@ -11,5 +11,6 @@ NAME_DISPLAY_MAP = {
"order_volume": "单笔委托", "order_volume": "单笔委托",
"timer_count": "本轮读秒", "timer_count": "本轮读秒",
"total_count": "累计读秒", "total_count": "累计读秒",
"template_name": "算法模板" "template_name": "算法模板",
"display_volume": "挂出数量"
} }

View File

@ -554,6 +554,10 @@ class AlgoManager(QtWidgets.QWidget):
widget = self.algo_widgets[template_name] widget = self.algo_widgets[template_name]
widget.update_setting(setting_name, setting) widget.update_setting(setting_name, setting)
ix = self.template_combo.findData(template_name)
self.template_combo.setCurrentIndex(ix)
self.show_algo_widget()
def show(self): def show(self):
"""""" """"""
self.showMaximized() self.showMaximized()