Les ressources ont été chargées... Je charge...

Système de contre-test

Après avoir réalisé la conception d'une stratégie de trading quantitative, comment pouvez-vous connaître la situation de base de votre stratégie, telle que la logique de la stratégie et la direction des rendements de la stratégie? Bien sûr, nous ne pouvons pas utiliser de l'argent réel directement pour exécuter la stratégie sur le marché de trading réel, mais nous pouvons utiliser des données historiques pour tester votre stratégie et connaître les profits de votre stratégie dans les données historiques.

Modèle de système de contre-test

FMZ Quant Trading Platform divise le système de backtest enniveau de botetniveau de simulation. Le niveau de bot est de backtest complètement selon les données historiques complètes; tandis que le niveau de simulation backtest génèretickles données sont basées sur les données historiques réelles, mais les données au niveau du bot sont plus précises et les résultats sont plus crédibles. Cependant, le backtesting n'est que la performance de la stratégie selon les données historiques. Les données historiques ne peuvent pas représenter pleinement le marché futur. Le marché historique peut se répéter, ou cela peut également conduire au cygne noir. Par conséquent, les résultats du backtest doivent être traités de manière rationnelle et objective.

Leniveau de simulation Tickgénère la simulationDonnées de tiquesLes résultats de l'expérience sont basés sur la période de la ligne K sous-jacente, chaque période de la ligne K sous-jacente générera un maximum de 12 points de temps de backtest.Niveau du marché réelLe mécanisme de backtesting de FMZ Quant permet à la stratégie de négocier plusieurs fois sur une seule ligne K, évitant la situation où la négociation ne peut être exécutée qu'au prix de clôture.

Description du mécanisme du système de backtesting

  • Tick de niveau de simulation Leniveau de simulation Tickest basé sur les données de ligne K sous-jacentes du système de backtest, simulant les données de tick pour backtest dans le cadre des valeurs du prix le plus élevé, le prix le plus bas, le prix d'ouverture et le prix de clôture d'une barre de ligne K sous-jacente donnée selon un certain algorithme.Description du mécanisme de simulation au niveau du système de backtesting.

  • Tick au niveau du robot Le backtest de niveau de bot est les données réelles de niveau de tick dans la série de temps Bar. Pour les stratégies basées sur les données de niveau de tick, l'utilisation du niveau réel du marché pour le backtest est plus proche de la réalité. Dans le backtest de niveau de bot, les données de tick sont des données enregistrées réelles, pas simulées. Il prend en charge les données de profondeur, la lecture des données d'enregistrement des transactions sur le marché, la profondeur personnalisée et chaque donnée de trading individuelle. La taille maximale du backtest de données de niveau de marché réel est jusqu'à un maximum de 50 Mo, sans limite sur la plage de temps de backtest dans la limite supérieure de l'ensemble de données. Si vous avez besoin d'élargir la plage de temps de backtest autant que possible, vous pouvez réduire la valeur du réglage de la profondeur d'équipement et ne pas utiliser chaque donnée de trading individuelle pour augmenter la plage de temps de backtest Call.GetDepth, GetTradesDans un moment de données de marché sur la chronologie, appelantGetTicker, GetTrades, GetDepthetGetRecordsNe pas pousser le temps plusieurs fois lorsque le temps se déplace sur la chronologie du backtest (ce qui ne déclenchera pas un saut vers le prochain moment des données du marché). Les appels répétés à l'une des fonctions ci-dessus pousseront le temps du backtest pour se déplacer sur la chronologie du backtest (sauter vers le prochain moment des données du marché). Lorsque le niveau réel du marché est utilisé pour le backtest, il n'est pas recommandé de choisir un moment antérieur. Il peut ne pas y avoir de données au niveau du marché réel dans la période de temps prématurée.

Tick au niveau du robotetTick au niveau de la simulationLes modes de négociation sont les suivants: le mécanisme de correspondance des transactions du système de backtest: la correspondance des transactions d'ordre est effectuée en fonction du prix observé et le volume total est négocié.

Le système de backtesting prend en charge plusieurs langages de programmation

Le système de backtesting prend en charge les stratégies de backtesting écrites et conçues par:JavaScript, TypeScript, Python, C++, PINE, MyLanguage, Blocklyvisualisation. Le backtest deJavaScriptetC++Les stratégies de trading est menée dans le navigateur, et le vrai marché bot ouNous avons une application.Le marché réel de change émulé (c'est-à-dire leNous avons une application.L'échange émulé de la plateforme de trading FMZ Quant) s'exécute sans installer aucun autre logiciel, bibliothèques ou modules. Le backtest dePythonL'opération de marché réelle et le backtest dépendent tous deux de la capacité de l'utilisateur à effectuer des tests sur les marchés.PythonSi certaines bibliothèques sont nécessaires, elles doivent être installées manuellement (uniquement les bibliothèques communes)Pythonles bibliothèques sont prises en charge sur les serveurs publics FMZ Quant).

Il soutientJavaScriptle débogage des stratégies de backtesting dans Chrome DevTools,Veuillez vous référer à.

Échanges pris en charge dans le système de backtesting

  • Crypto-monnaie Échange de devises en espèces et à terme pour les crypto-monnaies; prend en charge les données sur tous les types d'échanges.
  • Titres de Futu Les actions de Hong Kong, les actions américaines et d'autres marchés.

Optimisation des paramètres du système de backtesting

La fonction d'optimisation des paramètres du système de backtest de la plateforme de trading quantique FMZ consiste à définir les combinaisons de paramètres selon chaque option d'optimisation des paramètres pendant le backtest.Optimisationoption située sur le côté droit du paramètre de stratégie pour afficher les paramètres d'optimisation.

  • Valeur minimale: pour limiter la valeur de départ des paramètres.
  • Valeur maximale: pour limiter la valeur maximale des paramètres après des modifications incrémentielles.
  • Taille d'étape: la valeur de la variable incrémentielle des paramètres.
  • Les fils concomitants: Pendant l'optimisation des paramètres, définissez le nombre de threads pour l'exécution simultanée de chaque combinaison de paramètres de backtest.JavaScript, PINE, etMy Language, et ne prend pas en charge l'optimisation des paramètres sur les modèles.

Les combinaisons de paramètres sont générées sur la base deminimum, maximum, etstep sizeLe système de backtesting itère à travers ces combinaisons de paramètres pour le backtesting (c'est-à-dire, backtesting chaque combinaison de paramètres une fois).NuméroLe système de backtesting permet d'optimiser le type de données.

Enregistrer les paramètres de test arrière

Dans lepage d'édition de stratégie, dans la pagination de Backtest (à savoir le système de backtest), vous pouvez définir des options telles que les configurations de backtest et les paramètres de stratégie pour backtest la stratégie. Lorsque ces paramètres sont définis, vous pouvez suivre la stratégie de backtesting, alors comment enregistrer les informations de configuration?

    1. Vous pouvez utiliser le bouton Enregistrer les paramètres de test arrière sur lePage d'édition de stratégiepour enregistrer toutes les informations de configuration des backtests (y compris les paramètres des backtests et des paramètres de stratégie) dans le code source de la stratégie sous forme de code.
    1. Lorsque vous enregistrez une stratégie en cliquant sur le bouton Enregistrer stratégie sur la page d'édition de stratégie, la plateforme enregistre automatiquement les paramètres actuels de backtest, les paramètres de stratégie et d'autres informations. Comment charger la configuration de backtest dans le système de backtest?
    1. Lors de la mise à jour de la page d'édition de stratégie ou de la réouverture de cette page d'édition de stratégie, les informations de configuration de backtest enregistrées par le bouton Enregistrer les paramètres de backtest seront automatiquement chargées en premier.
    1. S'il n'y a aucune information de configuration de backtest enregistrée dans le code de stratégie en cours sous forme de commentairebacktest(enregistré dans le code de stratégie via le bouton Enregistrer les paramètres de backtest), le système de backtest configure automatiquement les paramètres de backtest à l'information de configuration de backtest lorsque le bouton Enregistrer la stratégie a été cliqué pour la dernière fois pour la stratégie en cours.
    1. Si les informations de configuration de backtest enregistrées sous forme de commentaires au début du code de stratégie sont modifiées sur la page d'édition de stratégie, vous devez synchroniser les informations de configuration de backtest actuellement mises à jour avec l'option d'interface de backtest de stratégie.backtestdans le domaine de l'édition de la stratégie.
/*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"}]
*/

Cliquez sur Enregistrer les paramètres de backtest, il y a de légères différences de format surJavaScript/Python/C++/MyLanguage/PINElangues lors de l'enregistrement des paramètres de backtest dans le code de stratégie: Mon langage:

(*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"}]
*)

Langue PINE:

/*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"}]
*/

Source de données personnalisée

Le système de backtesting de la plateforme de trading quantitatif FMZ prend en charge les sources de données personnalisées, le système de backtesting utilise lesGETméthode pour demander une URL personnalisée (URL accessible au public) afin d'obtenir une source de données externe pour le backtest.

Paramètre Signification Expliquer
le symbole Nom du symbole Données du marché au comptant, telles que:BTC_USDT, les données du marché à terme, telles que:BTC_USDT.swap, données sur les taux de financement des contrats perpétuels à terme, telles que:BTC_USDT.funding, les données relatives à l'indice des prix des contrats à terme perpétuels, telles que:BTC_USDT.index
- Je vous en prie. Les échanges Les éléments suivants doivent être pris en considération:
ronde La précision des données True signifie que la précision spécifique est définie dans les données transmises par la source de données personnalisée.round=true
période Période de données en ligne K (millièmes de seconde) par exemple:60000est une période de 1 minute
profondeur Niveaux de profondeur 1-20
commerces Si les données doivent être scindées vrai (1) / faux (2)
de Heure de début Le timestamp est unix
à Le temps de la fin Le timestamp est unix
détails Données demandées pour les détails du symbole True signifie qu'il doit être fourni par une source de données personnalisée.detail=true
personnalisation Ce paramètre peut être ignoré.

Lorsque la source de données des objets d'échange au comptant et des objets d'échange à terme est définie sur une source de données personnalisée (feeder), le système de backtesting envoie une demande au service de source de données personnalisée:

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

Format des données

Le format retourné doit être l'un des deux formats suivants (qui seront automatiquement reconnues par le système):

  • Niveau de simulation Tick, voici un exemple de données JSON:

    {
        "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]
        ]
    }
    
  • Cochez le niveau de bot, voici un exemple de données JSON: Les données de backtest au niveau du tick (contiennent des informations sur la profondeur du marché, et le format de profondeur est un tableau de[price, volume]Il peut avoir plusieurs niveaux de profondeur,askspour l'ordre croissant des prix,bidspour l' ordre décroissant des prix).

    {
        "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]
        ]
    }
    
Le champ Définition
détails Informations détaillées sur le type de données demandé,

le nom de la monnaie libellée, le nom de la la précision, la quantité de commande minimale, etc. Il spécifie les attributs des colonnes dans les données array, qui est sensible aux petites lettres et est limité au temps, ouvert, haut, bas, fermé, vol, demande, offre, négocie Les données La structure des colonnes, les données enregistrées selon le schéma réglages.

champ de détail

Le champ Définition
- Je vous en prie. Exchange Id, veuillez noter que le spot et les contrats à terme d'un
Certains échanges ont des effets différents.
le symbole Code du produit de négociation
alias Le symbole de l'échange correspondant au courant
code du produit commercial
Monnaie de base Monnaie de négociation
CitéMonnaie Monnaies libellées
MargeMonnaie Monnaie de marge
basePrécision Vérité de la monnaie de la transaction
Citation précise Précision de la devise de prix
MinQty Quantité minimale de commande
Le nombre maximal Quantité maximale de commande
Le projet de Montant minimum de la commande
maxNotif Montant maximal de la commande
prixTick Saut de prix
Le volume Valeur minimale de modification de la quantité d'ordre (un saut dans la quantité)
quantité de commande)
MargeLe niveau Valeur de l'effet de levier des contrats à terme
type de contrat Pour les contrats perpétuels fixés à:swap, le

Le système de backtest continuera à envoyer des indices de taux de financement et de prix Les demandes.

Attributs de colonne spéciauxasks, bids, trades:

Le champ Définition Les commentaires
demande / offre [prix, volume],...] Par exemple, les données

LeLive Trading Level TickExemple de données:[[9531300, 10]]Je ne sais pas. Les échanges, le temps, la direction, le prix, le volume... Par exemple, les donnéesLive Trading Level TickExemple de données:[[1564315200000, 0, 9531300, 10]] |

Lors du backtesting des contrats perpétuels sur les bourses à terme, les Les sources de données nécessitent également des données supplémentaires sur le taux de financement et le prix Le système de backtesting continuera d'envoyer des requêtes pour les taux de financement uniquement lorsque les données de marché demandées sont renvoyées et le champ de détail dans la structure retournée contient le"contractType": "swap"une paire clé-valeur.

Lorsque le système de backtesting reçoit des données sur le taux de financement, il continuer d'envoyer des demandes de données sur l'indice des prix.

La structure des données sur le taux de financement est la suivante:

{
    "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
        ]
        // ...
    ]
}
  • L'intervalle entre les périodes adjacentes est de 8 heures.
  • Par exemple, le taux de financement de Binance est mis à jour toutes les 8 heures. Les données relatives au taux de financement sont-elles -16795? Parce que, comme les données de ligne K, afin d'éviter la perte de précision en virgule flottante pendant la transmission réseau, les données utilisent le type entier; les données de taux de financement peuvent également être négatives.

Exemple de demande de données sur le taux de financement à partir du backtesting Le système est le suivant:

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

La structure des données relatives à l'indice des prix est la suivante:


{
    "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],
        // ...
    ]
}

Exemple de demande de données sur l'indice des prix envoyée par le backtesting Le système est le suivant:

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

Exemple de source de données personnalisée

Indiquer l'adresse de la source de données, par exemple:http://120.24.2.20:9090/dataLe programme de service de source de données personnalisé est écrit en utilisantGolang:

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)
}

stratégie de test,JavaScriptExemple:

/*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)
}

Moteur de test de retour local

FMZ Quant Trading Platform est open-source pour leJavaScriptLa langue et lePythonlangage du moteur de backtest local, prenant en charge le réglage de la période sous-jacente de la ligne K pendant le backtest.

Les touches de raccourci de page de test arrière

  • Touche de raccourci pour basculer entre la stratégie Édition page et la page Backtesting Utilisez la clé.Ctrl +,pour revenir à la page Backtest et Edit Strategy.CtrlAppuie sur la touche.,.

  • Touche de raccourci pour la stratégie d'économie Utilisez la clé.Ctrl + spour sauver des stratégies.

  • Raccourci pour démarrer le backtest de stratégie Utilisez la clé.Ctrl + bpour activer Start Backtest.

Télécharger les données de test arrière

  • Téléchargement des données du journal du système de backtesting Ouvrez la stratégie spécifique et passez à la page de test de retour pour tester la stratégie. Dans la colonne d'information de statut de la stratégie affichée après le test de retour, il y a un bouton de téléchargement de la table dans le coin supérieur droit. Cliquez dessus pour télécharger un fichier CSV des données de la colonne d'état à la fin du test de retour.
  • Tester en arrière-plan les données de la barre d'état du système Ouvrez la stratégie spécifique et passez à la page Backtest pour tester la stratégie. Dans la colonne Log Information de la stratégie affichée après le backtest, il y a un bouton Download Table dans le coin supérieur droit. Cliquez dessus pour télécharger le fichier au format CSV des données du journal de backtesting.

L'algorithme Sharpe dans le système de backtesting

Le code source de l'algorithme Sharpe dans le système de backtesting:

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
    }
}
Éditeur de stratégie Fonctions d'entrée de stratégie