Die Ressourcen sind geladen. Beförderung...

Multi-Exchange-Spot-Spread-Arbitrage-Strategie Logikfreigabe

Schriftsteller:Die Erfinder quantifizieren - Kleine Träume, Erstellt: 2022-07-12 17:20:06, aktualisiert: 2023-09-25 19:47:14

img

Grundsätze der Strategie

Aufgrund von Liquiditätsgründen, wenn es eine große Menge von Smashing und Pulling auf dem Markt gibt, wird es unweigerlich große Preisschwankungen geben, und eine sofortige Preisdifferenz wird zwischen den Börsen gebildet, und die Strategie besteht darin, diese Momente einzufangen, in denen schnelle Trades ausgeführt werden, um den Prozess des Kaufs niedrig und des Verkaufs hoch abzuschließen. Einige Kunden haben mich gefragt, warum ich so viele Börsen bekommen muss. Dies ist unvermeidlich. Was wir verdienen, ist die sofortige Preisdifferenz zwischen den Börsen. Je mehr Börsen, desto mehr Möglichkeiten für die Preisdifferenz nach dem Crossover gebildet.

Kernlogik der Strategie
  1. Für die gleichzeitige Akquisition ist der Tool-Plug-in zu beachten, den ich gemeinsam mit den Unternehmen erstellt habe, um zu ermitteln, ob die Marktinformationen für mehrere Börsen gleichzeitig erhältlich sind.Multi-Exchange gleichzeitiges Plug-in
  2. Kombinieren Sie das Angebot und das Angebot aller Börsengeschäfte, um eine kombinierte Auftragsinformation zu erhalten, wobei RealPrice der Preis nach Abzug der Bearbeitungsgebühr ist,
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. Berechnen Sie den besten Arbitrage-Spread aus den kombinierten Marktinformationen. Da wir die Bestellung nehmen, d.h. vom niedrigsten Preis kaufen und vom höchsten Preis bieten, solange bid.RealPrice > ask.RealPrice, gibt es Raum für Gewinn
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. An dieser Stelle haben wir die Informationen über die Arbitrage-Spread auf dem Markt erhalten, so dass es mehrere Urteilspunkte gibt, wie man wählt, ob man einen Handel ausführt und wie viel man handelt:
  • Laufende Restvermögenswerte
  • Die Größe des Spreads (wenn der Spread zu klein ist, wird nur der Betrag der Währung ausgeglichen, und wenn der Spread groß genug ist, wird die Anzahl der Trades maximiert)
  • Anzahl der ausstehenden Aufträge
    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. Nach Berechnung der Anzahl der zu platzierenden Aufträge kann die Transaktion ausgeführt werden.
            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. Alles, was bleibt, ist die Logik der Berechnung von Renditen, der Abwicklung von Stop-Losses bei fehlgeschlagenen Aufträgen und so weiter.
Die tatsächlichen Gewinne der Strategie

img img img

Aktuelles echtes Bot-Display, Kernlogik bleibt unverändert, optimiert für die Unterstützung mehrerer Währungen

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

Abschließend begrüßen wir Sie, sich der Mitteilung über den quantitativen Austausch von Laoqiu anzuschließen:https://t.me/laoqiu_arbitrage


Verwandt

Mehr