[Mod] change logic of arbitrage algo
This commit is contained in:
parent
961f7366a3
commit
0aa1bda8df
@ -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()
|
||||||
|
@ -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)
|
||||||
|
)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user