En la carga de los recursos... Cargando...

Las instrucciones de la API FMZ

El autor:No hay nada, Creado: 2020-04-20 10:19:00, Actualizado: 2023-04-12 14:44:56

XchangeList (en inglés)

GetExchangeList()devuelve la lista de intercambios compatibles y la información de configuración requerida.

  • Parámetro No hay

  • Valor de retorno

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

Elimina el Nodo (nudo)

DeleteNode(Nid)Elimina el nodo del muelle (IDesNid) correspondiente a laAPI KEYen la solicitud de la cuenta de la plataforma de negociación FMZ Quant.

  • ParámetroNides de tipo entero, es decir, el dockerID.

  • Valor de retorno

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

EliminaRobot(...)

DeleteRobot(RobotId, DeleteLogs)elimina el robot con el ID especificado (robotID: RobotId) correspondiente a laAPI KEYen la solicitud de la cuenta FMZ Quant.

  • ParámetroRobotIdes de tipo entero, es decir, el robotIDque se suprimen.DeleteLogses de tipo booleano; conjuntoDeleteLogspara decidir si borrar el registro o no;trueindica la eliminación del registro.

  • Valor de retorno

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

Obtenga la lista de estrategias

GetStrategyList()Obtiene la información estratégica correspondiente a laAPI KEYen la solicitud de la cuenta de la plataforma de negociación FMZ Quant.

  • Parámetro No hay

  • Valor de retorno

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

NuevoRobot ((Configuración)

NewRobot(Settings)crea un nuevo bot de acuerdo con la configuración de parámetros, correspondiente a laAPI KEYen la solicitud de la cuenta FMZ Quant.

  • ParámetroSettingses deJSONtipo de objeto.Settingses unaJSONObjeto configurado por el bot.

    ElSettingsLa descripción se explica de la siguiente manera:

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

    Nota: Cuando utiliza la información confidencial, como la plataformaAPI KEY, incluidos"meta":{"AccessKey":"xxx","SecretKey":"yyy"}en la configuración deeid, usted debe saber FMZ no almacena los datos. Los datos serán enviados directamente al programa docker, por lo que esta información debe ser configurado cada vez que el bot se crea o se reinicia.

    Para reiniciar el bot que utiliza el complemento para apoyar la plataforma, al configurar elSettingsParámetro, debe hacer las siguientes configuraciones para elexchangesel atributo:

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

    labelEl atributo es establecer una etiqueta para el objeto de intercambio al que accede el protocolo general actual, que puede obtenerse mediante elexchange.GetLabel()El objetivo de la estrategia es:

  • Estrategia de ensayo:

    • Parámetro de la estrategiaInterval

    • JavaScriptCódigo de estrategia

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

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

PluginRun ((Configuración)

PluginRun(Settings)utiliza la API extendida para llamarherramienta de depuración function.

  • ParámetroSettingses unaJSONObjeto, es decir, la configuración de la herramienta de depuración (Settingscontiene el código de prueba escrito en el atributosource).

  • Código de ensayoPythonEjemplo:

    #!/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)
    

    Nota:{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}} {"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}Para elexchangesatributo en elajustes, el atributo sólo tiene que ser establecido en 1, cuando se llama elPluginRuninterfaz (solo se puede admitir un objeto de intercambio cuando se utiliza la página Debug Tool). No se reportará ningún error cuando se establezcan 2 objetos de intercambio enajustes, pero se informará de un error cuando se acceda al segundo objeto de intercambio en el código.

  • Valor de retornoapi("PluginRun", settings)Resultados devueltos:

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

GetRobotLogs ((...)

GetRobotLogs(robotId, logMinId, logMaxId, logOffset, logLimit, profitMinId, profitMaxId, profitOffset, profitLimit, chartMinId, chartMaxId, chartOffset, chartLimit, chartUpdateBaseId, chartUpdateDate, summaryLimit)Obtiene la información del registro del robot (robotID: robotId), correspondiente a laAPI KEYen la solicitud de la cuenta FMZ Quant.

  • Parámetro

    Nombre del parámetro Tipo de producto Las observaciones
    El robot número entero Identificador de bot

    Cuadro Registroconsulta los datos del registro de la tabla de la base de datos:

    Nombre del parámetro Tipo de producto Las observaciones
    LogMinId número entero Identificación mínima del registro
    LogMaxId número entero Identificación máxima del registro
    LogOffset (descenso de registro) número entero Después de que el rango se determina por logMinId y logMaxId, el desplazamiento de logOffset (cuántos registros se saltan) comienza a utilizarse como posición de partida para obtener datos
    LogLimit (Límite de registro) número entero Después de determinar la posición inicial, el número de registros de datos seleccionados

    Cuadro Gananciaconsulta los datos de utilidad de la tabla de la base de datos:

    Nombre del parámetro Tipo de producto Las observaciones
    Profitos número entero Identificación mínima del registro
    gananciaMaxId número entero Identificación máxima del registro
    ProfitOffset número entero El desplazamiento (cuántos registros se saltan) comienza a utilizarse como la posición de partida
    ProfitLimit número entero Después de determinar la posición inicial, el número de registros de datos seleccionados

    Cuadro de la tablaconsulta los datos del gráfico de la tabla de la base de datos:

    Nombre del parámetro Tipo de producto Las observaciones
    Cuadro número entero Identificación mínima del registro
    gráfico MaxId número entero Identificación máxima del registro
    gráficoOffset número entero Compensación
    el gráfico límite número entero el número de registros a obtener
    Diagrama ActualizaciónBaseId número entero Buscar el ID de base actualizado
    Diagrama actualización fecha número entero Registro de datos actualiza la marca de tiempo, que filtrará los registros más grandes que esta marca de tiempo

    Resumen Limitaciónconsulta los datos de la barra de estado:

    Se consulta los datos de la barra de estado del bot. El tipo de parámetro es entero. Estableciendo 0 significa que no hay necesidad de consultar la información de la barra de estado, y la configuración a un número diferente de cero indica el número de bytes de la información de la barra de estado a consultar (la interfaz no limita la cantidad de datos, por lo que puede especificar un mayorsummaryLimitParámetro para obtener toda la información de la barra de estado). Los datos de la barra de estado se almacenan en los datos retornadossummary.

    PythonEjemplo:

    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"
    
  • Valor de retorno datos devueltos:

    {
        "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
        }
    }
    
  • La tabla de registro de estrategias en la base de datos

    ElArrDescripción del valor del atributo en los datos de resultado devueltos anteriormente:

    "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, "", ""]
    ],
    
    el número de Tipo de registro el día ordenado precio cantidad extra fecha ContratoTipo Dirección
    3977 3 Los futuros_OKCoin "" 0 0 Venda ((688.9, 2): 20016 1526954372591 "" ""
    3976 5 "" "" 0 0 OKCoin:esta_semana demasiadas posiciones, largo: 2 1526954372410 "" ""

    extraes el mensaje adjunto del registro impreso.

    Tipos específicos de troncos representados porlogTypeel valor:

    Tipo de registro: 0 1 2 3 4 5 6
    Significado de logType: Comprar VENTA Se retirará Error de registro Profitos El mensaje Reinicio
    Significado chino Registro del tipo de orden de compra Registro del tipo de orden de venta Retirarse Error en el sistema Ingresos Registro Reinicio
  • Cuadro de registro del gráfico de ingresos en la base de datos Los datos de la tabla de registro del gráfico son consistentes con el registro de ingresos de la tabla de registro de la estrategia.

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

    Tomemos como ejemplo uno de los datos de registro:

    [202, 2515.44, 1575896700315]
    

    202en forma de registroID; 2515.44como valor de los ingresos;1575896700315como sellos de tiempo.

  • Tabla de registro de gráficos en la base de datos

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

    Tomemos como ejemplo uno de los datos de registro:

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

    23637es el registroID, 0es el índice de la serie de datos del gráfico, y los últimos datos"{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"es los datos de registro; estos datos son los datos de la línea K en el gráfico.

Plugin para el comercio

Introducción

Con el fin de mejorar las funciones del terminal de negociación y facilitar la negociación manual, ahora está disponible una función plug-in.

img

Principio del complemento

El principio es el mismo que la herramienta de depuración: enviar un pedazo de código al docker de la página terminal de Trade para ejecutar, y soportar la devolución de gráficos y tablas (la herramienta de depuración también es capaz de soportar después de la actualización).herramienta de depuraciónPuede realizar algunas pequeñas funciones simples, estrategias complejas que aún necesitan ejecutarse en el comercio real.

Escribir el complemento

En la página Nueva Estrategia, establecer el tipo de estrategia en:Trading Plugin, que apoyaJavaScript, Python, cppyMyLanguage.

img

Uso del complemento

El complemento puede ejecutar el código durante un período de tiempo, y puede realizar algunas operaciones simples, tales comoórdenes de iceberg, órdenes pendientes, cancelación de la ordenyEl cálculo de la ordenLo mismo que elherramienta de depuración, se utilizareturnAquí hay algunos ejemplos, y otras funciones se pueden explorar por sí mismo.

  • Vuelve a la instantánea de profundidad

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

  • Dibujar los diferenciales entre períodos

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

    Hay otros ejemplos en Más Estrategias, como:Comprar / vender en pequeñas cantidades, Dirección de la estrategia.

Cómo usar

  • Añadir el módulo de complemento de la terminal de negociación Como se muestra en la figura, abra el menú de añadir módulos en la página del terminal Trade, los plugins del terminal de negociación en elbiblioteca de estrategiasde la cuenta FMZ actual se mostrará en la lista automáticamente, encontrar el complemento a agregar y haga clic en Añadir.

    img

  • Ejecute el complemento Haga clic en Execute, y el complemento de terminal de trading comenzará a ejecutarse.

  • Tiempo de ejecución del complemento El tiempo máximo de ejecución del complemento es de 3 minutos; y dejará de funcionar automáticamente después de superar los 3 minutos.

Herramienta de análisis del factor alfa

Introducción

La fórmula de análisis se refiere al método de cálculo de las cotizaciones de mercado en el público.alpha101de lasworldquant: http://q.fmz.com/chart/doc/101_Formulaic_Alphas.pdf, que es básicamente compatible con su gramática (con explicaciones de características no implementadas), y ha sido mejorada. Se utiliza para realizar rápidamente cálculos sobre series de tiempo y validar ideas,Usar la dirección.

Página Introducción:

img

Funciones y operadores

"{}" a continuación representa el marcador de posición, todas las expresiones no son sensibles a mayúsculas y minúsculas, y x representa las series temporales de datos

  • abs(x), log(x), sign(x)literalmente significa valor absoluto, logaritmo y función de signo, respectivamente.

Los siguientes operadores, incluidos:+, -, *, /, >, <, también cumplen con los significados de sus normas;==representa igual o no;||significa o;x? y: zIndica el operador ternario.

  • rank(x): la clasificación de las secciones transversales, que devuelve el porcentaje de la ubicación; es necesario especificar múltiples grupos objetivo candidatos, que no pueden calcularse para un mercado único y devuelven directamente el resultado original.
  • delay(x, d): el valor anterior al período d de la secuencia.
  • sma(x, d): la media móvil simple del período d de la secuencia.
  • correlation(x, y, d): el coeficiente de correlación de las series de tiempo x y y durante los últimos periodos d.
  • covariance(x, y, d): la covariancia de las series de tiempo x y y en los últimos periodos d.
  • scale(x, a): normaliza los datos, de modo quesum(abs(x)) = a(a por defecto a 1).
  • delta(x, d): el valor actual de la serie temporal x menos el valor anterior a d períodos.
  • signedpower(x, a): x^a.
  • decay_linear(x, d): media móvil ponderada de los periodos d de la serie de tiempo x, con ponderaciones d, d-1, d-2... 1 (normalizada).
  • indneutralize(x, g): el procesamiento neutro para la clasificación industrial g, actualmente no soportado.
  • ts_{O}(x, d): realizar operaciones O en la serie de tiempo x en los últimos periodos d (O puede representar específicamente min y max, etc., introducidos más adelante), d se convertirá en un número entero.
  • ts_min(x, d): el valor mínimo de los últimos d períodos.
  • ts_max(x, d): el valor máximo de los últimos d períodos.
  • ts_argmax(x, d): ts_max(x, d) position.
  • ts_argmin(x, d): ts_min(x, d) position.
  • ts_rank(x, d): clasificación de los valores de las series temporales x de los últimos d períodos (sortado por porcentaje).
  • min(x, d): ts_min(x, d).
  • max(x, d): ts_max(x, d).
  • sum(x, d): la suma de los últimos d períodos.
  • product(x, d): el producto de los últimos d períodos.
  • stddev(x, d): la desviación estándar de los últimos d períodos.

Datos de entrada

Los datos de entrada no son sensibles a mayúsculas y minúsculas; los datos predeterminados son el símbolo seleccionado en la página web, o se puede especificar directamente, comobinance.ada_bnb

  • returns: devoluciones del precio de cierre.
  • open, close, high, low, volume: es decir, el precio de apertura, el precio de cierre, el precio más alto, el precio más bajo y el volumen de operaciones durante el período.
  • vwap: precio ejecutado ponderado por volumen, aún no ejecutado, que es actualmente el precio de cierre.
  • cap: valor de mercado total, aún no aplicado.
  • IndClass: clasificación de las industrias, aún no aplicada.

Las demás

Se admite la salida de múltiples resultados (expresados por lista) a la vez; por ejemplo,[sma(close, 10), sma(high, 30)]Además de introducir datos de series temporales, también se puede utilizar como una simple calculadora.

Apéndice

Protocolo general

Para la plataforma FMZ Quant Trading que aún no ha encapsulado la interfaz API del intercambio, se puede acceder escribiendo un programa de complemento de protocolo general.

La diferencia entre elFIXel protocolo de programa de conexión y elRESTEl protocolo plug-in tiene el mismo procesamiento detallado de la interacción del programa docker y el formato de datos que FMZ Quant. Para más detalles, consulte los ejemplos en los enlaces anteriores.

Terminal de negociación

La plataforma Quant Trading de FMZ ofrece una plataforma modular y personalizable Comercio Puede agregar libremente varios módulos de datos y módulos de función de trading, e incluso desarrollar sus propios módulos de código (plugins de terminal de trading). Se pueden arrastrar y ampliar varios módulos en la página Trade, se pueden modificar los ajustes de los pares de operaciones y los intercambios vinculados por los módulos y se pueden agregar múltiples módulos del mismo tipo.

img

Herramienta de depuración

Herramienta de depuraciónpágina proporciona un entorno para probar rápidamente los códigos por bot, apoyando sóloJavaScript currently.

img

Edición remota

Es compatible con el editor local de código de estrategia de sincronización remota a la plataforma de comercio FMZ Quant, y es compatible conSublime Text/Atom/Vim/VSCodeEn la página de edición de la estrategia, haga clic en Remote Edit para abrir el botón de descarga de la dirección del complemento para mostrar la clave de sincronización remota (token) de la estrategia actual.

img

Haga clic en Actualizar clave para actualizar la pantalla de la clave actual, y haga clic en Eliminar clave para eliminar la clave secreta (token) de la estrategia actual.

img

Los métodos de instalación de los complementos de diferentes editores son ligeramente diferentes. Puede hacer clic en el botón de descarga para saltar al elemento específico del complement de sincronización remota.

img

Parámetros de bot Importar y exportar

img

Cuando se ejecuta el comercio en vivo, usted necesita guardar los datos de parámetros de la configuración real bot, puede hacer clic en el botón Export.JSONEn este caso, el bot puede importar los parámetros de la estrategia guardados en el bot actual. Luego, haga clic en Guardar para guardar.

Archivos de estrategia de importación y exportación

img

  • Descarga el código fuente Exportar el código fuente de la estrategia, y el tipo del archivo de exportación se basa en el lenguaje de programación de la estrategia.js; Python estrategia exporta los archivos con la extensiónpy; C++ estrategia exporta los archivos con la extensióncpp; Mylanguage estrategia exporta los archivos con la extensióntxtTenga en cuenta que sólo se exporta el código fuente de la estrategia, sin incluir los parámetros de la estrategia, las referencias de plantillas, etc.

  • Estrategia de exportación Exportar la estrategia completa, incluida toda la información de la estrategia, como el código fuente de la estrategia y el diseño de parámetros.xml file.

  • Estrategia de importación Utilice elxmlarchivo exportado por la función Export, y haga clic en el botón Import en la página de edición de la estrategia para seleccionar elxmlDespués de importar, debe hacer clic en el botón Guardar para guardar la estrategia.

Apoyo multilingüe

Los nombres de estrategias y las descripciones de parámetros de estrategia pueden escribirse enChinese|English, se muestra automáticamente en el idioma reconocido por las páginas web.

img

img

En otros lugares, como:Descripción de la estrategia, instrucciones de usoy otros textos enMarkdownel formato, utilizando[trans]Chinese|English[/trans]o bien[trans]Chinese||English[/trans]El efecto del ejemplo anterior se muestra en la siguiente figura:

  • Muestra de página en chino:img

  • Muestra de página en inglés:img

Después de cambiar el idioma, tendrá efectos después de actualizar la página web.

Las funciones que pueden escribir cadenas en el código de estrategia también admiten el cambio de idioma, como la funciónLog, funciónLogStatus, 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]");
}

Mercado de simulación de WexApp

  • 24 horas de operación sin parar, sistema de comparación de operaciones potente, simulando el comercio real.
  • Potente robot de creación de mercado que proporciona buena liquidez y profundidad de la cartera de órdenes.
  • Soporte completo de la interfaz API, no sólo se puede probar en FMZ Quant para la simulación de comercio cuantitativo, sino que también se puede conectar a la interfaz API por sí mismo, dirección:WexApp es una aplicación.

Parámetros del programa Docker

Después de descargar el software docker, el archivo ejecutable después de la descompresión (nombre del archivo:robot) es el programa docker; los parámetros se pueden especificar para el programa docker, al desplegar el docker.

  • -v: comprobar la información, incluida la versión y el tiempo de compilación del programa docker actual. El comando de ejecución completo se basa enApple Mac System: ./robot -v.
  • -s: la dirección especificada para comunicarse con la plataforma Quant Trading de FMZ al ejecutar el programa docker. El comando de ejecución completo se basa enApple Mac System: ./robot -s node.fmz.com/xxxxxxx; xxxxxxxes el identificador único de identificación de cada cuenta en la plataforma de negociación de FMZ Quant; después de ejecutar el comando, se solicitará la introducción de la contraseña para la cuenta correspondiente de la plataforma de negociación de FMZ Quant.
  • -p: puede especificar directamente el parámetro en el comando de ejecución para introducir la contraseña, que no se recomienda, porque el parámetro de contraseña se dejará en el registro del sistema actual.node.fmz.com/xxxxxxxes:abc123456¿ Qué pasa? El comando de ejecución completo se basa enApple Mac System: ./robot -s node.fmz.com/xxxxxxx -p abc123456.
  • -n: adjuntar información de etiqueta al programa de docker en ejecución. El comando de ejecución completo se basa enApple Mac System: ./robot -n macTest -s node.fmz.com/xxxxxxxHabrá unamacTestEtiqueta de texto en la información del docker en la página de gestión del docker de la plataforma.
  • -l: imprimir la lista de intercambio compatible con el docker actual. El comando de ejecución completo se basa enApple Mac System: ./robot -l, es decir, los nombres de los intercambios apoyados pueden ser emitidos.

Causas comunes del error del bot y salida anormal

  • Errores gramaticales estáticos de la estrategia (tales errores son obvios, y por lo general se puede ver la marca de error en la página de edición de la estrategia), que se pueden encontrar y corregir durante el backtest.
  • Los errores de ejecución de la estrategia, el ejemplo más común es el uso directo del valor de retorno de la función sin hacer un juicio legal.
  • Demasiado contenido que no puede ser recogido como basura se almacena en variables globales, lo que resulta en un uso excesivo de la memoria.
  • Cuando se utiliza el asíncronoexchange.GoFunción, no hay una función razonablewaitpara esperar el final de la coroutine durante la operación, lo que resulta en un gran número de coroutines.
  • Demasiadas capas de llamadas de funciones recursivas causan el tamaño excesivo de la pila de las coroutinas.
  • Interfaz de errores de negocio y errores de solicitud de red, etc.; tales mensajes de error mostrarán la información, incluyendo los nombres de objetos de intercambio relevantes, nombres de funciones, mensajes relacionados con errores y razones, y otra información.Excepciones del programa causadas por el uso directo sin el valor de retorno de la interfaz para juzgar la legalidad).
  • Los errores de la capa inferior de la plataforma, el ejemplo común esDecrypt: Secret key decrypt failedLa razón del error es que la modificación de la contraseña de la cuenta FMZ causa todos losAPI KEYPara resolver el problema, elAPI KEYnecesita ser reconfigurado, y el docker necesita ser reiniciado.
  • Al alquilar una estrategia de Python, se informa un error debido a la incompatibilidad de versión entre el Python cifrado por la plataforma y el Python en el tiempo de ejecución de la estrategia:ValueError: bad marshal data (unknown type code). Actualizar o instalar el entorno Python ejecutado por la estrategia a una de las versiones soportadas por la estrategia:Python 2.7, Python 3.5yPython 3.6.
  • interrupterror; el error se debe a que el usuario hace clic enPara el bot.bot en la página del bot cuando el programa realiza una operación (como acceder a la interfaz de la plataforma), y el bot detiene e interrumpe el mensaje de error impreso por la operación actual.

Bot y estrategia de agrupación

En la página Bot y Strategy de la plataforma de comercio de FMZ Quant, puede hacer clicConfiguración de grupoEn el caso de las operaciones de negociación, el botón de la derecha permite gestionar las estrategias y las operaciones reales en grupos.Modelo, Estrategia de JavaScriptyEstrategia para las pruebas de retrocesoSe pueden dividir en tres grupos, respectivamente.

Subcuenta y bot en vivo

Subcuenta Después de iniciar sesión en la plataforma, haga clic en Dashboard y Account para pasar a la cuenta de FMZ [página de administración] (https://www.fmz.com/m/accountPara ver la página de creación de la subcuenta, seleccione el bot al que puede acceder la subcuenta añadida en elpermisos disponiblesControl, y establecer las subcuentasnombre de usuarioycontraseña de inicio de sesión de la subcuentaEn elInformación del usuariocontrol. Haga clic en el botón Añadir submiembro para crear una subcuenta. La subcuenta añadida se mostrará en la página actual y se puede modificar, bloquear/desbloquear y borrar.

Las subcuentas tienen permisos limitados; sólo los bots autorizados en la configuración depermisos disponiblesse puede ver en las subcuentas. El bot autorizado tiene la autoridad para modificar los parámetros, detener y reiniciar el comercio en vivo, pero no puede modificar el objeto de intercambio configurado por el bot.

  • R. Es conveniente iniciar sesión y administrar cuando el equipo cuantitativo gestiona múltiples estrategias de bots.
  • B. Debugging cuando la estrategia está en alquiler.

Visión de operaciones en vivo En la lista de bots de la plataforma FMZPágina de bot, haga clic en el botón Público para mostrar los bots de la fila actual públicamente.

    1. Muestra los bots en el [Vista en vivo] (https://www.fmz.com/live) página publicada en la plataforma FMZ, después de hacer clic en el botón Público y seleccionarParticipación del público.
    1. Crear un enlace privado para ver. Después de hacer clic en el botón Público y seleccionarCuota interna, puede establecer un período de validez para generar un enlace privado para iniciar sesión en la página de vista en vivo privada del bot de estrategia.

Compartir y alquilar estrategias

En elEstrategiapágina, después de hacer clic en el botón Acción en el lado derecho de la estrategia, el menú que aparece tiene opciones para compartir y alquilar.

Compartir estrategias

  • Compartir con el público Después de hacer clic en el botón Compartir, aparecerá un cuadro de diálogo, y puede elegir Compartir público, por lo que la estrategia se comparte completamente en las plataformas Más estrategias, y cualquier usuario puede copiar la estrategia.

  • Compartición interna Después de hacer clic en el botón Compartir, aparecerá un cuadro de diálogo, y puede elegir Compartir Internamente.dirección de la página de copiayCódigo de copiaLos usuarios que necesiten esta estrategia sólo necesitan utilizar eldirección de la página de copiaenlace, para iniciar sesión en elpágina de copiaDespués de obtener la estrategia, aparecerá en la página Estrategia automáticamente.

Estrategia de alquiler

  • Venta pública Después de hacer clic en el botón Alquiler, aparecerá un cuadro de diálogo, y puede elegir Venta pública.

  • Venta interna Después de hacer clic en el botón Rent, aparecerá un cuadro de diálogo, y puede elegir Internal Sale.dirección de la página de registroyel token de estrategiaEn el caso de los usuarios que necesitan esta estrategia, sólo necesitan utilizar la estrategia de FMZ.dirección de la página de registroenlace, para iniciar sesión en elpágina de registro. Luego, ingrese el token de estrategia para obtener el derecho de usar la estrategia. La estrategia también se mostrará en la página Estrategia, pero solo con el derecho de usar el backtest y el bot. La información como el código fuente de la estrategia es inaccesible.

Nota importante: Al crear y distribuir elel token de estrategia, asegúrese de confirmar cuidadosamente si se trata de un token de estrategia o de un código de copia, para no compartir la estrategia por error.

Algoritmo de Sharpe en el sistema de pruebas de retroceso

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

Instrucciones especiales de intercambio

  • Los futuros de Binance Apoya el modo de posición dual de futuros de Binance; se puede utilizarexchange.IOpara cambiar:

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

    Apoya el cambio entre posición cruzada/posición aislada

    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);
    }
    
  • Futures_HuobiDM Apoya la modificación de la dirección de Huobi Futures que participa en la firma, que no se cambia por defecto.exchange.IO("signHost", "")para establecer una cadena vacía. Utilizaciónexchange.IO("signHost", "https://aaa.xxx.xxx")cambiar la dirección de base de Huobi Futures que participa en la verificación de firmas. Utilizaciónexchange.IO("base", "https://bbb.xxx.xxx")o bienexchange.SetBase("https://bbb.xxx.xxx")para cambiar la dirección base de la interfaz de la plataforma. Cuando el par de operaciones está configurado paraXXX_USDT, utilizar la funciónexchange.SetContractType("swap")para establecer el código del contrato aswapContrato perpetuo, utilizandoexchange.IO("cross", true)puede cambiar aUSDT- contrato perpetuo con margen en el modo de posición cruzada.exchange.IO("cross", false)El valor por defecto inicial es el modo de posición aislada.

  • - ¿ Qué? Apoya tokens de apalancamiento al contado de Huobi, como:LINK*(-3); el código definido por la bolsa es:link3susdt, que se escribe cuando FMZ establece el par de operacionesLINK3S_USDT¿ Qué pasa? También es posible cambiar de par de operaciones en la estrategia:

    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());
    }
    
  • No hay problema. La interfaz OKX puede cambiar al entorno de prueba de simulación del bot de OKX; utilizandoexchange.IO("simulate", true)Si desea cambiar a un entorno de negociación real, utiliceexchange.IO("simulate", false)El valor inicial por defecto es el entorno comercial real. Apoya el cambio de modos de margen de cuenta; usoexchange.IO("cross", true)para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)para cambiar al modo de posición aislada, el valor por defecto inicial es el modo de posición cruzada.

  • El valor de la inversión se calcula de acuerdo con el método de cálculo. Utilizaciónexchange.IO("cross", true)para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)para cambiar al modo de posición aislada; el valor por defecto inicial es el modo de posición cruzada. El intercambio no admite la consulta de las órdenes pendientes actuales y la interfaz para consultar los registros históricos de negociación del mercado, por lo que elGetOrdersyGetTradeslas funciones no son compatibles.

  • Los futuros_Bitget Utilizaciónexchange.IO("cross", true)para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)para cambiar al modo de posición aislada.

  • Las operaciones de garantía de los bancos centrales Utilizaciónexchange.IO("cross", true)para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)para cambiar al modo de posición aislada.

  • Los futuros_MEXC Utilizaciónexchange.IO("cross", true)para cambiar al modo de posición cruzada y utilizar` ` intercambio.IO("cruz",


Más.