[Add]SniperAlgo and IcebergAlgo
This commit is contained in:
parent
4472e026c9
commit
2f674f2019
@ -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()
|
@ -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()
|
@ -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
|
|
||||||
|
@ -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):
|
||||||
""""""
|
""""""
|
||||||
|
@ -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,
|
||||||
|
@ -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": "挂出数量"
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user