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

Instructions de l'API FMZ

Auteur:Nul, Créé: 2020-04-20 10:19:00, Mis à jour: 2023-04-12 14:44:56

Je suis désolé.

GetExchangeList()renvoie la liste des échanges pris en charge et les informations de configuration requises.

  • Paramètre Aucune

  • Valeur de retour

    {
        "code": 0,
        "data": {
            "result": {
                "exchanges": [{
                    "website": "https://www.huobi.pro/",
                    "name": "Huobi",
                    "priority": 1,
                    "meta": "[{"desc": "Access Key", "required": true, "type": "string", "name": "AccessKey", "label": "Access Key"}, {"encrypt": true, "name": "SecretKey", "required": true, "label": "Secret Key", "type": "password", "desc": "Secret Key"}]",
                    "eid": "Huobi",
                    "logo": "huobi.png",
                    "id": 1
                }, {
                    "website": "https://www.kex.com/",
                    "name": "KEX",
                    "priority": -99,
                    "meta": "[{"desc": "Access Key", "required": true, "type": "string", "name": "AccessKey", "label": "Access Key"}, {"encrypt": true, "name": "SecretKey", "required": true, "label": "Secret Key", "type": "password", "desc": "Secret Key"}, {"encrypt": true, "required": true, "type": "password", "name": "Password", "label": "Trading Password"}]",
                    "eid": "KEX",
                    "logo": "",
                    "id": 43
                }, 
    
                 ...
          
                ]
            },
            "error": null
        }
    }
    

Supprimez le nœud

DeleteNode(Nid)supprime le nœud d'accueil (IDestNid) correspondant à laAPI KEYà la demande du compte de la plateforme de négociation FMZ Quant.

  • ParamètreNidest de type entier, à savoir le dockerID.

  • Retour de valeur

    {
        "code":0,
        "data":{
            "result":true,
            "error":null
        }
    }
    

SupprimerRobot (en anglais)

DeleteRobot(RobotId, DeleteLogs)supprime le robot avec l'ID spécifié (robotID: RobotId) correspondant à laAPI KEYdans la demande au titre du compte FMZ Quant.

  • ParamètreRobotIdest de type entier, à savoir le robotIDà supprimer.DeleteLogsest de type booléen; ensembleDeleteLogspour décider de supprimer ou non le journal;trueindique la suppression du journal.

  • Retour de valeur

    // Return value after successful deletion
    {
        "code": 0,
        "data": {
            "result": 0,
            "error": null
        }
    }
    

Vous avez une liste de stratégie?

GetStrategyList()Il obtient les informations stratégiques correspondant à laAPI KEYà la demande du compte de la plateforme de négociation FMZ Quant.

  • Paramètre Aucune

  • Valeur de retour

    {
        "code": 0,
        "data": {
            "result": {
                "strategies": [{
                    "category": 0,
                    "username": "yifidslei",
                    "is_owner": true,
                    "name": "fmz simulation market test strategy",
                    "language": 0,
                    "hasToken": false,
                    "args": "[]",
                    "is_buy": false,
                    "public": 0,
                    "last_modified": "2018-01-18 12:36:03",
                    "date": "2018-01-17 09:19:32",
                    "forked": 0,
                    "id": 63372
                }, {
                    "category": 20,
                    "username": "bifndslez",
                    "is_owner": true,
                    "name": "Line drawing library",
                    "language": 0,
                    "hasToken": false,
                    "args": "[]",
                    "is_buy": false,
                    "public": 0,
                    "last_modified": "2017-05-08 09:44:18",
                    "date": "2017-04-19 10:38:14",
                    "forked": 0,
                    "id": 39677
                },
                
                ...
                ],
                "all": 20
            },
            "error": null
        }
    }
    

Je ne peux pas faire ça.

NewRobot(Settings)crée un nouveau bot selon les paramètres,API KEYdans la demande du compte FMZ Quant.

  • ParamètreSettingsest deJSONtype d'objet.Settingsest unJSONObjet configuré par le bot.

    LeSettingsla description est expliquée comme suit:

    Settings = {
        "name": "hedge test",
        /*
        Strategy parameters; the order does not have to be in correspondence with the parameter order, but the name must be the same as the parameter name 
        Note: the second element in the parameter array ["MAType", 0, 75882] is an array including three elements, in which the first one "MAType" is the parameter on the pattern referred by the bot-binding strategy, and the second one "0" is the specific value set by the parameter "MAType", and the third one "75882" is the pattern ID containing the parameter "MAType"
        */
        "args": [["Interval", 500], ["MAType", 0, 75882]],
        // Strategy ID, which can be obtained by "GetStrategyList" method
        "strategy": 25189,                      
        // K-line period parameter; "60" indicates 60 seconds
        "period": 60,                           
        // it can be specified to run on which docker; no writing of the attribute will lead to automatic assignment 
        "node" : 52924,                         
        // custom field
        "appid": "member2",
        // Specify a bot group
        "group": 1122,
        "exchanges": [
            // ZB; "pid" can be obtained by "GetPlatformList" method 
            {"pid": 15445, "pair": "ETH_BTC"},     
            // OKEX
            {"pid": 13802, "pair": "BCH_BTC"},     
            // In addition to the exchanges configured by the FMZ dashboard (pid identification), you can also set exchange configuration information that has not been configured to operate the bot 
            {"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "xxx", "SecretKey": "yyy"}},
            {"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "xxx", "SecretKey": "yyy"}}
        ]
    }
    

    Note: le numéro de série Lorsque vous utilisez des informations sensibles, telles que la plateformeAPI KEY, y compris"meta":{"AccessKey":"xxx","SecretKey":"yyy"}dans la configuration deeid, vous devez savoir que FMZ ne stocke pas les données. Les données seront envoyées directement au programme docker, donc ces informations doivent être configurées à chaque fois que le bot est créé ou redémarré.

    Pour redémarrer le bot qui utilise le plugin pour supporter la plate-forme, lors de la configuration duSettingsparamètre, vous devez effectuer les réglages suivants pour leexchangesattribut:

    {"eid": "Exchange", "label" : "testXXX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123", "SecretKey": "1234", "Front" : "http://127.0.0.1:6666/XXX"}}
    

    labelL'attribut est de définir une étiquette pour l'objet d'échange accessible par le protocole général actuel, qui peut être obtenue par leexchange.GetLabel()Le rôle de l'entreprise dans la stratégie.

  • Stratégie de test:

    • Paramètre de stratégieInterval

    • JavaScriptcode de stratégie

      function main(){
          Log(exchange.GetAccount())
          Log(exchange.GetTicker())
          Log(exchange.GetDepth())
          Log("Interval:", Interval)
      }
      
  • Valeur de retour

    // Create the bot successfully 
    {
        "code": 0,
        "data": {
            "result": 74260,
            "error": null
        }
    }
    

PluginRun ((Paramètres)

PluginRun(Settings)utilise l'API étendue pour appeleroutil de débogage function.

  • ParamètreSettingsest unJSONl'objet, à savoir les paramètres de l'outil de débogage (Settingscontient le code de test écrit dans l'attributsource).

  • Code de testPythonExemple:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import time
    import md5
    import urllib
    import json
    
    # API KEY has been blurred; you can use your own API KEY to test
    accessKey = 'f77XXXXXXXXXXXXXXX757'              
    # API KEY has been blurred; you can use your own API KEY to test
    secretKey = 'd8XXXXXXXXXXXXXXXX41ca97ea15'       
    
    def api(method, *args):
        d = {
            'version': '1.0',
            'access_key': accessKey,
            'method': method,
            'args': json.dumps(list(args)),
            'nonce': int(time.time() * 1000),
            }
        d['sign'] = md5.md5('%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], secretKey)).hexdigest()
        return json.loads(urllib.urlopen('https://www.fmz.com/api/v1', urllib.urlencode(d)).read())
    
    code = '''
    function main() {
        Log(exchange.GetTicker())
        exchange.SetTimeout(2000);
        return exchanges[0].GetTicker()
    }
    '''
    
    settings = { 
        # K-line period parameter "60" indicates 60 seconds
        "period": 60,                                 
        "source": code, 
        # The docker ID can specify which docker to run the bot on; if the value is -1, it means automatic assignment 
        "node" : 54913,                               
        "exchanges": [
            {"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}},
            {"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}
        ]
    }
    
    print api("PluginRun", settings)
    

    Note: le numéro de série{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}} {"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}Pour leexchangesattribut dans leréglages, l'attribut ne doit être défini qu'à 1, lors de l'appel duPluginRuninterface (pour un seul objet d'échange peut être pris en charge lorsque vous utilisez la page Debug Tool). Aucune erreur ne sera signalée lorsque vous définissez 2 objets d'échange dansréglages, mais une erreur sera signalée lorsque le deuxième objet d'échange est consulté dans le code.

  • Valeur de retourapi("PluginRun", settings)résultats retournés:

    {
        u'code': 0, 
        u'data': {
            u'result': u'{"logs":[{"PlatformId":"","OrderId":"0","LogType":5,"Price":0,"Amount":0,"Extra":"{\\"Info\\":{\\"date\\":\\"1523715057\\",\\"ticker\\":{\\"high\\":\\"0.06400845\\",\\"vol\\":\\"117648.31546800\\",\\"last\\":\\"0.06204514\\",\\"low\\":\\"0.06178666\\",\\"buy\\":\\"0.06200001\\",\\"sell\\":\\"0.06208728\\"}},\\"High\\":0.06400845,\\"Low\\":0.06178666,\\"Sell\\":0.06208728,\\"Buy\\":0.06200001,\\"Last\\":0.06204514,\\"Volume\\":117648.315468,\\"OpenInterest\\":0,\\"Time\\":1523715057726}","Instrument":"","Direction":"","Time":1523715057726}],"result":"{\\"Info\\":{\\"date\\":\\"1523715057\\",\\"ticker\\":{\\"vol\\":\\"117648.31546800\\",\\"last\\":\\"0.06204514\\",\\"low\\":\\"0.06178666\\",\\"buy\\":\\"0.06200001\\",\\"sell\\":\\"0.06208728\\",\\"high\\":\\"0.06400845\\"}},\\"High\\":0.06400845,\\"Low\\":0.06178666,\\"Sell\\":0.06208728,\\"Buy\\":0.06200001,\\"Last\\":0.06204514,\\"Volume\\":117648.315468,\\"OpenInterest\\":0,\\"Time\\":1523715057774}"}\n', 
            u'error': None
        }
    }
    

Je suis un robot.

GetRobotLogs(robotId, logMinId, logMaxId, logOffset, logLimit, profitMinId, profitMaxId, profitOffset, profitLimit, chartMinId, chartMaxId, chartOffset, chartLimit, chartUpdateBaseId, chartUpdateDate, summaryLimit)obtient les informations du journal du robot (robotID: robotId), correspondant à laAPI KEYdans la demande du compte FMZ Quant.

  • Paramètre

    Nom du paramètre Le type Les commentaires
    robotId nombre entier Identifiant du robot

    Tableau journalinterroge les données du journal de la table de base de données:

    Nom du paramètre Le type Les commentaires
    LogMinId nombre entier Identifiant minimal du journal
    LogMaxId nombre entier Identifiant maximal du journal
    LogOffset nombre entier Une fois que la plage est déterminée par logMinId et logMaxId, le décalage de logOffset (combien d'enregistrements sont sautés) commence à être utilisé comme position de départ pour l'obtention de données
    LogLimit nombre entier Après détermination de la position de départ, le nombre d'enregistrements de données sélectionnés

    Tableau Bénéficeinterroge les données sur les bénéfices du tableau de la base de données:

    Nom du paramètre Le type Les commentaires
    Profité nombre entier Identifiant minimal de l'enregistrement
    profitMaxId nombre entier Identifiant maximal de l'enregistrement
    ProfitOffset nombre entier Le décalage (combien d'enregistrements sont sautés) commence à être utilisé comme position de départ
    profit Limite nombre entier Après détermination de la position de départ, le nombre d'enregistrements de données sélectionnés

    Tableau graphiqueeffectue des requêtes sur les données du graphique du tableau de la base de données:

    Nom du paramètre Le type Les commentaires
    Le tableau de bord nombre entier Identifiant minimal de l'enregistrement
    graphique MaxId nombre entier Identifiant maximal de l'enregistrement
    graphiqueOffset nombre entier Compte rendu
    graphique Limite nombre entier le nombre d'enregistrements à obtenir
    Tableau ActualisationBaseId nombre entier Rechercher l' ID de base mis à jour
    Tableau Date de mise à jour nombre entier L'enregistrement de données met à jour l'horodatage, ce qui filtrera les enregistrements plus grands que cet horodatage

    Résumé Limiteinterroge les données de la barre d'état:

    Il interroge les données de la barre d'état du bot. Le type de paramètre est entier. Le réglage à 0 signifie qu'il n'est pas nécessaire de interroger les informations de la barre d'état, et le réglage à un nombre autre que zéro indique le nombre d'octets de l'information de la barre d'état à interroger (l'interface ne limite pas la quantité de données, vous pouvez donc spécifier une plus grandesummaryLimitparamètre pour obtenir toutes les informations de la barre d'état). Les données de la barre d'état sont stockées dans les données retournéessummary.

    PythonExemple:

    api('GetRobotLogs', 63024, 0, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)    # For the specific code, please refer to the above content: 4. Simple examples, which will not be repeated here; here only write the call and pass of "GetRobotLogs"
    
  • Valeur de retour données renvoyées:

    {
        "code": 0,
        "data": {
            "result": {
                "status": 1,
                "updateTime": 1527049990197,
                "wd": 0,
                // The first data structure in logs is the log records in the strategy log table in the bot database
                "logs": [{            
                    "Max": 3984,
                    "Arr": [
                        [3977, 3, "Futures_OKCoin", "", 0, 0, "Sell(688.9, 2): 20016", 1526954372591, "", ""],
                        [3976, 5, "", "", 0, 0, "OKCoin:this_week too many positions, long: 2", 1526954372410, "", ""]
                    ],
                    "Total": 1503,
                    "Min": 2482
                }, {                  
                    // The second data structure in logs is the log records in the strategy log table in the bot database
                    "Max": 0,
                    "Arr": [],
                    "Total": 0,
                    "Min": 0
                }, {                  
                    // The third data structure in logs is the log records in the strategy log table in the bot database
                    "Max": 0,
                    "Arr": [],
                    "Total": 0,
                    "Min": 0
                }],
                "chart": "",
                "refresh": 1527049988000,
                "summary": "...", 
                "chartTime ": 0, 
                "node_id ": 50755, 
                "online ": true
            }, 
            "error ": null
        }
    }
    
  • Le tableau du journal de stratégie dans la base de données

    LeArrdescription de la valeur de l'attribut dans les données de résultat renvoyées ci-dessus:

    "Arr": [
        [3977, 3, "Futures_OKCoin", "", 0, 0, "Sell(688.9, 2): 20016", 1526954372591, "", ""],
        [3976, 5, "", "", 0, 0, "OKCoin:this_week too many positions, long: 2", 1526954372410, "", ""]
    ],
    
    Nom de l'entreprise Type de fichier - Je vous en prie. commandé prix Le montant en plus date de sortie type de contrat direction
    3977 3 Futures_OKCoin "" 0 0 Vendre ((688,9, 2): 20016 1526954372591 "" ""
    3976 5 "" "" 0 0 OKCoin:cette_semaine trop de positions, long: 2 1526954372410 "" ""

    extraest le message joint du journal imprimé.

    Types de bûches spécifiques représentés par:logTypevaleur:

    Type de journal: 0 1 2 3 4 5 6
    Signification de logType: À acheter VENDE RETRAIT ÉVÉNEMENT Résultats Le message Démarrer
    Signification chinoise Compte de type de commande Journal des types d'ordres de vente Retirer Erreur Revenu Le journal Relancer
  • Tableau de journaux du graphique des recettes dans la base de données Les données figurant dans le tableau de journaux du graphique sont cohérentes avec les données figurant dans le tableau de journaux de la stratégie.

    "Arr": [
        [202, 2515.44, 1575896700315],
        [201, 1415.44, 1575896341568]
    ]
    

    Prenons l'exemple de l'une des données du journal:

    [202, 2515.44, 1575896700315]
    

    202en logID; 2515.44en valeur des recettes;1575896700315comme timbres.

  • Tableau de journaux des graphiques dans la base de données

    "Arr": [
        [23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
        [23636, 5, "{\"x\":1575960300000,\"y\":3.0735}"]
    ]
    

    Prenons l'exemple de l'une des données du journal:

    [23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
    

    23637est le journalID, 0est l'indice de la série de données du graphique et les dernières données"{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"est les données journalières; ces données sont les données de la ligne K sur le graphique.

Plugin de trading

Introduction au projet

Afin d'améliorer les fonctions du terminal de négociation et de faciliter la négociation manuelle, une fonction plug-in est désormais disponible.

img

Principe du plugin

Le principe est le même que celui de l'outil de débogage: envoyer un morceau de code au docker de la page de terminal Trade pour l'exécuter, et prendre en charge le retour de graphiques et de tableaux (l'outil de débogage est également capable de prendre en charge après mise à niveau).outil de débogageIl peut réaliser quelques petites fonctions simples, des stratégies complexes encore à exécuter dans le commerce réel.

Écriture de plugins

Sur la page Nouvelle stratégie, définissez le type de stratégie comme suit:Trading Plugin, qui soutientJavaScript, Python, cppetMyLanguage.

img

Utilisation du plugin

Le plugin peut exécuter le code pendant une période de temps, et il peut effectuer des opérations simples, telles quecommandes de glacier, commandes en attente, annulation de commandeetcalcul de la commandeComme leoutil de débogage, il utilisereturnVoici quelques exemples, et d'autres fonctions peuvent être explorées par vous-même.

  • Revenir à l'instantané de profondeur

    // Return to the depth snapshot
    function main() {
        var tbl = { 
            type: 'table', 
            title: 'snapshot of the order depth @ ' + _D(), 
            cols: ['#', 'Amount', 'Ask', 'Bid', 'Amount'], 
            rows: []
        }
        var d = exchange.GetDepth()
        for (var i = 0; i < Math.min(Math.min(d.Asks.length, d.Bids.length), 15); i++) {
            tbl.rows.push([i, d.Asks[i].Amount, d.Asks[i].Price+'#ff0000', d.Bids[i].Price+'#0000ff', d.Bids[i].Amount])
        }
        return tbl
    }
    
    def main():
        tbl = {
            "type": "table",
            "title": "snapshot of the order depth @ " + _D(),
            "cols": ["#", "Amount", "Ask", "Bid", "Amount"],
            "rows": []
        }
        d = exchange.GetDepth()
        for i in range(min(min(len(d["Asks"]), len(d["Bids"])), 15)):
            tbl["rows"].append([i, d["Asks"][i]["Amount"], str(d["Asks"][i]["Price"]) + "#FF0000", str(d["Bids"][i]["Price"]) + "#0000FF", d["Bids"][i]["Amount"]])
        return tbl
    
    void main() {
        json tbl = R"({
            "type": "table",
            "title": "abc",
            "cols": ["#", "Amount", "Ask", "Bid", "Amount"],
            "rows": []   
        })"_json;
        
        tbl["title"] = "snapshot of the order depth @" + _D(); 
        auto d = exchange.GetDepth();
        for(int i = 0; i < 5; i++) {
            tbl["rows"].push_back({format("%d", i), format("%f", d.Asks[i].Amount), format("%f #FF0000", d.Asks[i].Price), format("%f #0000FF", d.Bids[i].Price), format("%f", d.Bids[i].Amount)});
        }
        
        LogStatus("`" + tbl.dump() + "`");
        // C++ does not support "return json" to display the table, and you can create a bot to display the table of the status bar 
    }
    

    img

  • Tirer les écarts entre les périodes

    // Draw cross-period spreads
    var chart = { 
        __isStock: true,    
        title : { text : 'spread analysis chart'},                     
        xAxis: { type: 'datetime'},                 
        yAxis : {                                        
            title: {text: 'spread'},                   
            opposite: false                   
        },
        series : [                    
            {name : "diff", data : []}
        ]
    }  
    
    function main() {
        exchange.SetContractType('quarter')
        var recordsA = exchange.GetRecords(PERIOD_M5)
        exchange.SetContractType('this_week')
        var recordsB = exchange.GetRecords(PERIOD_M5)
        
        for(var i = 0; i < Math.min(recordsA.length, recordsB.length); i++){
            var diff = recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Close - recordsB[recordsB.length - Math.min(recordsA.length, recordsB.length) + i].Close
            chart.series[0].data.push([recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Time, diff])
        }
        return chart
    }
    
    chart = {
        "__isStock": True,
        "title": {"text": "spread analysis chart"},
        "xAxis": {"type": "datetime"},
        "yAxis": {
            "title": {"text": "spread"}, 
            "opposite": False
        }, 
        "series": [
            {"name": "diff", "data": []}
        ]
    }  
    
    def main():
        exchange.SetContractType("quarter")
        recordsA = exchange.GetRecords(PERIOD_M5)
        exchange.SetContractType("this_week")
        recordsB = exchange.GetRecords(PERIOD_M5)  
    
        for i in range(min(len(recordsA), len(recordsB))):
            diff = recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i].Close - recordsB[len(recordsB) - min(len(recordsA), len(recordsB)) + i].Close
            chart["series"][0]["data"].append([recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i]["Time"], diff])
        return chart
    
    // C++ does not support "return json" structure drawing
    

    img

    Il y a d'autres exemples dans Plus de stratégies, tels que:acheter / vendre en petites quantités, Adresse de la stratégie.

Comment l' utiliser

  • Ajouter le module plugin du terminal de trading Comme indiqué sur la figure, ouvrez le menu ajouter des modules sur la page du terminal Trade, les plugins du terminal de trading dans lebibliothèque de stratégiede votre compte FMZ actuel apparaîtra dans la liste automatiquement, trouvez le plugin à ajouter et cliquez sur Add.

    img

  • Exécutez le plugin Cliquez sur Execute, et le plugin du terminal de trading va commencer à fonctionner.

  • Temps d'exécution du plugin La durée maximale de fonctionnement du plugin est de 3 minutes; et il cessera de fonctionner automatiquement après avoir dépassé 3 minutes.

Outil d'analyse du facteur alpha

Introduction au projet

La formule d'analyse fait référence à la méthode de calcul des cotations de marché utilisée par le public.alpha101deworldquant: http://q.fmz.com/chart/doc/101_Formulaic_Alphas.pdf, qui est fondamentalement compatible avec sa grammaire (avec des explications pour les caractéristiques non mises en œuvre), et a été améliorée. Il est utilisé pour effectuer rapidement des calculs sur des séries temporelles et valider des idées,Utiliser l' adresse.

Introduction à la page:

img

Fonctions et opérateurs

"{}" ci-dessous représente un espace réservé, toutes les expressions ne sont pas sensibles aux majuscules et x représente les séries temporelles de données

  • abs(x), log(x), sign(x)signifie littéralement valeur absolue, logarithme et fonction de signe, respectivement.

Les opérateurs suivants, dont+, -, *, /, >, <, répondent également aux significations de leurs normes;==représente égalité ou non;||signifie ou;x? y: zindique l'opérateur ternaire.

  • rank(x): le classement des sections transversales, en renvoyant le pourcentage de l'emplacement; il est nécessaire de spécifier plusieurs groupes cibles candidats, qui ne peuvent pas être calculés pour un marché unique et renvoient directement le résultat initial.
  • delay(x, d): la valeur avant la période d de la séquence.
  • sma(x, d): la moyenne mobile simple de la période d de la séquence.
  • correlation(x, y, d): le coefficient de corrélation des séries de temps x et y au cours des dernières périodes d.
  • covariance(x, y, d): la covariance des séries chronologiques x et y au cours des dernières périodes d.
  • scale(x, a): il normalise les données, de sorte quesum(abs(x)) = a(a par défaut à 1).
  • delta(x, d): la valeur actuelle de la série temporelle x moins la valeur avant d périodes.
  • signedpower(x, a): x^a.
  • decay_linear(x, d): moyenne mobile pondérée d'une série de temps x, avec des pondérations d, d-1, d-2... 1 (normalisée).
  • indneutralize(x, g): le traitement neutre pour la classification industrielle g, actuellement non pris en charge.
  • ts_{O}(x, d): effectuer des opérations O sur la série temporelle x dans les périodes d passées (O peut spécifiquement représenter min et max, etc., introduit plus tard), d sera converti en entier.
  • ts_min(x, d): la valeur minimale des dernières périodes d.
  • ts_max(x, d): la valeur maximale des dernières périodes d.
  • ts_argmax(x, d): ts_max(x, d) position.
  • ts_argmin(x, d): ts_min(x, d) position.
  • ts_rank(x, d): tri des valeurs de séries de temps x des périodes passées d (tri en pourcentage).
  • min(x, d): ts_min(x, d).
  • max(x, d): ts_max(x, d).
  • sum(x, d): la somme des périodes passées d.
  • product(x, d): le produit des périodes précédentes d.
  • stddev(x, d): l'écart type des dernières périodes d.

Données d'entrée

Les données d'entrée ne sont pas sensibles aux majuscules et minuscules; les données par défaut sont le symbole sélectionné sur la page Web, ou il peut être spécifié directement, commebinance.ada_bnb

  • returns: rendement du prix de clôture.
  • open, close, high, low, volume: à savoir le prix d'ouverture, le prix de clôture, le prix le plus élevé, le prix le plus bas et le volume des transactions au cours de la période.
  • vwap: prix d'exécution pondéré par volume, non encore mis en œuvre, qui est actuellement le prix de clôture.
  • cap: valeur de marché totale, pas encore mise en œuvre.
  • IndClass: classification de l'industrie, pas encore mise en œuvre.

Autres

La sortie de résultats multiples (exprimés par liste) est prise en charge à la fois; par exemple,[sma(close, 10), sma(high, 30)]En plus d'entrer des données de séries temporelles, il peut également être utilisé comme une simple calculatrice.

Le titre de l'annexe

Protocole général

Pour la plateforme de trading FMZ Quant qui n'a pas encore encapsulé l'interface API de l'échange, elle peut être consultée en écrivant un plug-in de protocole général.

La différence entreFIXle protocole plug-in et leRESTle programme de plug-in de protocole est uniquement l'interaction entre le programme de plug-in de protocole et l'interface d'échange. Le programme de plug-in de protocole a le même traitement détaillé de l'interaction du programme docker et du format de données que FMZ Quant. Pour plus de détails, veuillez vous référer aux exemples dans les liens ci-dessus.

Terminal de négociation

La plate-forme de négociation quantitative FMZ fournit une plateforme modulaire et personnalisable Commerce Vous pouvez librement ajouter divers modules de données et modules de fonction de trading, et même développer leurs propres modules de code (plugins de terminal de trading). Divers modules sur la page Trade peuvent être glissés et zoomés, les paramètres des paires de négociation et des bourses liées par les modules peuvent être modifiés et plusieurs modules du même type peuvent être ajoutés.

img

Outil de débogage

Outil de débogagepage fournit un environnement pour tester rapidement les codes par bot, ne prenant en charge queJavaScript currently.

img

Montage à distance

Il prend en charge le code de stratégie de synchronisation à distance de l'éditeur local à la plateforme de trading FMZ Quant, et il prend en chargeSublime Text/Atom/Vim/VSCodesur la page d'édition de stratégie, cliquez sur Remote Edit pour déployer le bouton d'adresse de téléchargement du plugin pour afficher la clé de synchronisation à distance (token) de la stratégie actuelle.

img

Cliquez sur Mise à jour pour actualiser l'affichage de la touche actuelle, et cliquez sur Supprimer pour supprimer la clé secrète (token) de la stratégie actuelle.

img

Les méthodes d'installation des plug-ins de différents éditeurs sont légèrement différentes. Vous pouvez cliquer sur le bouton de téléchargement pour accéder à l'élément spécifique du plug-in de synchronisation à distance.

img

Paramètres du bot Import & Export

img

Lorsque vous exécutez le trading en direct, vous devez enregistrer les données de paramètres de la configuration réelle du bot, vous pouvez cliquer sur le bouton Exporter.JSONle fichier, et la configuration du paramètre de stratégie exportée peut également être importée dans le bot réel à nouveau. Cliquez sur le bouton Importer pour importer les paramètres du bot de stratégie enregistrés dans le bot réel actuel. Ensuite, cliquez sur Enregistrer pour enregistrer.

Fichiers de stratégie Import & Export

img

  • Télécharger le code source Exporter le code source de stratégie, et le type du fichier d'exportation est basé sur le langage de programmation de stratégie.js; la stratégie python exporte les fichiers avec l'extensionpy; la stratégie C++ exporte les fichiers avec l'extensioncpp; Mylanguage stratégie exporte les fichiers avec l'extensiontxt. Notez que seul le code source de la stratégie est exporté, sans inclure les paramètres de la stratégie, les références de modèles, etc.

  • Stratégie d'exportation Exporter la stratégie complète, y compris toutes les informations sur la stratégie, telles que le code source de la stratégie et la conception des paramètres.xml file.

  • Stratégie d'importation Utilisez lexmlle fichier exporté par la fonction Export, et cliquez sur le bouton Import sur la page d'édition de stratégie pour sélectionner lexmlPour importer une stratégie complète, vous devez cliquer sur le bouton Enregistrer.

Soutien multilingue

Les noms de stratégie et les descriptions des paramètres de stratégie peuvent être écrits enChinese|English, affichée automatiquement dans la langue reconnue par les pages Web.

img

img

Dans d'autres endroits, par exemple:description de la stratégie, instructions d'utilisationet autres textesMarkdownformat, en utilisant[trans]Chinese|English[/trans]ou[trans]Chinese||English[/trans]L'effet de l'exemple ci-dessus est illustré sur la figure suivante:

  • Affichage de la page en chinois:img

  • Affichage de la page en anglais:img

Après avoir changé la langue, il prendra effet après avoir rafraîchi la page Web.

Les fonctions qui peuvent écrire des chaînes dans le code de stratégie prennent également en charge la commutation de langage, comme la fonctionLog, fonctionLogStatus, etc.

function main() {
    Log("[trans]日志|log[/trans]")
    var table = {
        type: "table", 
        title: "[trans]操作|option[/trans]", 
        cols: ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
        rows: [ 
            ["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}]  // Note: It doesn't need to add [trans] tag in the button
        ]
    }
    LogStatus("[trans]信息|message[/trans]", "\n`" + JSON.stringify(table) + "`")
    throw "[trans]错误|error[/trans]"
}
import json
def main():
    Log("[trans]日志|log[/trans]")
    table = {
        "type": "table", 
        "title": "[trans]操作|option[/trans]", 
        "cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
        "rows": [ 
            ["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}]
        ]
    }
    LogStatus("[trans]信息|message[/trans]", "\n`" + json.dumps(table) + "`")
    raise Exception("[trans]错误|error[/trans]")
void main() {
    Log("[trans]日志|log[/trans]");
    json table = R"({
        "type": "table", 
        "title": "[trans]操作|option[/trans]", 
        "cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
        "rows": [ 
            ["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}]
        ]
    })"_json;
    LogStatus("[trans]信息|message[/trans]", "\n`" + table.dump() + "`");
    Panic("[trans]错误|error[/trans]");
}

Le marché de la simulation WexApp

  • Opération 24 heures sur 24, puissant système de correspondance de trading, simulant le vrai trading.
  • Un puissant robot de création de marché qui fournit une bonne liquidité et une profondeur du carnet de commandes.
  • Appui complet à l'interface API, non seulement peut être testé sur FMZ Quant pour simuler le trading quantitatif, mais peut également se connecter à l'interface API par vous-même, adresse:Nous avons une application..

Paramètres du programme Docker

Après avoir téléchargé le logiciel docker, le fichier exécutable après décompression (nom du fichier:robot) est le programme docker; les paramètres peuvent être spécifiés pour le programme docker, lors du déploiement du docker.

  • -v: vérifiez les informations, y compris la version et l'heure de compilation du programme docker en cours. La commande d'exécution est basée surApple Mac System: ./robot -v.
  • -s: l'adresse spécifiée pour communiquer avec la plateforme de trading FMZ Quant lors de l'exécution du programme docker. La commande d'exécution est basée surApple Mac System: ./robot -s node.fmz.com/xxxxxxx; xxxxxxxest l'identifiant d'identification unique de chaque compte sur la plate-forme de négociation quantitative FMZ; après l'exécution de la commande, il sera demandé de saisir le mot de passe du compte de la plate-forme de négociation quantitative correspondante FMZ.
  • -p: vous pouvez spécifier directement le paramètre dans la commande run pour saisir le mot de passe, ce qui n'est pas recommandé, car le paramètre de mot de passe sera laissé dans l'enregistrement système en cours.node.fmz.com/xxxxxxxest:abc123456Je suis désolée. La commande d'exécution est basée surApple Mac System: ./robot -s node.fmz.com/xxxxxxx -p abc123456.
  • -n: joignez des informations d'étiquette au programme docker en cours d'exécution. La commande d'exécution est basée surApple Mac System: ./robot -n macTest -s node.fmz.com/xxxxxxxIl y aura unmacTestÉtiquette de texte dans les informations du docker sur la page de gestion du docker de la plateforme.
  • -l: imprimer la liste d'échange prise en charge par le docker actuel. La commande d'exécution est basée surApple Mac System: ./robot -l, c'est-à-dire que les noms des échanges pris en charge peuvent être sortis.

Causes courantes d'erreur de bot et de sortie anormale

  • Stratégie erreurs grammaticales statiques (de telles erreurs sont évidentes, et généralement vous pouvez voir la marque d'erreur sur la page d'édition de la stratégie), qui peuvent être trouvées et corrigées pendant le backtest.
  • Erreurs d'exécution de la stratégie, l'exemple le plus courant est l'utilisation directe de la valeur de retour de la fonction sans porter un jugement juridique.
  • Trop de contenu qui ne peut pas être récupéré est stocké dans des variables globales, ce qui entraîne une utilisation excessive de la mémoire.
  • Lorsque l'on utilise leexchange.Gofonction, il n'y a pas de fonction raisonnablewaitd'attendre la fin de la coroutine pendant l'opération, ce qui entraîne un grand nombre de coroutines.
  • Trop de couches d'appels de fonction récursifs provoquent la taille de pile dépassée des coroutines.
  • Les erreurs d'interface et les erreurs de demande de réseau, etc.; ces messages d'erreur afficheront les informations, y compris les noms d'objets d'échange pertinents, les noms de fonctions, les messages et les raisons liés aux erreurs, et d'autres informations.les exceptions du programme causées par l'utilisation directe sans la valeur de retour de l'interface pour juger de la légalité).
  • Les erreurs de sous-couche de la plate-forme, l'exemple commun estDecrypt: Secret key decrypt failedLa raison de l'erreur est que la modification du mot de passe du compte FMZ provoque tous lesAPI KEYPour résoudre le problème, leAPI KEYIl faut reconfigurer et redémarrer le dock.
  • Lors de la location d'une stratégie Python, une erreur est signalée en raison de l'incompatibilité de version entre le Python crypté par la plateforme et le Python dans l'exécution de la stratégie:ValueError: bad marshal data (unknown type code). Mettre à niveau ou installer l'environnement Python exécuté par la stratégie vers une des versions prises en charge par la stratégie:Python 2.7, Python 3.5etPython 3.6.
  • interrupterreur; l'erreur est due au fait que l'utilisateur cliqueArrêtez le bot.bouton sur la page Bot lorsque le programme effectue une opération (comme accéder à l'interface de la plateforme), et le bot arrête et interrompt le message d'erreur imprimé par l'opération en cours.

Groupe des robots et des stratégies

Sur la page Bot et Strategy de la plateforme de trading FMZ Quant, vous pouvez cliquerRéglage du groupeLe bouton de droite pour gérer les stratégies et les transactions réelles en groupe.Modèle, Stratégie JavaScriptetStratégie pour le backtestpeuvent être divisées en trois groupes, respectivement.

Sous-compte et bot en direct

Sous-compte Après vous être connecté à la plateforme, cliquez sur Dashboard et Account pour accéder au compte FMZ [page de gestion] (https://www.fmz.com/m/accountPour voir la page de création du sous-compte, sélectionnez le bot auquel le sous-compte ajouté peut accéder dans leles autorisations disponiblesLe contrôle et la mise en place des sous-comptesnom d'utilisateuretmot de passe de connexion du sous-comptedans leinformations relatives à l'utilisateurle contrôle. Cliquez sur le bouton Ajouter un sous-membre pour créer un sous-compte. Le sous-compte ajouté sera affiché sur la page actuelle et peut être modifié, verrouillé/déverrouillé, et supprimé.

Les sous-comptes ont des autorisations limitées; seuls les bots autorisés dans les paramètres deles autorisations disponiblespeuvent être consultées dans les sous-comptes. Le bot autorisé a le pouvoir de modifier les paramètres, d'arrêter et de redémarrer le trading en direct, mais il ne peut pas modifier l'objet d'échange configuré par le bot. Les scénarios d'utilisation des sous-comptes sont généralement:

  • A. Il est pratique de se connecter et de gérer lorsque l'équipe quantitative gère plusieurs stratégies de bots.
  • B. Débogage lorsque la stratégie est à louer.

Vue de négociation en direct Dans la liste des robots de la plateforme FMZpage du robot, cliquez sur le bouton Public pour afficher publiquement les bots de la ligne en cours.

    1. Afficher les robots sur le [Live View] (https://www.fmz.com/live) publiée sur la plateforme FMZ, après avoir cliqué sur le bouton Public, et sélectionnerPart du public.
    1. Créez un lien privé pour la visualisation. Après avoir cliqué sur le bouton Public et sélectionnéPart interne, vous pouvez définir une période de validité pour générer un lien privé pour vous connecter à la page de vue privée du bot de stratégie.

Partage et location de stratégies

ÀStratégiepage, après avoir cliqué sur le bouton Action sur le côté droit de la stratégie, le menu qui apparaît a des options pour le partage et la location.

Partage des stratégies

  • Partage public Après avoir cliqué sur le bouton Partage, une boîte de dialogue apparaîtra, et vous pouvez choisir Partage public, de sorte que la stratégie est complètement partagée dans les plateformes Plus de stratégies, et tout utilisateur peut copier la stratégie.

  • Partage interne Après avoir cliqué sur le bouton Partage, une boîte de dialogue s'ouvrira et vous pourrez choisir Partage interne.adresse de la page de copieetcode de copieLes utilisateurs qui ont besoin de cette stratégie n'ont qu'à utiliser leadresse de la page de copielien, pour vous connecter aupage de copieAprès avoir obtenu la stratégie, elle apparaîtra automatiquement sur la page Strategy.

Stratégie de location

  • Vente publique Après avoir cliqué sur le bouton Rent, une boîte de dialogue apparaîtra et vous pourrez choisir Public Sale.

  • Vente interne Après avoir cliqué sur le bouton Rent, une boîte de dialogue s'ouvrira et vous pourrez choisir Vente interne.adresse de la page d'enregistrementetle jeton de stratégieLes utilisateurs qui ont besoin de cette stratégie n'ont qu'à utiliser leadresse de la page d'enregistrementlien, pour vous connecter aupage d'enregistrement. Ensuite, entrez le jeton de stratégie pour obtenir le droit d'utiliser la stratégie. La stratégie sera également affichée sur la page Strategy, mais uniquement avec le droit d'utiliser le backtest et le bot. Les informations comme le code source de la stratégie sont inaccessibles.

Note importante: Lors de la création et de la distribution desle jeton de stratégie, s'il vous plaît assurez-vous de confirmer soigneusement s'il s'agit d'un jeton stratégie ou d'un code copie, afin de ne pas partager la stratégie par erreur.

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

Instructions spéciales d'échange

  • Les contrats à terme avec Binance Il prend en charge le mode de double position des contrats à terme Binance; vous pouvez utiliserexchange.IOPour passer:

    function main() {
        var ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=true")
        // ret : {"code":200,"msg":"success"}
        Log(ret)
    }
    
    def main():
        ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=false")
        Log(ret)
    
    void main() {
        auto ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=true");
        Log(ret);
    }
    

    Il prend en charge la commutation entre position croisée/position isolée

    function main() {
        exchange.SetContractType("swap")
        exchange.IO("cross", true)    // Switch to crossed position
        exchange.IO("cross", false)   // Switch to isolated position
    }
    
    def main():
        exchange.SetContractType("swap")
        exchange.IO("cross", True)
        exchange.IO("cross", False)
    
    void main() {
        exchange.SetContractType("swap");
        exchange.IO("cross", true);
        exchange.IO("cross", false);
    }
    
  • Les contrats à terme Il prend en charge la modification de l'adresse de Huobi Futures participant à la signature, qui n'est pas commuté par défaut.exchange.IO("signHost", "")pour définir une chaîne vide. Utilisationexchange.IO("signHost", "https://aaa.xxx.xxx")modifier l'adresse de base de Huobi Futures participant à la vérification de la signature. Utilisationexchange.IO("base", "https://bbb.xxx.xxx")ouexchange.SetBase("https://bbb.xxx.xxx")pour changer l'adresse de base de l'interface de la plateforme. Lorsque la paire de négociation est réglée surXXX_USDT, utilisez la fonctionexchange.SetContractType("swap")pour régler le code du contrat àswaple contrat perpétuel, en utilisantexchange.IO("cross", true)peut passer àUSDT- un contrat perpétuel à marge en mode position croisée.exchange.IO("cross", false)Le paramètre par défaut initial est le mode de position isolée.

  • Huobi Il prend en charge les jetons Huobi au comptant, tels que:LINK*(-3); le code défini par la bourse est:link3susdt, qui est écrit lorsque FMZ définit la paire de négociationLINK3S_USDTJe suis désolée. Il est également possible de changer de paire de négociation dans la stratégie:

    function main() {
        exchange.SetCurrency("LINK3S_USDT")
        Log(exchange.GetTicker())
    }
    
    def main():
        exchange.SetCurrency("LINK3S_USDT")
        Log(exchange.GetTicker())
    
    void main() {
        exchange.SetCurrency("LINK3S_USDT");
        Log(exchange.GetTicker());
    }
    
  • - Je suis désolé. L'interface OKX peut basculer vers l'environnement de simulation de test du robot OKX; en utilisantexchange.IO("simulate", true)Si vous souhaitez passer à l'environnement de trading réel, utilisezexchange.IO("simulate", false)Le défaut initial est l'environnement commercial réel. Il prend en charge le changement de mode de marge de compte; utilisationexchange.IO("cross", true)pour passer en mode position croisée et utiliserexchange.IO("cross", false)pour passer au mode de position isolée, la valeur par défaut initiale est le mode de position croisée.

  • Les échanges à terme Utilisationexchange.IO("cross", true)pour passer au mode position croisée et utiliserexchange.IO("cross", false)pour passer au mode de position isolée; le paramètre par défaut initial est le mode de position croisée. L'échange ne prend pas en charge la requête des ordres en attente actuels et l'interface pour la requête des dossiers de négociation historiques du marché, de sorte que leGetOrdersetGetTradesles fonctions ne sont pas prises en charge.

  • Les contrats à terme avec Bitget Utilisationexchange.IO("cross", true)pour passer en mode position croisée et utiliserexchange.IO("cross", false)pour passer au mode de position isolée.

  • Le montant de la garantie est calculé à partir de la valeur de la garantie. Utilisationexchange.IO("cross", true)pour passer en mode position croisée et utiliserexchange.IO("cross", false)pour passer au mode de position isolée.

  • Les échanges à terme Utilisationexchange.IO("cross", true)pour passer en mode position croisée et utiliser` ` échange.IO("croix",


Plus de