[Mod] change logic of arbitrage algo

This commit is contained in:
vn.py 2019-06-15 23:58:10 +08:00
parent 961f7366a3
commit 0aa1bda8df
3 changed files with 96 additions and 80 deletions

View File

@ -3,29 +3,30 @@ from vnpy.event import EventEngine
from vnpy.trader.engine import MainEngine from vnpy.trader.engine import MainEngine
from vnpy.trader.ui import MainWindow, create_qapp from vnpy.trader.ui import MainWindow, create_qapp
# from vnpy.gateway.binance import BinanceGateway from vnpy.gateway.binance import BinanceGateway
# from vnpy.gateway.bitmex import BitmexGateway from vnpy.gateway.bitmex import BitmexGateway
# from vnpy.gateway.futu import FutuGateway from vnpy.gateway.futu import FutuGateway
# from vnpy.gateway.ib import IbGateway from vnpy.gateway.ib import IbGateway
from vnpy.gateway.ctp import CtpGateway from vnpy.gateway.ctp import CtpGateway
# from vnpy.gateway.ctptest import CtptestGateway # from vnpy.gateway.ctptest import CtptestGateway
# from vnpy.gateway.femas import FemasGateway from vnpy.gateway.femas import FemasGateway
# from vnpy.gateway.tiger import TigerGateway from vnpy.gateway.tiger import TigerGateway
# from vnpy.gateway.oes import OesGateway from vnpy.gateway.oes import OesGateway
# from vnpy.gateway.okex import OkexGateway from vnpy.gateway.okex import OkexGateway
# from vnpy.gateway.huobi import HuobiGateway from vnpy.gateway.huobi import HuobiGateway
# from vnpy.gateway.bitfinex import BitfinexGateway from vnpy.gateway.bitfinex import BitfinexGateway
# from vnpy.gateway.onetoken import OnetokenGateway from vnpy.gateway.onetoken import OnetokenGateway
# from vnpy.gateway.okexf import OkexfGateway from vnpy.gateway.okexf import OkexfGateway
# from vnpy.gateway.xtp import XtpGateway # from vnpy.gateway.xtp import XtpGateway
# from vnpy.gateway.hbdm import HbdmGateway from vnpy.gateway.hbdm import HbdmGateway
# from vnpy.gateway.tap import TapGateway
# from vnpy.app.cta_strategy import CtaStrategyApp from vnpy.app.cta_strategy import CtaStrategyApp
# from vnpy.app.csv_loader import CsvLoaderApp from vnpy.app.csv_loader import CsvLoaderApp
from vnpy.app.algo_trading import AlgoTradingApp from vnpy.app.algo_trading import AlgoTradingApp
# from vnpy.app.cta_backtester import CtaBacktesterApp from vnpy.app.cta_backtester import CtaBacktesterApp
# from vnpy.app.data_recorder import DataRecorderApp from vnpy.app.data_recorder import DataRecorderApp
# from vnpy.app.risk_manager import RiskManagerApp from vnpy.app.risk_manager import RiskManagerApp
def main(): def main():
@ -36,29 +37,30 @@ def main():
main_engine = MainEngine(event_engine) main_engine = MainEngine(event_engine)
# main_engine.add_gateway(BinanceGateway) main_engine.add_gateway(BinanceGateway)
# main_engine.add_gateway(XtpGateway)
main_engine.add_gateway(CtpGateway) main_engine.add_gateway(CtpGateway)
# main_engine.add_gateway(CtptestGateway) # main_engine.add_gateway(CtptestGateway)
# main_engine.add_gateway(FemasGateway) main_engine.add_gateway(FemasGateway)
# main_engine.add_gateway(IbGateway) main_engine.add_gateway(IbGateway)
# main_engine.add_gateway(FutuGateway) main_engine.add_gateway(FutuGateway)
# main_engine.add_gateway(BitmexGateway) main_engine.add_gateway(BitmexGateway)
# main_engine.add_gateway(TigerGateway) main_engine.add_gateway(TigerGateway)
# main_engine.add_gateway(OesGateway) main_engine.add_gateway(OesGateway)
# main_engine.add_gateway(OkexGateway) main_engine.add_gateway(OkexGateway)
# main_engine.add_gateway(HuobiGateway) main_engine.add_gateway(HuobiGateway)
# main_engine.add_gateway(BitfinexGateway) main_engine.add_gateway(BitfinexGateway)
# main_engine.add_gateway(OnetokenGateway) main_engine.add_gateway(OnetokenGateway)
# main_engine.add_gateway(OkexfGateway) main_engine.add_gateway(OkexfGateway)
# main_engine.add_gateway(HbdmGateway) main_engine.add_gateway(HbdmGateway)
# main_engine.add_gateway(XtpGateway)
# main_engine.add_gateway(TapGateway)
# main_engine.add_app(CtaStrategyApp) main_engine.add_app(CtaStrategyApp)
# main_engine.add_app(CtaBacktesterApp) main_engine.add_app(CtaBacktesterApp)
# main_engine.add_app(CsvLoaderApp) main_engine.add_app(CsvLoaderApp)
main_engine.add_app(AlgoTradingApp) main_engine.add_app(AlgoTradingApp)
# main_engine.add_app(DataRecorderApp) main_engine.add_app(DataRecorderApp)
# main_engine.add_app(RiskManagerApp) main_engine.add_app(RiskManagerApp)
main_window = MainWindow(main_engine, event_engine) main_window = MainWindow(main_engine, event_engine)
main_window.showMaximized() main_window.showMaximized()

View File

@ -12,7 +12,7 @@ class ArbitrageAlgo(AlgoTemplate):
default_setting = { default_setting = {
"active_vt_symbol": "", "active_vt_symbol": "",
"passive_vt_symbol": "", "passive_vt_symbol": "",
"spread_up": 0.0, "spread_up": 0.0,
"spread_down": 0.0, "spread_down": 0.0,
"max_pos": 0, "max_pos": 0,
@ -23,8 +23,8 @@ class ArbitrageAlgo(AlgoTemplate):
"timer_count", "timer_count",
"active_vt_orderid", "active_vt_orderid",
"passive_vt_orderid", "passive_vt_orderid",
"net_pos", "active_pos",
"acum_pos" "passive_pos"
] ]
def __init__( def __init__(
@ -43,16 +43,17 @@ class ArbitrageAlgo(AlgoTemplate):
self.spread_down = setting["spread_down"] self.spread_down = setting["spread_down"]
self.max_pos = setting["max_pos"] self.max_pos = setting["max_pos"]
self.interval = setting["interval"] self.interval = setting["interval"]
# Variables # Variables
self.active_vt_orderid = "" self.active_vt_orderid = ""
self.passive_vt_orderid = "" self.passive_vt_orderid = ""
self.net_pos = 0 self.active_pos = 0
self.acum_pos = 0 self.passive_pos = 0
self.timer_count = 0 self.timer_count = 0
self.subscribe(self.active_vt_symbol) self.subscribe(self.active_vt_symbol)
self.subscribe(self.passive_vt_symbol) self.subscribe(self.passive_vt_symbol)
self.put_parameters_event() self.put_parameters_event()
self.put_variables_event() self.put_variables_event()
@ -72,41 +73,44 @@ class ArbitrageAlgo(AlgoTemplate):
def on_trade(self, trade: TradeData): def on_trade(self, trade: TradeData):
"""""" """"""
# Update net position volume # Update pos
if trade.direction == Direction.LONG: if trade.direction == Direction.LONG:
self.net_pos += trade.volume if trade.vt_symbol == self.active_vt_symbol:
else: self.active_pos += trade.volume
self.net_pos -= trade.volume
# Update active symbol position
if trade.vt_symbol == self.active_vt_symbol:
if trade.direction == Direction.LONG:
self.acum_pos += trade.volume
else: else:
self.acum_pos -= trade.volume self.passive_pos += trade.volume
else:
if trade.vt_symbol == self.active_vt_symbol:
self.active_pos -= trade.volume
else:
self.passive_pos -= trade.volume
# Hedge if active symbol traded # Hedge if active symbol traded
if trade.vt_symbol == self.active_vt_symbol: if trade.vt_symbol == self.active_vt_symbol:
self.hedge() self.hedge()
self.put_variables_event() self.put_variables_event()
def on_timer(self): def on_timer(self):
"""""" """"""
# Run algo by fixed interval
self.timer_count += 1 self.timer_count += 1
if self.timer_count < self.interval: if self.timer_count < self.interval:
self.put_variables_event() self.put_variables_event()
return return
self.timer_count = 0 self.timer_count = 0
# Cancel all active orders before moving on
if self.active_vt_orderid or self.passive_vt_orderid: if self.active_vt_orderid or self.passive_vt_orderid:
self.cancel_all() self.cancel_all()
return return
if self.net_pos: # Make sure that active leg is fully hedged by passive leg
if (self.active_pos + self.passive_pos) != 0:
self.hedge() self.hedge()
return return
# Make sure that tick data of both leg are available
active_tick = self.get_tick(self.active_vt_symbol) active_tick = self.get_tick(self.active_vt_symbol)
passive_tick = self.get_tick(self.passive_vt_symbol) passive_tick = self.get_tick(self.passive_vt_symbol)
if not active_tick or not passive_tick: if not active_tick or not passive_tick:
@ -116,46 +120,55 @@ class ArbitrageAlgo(AlgoTemplate):
spread_bid_price = active_tick.bid_price_1 - passive_tick.ask_price_1 spread_bid_price = active_tick.bid_price_1 - passive_tick.ask_price_1
spread_ask_price = active_tick.ask_price_1 - passive_tick.bid_price_1 spread_ask_price = active_tick.ask_price_1 - passive_tick.bid_price_1
spread_bid_volume = min(active_tick.bid_volume_1, passive_tick.ask_volume_1) spread_bid_volume = min(active_tick.bid_volume_1,
spread_ask_volume = min(active_tick.ask_volume_1, passive_tick.bid_volume_1) passive_tick.ask_volume_1)
spread_ask_volume = min(active_tick.ask_volume_1,
passive_tick.bid_volume_1)
# Sell condition self.write_log(f"盘口价差,买:{spread_bid_volume}@{spread_bid_price}")
self.write_log(f"盘口价差,卖:{spread_ask_volume}@{spread_ask_price}")
# Sell condition
if spread_bid_price > self.spread_up: if spread_bid_price > self.spread_up:
if self.acum_pos <= -self.max_pos: if self.active_pos > -self.max_pos:
return volume = min(spread_bid_volume,
else: self.active_pos + self.max_pos)
self.active_vt_orderid = self.sell( self.active_vt_orderid = self.sell(
self.active_vt_symbol, self.active_vt_symbol,
active_tick.bid_price_1, active_tick.bid_price_1,
spread_bid_volume volume
) )
# Buy condition # Buy condition
elif spread_ask_price < -self.spread_down: elif spread_ask_price < -self.spread_down:
if self.acum_pos >= self.max_pos: if self.active_pos < self.max_pos:
return volume = min(spread_ask_volume,
else: self.max_pos - self.active_pos)
self.active_vt_orderid = self.buy( self.active_vt_orderid = self.buy(
self.active_vt_symbol, self.active_vt_symbol,
active_tick.ask_price_1, active_tick.ask_price_1,
spread_ask_volume volume
) )
# Update GUI
self.put_variables_event() self.put_variables_event()
def hedge(self): def hedge(self):
"""""" """"""
tick = self.get_tick(self.passive_vt_symbol) tick = self.get_tick(self.passive_vt_symbol)
volume = abs(self.net_pos) volume = -self.active_pos - self.passive_pos
if self.net_pos > 0: if volume > 0:
self.passive_vt_orderid = self.sell(
self.passive_vt_symbol,
tick.bid_price_5,
volume
)
elif self.net_pos < 0:
self.passive_vt_orderid = self.buy( self.passive_vt_orderid = self.buy(
self.passive_vt_symbol, self.passive_vt_symbol,
tick.ask_price_5, tick.ask_price_1,
volume volume
) )
elif volume < 0:
self.passive_vt_orderid = self.sell(
self.passive_vt_symbol,
tick.bid_price_1,
abs(volume)
)

View File

@ -4,6 +4,7 @@ from typing import List
from rqdatac import init as rqdata_init from rqdatac import init as rqdata_init
from rqdatac.services.basic import all_instruments as rqdata_all_instruments from rqdatac.services.basic import all_instruments as rqdata_all_instruments
from rqdatac.services.get_price import get_price as rqdata_get_price from rqdatac.services.get_price import get_price as rqdata_get_price
from rqdatac.share.errors import AuthenticationFailed
from .setting import SETTINGS from .setting import SETTINGS
from .constant import Exchange, Interval from .constant import Exchange, Interval
@ -55,7 +56,7 @@ class RqdataClient:
df = rqdata_all_instruments(date=datetime.now()) df = rqdata_all_instruments(date=datetime.now())
for ix, row in df.iterrows(): for ix, row in df.iterrows():
self.symbols.add(row['order_book_id']) self.symbols.add(row['order_book_id'])
except RuntimeError: except (RuntimeError, AuthenticationFailed):
return False return False
self.inited = True self.inited = True