FMZ Quant: Eine Analyse von gemeinsamen Anforderungen Designbeispielen auf dem Kryptowährungsmarkt (I)

Schriftsteller:Lydia., Erstellt: 2023-12-19 16:02:58, aktualisiert: 2024-01-02 21:21:58

img

In der Kryptowährungs-Asset-Handelswelt sind die Erfassung und Analyse von Marktdaten, Abfrageraten und die Überwachung von Kontovermögensbewegungen alle kritische Operationen.

1. Wie schreibe ich den Code, um die Währung mit dem höchsten Anstieg in 4 Stunden auf Binance Spot zu erhalten?

Bei der Erstellung eines quantitativen Handelsstrategieprogramms auf der FMZ-Plattform ist das erste, was Sie tun müssen, wenn Sie auf eine Anforderung stoßen, sie zu analysieren.

  • Welche Programmiersprache soll ich verwenden? Der Plan ist es, Javascript zu verwenden, um es zu implementieren.
  • Erfordert Echtzeit-Spot-Noten in allen Währungen Das erste, was wir taten, als wir die Anforderung sahen, war, das Binance API-Dokument aufzusuchen, um herauszufinden, ob es aggregierte Angebote gibt (es ist am besten, aggregierte Angebote zu haben, es ist viel Arbeit, eins nach dem anderen aufzusuchen). Wir haben die zusammengefasste Anführungsoberfläche gefunden:GET https://api.binance.com/api/v3/ticker/price- Ich weiß. Auf der FMZ-Plattform verwenden Sie dieHttpQueryFunktion zum Zugriff auf die Exchange-Ticker-Schnittstelle (öffentliche Schnittstelle, für die keine Signatur erforderlich ist).
  • Daten für ein rollendes Fenster von 4 Stunden zählen müssen Konzeptionieren Sie, wie die Struktur des statistischen Programms gestaltet wird.
  • Berechnen und sortieren Sie Preisschwankungen Denken wir über den Preisschwankungs-Algorithmus nach, ist es:price fluctuations (%) = (current price - initial price) / initial price * 100in %

Nachdem wir das Problem gelöst und das Programm definiert hatten, begannen wir, das Programm zu entwerfen.

Codeentwurf

var dictSymbolsPrice = {}

function main() {
    while (true) {
        // GET https://api.binance.com/api/v3/ticker/price
        try {
            var arr = JSON.parse(HttpQuery("https://api.binance.com/api/v3/ticker/price"))
            if (!Array.isArray(arr)) {
                Sleep(5000)
                continue 
            }
            
            var ts = new Date().getTime()
            for (var i = 0; i < arr.length; i++) {
                var symbolPriceInfo = arr[i]
                var symbol = symbolPriceInfo.symbol
                var price = symbolPriceInfo.price

                if (typeof(dictSymbolsPrice[symbol]) == "undefined") {
                    dictSymbolsPrice[symbol] = {name: symbol, data: []}
                }
                dictSymbolsPrice[symbol].data.push({ts: ts, price: price})
            }
        } catch(e) {
            Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
        }
        
        // Calculate price fluctuations
        var tbl = {
            type : "table",
            title : "Price fluctuations",
            cols : ["trading pair", "current price", "price 4 hours ago", "price fluctuations", "data length", "earliest data time", "latest data time"],
            rows : []
        }
        for (var symbol in dictSymbolsPrice) {
            var data = dictSymbolsPrice[symbol].data
            if (data[data.length - 1].ts - data[0].ts > 1000 * 60 * 60 * 4) {
                dictSymbolsPrice[symbol].data.shift()
            }

            data = dictSymbolsPrice[symbol].data
            dictSymbolsPrice[symbol].percentageChange = (data[data.length - 1].price - data[0].price) / data[0].price * 100
        }

        var entries = Object.entries(dictSymbolsPrice)
        entries.sort((a, b) => b[1].percentageChange - a[1].percentageChange)

        for (var i = 0; i < entries.length; i++) {
            if (i > 9) {
                break
            }   
            var name = entries[i][1].name
            var data = entries[i][1].data
            var percentageChange = entries[i][1].percentageChange
            var currPrice = data[data.length - 1].price
            var currTs = _D(data[data.length - 1].ts)
            var prePrice = data[0].price
            var preTs = _D(data[0].ts)
            var dataLen = data.length

            tbl.rows.push([name, currPrice, prePrice, percentageChange + "%", dataLen, preTs, currTs])
        }
        
        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
        Sleep(5000)
    }
}

Codeanalyse

    1. Datenstrukturvar dictSymbolsPrice = {}: Ein leeres Objekt zum Speichern von Preisinformationen für jedes Handelspaar. Der Schlüssel ist das Symbol des Handelspaares, und der Wert ist ein Objekt, das den Namen des Handelspaares, ein Array von Preisdaten und Informationen über die Preisschwankungen enthält.
    1. Hauptfunktion 2.1 Unendliche Schleife
while (true) {
    // ...
}

Das Programm überwacht kontinuierlich die Preise der Binance-API-Tradingpaare durch eine unendliche Schleife. 2.2. Preisinformationen erhalten

var arr = JSON.parse(HttpQuery("https://api.binance.com/api/v3/ticker/price"))

Holen Sie sich die aktuellen Preisinformationen des Handelspares über die Binance API. Wenn die Rendite kein Array ist, warten Sie 5 Sekunden und versuchen Sie es erneut. 2.3. Aktualisierung der Preisdaten

for (var i = 0; i < arr.length; i++) {
    // ...
}

Iteration durch das Array der erhaltenen Preisinformationen und Aktualisierung der Daten in dictSymbolsPrice. Für jedes Handelspaar fügen Sie den aktuellen Zeitstempel und den aktuellen Preis zum entsprechenden Datensatz hinzu. 2.4. Ausnahmeregelung

} catch(e) {
    Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}

Ausnahmen erfassen und die Ausnahmeinformationen protokollieren, um sicherzustellen, dass das Programm weiterhin ausgeführt werden kann. 2.5. Berechnung der Preisschwankungen

for (var symbol in dictSymbolsPrice) {
    // ...
}

Iteration durch dictSymbolsPrice, Berechnung der Kursschwankungen jedes Handelspaares und Entfernung der frühesten Daten, wenn sie länger als 4 Stunden sind. 2.6. Sortieren und erstellen von Tabellen

var entries = Object.entries(dictSymbolsPrice)
entries.sort((a, b) => b[1].percentageChange - a[1].percentageChange)

for (var i = 0; i < entries.length; i++) {
    // ...
}

Sortieren Sie die Handelspare in absteigender Reihenfolge ihrer Kursschwankungen und erstellen Sie eine Tabelle mit Informationen über die Handelspare. 2.7. Log-Ausgabe und Verzögerung

LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(5000)

Die Tabelle und die aktuelle Uhrzeit werden in Form eines Logs ausgeführt und 5 Sekunden warten, bis die nächste Runde der Schleife fortgesetzt wird.

Das Programm erhält die Echtzeitpreisinformationen des Handelspares über die Binance API, berechnet dann die Preisschwankungen und liefert sie in Form einer Tabelle an das Protokoll aus. Das Programm wird in einer kontinuierlichen Schleife ausgeführt, um die Funktion der Echtzeitüberwachung der Preise von Handelsparen zu realisieren. Beachten Sie, dass das Programm eine Ausnahmeverarbeitung umfasst, um sicherzustellen, dass die Ausführung nicht durch Ausnahmen unterbrochen wird.

Live-Trading-Lauftest

img

Da die Daten zu Beginn nur schrittweise erhoben werden können, ist es nicht möglich, die Kursschwankungen kontinuierlich zu berechnen, ohne genügend Daten für ein 4-Stunden-Fenster zu sammeln. Daher wird der Anfangspreis als Berechnungsgrundlage verwendet, und nachdem genügend Daten für 4 Stunden gesammelt wurden, werden die ältesten Daten eliminiert, um das 4-Stunden-Fenster für die Berechnung der Kursschwankungen zu erhalten.

2. Überprüfen Sie die vollständige Auswahl an Finanzierungsquoten für Binance-U-Kontrakte

Die Überprüfung der Förderquote ist ähnlich wie der obige Code, zunächst müssen wir die Dokumentation der Binance API überprüfen, um die mit der Förderquote verbundene Schnittstelle zu finden. Binance hat mehrere Schnittstellen, mit denen wir die Förderquote abfragen können, hier nehmen wir die Schnittstelle des U-denominierten Vertrags als Beispiel:

GET https://fapi.binance.com/fapi/v1/premiumIndex

Umsetzung des Codes

Da es so viele Verträge gibt, exportieren wir hier die 10 größten Förderquoten.

function main() {
    while (true) {
        // GET https://fapi.binance.com/fapi/v1/premiumIndex
        try {
            var arr = JSON.parse(HttpQuery("https://fapi.binance.com/fapi/v1/premiumIndex"))
            if (!Array.isArray(arr)) {
                Sleep(5000)
                continue 
            }
            
            arr.sort((a, b) => parseFloat(b.lastFundingRate) - parseFloat(a.lastFundingRate))
            var tbl = {
                type: "table",
                title: "Top 10 funding rates for U-denominated contracts",
                cols: ["contracts", "funding rate", "marked price", "index price", "current rate time", "next rate time"],
                rows: []
            }
            for (var i = 0; i < 9; i++) {
                var obj = arr[i]
                tbl.rows.push([obj.symbol, obj.lastFundingRate, obj.markPrice, obj.indexPrice, _D(obj.time), _D(obj.nextFundingTime)])
            }
            LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
        } catch(e) {
            Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
        }
        Sleep(1000 * 10)
    }
}

Die zurückgegebene Datenstruktur ist wie folgt, und überprüfen Sie die Binance-Dokumentation, es zeigt, dass lastFundingRate ist die Finanzierung Rate, die wir wollen.

{
    "symbol":"STMXUSDT",
    "markPrice":"0.00883606",
    "indexPrice":"0.00883074",
    "estimatedSettlePrice":"0.00876933",
    "lastFundingRate":"0.00026573",
    "interestRate":"0.00005000",
    "nextFundingTime":1702828800000,
    "time":1702816229000
}

Live-Trading-Lauftest:

img

Erhalten OKX Austauschvertrag Finanzierungssätze von Python Version

Ein Benutzer hat nach einer Python-Version des Beispiels gefragt, und es ist für den OKX-Austausch. Hier ein Beispiel:

Die von der Schnittstelle zurückgegebenen Datenhttps://www.okx.com/priapi/v5/public/funding-rate-all?currencyType=1:

{
    "code":"0",
    "data":[
        {
            "fundingTime":1702828800000,
            "fundingList":[
                {
                    "instId":"BTC-USDT-SWAP",
                    "nextFundingRate":"0.0001102188733642",
                    "minFundingRate":"-0.00375",
                    "fundingRate":"0.0000821861465884",
                    "maxFundingRate":"0.00375"
                } ...

Spezifischer Code:

import requests
import json
from time import sleep
from datetime import datetime

def main():
    while True:
        # https://www.okx.com/priapi/v5/public/funding-rate-all?currencyType=1
        try:
            response = requests.get("https://www.okx.com/priapi/v5/public/funding-rate-all?currencyType=1")
            arr = response.json()["data"][0]["fundingList"]
            Log(arr) 
            if not isinstance(arr, list):
                sleep(5)
                continue

            arr.sort(key=lambda x: float(x["fundingRate"]), reverse=True)

            tbl = {
                "type": "table",
                "title": "Top 10 funding rates for U-denominated contracts",
                "cols": ["contracts", "next rate", "minimum", "current", "maximum"],
                "rows": []
            }

            for i in range(min(9, len(arr))):
                obj = arr[i]
                row = [
                    obj["instId"],
                    obj["nextFundingRate"],
                    obj["minFundingRate"],
                    obj["fundingRate"],
                    obj["maxFundingRate"]
                ]
                tbl["rows"].append(row)
            
            LogStatus(_D(), "\n", '`' + json.dumps(tbl) + '`')

        except Exception as e:
            Log(f"Error: {str(e)}")

        sleep(10)

Live-Trading-Lauftest:

img

Ende

Diese Beispiele liefern grundlegende Designideen und Anrufmethoden, das eigentliche Projekt muss möglicherweise geeignete Änderungen und Erweiterungen basierend auf den spezifischen Bedürfnissen vornehmen.


Mehr