程序员常用的IDEA插件:https://github.com/silently9527/Toolkit
微信公众号:贝塔学Java
前提
本文使用的交易所SDK是 ExchangeSDK
本文所有内容仅用于讨论,没有任何交易建议,不对任何交易行为负责
永续合约
在开始分享套利策略之前,需要先来了解一些合约的概念。
永续合约是一种没有到期日的衍生品合约形式,广泛应用于加密货币和其他金融市场。与传统的期货合约不同,永续合约没有预定的交割日期,因此交易者可以无限期持有该合约。
永续合约的设计目的是为了模拟现货市场,但允许使用杠杆和做空。
永续合约的特点:
没有到期日:永续合约没有到期时间,交易者可以根据需要持有合约,直到选择平仓。
杠杆交易:交易者可以利用杠杆进行永续合约交易,即用较少的资金控制更大规模的头寸。
双向交易:永续合约允许交易者做多或做空标的资产。做多即买入合约,预期标的资产价格上涨;做空则是卖出合约,预期标的资产价格下跌。
这里可以考虑下,由于永续合约没有到期时间,不同于交割合约到期后会有个交割价格,这就导致了永续合约的价格可能会远远的偏离现货的价格,为了解决这个问题就引入了资金费率
资金费率
合约市场中的资金费率是永续合约中的一个重要机制,主要用于保证合约价格与现货市场价格的接近。如何保证的呢?
当合约市场价格高于现货市场价格时,资金费率为正。此时,做多的交易者需要支付资金费率给做空的交易者。
当合约市场价格低于现货市场价格时,资金费率为负。此时,做空的交易者需要支付资金费率给做多的交易者。
通过收取资金费用来保证合约市场的价格尽量与现货市场价格接近,通常每隔8小时进行一次资金费用结算。
套利策略的思路
监控市场所有合约的资金费率,找出市场中资金费率最大
采用高倍杠杆在资金费用开始结算前几秒使用脚本开仓
等待资金费用结算完成后立即平仓(越快越好,所以需要服务器网速快)
查询资金费率
这里只展示KC的资金费率查询,其他交易所类似
查询出所有的永续合约,再去遍历查询合约的资金费率,然后排序取出资金费率前5的合约信息(这里用到的交易所接口都封装到了ExchangeSDK)
FutureRestApiClient restApiClient = FutureApiInternalFactory.getInstance()
.createKucoinFutureRestApiClient(Constants.Future.KUCOIN_REST_API_BASE_URL, "your appKey", "your appSecret", "your passphrase");
List<FundingRate> fundingRateList = restApiClient.getFutures()
.stream()
.filter(future -> "USDT".equals(future.getQuoteAsset()) && future.getFutureType().equals(FutureType.PERPETUAL))
.map(future -> {
Utils.sleep(500);
return restApiClient.getFundingRate(future.getSymbol());
})
.sorted(sortFundingRate())
.limit(5)
.collect(toList());
String message = fundingRateList
.stream()
.map(fundingRate -> String.format("SYMBOL: %s, FundingRate: %s", fundingRate.getSymbol(), fundingRate.getFundingRate()))
.collect(Collectors.joining("
"));
log.info("current FundingRate: {}", message);
由于资金费率可能为正,也可能为负,所以我们在排序的时候需要使用绝对值比较
private Comparator<FundingRate> sortFundingRate() {
return (o1, o2) -> {
int compare = o1.getFundingRate().abs().compareTo(o2.getFundingRate().abs());
if (compare > 0) {
return -1;
} else if (compare < 0) {
return 1;
}
return 0;
};
}
套利程序
设计套利程序的参数
symbol: 设置需要套利的交易对;在上面我们已经查询出来了最大的资金费率,通过会在前5进行选择
money: 设置需要套利的本金;
openSide: 设置开仓方向;资金费率为正,就去卖;资金费率为负,就去买
leverage: 设置开仓杠杆(通常是逐仓使用,全仓使用的全局杠杆)
public void start() throws Exception {
Future future = this.restApiClient.getFuture(this.symbol);
SymbolPrice ticker = this.restApiClient.getSymbolPriceTicker(this.symbol);
BigDecimal tradeAmount = this.money.multiply(new BigDecimal(this.leverage))
.divide(ticker.getPrice(), 10, RoundingMode.DOWN)
.divide(future.getMultiplier(), 0, RoundingMode.DOWN);
log.info("current market price:{}, tradeAmount:{}", ticker.getPrice(), tradeAmount);
if (tradeAmount.doubleValue() <= 0) {
return;
}
this.restApiClient.postOrder(symbol, openSide, PositionSide.BOTH, OrderType.MARKET, TimeInForce.GTC, tradeAmount, ticker.getPrice(), false, Utils.uuid(), null, null, leverage);
Utils.sleep(200);
this.restApiClient.postOrder(symbol, openSide.oppositeSide(), PositionSide.BOTH, OrderType.MARKET, TimeInForce.GTC, tradeAmount, ticker.getPrice(), false, Utils.uuid(), null, null, leverage);
log.info("FutureQuickInOutPolicy Finish");
}
由于开仓和平仓都是使用的市价单,所以该策略很依赖盘口深度,如果深度太差会导致滑点很大
若需完整源码加微信
silently9527
,免费分享
原文链接: https://herman7z.site/Notes/No2TechColumn/05%20Trader/01%20%E6%B0%B8%E7%BB%AD%E5%90%88%E7%BA%A6%E5%BF%AB%E8%BF%9B%E5%BF%AB%E5%87%BA%E5%A5%97%E5%88%A9%E7%AD%96%E7%95%A5.html
最后(看完不点关注,你们想白嫖我吗)
文中或许会存在或多或少的不足、错误之处,有建议或者意见也非常欢迎大家在评论交流。
最后,写作不易,请不要白嫖我哟,希望朋友们可以点赞评论关注三连,因为这些就是我分享的全部动力来源🙏