[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.ui import MainWindow, create_qapp
|
||||
|
||||
# from vnpy.gateway.binance import BinanceGateway
|
||||
# from vnpy.gateway.bitmex import BitmexGateway
|
||||
# from vnpy.gateway.futu import FutuGateway
|
||||
# from vnpy.gateway.ib import IbGateway
|
||||
from vnpy.gateway.binance import BinanceGateway
|
||||
from vnpy.gateway.bitmex import BitmexGateway
|
||||
from vnpy.gateway.futu import FutuGateway
|
||||
from vnpy.gateway.ib import IbGateway
|
||||
from vnpy.gateway.ctp import CtpGateway
|
||||
# from vnpy.gateway.ctptest import CtptestGateway
|
||||
# from vnpy.gateway.femas import FemasGateway
|
||||
# from vnpy.gateway.tiger import TigerGateway
|
||||
# from vnpy.gateway.oes import OesGateway
|
||||
# from vnpy.gateway.okex import OkexGateway
|
||||
# from vnpy.gateway.huobi import HuobiGateway
|
||||
# from vnpy.gateway.bitfinex import BitfinexGateway
|
||||
# from vnpy.gateway.onetoken import OnetokenGateway
|
||||
# from vnpy.gateway.okexf import OkexfGateway
|
||||
from vnpy.gateway.femas import FemasGateway
|
||||
from vnpy.gateway.tiger import TigerGateway
|
||||
from vnpy.gateway.oes import OesGateway
|
||||
from vnpy.gateway.okex import OkexGateway
|
||||
from vnpy.gateway.huobi import HuobiGateway
|
||||
from vnpy.gateway.bitfinex import BitfinexGateway
|
||||
from vnpy.gateway.onetoken import OnetokenGateway
|
||||
from vnpy.gateway.okexf import OkexfGateway
|
||||
# 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.csv_loader import CsvLoaderApp
|
||||
from vnpy.app.cta_strategy import CtaStrategyApp
|
||||
from vnpy.app.csv_loader import CsvLoaderApp
|
||||
from vnpy.app.algo_trading import AlgoTradingApp
|
||||
# from vnpy.app.cta_backtester import CtaBacktesterApp
|
||||
# from vnpy.app.data_recorder import DataRecorderApp
|
||||
# from vnpy.app.risk_manager import RiskManagerApp
|
||||
from vnpy.app.cta_backtester import CtaBacktesterApp
|
||||
from vnpy.app.data_recorder import DataRecorderApp
|
||||
from vnpy.app.risk_manager import RiskManagerApp
|
||||
|
||||
|
||||
def main():
|
||||
@ -36,29 +37,30 @@ def main():
|
||||
|
||||
main_engine = MainEngine(event_engine)
|
||||
|
||||
# main_engine.add_gateway(BinanceGateway)
|
||||
# main_engine.add_gateway(XtpGateway)
|
||||
main_engine.add_gateway(BinanceGateway)
|
||||
main_engine.add_gateway(CtpGateway)
|
||||
# main_engine.add_gateway(CtptestGateway)
|
||||
# main_engine.add_gateway(FemasGateway)
|
||||
# main_engine.add_gateway(IbGateway)
|
||||
# main_engine.add_gateway(FutuGateway)
|
||||
# main_engine.add_gateway(BitmexGateway)
|
||||
# main_engine.add_gateway(TigerGateway)
|
||||
# main_engine.add_gateway(OesGateway)
|
||||
# main_engine.add_gateway(OkexGateway)
|
||||
# main_engine.add_gateway(HuobiGateway)
|
||||
# main_engine.add_gateway(BitfinexGateway)
|
||||
# main_engine.add_gateway(OnetokenGateway)
|
||||
# main_engine.add_gateway(OkexfGateway)
|
||||
# main_engine.add_gateway(HbdmGateway)
|
||||
main_engine.add_gateway(FemasGateway)
|
||||
main_engine.add_gateway(IbGateway)
|
||||
main_engine.add_gateway(FutuGateway)
|
||||
main_engine.add_gateway(BitmexGateway)
|
||||
main_engine.add_gateway(TigerGateway)
|
||||
main_engine.add_gateway(OesGateway)
|
||||
main_engine.add_gateway(OkexGateway)
|
||||
main_engine.add_gateway(HuobiGateway)
|
||||
main_engine.add_gateway(BitfinexGateway)
|
||||
main_engine.add_gateway(OnetokenGateway)
|
||||
main_engine.add_gateway(OkexfGateway)
|
||||
main_engine.add_gateway(HbdmGateway)
|
||||
# main_engine.add_gateway(XtpGateway)
|
||||
# main_engine.add_gateway(TapGateway)
|
||||
|
||||
# main_engine.add_app(CtaStrategyApp)
|
||||
# main_engine.add_app(CtaBacktesterApp)
|
||||
# main_engine.add_app(CsvLoaderApp)
|
||||
main_engine.add_app(CtaStrategyApp)
|
||||
main_engine.add_app(CtaBacktesterApp)
|
||||
main_engine.add_app(CsvLoaderApp)
|
||||
main_engine.add_app(AlgoTradingApp)
|
||||
# main_engine.add_app(DataRecorderApp)
|
||||
# main_engine.add_app(RiskManagerApp)
|
||||
main_engine.add_app(DataRecorderApp)
|
||||
main_engine.add_app(RiskManagerApp)
|
||||
|
||||
main_window = MainWindow(main_engine, event_engine)
|
||||
main_window.showMaximized()
|
||||
|
@ -12,7 +12,7 @@ class ArbitrageAlgo(AlgoTemplate):
|
||||
|
||||
default_setting = {
|
||||
"active_vt_symbol": "",
|
||||
"passive_vt_symbol": "",
|
||||
"passive_vt_symbol": "",
|
||||
"spread_up": 0.0,
|
||||
"spread_down": 0.0,
|
||||
"max_pos": 0,
|
||||
@ -23,8 +23,8 @@ class ArbitrageAlgo(AlgoTemplate):
|
||||
"timer_count",
|
||||
"active_vt_orderid",
|
||||
"passive_vt_orderid",
|
||||
"net_pos",
|
||||
"acum_pos"
|
||||
"active_pos",
|
||||
"passive_pos"
|
||||
]
|
||||
|
||||
def __init__(
|
||||
@ -43,16 +43,17 @@ class ArbitrageAlgo(AlgoTemplate):
|
||||
self.spread_down = setting["spread_down"]
|
||||
self.max_pos = setting["max_pos"]
|
||||
self.interval = setting["interval"]
|
||||
|
||||
|
||||
# Variables
|
||||
self.active_vt_orderid = ""
|
||||
self.passive_vt_orderid = ""
|
||||
self.net_pos = 0
|
||||
self.acum_pos = 0
|
||||
self.active_pos = 0
|
||||
self.passive_pos = 0
|
||||
self.timer_count = 0
|
||||
|
||||
self.subscribe(self.active_vt_symbol)
|
||||
self.subscribe(self.passive_vt_symbol)
|
||||
|
||||
self.put_parameters_event()
|
||||
self.put_variables_event()
|
||||
|
||||
@ -72,41 +73,44 @@ class ArbitrageAlgo(AlgoTemplate):
|
||||
|
||||
def on_trade(self, trade: TradeData):
|
||||
""""""
|
||||
# Update net position volume
|
||||
# Update pos
|
||||
if trade.direction == Direction.LONG:
|
||||
self.net_pos += trade.volume
|
||||
else:
|
||||
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
|
||||
if trade.vt_symbol == self.active_vt_symbol:
|
||||
self.active_pos += trade.volume
|
||||
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:
|
||||
self.hedge()
|
||||
|
||||
|
||||
self.put_variables_event()
|
||||
|
||||
def on_timer(self):
|
||||
""""""
|
||||
# Run algo by fixed interval
|
||||
self.timer_count += 1
|
||||
if self.timer_count < self.interval:
|
||||
self.put_variables_event()
|
||||
return
|
||||
self.timer_count = 0
|
||||
|
||||
# Cancel all active orders before moving on
|
||||
if self.active_vt_orderid or self.passive_vt_orderid:
|
||||
self.cancel_all()
|
||||
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()
|
||||
return
|
||||
|
||||
|
||||
# Make sure that tick data of both leg are available
|
||||
active_tick = self.get_tick(self.active_vt_symbol)
|
||||
passive_tick = self.get_tick(self.passive_vt_symbol)
|
||||
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_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_ask_volume = min(active_tick.ask_volume_1, passive_tick.bid_volume_1)
|
||||
spread_bid_volume = min(active_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 self.acum_pos <= -self.max_pos:
|
||||
return
|
||||
else:
|
||||
if self.active_pos > -self.max_pos:
|
||||
volume = min(spread_bid_volume,
|
||||
self.active_pos + self.max_pos)
|
||||
|
||||
self.active_vt_orderid = self.sell(
|
||||
self.active_vt_symbol,
|
||||
active_tick.bid_price_1,
|
||||
spread_bid_volume
|
||||
volume
|
||||
)
|
||||
|
||||
# Buy condition
|
||||
elif spread_ask_price < -self.spread_down:
|
||||
if self.acum_pos >= self.max_pos:
|
||||
return
|
||||
else:
|
||||
if self.active_pos < self.max_pos:
|
||||
volume = min(spread_ask_volume,
|
||||
self.max_pos - self.active_pos)
|
||||
|
||||
self.active_vt_orderid = self.buy(
|
||||
self.active_vt_symbol,
|
||||
active_tick.ask_price_1,
|
||||
spread_ask_volume
|
||||
volume
|
||||
)
|
||||
|
||||
# Update GUI
|
||||
self.put_variables_event()
|
||||
|
||||
|
||||
def hedge(self):
|
||||
""""""
|
||||
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:
|
||||
self.passive_vt_orderid = self.sell(
|
||||
self.passive_vt_symbol,
|
||||
tick.bid_price_5,
|
||||
volume
|
||||
)
|
||||
elif self.net_pos < 0:
|
||||
if volume > 0:
|
||||
self.passive_vt_orderid = self.buy(
|
||||
self.passive_vt_symbol,
|
||||
tick.ask_price_5,
|
||||
tick.ask_price_1,
|
||||
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.services.basic import all_instruments as rqdata_all_instruments
|
||||
from rqdatac.services.get_price import get_price as rqdata_get_price
|
||||
from rqdatac.share.errors import AuthenticationFailed
|
||||
|
||||
from .setting import SETTINGS
|
||||
from .constant import Exchange, Interval
|
||||
@ -55,7 +56,7 @@ class RqdataClient:
|
||||
df = rqdata_all_instruments(date=datetime.now())
|
||||
for ix, row in df.iterrows():
|
||||
self.symbols.add(row['order_book_id'])
|
||||
except RuntimeError:
|
||||
except (RuntimeError, AuthenticationFailed):
|
||||
return False
|
||||
|
||||
self.inited = True
|
||||
|
Loading…
Reference in New Issue
Block a user