在第一篇文章中,大概介绍了如何Lead-Lag现象进行套利,本文将主要介绍跨交易所的“搬砖”套利。其基本原理是通过利用不同交易所之间的价格滞后现象(Lead-Lag效应),因为各个交易所的市场流动性、成交速度和网络延迟不同,导致同一种币在不同交易所的价格往往不同步。套利者可以通过监测这种滞后的价格变化,快速进行套利,从而获取无风险利润。
首先,套利者需要实时监控不同交易所之间的价格差异,尤其是卖一价和买一价。通过跟踪交易所A的卖一价与交易所B的买一价,若交易所A的卖一价低于交易所B的买一价,则可认为存在套利机会。例如,交易所A的卖一价为10,000 USDT,交易所B的买一价为10,100 USDT,价格差为100 USDT,这时即为一个潜在的套利机会。当然也要考虑到最近历史的差价范围,作为开仓、平仓差价的参考,等待的时间也是成本之一。
一旦发现套利机会,套利者应在卖价较低的交易所(如交易所A)买入资产,并在买价较高的交易所(如交易所B)卖出。这一操作可以通过API自动化完成,确保快速执行,最大程度地利用价格差异。然而,在执行交易时,必须考虑交易成本(如手续费和滑点)以及价格冲击。假设交易所A的手续费为0.1%,而交易所B的手续费为0.2%,同时市场存在滑点。例如,在交易所A买入1个比特币时,实际成交价可能会因大额订单的执行导致价格上升,假设滑点为0.1%。那么,实际成交价格将比预期高出0.1%,导致买入成本增加。
如果考虑滑点和手续费,实际的买入成本和卖出收入会与预期有所差距。
套利的最后一步是平仓。如一段时间后,交易所A的买一价为10,100 USDT,交易所B的卖一价为10,150 USDT,价格差从100 USDT缩小到50 USDT时,程序会自动平仓获利了结。当然在一些情况下,差价还有可能继续扩大,可以继续开仓,知道资金耗尽。交易所的差价之所以无法维持,套利者贡献了绝大多数的力量。
由于大量套利者和做市商的存在,不同交易所的价差不会差的很多,否则很快会被搬平。这是套利交易面临的最大问题。
抢单失败是常见问题,当程序发现差价去套利下单,结果实际成交的差价没有这么大,往往还亏损。这时,最快的反应和执行速度至关重要。
单腿成交指的是一方操作完成,而另一方未能成交,这通常发生在市场快速波动的情况下。如果只有一方订单成功,套利者便会面临敞口风险。
当差价长期存在,某个交易所的资金会迅速的全部买入,套利者可能无法继续进行套利操作。此时,套利者需要快速转移资金或调整持仓。
代码不是实盘代码,仅供演示使用,如没有考虑到盘口数量、API访问失败用错、异步下单提速等等问题。
// symbol 是套利的交易对,比如 BTC/USDT
let symbol = "BTC_USDT";
// 设置手续费、滑点、开仓和平仓的利润率
let fee = 0.1 / 100; // 0.1% 手续费
let slippage = 0.1 / 100; // 0.1% 滑点
let entryThreshold = 0.005; // 开仓阈值:价差大于0.5%时开仓
let exitThreshold = 0.001; // 平仓阈值:价差回归到0.1%时平仓
// 每次循环执行的具体操作
function OnTick() {
// 获取各个交易所的行情数据
let tickers = exchanges.map(exchange => exchange.GetTicker(symbol));
// 计算套利机会(基于利润率)
// profitAB: 从交易所0买入,从交易所1卖出
const profitAB = (tickers[1].bid - tickers[0].ask) / tickers[0].ask - fee * 2 - slippage * 2;
// profitBA: 从交易所1买入,从交易所0卖出
const profitBA = (tickers[0].bid - tickers[1].ask) / tickers[1].ask - fee * 2 - slippage * 2;
// 打印日志
Log(`Tickers: Exchange0 Buy: ${tickers[0].ask}, Exchange1 Sell: ${tickers[1].bid}, Profit AB: ${profitAB} USDT`);
Log(`Tickers: Exchange1 Buy: ${tickers[1].ask}, Exchange0 Sell: ${tickers[0].bid}, Profit BA: ${profitBA} USDT`);
// 根据利润判断是否执行套利操作
if (profitAB > entryThreshold) { // 当利润大于开仓阈值时开仓
Log(`套利机会:从交易所0买入BTC,从交易所1卖出,利润:${profitAB} USDT`);
executeArbitrage(0, 1, tickers[0].ask, tickers[1].bid, profitAB); // 从交易所0买入并在交易所1卖出
} else if (profitBA > entryThreshold) {
Log(`套利机会:从交易所1买入BTC,从交易所0卖出,利润:${profitBA} USDT`);
executeArbitrage(1, 0, tickers[1].ask, tickers[0].bid, profitBA); // 从交易所1买入并在交易所0卖出
} else if (profitAB < exitThreshold) { // 如果价差回归,平仓
Log(`平仓:从交易所0买入并在交易所1卖出的套利机会,利润已回归至平仓阈值`);
closeArbitrage(0, 1, tickers[0].ask, tickers[1].bid); // 执行平仓操作
} else if (profitBA < exitThreshold) {
Log(`平仓:从交易所1买入并在交易所0卖出的套利机会,利润已回归至平仓阈值`);
closeArbitrage(1, 0, tickers[1].ask, tickers[0].bid); // 执行平仓操作
} else {
Log("没有足够的利润进行套利或平仓");
}
}
// 执行套利交易
function executeArbitrage(buyExchangeIndex, sellExchangeIndex, buyPrice, sellPrice) {
let buyExchange = exchanges[buyExchangeIndex];
let sellExchange = exchanges[sellExchangeIndex];
// 获取账户余额(假设为BTC余额)
let accountBuy = buyExchange.GetAccount();
let accountSell = sellExchange.GetAccount();
let amountBTC = Math.min(accountBuy.Balance / buyPrice, accountSell.Amount);
// 假设每次交易量为 0.1 BTC
let amount = Math.min(amountBTC, 0.1);
// 确保交易量充足
if (amount <= 0) {
Log("余额不足,无法进行套利");
return;
}
// 在买入交易所挂单买入
Log(`在交易所${buyExchangeIndex} 下单买入 ${amount} BTC @ ${buyPrice}`);
buyExchange.Buy(symbol, buyPrice * (1 + slippage), amount);
// 在卖出交易所挂单卖出
Log(`在交易所${sellExchangeIndex} 下单卖出 ${amount} BTC @ ${sellPrice}`);
sellExchange.Sell(symbol, sellPrice * (1 - slippage), amount);
}
// 平仓操作
function closeArbitrage(buyExchangeIndex, sellExchangeIndex, buyPrice, sellPrice) {
let buyExchange = exchanges[buyExchangeIndex];
let sellExchange = exchanges[sellExchangeIndex];
// 获取账户余额(假设为BTC余额)
let accountBuy = buyExchange.GetAccount();
let accountSell = sellExchange.GetAccount();
let amountBTC = Math.min(accountBuy.Balance / buyPrice, accountSell.Amount);
let amount = Math.min(amountBTC, 0.1);
// 在买入交易所挂单卖出
Log(`在交易所${buyExchangeIndex} 平仓卖出 ${amount} BTC @ ${buyPrice}`);
buyExchange.Sell(symbol, buyPrice * (1 - slippage), amount);
// 在卖出交易所挂单买入
Log(`在交易所${sellExchangeIndex} 平仓买入 ${amount} BTC @ ${sellPrice}`);
sellExchange.Buy(symbol, sellPrice * (1 + slippage), amount);
}
// 主循环
function main() {
while (true) {
OnTick();
Sleep(1000); // 每秒钟执行一次
}
}
Lead-Lag搬砖套利是一个基于市场滞后反应的跨交易所套利策略。通过准确分析市场的价格差异并快速执行交易,套利者能够在数字货币市场中获取稳定的利润。然而,这一策略的成功不仅依赖于策略本身的设计,还需要良好的执行力和对市场时机的敏感把握。随着市场竞争的加剧,套利者需要不断优化策略和技术,提升速度和反应能力,以保持套利机会的持续有效性。