Die Ressourcen sind geladen. Beförderung...

Backtest-System

Nachdem Sie die Gestaltung einer quantitativen Handelsstrategie abgeschlossen haben, wie können Sie die grundlegende Situation Ihrer Strategie kennen, wie die Logik der Strategie und die Richtung der Rendite der Strategie? Natürlich können wir nicht direkt echtes Geld verwenden, um die Strategie auf dem realen Handelsmarkt auszuführen, aber wir können historische Daten verwenden, um Ihre Strategie zu testen und die Gewinne Ihrer Strategie in den historischen Daten zu kennen.

Backtest-Systemmodell

FMZ Quant Trading Platform teilt das Backtestsystem inBot-EbeneundSimulationsstufe. Die Bot-Ebene ist, um Backtest vollständig nach den vollständigen historischen Daten; während die Simulation-Ebene Backtest erzeugttickDie Daten basieren beide auf den realen historischen Daten, aber die Daten auf Bot-Ebene sind genauer und die Ergebnisse glaubwürdiger. Allerdings ist das Backtesting nur die Leistung der Strategie nach historischen Daten. Die historischen Daten können den zukünftigen Markt nicht vollständig repräsentieren. Der historische Markt kann sich wiederholen oder auch zum Schwarzen Schwanen führen. Daher sollten die Rücktests rational und objektiv behandelt werden.

DieSimulationsstufe Tickerzeugt die simulierteZeichendatenAuf der Grundlage der zugrunde liegenden K-Linienperiode erzeugt jede zugrunde liegende K-Linienperiode maximal 12 Backtest-Zeitpunkte.Marktwert TickDas Backtesting-Mechanismus von FMZ Quant ermöglicht es der Strategie, mehrmals auf einer einzigen K-Linie zu handeln, wodurch die Situation vermieden wird, in der der Handel nur zum Schlusskurs ausgeführt werden kann.

Beschreibung des Mechanismus des Backtestsystems

  • Simulationsstufe Tick DieSimulationsstufe Tickbasiert auf den zugrunde liegenden K-Liniendaten des Backtestsystems, simuliert Tick-Daten zum Backtest im Rahmen des höchsten Preises, des niedrigsten Preises, des Eröffnungspreises und des Schlusskurswerts einer gegebenen zugrunde liegenden K-Linienleiste nach einem bestimmten Algorithmus. Als Echtzeit-Tick-Daten auf der Backtesting-Zeitreihe wird es zurückgegeben, wenn das Strategieprogramm die Schnittstelle aufruft.Beschreibung des Mechanismus für die Simulation der Backtest-Systeme.

  • Tick auf Bot-Ebene Der Bot-Level-Backtest ist die tatsächlichen Tick-Level-Daten in der Bar-Zeitrahmenreihe. Für Strategien, die auf Tick-Level-Daten basieren, ist die Verwendung von echtem Marktniveau zum Backtest näher an der Realität. Im Bot-Level-Backtest sind Tick-Daten echte aufgezeichnete Daten, keine simulierte. Es unterstützt Tiefendaten, Datenspielung von Markthandeln, benutzerdefinierte Tiefe und jedes einzelne Handelsdaten. Die maximale Größe des Real-Markt-Level-Daten-Backtests beträgt maximal 50 MB, ohne Begrenzung des Backtest-Zeitrahmens innerhalb der oberen Grenze des Datensatzes. Wenn Sie den Backtest-Zeitrahmen so weit wie möglich vergrößern müssen, können Sie den Wert der Gear-Tiefe-Einstellung reduzieren und nicht jede einzelne Calltest-Tradingdaten verwenden, um den Backtest-Zeitrahmen zu erhöhen.GetDepth, GetTradesIn einem Moment, in dem Marktdaten auf der ZeitleisteGetTicker, GetTrades, GetDepthundGetRecordswird die Zeit nicht mehrmals verschieben, wenn sich die Zeit auf der Backtest-Zeitleiste bewegt (was keinen Sprung zum nächsten Marktdatenmoment auslösen wird). Wiederholte Aufrufe zu einer der oben genannten Funktionen werden die Backtest-Zeit verschieben, um auf der Backtest-Zeitleiste zu bewegen (springen Sie zum nächsten Marktdatenmoment). Wenn das reale Marktniveau für den Backtest verwendet wird, wird eine frühere Zeit nicht empfohlen. Es kann in der vorzeitigen Zeitspanne keine Daten auf echtem Marktniveau geben.

Tick auf Bot-EbeneundTick auf SimulationsebeneDie Methode des Backtest-Systems, das als Transaktionsmatching-Mechanismus dient: Die Auftragstransaktionsmatching erfolgt nach dem angesehenen Preis und das gesamte Volumen wird gehandelt.

Das Backtesting System unterstützt mehrere Programmiersprachen

Das Backtesting-System unterstützt Backtesting-Strategien, die von:JavaScript, TypeScript, Python, C++, PINE, MyLanguage, BlocklyVisualisierung. Der Rücktest vonJavaScriptundC++Handelsstrategien wird im Browser durchgeführt, und der echte Marktbot oderWexAppIm Rahmen der Evaluierung derWexAppDie Anwendungen werden von den Herstellern der Produkte und Dienstleistungen unterstützt. Der Rücktest vonPythonDer Marktbetrieb und der Backtest beruhen beide auf derPythonWenn einige Bibliotheken benötigt werden, müssen sie manuell installiert werden (nur allgemeinePythondie Bibliotheken auf den öffentlichen FMZ Quant-Servern unterstützt werden).

Es unterstütztJavaScriptStrategie-Backtesting-Debugging in Chrome DevTools,Siehe.

Im Backtesting-System unterstützte Austausch

  • Kryptowährung Mainstream-Spot- und Futures-Börsen für Kryptowährungen; unterstützt Daten zu allen Arten von Börsen.
  • Wertpapiere von Futu Hongkong-Aktien, US-Aktien und andere Märkte.

Optimierung der Backtesting-Systemparameter

Die Parameteroptimierungsfunktion des Backtestsystems der FMZ Quant Trading Platform besteht darin, die Parameterkombinationen gemäß jeder Parameteroptimierungsoption während des Backtests festzulegen.OptimierungOption auf der rechten Seite des Strategieparameters, um die Optimierungseinstellungen anzuzeigen.

  • Mindestwert: zur Begrenzung des Anfangswerts der Parameter.
  • Höchstwert: Um den Höchstwert der Parameter nach inkrementellen Änderungen zu begrenzen.
  • Schrittgröße: die inkrementelle Variable der Parameter.
  • Gleichzeitige Fäden: Während der Parameteroptimierung die Anzahl der Threads für die gleichzeitige Ausführung jeder Backtest-Parameterkombination festlegen.JavaScript, PINE, undMy Language, und unterstützt keine Parameteroptimierung für Vorlagen.

Die Parameterkombinationen werden auf der Grundlage derminimum, maximum, undstep sizeDas Backtesting-System wiederholt diese Parameterkombinationen für das Backtesting (d.h. jede Parameterkombination wird einmal zurück getestet).ZahlDer Typ kann im Backtesting-System optimiert werden.

Speichern von Einstellungen für Backtest

In derStrategiebearbeitungsseite, in der Paginierung von Backtest (nämlich das Backtest-System), können Sie Optionen wie Backtest-Konfigurationen und Strategieparameter festlegen, um die Strategie zurück zu testen. Wenn diese Parameter eingestellt sind, können Sie die Set-Backtesting-Strategie folgen, dann wie speichern Sie die Set-Konfigurationsinformationen?

    1. Sie können die Schaltfläche Backtest-Einstellungen speichernStrategie-Bearbeitungsseitealle Informationen zur Backtest-Konfiguration (einschließlich Backtest-Einstellungen und Strategieparameter-Einstellungen) im Strategie-Quellcode in Codeform aufzuzeichnen.
    1. Wenn Sie eine Strategie speichern, indem Sie auf der Strategiebearbeitungsseite auf die Schaltfläche Save Strategy klicken, wird die Plattform automatisch die aktuellen Backtest-Einstellungen, die Konfiguration der Strategieparameter und andere Informationen aufzeichnen. Wie laden Sie die Backtest-Konfiguration in das Backtest-System?
    1. Wenn Sie die Strategiebearbeitungsseite aktualisieren oder diese Strategiebearbeitungsseite erneut öffnen, werden die von der Schaltfläche Save Backtest Settings aufgezeichneten Backtest-Konfigurationsinformationen automatisch zuerst geladen.
    1. Wenn keine Backtest-Konfigurationsinformationen im aktuellen Strategiecode als Kommentar erfasst werdenbacktest(über die Schaltfläche Save Backtest Settings im Strategiecode gespeichert) konfiguriert das Backtest-System automatisch die Backtest-Einstellungen nach den Backtest-Konfigurationsinformationen, wenn die Schaltfläche Save Strategy zuletzt für die aktuelle Strategie angeklickt wurde.
    1. Wenn auf der Strategiebearbeitungsseite die in Form von Kommentaren am Anfang des Strategiecodes aufgezeichneten Backtest-Konfigurationsinformationen geändert werden, müssen Sie die aktuell aktualisierten Backtest-Konfigurationsinformationen mit der Strategie-Backtest-Schnittstelle synchronisieren.backtestin der Strategiebearbeitung.
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
'''backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
'''
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

Klicken Sie auf Save backtest-Einstellungen, es gibt leichte Formatunterschiede aufJavaScript/Python/C++/MyLanguage/PINESprachen beim Speichern von Backtest-Einstellungen in den Strategiecode: MyLanguage:

(*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*)

PINE Sprache:

/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

Benutzerdefinierte Datenquelle

Das Backtesting-System der FMZ Quant Trading Platform unterstützt benutzerdefinierte Datenquellen, das Backtesting-System verwendet dieGETMethode zur Anforderung einer benutzerdefinierten URL (öffentlich zugängliche URL), um eine externe Datenquelle für Backtest zu erhalten.

Parameter Bedeutung Erläuterung
Symbol Name des Symbols Spotmarktdaten wie:BTC_USDT, Futures-Marktdaten wieBTC_USDT.swap, Futures-Perpetual Contract Financing Rate Daten, wie zum Beispiel:BTC_USDT.funding, Futures-Perpetuum-Kontraktpreisindexdaten, wie zum Beispiel:BTC_USDT.index
Eid Auswechslungen Der Wert der Vermögenswerte wird in den folgenden Zahlen angegeben:
rund Genauigkeit der Daten True bedeutet, dass die spezifische Präzision in den Daten definiert wird, die von der benutzerdefinierten Datenquelle zurückgegeben werden.round=true
Periode K-Liniendatenperiode (Millisekunden) wie z. B.:60000ist ein Zeitraum von 1 Minute
Tiefe Tiefenebenen 1-20
Handel Ob Daten aufgeteilt werden müssen (genau) / (falsch)
von Startzeit Unix-Zeitstempel
zu Die Endzeit Unix-Zeitstempel
Einzelheiten Anforderung von Daten für Symboldetails Die Anfrage, die vom FMZ Quant Trading Platform Backtesting System an die benutzerdefinierte Datenquelle gesendet wird, ist festgesetzt:detail=true
Gewohnheit Dieser Parameter kann ignoriert werden

Wenn die Datenquelle der Spot- und Futures-Börsenobjekte auf eine benutzerdefinierte Datenquelle (Feeder) eingestellt ist, sendet das Backtesting-System eine Anfrage an den benutzerdefinierten Datenquelle-Dienst:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Bitget&from=1351641600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_OKX&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=1

Datenformat

Das zurückgegebene Format muss eines der folgenden zwei Formate sein (das vom System automatisch erkannt werden):

  • Simulationsstufe Tick, Folgendes ist ein Beispiel für JSON-Daten:

    {
        "detail": {
            "eid": "Binance",
            "symbol": "BTC_USDT",
            "alias": "BTCUSDT",
            "baseCurrency": "BTC",
            "quoteCurrency": "USDT",
            "marginCurrency": "USDT",
            "basePrecision": 5,
            "quotePrecision": 2,
            "minQty": 0.00001,
            "maxQty": 9000,
            "minNotional": 5,
            "maxNotional": 9000000,
            "priceTick": 0.01,
            "volumeTick": 0.00001,
            "marginLevel": 10
        },
        "schema":["time", "open", "high", "low", "close", "vol"],
        "data":[
            [1564315200000, 9531300, 9531300, 9497060, 9497060, 787],
            [1564316100000, 9495160, 9495160, 9474260, 9489460, 338]
        ]
    }
    
  • Hier ist ein Beispiel für JSON-Daten: Tick-Level-Backtestdaten (enhalten Informationen über die Markttiefe, und das Tiefenformat ist ein Array von[price, volume]Es kann mehrere Ebenen der Tiefe haben,asksfür Preiserhöhungsbestellungen,bidsfür die Preisnachlässigkeit).

    {
        "detail": {
            "eid": "Binance",
            "symbol": "BTC_USDT",
            "alias": "BTCUSDT",
            "baseCurrency": "BTC",
            "quoteCurrency": "USDT",
            "marginCurrency": "USDT",
            "basePrecision": 5,
            "quotePrecision": 2,
            "minQty": 0.00001,
            "maxQty": 9000,
            "minNotional": 5,
            "maxNotional": 9000000,
            "priceTick": 0.01,
            "volumeTick": 0.00001,
            "marginLevel": 10
        },
        "schema":["time", "asks", "bids", "trades", "close", "vol"],
        "data":[
            [1564315200000, [[9531300, 10]], [[9531300, 10]], [[1564315200000, 0, 9531300, 10]], 9497060, 787],
            [1564316100000, [[9531300, 10]], [[9531300, 10]], [[1564316100000, 0, 9531300, 10]], 9497060, 787]
        ]
    }
    
Feld Beschreibung
Einzelheiten Ausführliche Angaben zum angeforderten Datentyp,

einschließlich des Namens der Währung, des Namens der Handelswährung, Präzision, Mindestbestellmenge usw. Es gibt die Attribute der Spalten in den Daten an. Anschrift, die kleinbuchstabenempfindlich ist und nur zeitlich begrenzt ist, offen, Hoch, niedrig, dicht, vol, bittet, bietet, handelt Daten. Die Spaltenstruktur, aufgezeichnete Daten nach dem Schema. Einstellungen.

Detailfeld

Feld Beschreibung
Eid Exchange Id, bitte beachten Sie, dass die Spot- und Futures-
Einige Börsen haben unterschiedliche Eids.
Symbol Code des Handelsprodukts
Alias Das Symbol in der Umschaltung entspricht dem aktuellen
Code des Handelsprodukts
Basiswährung Handelswährung
ZitatWährung Währung
MargeWährung Margenwährung
BasisGenauigkeit Genauigkeit der Transaktionswährung
ZitatGenauigkeit Genauigkeit bei der Preisgestaltung
MinQty Mindestbestellmenge
maxQty Höchstbestellmenge
MinNotionale Mindestbestellbetrag
maxNationale Höchstbestellbetrag
PreisTick Preissprung
VolumenTick Mindeständerungswert der Auftragsmenge (ein Sprung in
Bestellmenge)
MarginEbene Futures mit Hebelwert
Vertrag Typ Für dauerhafte Verträge:swap, die

Das Backtest-System wird weiterhin die Finanzierungssätze und den Preisindex senden Bitte.

Spezielle Spaltenattributeasks, bids, trades:

Feld Beschreibung Anmerkungen
Anfragen / Angebote [Preis, Volumen],...] Die Daten in

DieLive Trading Level TickDatenbeispiel:[[9531300, 10]]Das ist ein sehr gutes Beispiel. Ich bin nicht derjenige, der das Problem hat, aber ich bin derjenige, der es hat. Die Daten in derLive Trading Level TickDatenbeispiel:[[1564315200000, 0, 9531300, 10]] |

Bei der Rückprüfung von Dauerverträgen an Futures-Börsen werden Datenquellen erfordern auch zusätzliche Finanzierungsrate und Preisdaten Das Backtesting-System wird weiterhin Anfragen senden. für Finanzierungsquoten nur, wenn die angeforderten Marktdaten zurückgegeben werden und das Detailfeld in der zurückgegebenen Struktur enthält die"contractType": "swap"Schlüssel-Wert-Paar.

Wenn das Backtesting-System Daten über die Förderquote erhält, wird es weiterhin Anfragen nach Preisindexdaten zu senden.

Die Datenstruktur der Förderquote ist wie folgt:

{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.funding",
        "alias": "BTC_USDT.funding",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "marginCurrency": "",
        "basePrecision": 8,
        "quotePrecision": 8,
        "minQty": 1,
        "maxQty": 10000,
        "minNotional": 1,
        "maxNotional": 100000000,
        "priceTick": 1e-8,
        "volumeTick": 1e-8,
        "marginLevel": 10
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [
            1584921600000,
            -16795,
            -16795,
            -16795,
            -16795,
            0
        ],
        [
            1584950400000,
            -16294,
            -16294,
            -16294,
            -16294,
            0
        ]
        // ...
    ]
}
  • Das Intervall zwischen benachbarten Perioden beträgt 8 Stunden.
  • Zum Beispiel wird der Finanzierungsgrad von Binance alle 8 Stunden aktualisiert. Sind die Finanzierungsquoten -16795? Denn wie bei K-Liniendaten werden bei der Netzübertragung auch bei den Daten der Ganzzahltyp verwendet, um den Verlust der Schwingpunktgenauigkeit zu vermeiden; die Finanzierungsrate kann auch negativ sein.

Ein Beispiel für eine Anfrage nach Finanzierungsraten aus dem Backtesting Das System ist:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.funding&to=1611244800&trades=0

Die Datenstruktur für den Preisindex ist wie folgt:


{
    "detail": {
        "eid": "Futures_Binance",
        "symbol": "BTC_USDT.index",
        "alias": "BTCUSDT",
        "baseCurrency": "BTC",
        "quoteCurrency": "USDT",
        "contractType": "index",
        "marginCurrency": "USDT",
        "basePrecision": 3,
        "quotePrecision": 1,
        "minQty": 0.001,
        "maxQty": 1000,
        "minNotional": 0,
        "maxNotional": 1.7976931348623157e+308,
        "priceTick": 0.1,
        "volumeTick": 0.001,
        "marginLevel": 10,
        "volumeMultiple": 1
    },
    "schema": [
        "time",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ],
    "data": [
        [1584921600000, 58172, 59167, 56902, 58962, 0],
        [1584922500000, 58975, 59428, 58581, 59154, 0],
        // ...
    ]
}

Beispiel für eine Anfrage nach Preisindexdaten, die durch das Backtesting gesendet wurde Das System ist:

http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.index&to=1611244800&trades=0

Beispiel für benutzerdefinierte Datenquelle

Angabe der Datenquelle, z. B.http://120.24.2.20:9090/data. Das benutzerdefinierte Datenquelle-Dienstprogramm wird mitGolang:

package main

import (
    "fmt"
    "net/http"
    "encoding/json"
)

func Handle (w http.ResponseWriter, r *http.Request) {
    // e.g. set on backtest DataSourse: http://xxx.xx.x.xx:9090/data

    // request: GET http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=OKX&from=1584921600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
    //              http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1599958800&period=3600000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=0
    fmt.Println("request:", r)

    // response
    defer func() {
        // response data
        /* e.g. data
        {
            "detail": {
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10
            },
            "schema": [
                "time",
                "open",
                "high",
                "low",
                "close",
                "vol"
            ],
            "data": [
                [1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151],
                [1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738],
                [1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875],
                [1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777],
                [1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292],
                [1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666],
                [1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405],
                [1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768],
                [1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797],
                [1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692]
            ]
        }
        */
        
        // /* Simulation level Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time","open","high","low","close","vol"},
            "data": []interface{}{
                []int64{1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151},  // 1610755200000 : 2021-01-16 08:00:00
                []int64{1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738},  // 1610841600000 : 2021-01-17 08:00:00
                []int64{1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875},
                []int64{1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777},
                []int64{1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292},
                []int64{1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666},
                []int64{1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405},
                []int64{1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768},
                []int64{1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797},
                []int64{1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692},
            },
        }
        // */

        /* Bot level Tick
        ret := map[string]interface{}{
            "detail": map[string]interface{}{
                "eid": "Binance",
                "symbol": "BTC_USDT",
                "alias": "BTCUSDT",
                "baseCurrency": "BTC",
                "quoteCurrency": "USDT",
                "marginCurrency": "USDT",
                "basePrecision": 5,
                "quotePrecision": 2,
                "minQty": 0.00001,
                "maxQty": 9000,
                "minNotional": 5,
                "maxNotional": 9000000,
                "priceTick": 0.01,
                "volumeTick": 0.00001,
                "marginLevel": 10,
            },
            "schema": []string{"time", "asks", "bids", "trades", "close", "vol"},
            "data": []interface{}{
                []interface{}{1610755200000, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{1610755200000, 0, 9531300, 10}}, 9497060, 787},
                []interface{}{1610841600000, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{1610841600000, 0, 9531300, 11}}, 9497061, 789},                
            },
        }
        */

        b, _ := json.Marshal(ret)
        w.Write(b)
    }()
}
func main () {
    fmt.Println("listen http://localhost:9090")
    http.HandleFunc("/data", Handle)
    http.ListenAndServe(":9090", nil)
}

TeststrategieJavaScriptBeispiel:

/*backtest
start: 2021-01-16 08:00:00
end: 2021-01-22 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"OKX","currency":"BTC_USDT","feeder":"http://120.24.2.20:9090/data"}]
args: [["number",2]]
*/

function main() {
    var ticker = exchange.GetTicker()
    var records = exchange.GetRecords()
    Log(exchange.GetName(), exchange.GetCurrency())
    Log(ticker)
    Log(records)
}

Lokale Backtest-Engine

FMZ Quant Trading Platform hat für dieJavaScriptSprachePythonSprache der lokalen Backtest-Engine, die die Einstellung der zugrunde liegenden K-Line Periode während des Backtests unterstützt.

Backtest-Seiten-Verknüpfungstasten

  • Kurzschaltfläche zum Wechseln zwischen Strategie Bearbeiten und Backtesting Verwenden Sie den Schlüssel.Ctrl +,Sie können dann auf die Seite Backtest und auf die Seite Edit Strategy zurückschalten.CtrlDrücken Sie die Taste.,.

  • Abkürzung für die Sparstrategie Verwenden Sie den Schlüssel.Ctrl + sSie müssen ihre Strategien retten.

  • Abkürzung für den Start der Strategie-Backtest Verwenden Sie den Schlüssel.Ctrl + bum Start Backtest zu ermöglichen.

Backtest-Daten herunterladen

  • Backtesting-Logdaten für das System herunterladen Öffnen Sie die spezifische Strategie und wechseln Sie zur Backtest-Seite, um die Strategie zu backtesten. In der Spalte Status-Informationen der Strategie, die nach dem Backtest angezeigt wird, befindet sich in der oberen rechten Ecke eine Download-Tabelle-Schaltfläche. Klicken Sie darauf, um am Ende des Backtests eine CSV-Datei der Statusspalte-Daten herunterzuladen.
  • Backtesting-System-Statusleiste Daten herunterladen Öffnen Sie die spezifische Strategie und wechseln Sie zur Backtest-Seite, um die Strategie zu backtesten. In der Spalte Log Information der Strategie, die nach dem Backtest angezeigt wird, befindet sich eine Download Table-Taste in der oberen rechten Ecke. Klicken Sie darauf, um die CSV-Formatdatei der Backtesting-Logdaten herunterzuladen.

Sharpe-Algorithmus im Backtesting-System

Der Quellcode des Sharpe-Algorithmus im Backtesting-System:

function returnAnalyze(totalAssets, profits, ts, te, period, yearDays) {
    // force by days
    period = 86400000
    if (profits.length == 0) {
        return null
    }
    var freeProfit = 0.03 // 0.04
    var yearRange = yearDays * 86400000
    var totalReturns = profits[profits.length - 1][1] / totalAssets
    var annualizedReturns = (totalReturns * yearRange) / (te - ts)

    // MaxDrawDown
    var maxDrawdown = 0
    var maxAssets = totalAssets
    var maxAssetsTime = 0
    var maxDrawdownTime = 0
    var maxDrawdownStartTime = 0
    var winningRate = 0
    var winningResult = 0
    for (var i = 0; i < profits.length; i++) {
        if (i == 0) {
            if (profits[i][1] > 0) {
                winningResult++
            }
        } else {
            if (profits[i][1] > profits[i - 1][1]) {
                winningResult++
            }
        }
        if ((profits[i][1] + totalAssets) > maxAssets) {
            maxAssets = profits[i][1] + totalAssets
            maxAssetsTime = profits[i][0]
        }
        if (maxAssets > 0) {
            var drawDown = 1 - (profits[i][1] + totalAssets) / maxAssets
            if (drawDown > maxDrawdown) {
                maxDrawdown = drawDown
                maxDrawdownTime = profits[i][0]
                maxDrawdownStartTime = maxAssetsTime
            }
        }
    }
    if (profits.length > 0) {
        winningRate = winningResult / profits.length
    }
    // trim profits
    var i = 0
    var datas = []
    var sum = 0
    var preProfit = 0
    var perRatio = 0
    var rangeEnd = te
    if ((te - ts) % period > 0) {
        rangeEnd = (parseInt(te / period) + 1) * period
    }
    for (var n = ts; n < rangeEnd; n += period) {
        var dayProfit = 0.0
        var cut = n + period
        while (i < profits.length && profits[i][0] < cut) {
            dayProfit += (profits[i][1] - preProfit)
            preProfit = profits[i][1]
            i++
        }
        perRatio = ((dayProfit / totalAssets) * yearRange) / period
        sum += perRatio
        datas.push(perRatio)
    }

    var sharpeRatio = 0
    var volatility = 0
    if (datas.length > 0) {
        var avg = sum / datas.length;
        var std = 0;
        for (i = 0; i < datas.length; i++) {
            std += Math.pow(datas[i] - avg, 2);
        }
        volatility = Math.sqrt(std / datas.length);
        if (volatility !== 0) {
            sharpeRatio = (annualizedReturns - freeProfit) / volatility
        }
    }

    return {
        totalAssets: totalAssets,
        yearDays: yearDays,
        totalReturns: totalReturns,
        annualizedReturns: annualizedReturns,
        sharpeRatio: sharpeRatio,
        volatility: volatility,
        maxDrawdown: maxDrawdown,
        maxDrawdownTime: maxDrawdownTime,
        maxAssetsTime: maxAssetsTime,
        maxDrawdownStartTime: maxDrawdownStartTime,
        winningRate: winningRate
    }
}
Strategie-Editor Strategie-Eingabefunktionen