Type/to search
7
Follow
359
Followers
여러 거래소에서 현물 가격 차이 차익 거래 전략의 논리를 공유합니다.
Original
Created 2022-06-27 21:26:27  Updated 2024-12-02 21:35:44
 4
 10032

img

전략 원칙

유동성의 이유로, 시장에서 매도나 풀링이 많을 때는 필연적으로 큰 가격 변동이 있을 것이고, 거래소 간에 순간적인 가격 차이가 있을 것입니다. 전략은 이러한 순간을 포착하여 빠른 거래를 실행하는 것입니다. 낮은 가격에 사고 높은 가격에 파는 과정을 완료합니다.
일부 고객은 왜 그렇게 많은 거래소를 가지고 있는지 물었습니다. 이는 불가피한 일입니다. 우리가 돈을 버는 것은 거래소 간의 즉각적인 가격 차이입니다. 거래소가 많을수록 교차 후 가격 차이 기회가 더 많아질 것입니다.

전략 핵심 논리
  1. 여러 거래소의 시장 정보를 동시에 획득합니다. 시장 정보 획득의 지연을 줄이기 위해 동시에 획득하는 것이 필요합니다. 동시 획득의 경우 제가 공유한 도구 플러그인을 참조할 수 있습니다.다중 거래소 동시 플러그인
  2. 모든 거래소의 매도 및 매수 가격을 합산하여 결합된 견적 정보를 얻습니다. 여기서 RealPrice는 처리 수수료를 공제한 가격입니다.
function createOrders(depths, askOrders, bidOrders) { let asksIndex = 0; let bidIndex = 0; for (let i = 0; i < depths.length; i++) { let exchangeTariff = getExchangeTariff(i); let asks = depths[i].Asks; let bids = depths[i].Bids; for (let j = 0; j < Math.min(asks.length, bids.length, 20); j++) { if (asks[j].Amount >= minTakerAmount) { askOrders[asksIndex] = { "Price": asks[j].Price, "Amount": asks[j].Amount, "Fee": asks[j].Price * exchangeTariff, "RealPrice": asks[j].Price * (1 + exchangeTariff), "Index": i, }; asksIndex++; } if (bids[j].Amount >= minTakerAmount) { bidOrders[bidIndex] = { "Price": bids[j].Price, "Amount": bids[j].Amount, "Fee": bids[j].Price * exchangeTariff, "RealPrice": bids[j].Price * (1 - exchangeTariff), "Index": i, }; bidIndex++; } } } askOrders.sort(function (a, b) { return a.RealPrice - b.RealPrice; }); bidOrders.sort(function (a, b) { return b.RealPrice - a.RealPrice; }); }
  1. 종합된 시장 정보를 바탕으로 가장 수익성이 높은 차익거래 스프레드를 계산합니다. 우리는 주문을 받고 있기 때문에, 즉 가장 낮은 매도 가격에서 매수하고 가장 높은 매수 가격에서 매도하는 한 bid.RealPrice > ask.RealPrice이면 수익 공간이 있습니다.
function getArbitrageOrders(askOrders, bidOrders) { let ret = []; for (let i = 0; i < askOrders.length; i++) { for (let j = 0; j < bidOrders.length; j++) { let bidOrder = bidOrders[j]; let askOrder = askOrders[i]; if (bidOrder.Index === askOrder.Index) { continue } let minMigrateDiffPrice = ((askOrder.Price + bidOrder.Price) / 2 * minMigrateDiffPricePercent / 100); if (bidOrder.RealPrice - askOrder.RealPrice > minMigrateDiffPrice) { ret.push({ "Ask": askOrder, "Bid": bidOrder, }) } } } if (ret.length === 0) { ret.push({ "Ask": askOrders[0], "Bid": bidOrders[0], }); } //按最优价差排序 ret.sort((a, b) => { return (b.Bid.RealPrice - b.Ask.RealPrice) - (a.Bid.RealPrice - a.Ask.RealPrice); }); return ret; }
  1. 이제 시장에서 아비트라지 스프레드 정보를 얻었으니, 거래를 실행할지 여부와 얼마를 거래할지 어떻게 결정할까요? 고려해야 할 몇 가지 핵심 사항은 다음과 같습니다.
  • 현재 남은 자산
  • 스프레드의 크기(스프레드가 너무 작으면 통화량만 균형을 이루고, 스프레드가 충분히 크면 거래 수가 최대화됩니다)
  • 보류중인 주문 수
var askOrder = arbitrageOrder.Ask; var bidOrder = arbitrageOrder.Bid; var perAmountFee = arbitrageOrder.Ask.Fee + arbitrageOrder.Bid.Fee; var minRealDiffPrice = (askOrder.Price + bidOrder.Price) / 2 * minDiffPricePercent / 100; var minMigrateDiffPrice = ((askOrder.Price + bidOrder.Price) / 2 * minMigrateDiffPricePercent / 100); var curRealDiffPrice = arbitrageOrder.Bid.RealPrice - arbitrageOrder.Ask.RealPrice; var buyExchange = exchanges[arbitrageOrder.Ask.Index]; var sellExchange = exchanges[arbitrageOrder.Bid.Index]; var buySellAmount = 0; if (curRealDiffPrice > minRealDiffPrice) { buySellAmount = math.min( bidOrder.Amount, askOrder.Amount, maxTakerAmount, runningInfo.Accounts[bidOrder.Index].CurStocks, runningInfo.Accounts[askOrder.Index].CurBalance / askOrder.Price ); } else if (bidOrder.Index !== askOrder.Index) { if (migrateCoinEx == -1) { if (curRealDiffPrice > minMigrateDiffPrice && runningInfo.Accounts[bidOrder.Index].CurStocks - runningInfo.Accounts[askOrder.Index].CurStocks > maxAmountDeviation) { buySellAmount = math.min( bidOrder.Amount, askOrder.Amount, maxTakerAmount, runningInfo.Accounts[bidOrder.Index].CurStocks, runningInfo.Accounts[askOrder.Index].CurBalance / askOrder.Price, runningInfo.Accounts[bidOrder.Index].CurStocks - ((runningInfo.Accounts[bidOrder.Index].CurStocks + runningInfo.Accounts[askOrder.Index].CurStocks) / 2) ); if (buySellAmount >= minTakerAmount) { Log("启动交易所平衡!"); } } } else if (migrateCoinEx == askOrder.Index) { if (curRealDiffPrice > minMigrateDiffPrice && runningInfo.Accounts[bidOrder.Index].CurStocks > 0) { buySellAmount = math.min( bidOrder.Amount, askOrder.Amount, maxTakerAmount, runningInfo.Accounts[bidOrder.Index].CurStocks, runningInfo.Accounts[askOrder.Index].CurBalance / askOrder.Price ); if (buySellAmount >= minTakerAmount) { Log("启动货币迁移:", exchanges[bidOrder.Index].GetName(), "-->", exchanges[askOrder.Index].GetName()); } } } }
  1. 주문 수량이 계산되면 거래를 실행할 수 있습니다. 이 전략은 슬리피지를 직접 추가하여 주문을 받고 동시에 주문을 하는 방법을 사용합니다.
var buyWait = buyExchange.Go("Buy", _N(askOrder.Price * (1.01), pricePrecision), buySellAmount); var sellWait = sellExchange.Go("Sell", _N(bidOrder.Price * (0.99), pricePrecision), buySellAmount); var startWaitTime = new Date().getTime() Sleep(3000); var buyOrder = buyWait.wait() var sellOrder = sellWait.wait()
  1. 남는 것은 이익 계산, 실패한 주문에 대한 손절매 처리 등의 논리입니다.
이 전략의 실제 이점

img
img
img

현재 실시간 디스플레이, 핵심 로직은 변경되지 않고 여러 통화를 지원하도록 최적화되었습니다.

https://www.fmz.com/robot/464965

마지막으로, Laoqiu 양적 거래소에 오신 것을 환영합니다: https://t.me/laoqiu_arbitrage

Related Recommendations
Comment
All comments (4)

    大佬,minTakerAmount参数是怎么设置的

    2 years ago

    就怕小交易所跑路啊。

    3 years ago

    4 years ago

    秋哥威武。

    4 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)