# -*- coding: utf-8 -*-
'''
////////////////////////////////////////////////////////////////////////
//免责声明:本策略仅供学习使用,请勿直接进行实盘交易,本策略不承诺任何收益。//
///////////////////////////////////////////////////////////////////////
'''
from __future__ import print_function, absolute_import
from nf.api import *
def init():
#变量初始化
global exchange #交易所
global front #交易币对前项币
global base #交易币对后项币
global symbol #交易标的
global freq #频率
global cost #交易手续费
global slip #滑点
global bid #买一价
global ask #卖一价
global vol #买eos的量
exchange='OKEX'
front=['btc','eos']
base=['usdt','btc']
symbol=[get_symbol(market=exchange,front=front[1],rear=base[1]),get_symbol(exchange,front[0],base[0]),get_symbol(exchange,front[1],base[0])]
freq='tick'
cost=[0.0015,0.0015,0.0015]
slip=[0.000001,0.0001,0.0001]
ask=[0.0,0.0,0.0]
bid=[0.0,0.0,0.0]
vol=100
print('三角套利eos/btc,btc/usdt,eos/usdt')``
subscribe(symbols=symbol,frequency=freq,count=1)
def on_tick(tick):
global exchange #交易所
global front #交易币对前项币
global base #交易币对后项币
global symbol #交易标的
global freq #频率
global cost #交易手续费
global slip #滑点
global bid #买一价
global ask #卖一价
global vol #买eos的量
for i in range(len(ask)):
if tick['symbol']==symbol[i]:
ask[i]=tick['quotes'][0]['ask_p']
bid[i]=tick['quotes'][0]['bid_p']
if min(ask)>0 and min(bid)>0:
if ask[0]*ask[1]*(1+slip[0])*(1+slip[1]) < bid[2]*(1-slip[2])*(1-cost[0])*(1-cost[1])*(1-cost[2]) :
#正向套利,买100个eos
print(tick['created_at'].strftime('%Y-%m-%d %H:%M:%S'),'正向套利开始')
order_buy_btcusdt=order_volume(symbol[1],vol*ask[0]*(1+slip[0])/((1-cost[0])*(1-cost[1])),side=1,order_type=1,price=ask[1]*(1+slip[1]))
order_buy_eosbtc=order_volume(symbol[0],vol/(1-cost[0]),side=1,order_type=1,price=ask[0]*(1+slip[0]))
order_sell_eosusdt=order_volume(symbol[2],vol,side=2,order_type=1,price=bid[2]*(1-slip[2]))
print('正向套利结束','\n\n')
if bid[0]*bid[1]*(1-slip[0])*(1-slip[1])*(1-cost[0])*(1-cost[1])*(1-cost[2]) > ask[2]*(1+slip[2]) :
#逆向套利
print(tick['created_at'].strftime('%Y-%m-%d %H:%M:%S'),'逆向套利开始')
order_buy_eosusdt=order_volume(symbol[2],vol/(1-cost[2]),side=1,order_type=1,price=ask[2]*(1+slip[2]))
order_sell_eosbtc=order_volume(symbol[0],vol,side=2,order_type=1,price=bid[0]*(1-slip[0]))
order_sell_btcusdt=order_volume(symbol[1],bid[0]*(1-slip[0])*(1-cost[0])*vol,side=2,order_type=1,price=bid[1]*(1-slip[1]))
print('逆向套利结束','\n\n')
def on_execution_report(execrpt):
print('打印交易回执:',execrpt,'\n')
def on_error(code,info):
print('错误代码:',code,'错误代码说明:',info)
def on_backtest_finished(indicator):
print('绩效对象打印:',indicator)
if __name__ == '__main__':
run(strategy_id='f5ec03a4-b572-11e8-a0fb-00ffa9185dbb',
filename='main.py',
mode=MODE_LIVE,
token='6778ebc60a3b004bcc7286a5566a28df')
前言:三角套利本来是外汇市场中利用交叉汇率定价错误进行的套利。同样可以应用在数字货币市场。利用数字货币市场中币币兑换之间价格的不及时而产生的套利机会。
三角套利原理
既然是三角套利当然有三种币对啦。以eos/usdt、btc/usdt和eos/usdt为例进行套利说明。
1、正向套利(挣usdt)
套利条件(简化):P1*P2>P3
首先定义变量:
买卖三种币对的手续费率为cost[0],cost[1]和cost[2],滑点分别为slip[0],slip[1]和slip[2]。
假设买1个eos,由于存在手续费,因此实际购买时需要下单的eos的量为:
eosbuy=\frac{1}{1-cost[0]}
因为需要主动买,因此需要按照当时的卖一价下单,对应需要花费的btc的量为:
buybtc=\frac{P_1*(1+slip[0])}{1-cost[0]}
购买btc_buy个btc需要花费的usdt的数量为:
usdtcost=\frac{P_1*P_2*(1+slip[0])*(1+slip[1])}{(1-cost[0])*(1-cost[1])}
卖出1个eos得到的usdt的数量为:
usdtget=P_3*(1-slip[2])*(1-cost[2])
存在套利机会需要满足得到的USDT比USDT多,即:
\frac{P_1*P_2*(1+slip[0])*(1+slip[1])}{(1-cost[0])*(1-cost[1])}<P_3*(1-slip[2])*(1-cost[2])
\Rightarrow
P_1*P_2*(1+slip[0])*(1+slip[1])<P_3*(1-slip[2])*(1-cost[2])*(1-cost[1])*(1-cost[0])
由于滑点和手续费率相对于价格来说很小,因此套利条件可以简化为:
\frac{P_1*P_2}{P_3}<\frac{(1-slip[2])*(1-cost[0]-cost[1]-cost[2])}{1+slip[0]+slip[1]}
简化为:
P_1*P_2>P_3
即我们可以认为在满足上式的条件时存在正向套利策略。
2、反向套利
套利条件(简化):P1*P2<P3
反向套利的流程:买1个eos需要花费一定数量的usdt,卖eos得到btc,将得到的btc全部卖出得到usdt,只要得到的usdt大于花费的usdt,即满足套利条件。
策略的实现
在币宽回测平台中进行策略回测。
策略相关说明:
1、回测时间:2018-08-01至2018-09-11
2、K线频率:tick
3、初始资金:10000 USDT和0.5个btc
4、交易手续费率:0.2%
5、均线参数:快速10日均线,慢速30日均线
回测交易所和币对:OKEX的BTC/USDT、1、EOS/BTC和EOS/USDT
策略代码如下:
# -*- coding: utf-8 -*- ''' //////////////////////////////////////////////////////////////////////// //免责声明:本策略仅供学习使用,请勿直接进行实盘交易,本策略不承诺任何收益。// /////////////////////////////////////////////////////////////////////// ''' from __future__ import print_function, absolute_import from nf.api import * def init(): #变量初始化 global exchange #交易所 global front #交易币对前项币 global base #交易币对后项币 global symbol #交易标的 global freq #频率 global cost #交易手续费 global slip #滑点 global bid #买一价 global ask #卖一价 global vol #买eos的量 exchange='OKEX' front=['btc','eos'] base=['usdt','btc'] symbol=[get_symbol(market=exchange,front=front[1],rear=base[1]),get_symbol(exchange,front[0],base[0]),get_symbol(exchange,front[1],base[0])] freq='tick' cost=[0.0015,0.0015,0.0015] slip=[0.000001,0.0001,0.0001] ask=[0.0,0.0,0.0] bid=[0.0,0.0,0.0] vol=100 print('三角套利eos/btc,btc/usdt,eos/usdt')`` subscribe(symbols=symbol,frequency=freq,count=1) def on_tick(tick): global exchange #交易所 global front #交易币对前项币 global base #交易币对后项币 global symbol #交易标的 global freq #频率 global cost #交易手续费 global slip #滑点 global bid #买一价 global ask #卖一价 global vol #买eos的量 for i in range(len(ask)): if tick['symbol']==symbol[i]: ask[i]=tick['quotes'][0]['ask_p'] bid[i]=tick['quotes'][0]['bid_p'] if min(ask)>0 and min(bid)>0: if ask[0]*ask[1]*(1+slip[0])*(1+slip[1]) < bid[2]*(1-slip[2])*(1-cost[0])*(1-cost[1])*(1-cost[2]) : #正向套利,买100个eos print(tick['created_at'].strftime('%Y-%m-%d %H:%M:%S'),'正向套利开始') order_buy_btcusdt=order_volume(symbol[1],vol*ask[0]*(1+slip[0])/((1-cost[0])*(1-cost[1])),side=1,order_type=1,price=ask[1]*(1+slip[1])) order_buy_eosbtc=order_volume(symbol[0],vol/(1-cost[0]),side=1,order_type=1,price=ask[0]*(1+slip[0])) order_sell_eosusdt=order_volume(symbol[2],vol,side=2,order_type=1,price=bid[2]*(1-slip[2])) print('正向套利结束','\n\n') if bid[0]*bid[1]*(1-slip[0])*(1-slip[1])*(1-cost[0])*(1-cost[1])*(1-cost[2]) > ask[2]*(1+slip[2]) : #逆向套利 print(tick['created_at'].strftime('%Y-%m-%d %H:%M:%S'),'逆向套利开始') order_buy_eosusdt=order_volume(symbol[2],vol/(1-cost[2]),side=1,order_type=1,price=ask[2]*(1+slip[2])) order_sell_eosbtc=order_volume(symbol[0],vol,side=2,order_type=1,price=bid[0]*(1-slip[0])) order_sell_btcusdt=order_volume(symbol[1],bid[0]*(1-slip[0])*(1-cost[0])*vol,side=2,order_type=1,price=bid[1]*(1-slip[1])) print('逆向套利结束','\n\n') def on_execution_report(execrpt): print('打印交易回执:',execrpt,'\n') def on_error(code,info): print('错误代码:',code,'错误代码说明:',info) def on_backtest_finished(indicator): print('绩效对象打印:',indicator) if __name__ == '__main__': run(strategy_id='f5ec03a4-b572-11e8-a0fb-00ffa9185dbb', filename='main.py', mode=MODE_LIVE, token='6778ebc60a3b004bcc7286a5566a28df')
回测结果如下(所有结果按每日公允汇率币/USD结算):
累计收益率:2.11%
年化收益率:20.67%
基准收益率:-16.69%
最大回撤:4.58%
Alpha:0.38
Beta:0.25
从回测结果中可以发现三角套利实现了不错超额收益和绝对收益,其中回测中有一部分是由于固定持仓0.5个btc导致的。从每日持仓可以看出,btc的持仓始终没有发生变化,但是经过三角套利,账户中的usdt增加了。实现了套利挣usdt的目的。
小结:由于数字货币市场发展的不尽完善,因此各个币对之间的定价或多或少的存在误差,也正是因此存在了不同套利空间。实际操作中可以套利挣eos,也可以套利挣btc。有兴趣的读者可以进行相关的回测。
声明:本文主要用于共同探讨和学习,请勿直接用于实盘交易。
后续将推出更多系列的量化策略,欢迎大家关注,共同交流。
文章为本人原创,转载时请注明作者。
一周热门 更多>