리소스 로딩... 로딩...

다중 거래소 스팟 스프레드 중재 전략 논리 공유

저자:발명가들의 수량화 - 작은 꿈, 창작: 2022-07-12 17:20:06, 업데이트: 2024-12-02 21:43:21

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. 결합된 시장 정보에서 최고의 중재 스프레드를 계산합니다. 우리는 주문을 취하기 때문에, 즉, 가장 낮은 가격에서 구매하고 가장 높은 가격에서 판매합니다.
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],
        });
    }
    //Sort by best spread
    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("Start exchange balancing!");
                }
            }
        } 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("Initiate currency migration:", 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

마지막으로, 라오키우 양적 교환 의사 소통에 참여하는 것을 환영합니다.https://t.me/laoqiu_arbitrage


관련

더 많은