[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__(
|
||||
self,
|
||||
algo_engine: BaseEngine,
|
||||
@ -50,13 +57,6 @@ class TwapAlgo(AlgoTemplate):
|
||||
self.total_count = 0
|
||||
self.traded = 0
|
||||
|
||||
self.variables.extend([
|
||||
"traded",
|
||||
"order_volume",
|
||||
"timer_count",
|
||||
"total_count"
|
||||
])
|
||||
|
||||
self.subscribe(self.vt_symbol)
|
||||
self.put_parameters_event()
|
||||
self.put_variables_event()
|
||||
@ -66,6 +66,7 @@ class TwapAlgo(AlgoTemplate):
|
||||
self.traded += trade.volume
|
||||
|
||||
if self.traded >= self.volume:
|
||||
self.write_log(f"已交易数量:{self.traded},总数量:{self.volume}")
|
||||
self.stop()
|
||||
else:
|
||||
self.put_variables_event()
|
||||
@ -98,15 +99,7 @@ class TwapAlgo(AlgoTemplate):
|
||||
if tick.ask_price_1 <= self.price:
|
||||
self.buy(self.vt_symbol, self.price,
|
||||
order_volume, offset=self.offset)
|
||||
self.write_log(
|
||||
f"委托买入{self.vt_symbol}:{order_volume}@{self.price}")
|
||||
else:
|
||||
if tick.bid_price_1 >= self.price:
|
||||
self.sell(self.vt_symbol, self.price,
|
||||
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):
|
||||
""""""
|
||||
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):
|
||||
""""""
|
||||
|
@ -96,6 +96,8 @@ class AlgoTemplate:
|
||||
self.on_stop()
|
||||
self.put_variables_event()
|
||||
|
||||
self.write_log("停止算法")
|
||||
|
||||
def subscribe(self, vt_symbol):
|
||||
""""""
|
||||
self.algo_engine.subscribe(self, vt_symbol)
|
||||
@ -109,6 +111,9 @@ class AlgoTemplate:
|
||||
offset: Offset = Offset.NONE
|
||||
):
|
||||
""""""
|
||||
msg = f"委托买入{vt_symbol}:{volume}@{price}"
|
||||
self.write_log(msg)
|
||||
|
||||
return self.algo_engine.send_order(
|
||||
self,
|
||||
vt_symbol,
|
||||
@ -128,6 +133,9 @@ class AlgoTemplate:
|
||||
offset: Offset = Offset.NONE
|
||||
):
|
||||
""""""
|
||||
msg = f"委托卖出{vt_symbol}:{volume}@{price}"
|
||||
self.write_log(msg)
|
||||
|
||||
return self.algo_engine.send_order(
|
||||
self,
|
||||
vt_symbol,
|
||||
|
@ -11,5 +11,6 @@ NAME_DISPLAY_MAP = {
|
||||
"order_volume": "单笔委托",
|
||||
"timer_count": "本轮读秒",
|
||||
"total_count": "累计读秒",
|
||||
"template_name": "算法模板"
|
||||
"template_name": "算法模板",
|
||||
"display_volume": "挂出数量"
|
||||
}
|
||||
|
@ -554,6 +554,10 @@ class AlgoManager(QtWidgets.QWidget):
|
||||
widget = self.algo_widgets[template_name]
|
||||
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):
|
||||
""""""
|
||||
self.showMaximized()
|
||||
|
Loading…
Reference in New Issue
Block a user