O recurso está a ser carregado... Carregamento...

Instruções da API FMZ

Autora:Zero., Criado: 2020-04-20 10:19:00, Atualizado: 2023-04-12 14:44:56

XchangeList (()

GetExchangeList()Retorna a lista de intercâmbios suportados e as informações de configuração necessárias.

  • Parâmetro Nenhum

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

DeleteNode ((Nid)

DeleteNode(Nid)Elimina o nó do docker (IDéNid) correspondente aoAPI KEYNo pedido da conta da plataforma de negociação FMZ Quant.

  • ParâmetroNidé de tipo inteiro, ou seja, o dockerID.

  • Valor de retorno

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

DeleteRobot(...)

DeleteRobot(RobotId, DeleteLogs)Elimina o robô com o ID especificado (robôID: RobotId) correspondente aoAPI KEYNo pedido no âmbito da conta FMZ Quant.

  • ParâmetroRobotIdé de tipo inteiro, ou seja, o robôIDa ser suprimida.DeleteLogsé de tipo booleano; conjuntoDeleteLogspara decidir se deve apagar ou não o registo;trueindica a eliminação do registo.

  • Valor de retorno

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

GetStrategyList (Lista de estratégias)

GetStrategyList()Obtém as informações estratégicas correspondentes aoAPI KEYNo pedido da conta da plataforma de negociação FMZ Quant.

  • Parâmetro Nenhum

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

NewRobot ((Configurações)

NewRobot(Settings)cria um novo bot de acordo com as configurações do parâmetro, correspondente aoAPI KEYNo pedido da conta FMZ Quant.

  • ParâmetroSettingsé deJSONTipo de objeto.Settingsé umJSONObjeto configurado pelo bot.

    OSettingsA descrição é explicada do seguinte modo:

    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: Quando você usa as informações confidenciais, tais como plataformaAPI KEY, incluindo"meta":{"AccessKey":"xxx","SecretKey":"yyy"}na configuração deeidOs dados serão enviados diretamente para o programa docker, então essa informação deve ser configurada toda vez que o bot for criado ou reiniciado.

    Para reiniciar o bot que usa o plugin para suportar a plataforma, Ao configurar oSettingsParâmetro, você deve fazer as seguintes configurações para oexchangesAtributo:

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

    labelAtributo é definir um rótulo para o objeto de troca acessado pelo protocolo geral atual, que pode ser obtido peloexchange.GetLabel()A política de emprego

  • Estratégia de ensaio:

    • Parâmetro de estratégiaInterval

    • JavaScriptCódigo de estratégia

      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 ((Configurações)

PluginRun(Settings)usa a API estendida para chamarferramenta de depuração function.

  • ParâmetroSettingsé umJSONObjeto, nomeadamente as definições da ferramenta de depuração (Settingscontém o código de ensaio escrito no atributosource).

  • Código de ensaioPythonExemplo:

    #!/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 oexchangesatributo noconfigurações, o atributo só precisa ser definido para 1, quando oPluginRuninterface (para apenas um objeto de troca pode ser suportado quando você usa a página Debug Tool). Nenhum erro será relatado quando você definir 2 objetos de troca emconfigurações, mas um erro será relatado quando o segundo objeto de troca é acessado no código.

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

    {
        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)Obtém as informações do diário do robô (robotID: robotId), correspondente aoAPI KEYNo pedido da conta FMZ Quant.

  • Parâmetro

    Nome do parâmetro Tipo Observações
    robotId Número inteiro Identificador de bot

    Tabela RegistoPergunta os dados do log da tabela de banco de dados:

    Nome do parâmetro Tipo Observações
    logMinId Número inteiro Identificação mínima do registro
    LogMaxId Número inteiro Identificação máxima do registro
    LogOffset Número inteiro Após o intervalo ser determinado por logMinId e logMaxId, o logOffset offset (quantos registros são ignorados) começa a ser usado como posição de partida para obter dados
    LogLimit Número inteiro Após a determinação da posição de partida, o número de registos de dados selecionados

    Tabela Lucroconsulta os dados de lucro da tabela da base de dados:

    Nome do parâmetro Tipo Observações
    lucroMinId Número inteiro Identificação mínima do registo
    lucroMaxId Número inteiro Identificação máxima do registo
    lucroOffset Número inteiro O deslocamento (quantos registros são ignorados) começa a ser usado como posição de partida
    lucroLimite Número inteiro Após a determinação da posição de partida, o número de registos de dados selecionados

    Tabela Gráficoconsulta os dados do gráfico da tabela da base de dados:

    Nome do parâmetro Tipo Observações
    gráfico MinId Número inteiro Identificação mínima do registo
    gráficoMaxId Número inteiro Identificação máxima do registo
    gráficoOffset Número inteiro Compensação
    chartLimit Número inteiro número de registos a obter
    chartUpdateBaseId Número inteiro Consultar o ID de base atualizado
    DiagramaAtualizaçãoData Número inteiro Registro de dados atualiza o carimbo horário, que irá filtrar os registros maiores do que este carimbo horário

    Resumo Limiteconsulta os dados da barra de estado:

    Ele consulta os dados da barra de status do bot. O tipo de parâmetro é inteiro. A configuração para 0 significa que não há necessidade de consultar as informações da barra de status, e a configuração para um número diferente de zero indica o número de bytes da informação da barra de status a ser consultada (a interface não limita a quantidade de dados, então você pode especificar um maiorsummaryLimitParâmetro para obter todas as informações da barra de status). Os dados da barra de status são armazenados nos dados devolvidossummary.

    PythonExemplo:

    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 Dados devolvidos:

    {
        "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
        }
    }
    
  • A tabela de log da estratégia na base de dados

    OArrDescrição do valor do atributo nos dados de resultado devolvidos acima:

    "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, "", ""]
    ],
    
    Identificação Tipo de log eid Ordenado Preço quantidade extra data Contrato Tipo direção
    3977 3 Futures_OKCoin "" 0 0 Venda ((688,9, 2): 20016 1526954372591 "" ""
    3976 5 "" "" 0 0 OKCoin:esta_semana muitas posições, long: 2 1526954372410 "" ""

    extraé a mensagem anexada do registo impresso.

    Tipos específicos de troncos representados por:logTypeValor:

    Tipo de log: 0 1 2 3 4 5 6
    Significado de logType: Comprar Venda RETRAÇÃO ERROR Lucro Mensagem RESTART
    Significado chinês Registo do tipo de ordem de compra Registo do tipo de ordem de venda Retirar-se. Erro Receita Registo Reiniciar
  • Tabela de registo do gráfico de receitas na base de dados Os dados na tabela de registo do gráfico são consistentes com o registo das receitas na tabela de registo da estratégia.

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

    Tome um dos dados de registo como exemplo:

    [202, 2515.44, 1575896700315]
    

    202como logID; 2515.44em valor de receita;1575896700315como carimbos de tempo.

  • Tabela de registos de gráficos na base de dados

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

    Tome um dos dados de registo como exemplo:

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

    23637é o logID, 0é o índice da série de dados do gráfico e os últimos dados"{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"são os dados de log; Estes dados são os dados de linha K no gráfico.

Plugin de negociação

Introdução

A fim de melhorar as funções do terminal de negociação e facilitar melhor a negociação manual, está agora disponível uma função plug-in.

img

Princípio do Plugin

O princípio é o mesmo que a ferramenta de depuração: enviar um pedaço de código para o docker da página do terminal Trade para executar, e suportar o retorno de gráficos e tabelas (a ferramenta de depuração também é capaz de suportar após a atualização).ferramenta de depuraçãoPode realizar algumas pequenas funções simples, estratégias complexas ainda precisam ser executadas na negociação real.

Escrever plugins

Na página Nova Estratégia, definir o tipo de estratégia como:Trading Plugin, que apoiaJavaScript, Python, cppeMyLanguage.

img

Utilização do Plugin

O plug-in pode executar o código por um período de tempo, e ele pode realizar algumas operações simples, tais comoOrdens de iceberg, Ordens pendentes, cancelamento da encomendaeCalculo da ordemO mesmo que oferramenta de depuração, utilizareturnAqui estão alguns exemplos, e outras funções podem ser exploradas por si mesmo.

  • Volte ao instantâneo de profundidade

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

  • Desenhar os spreads 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

    Existem outros exemplos no Mais Estratégias, tais como:comprar / vender em pequenas quantidades, Endereço da estratégia.

Como usar

  • Adicionar o módulo plugin do terminal de negociação Como mostrado na figura, abra o menu adicionar módulo na página do terminal Trade, os plugins do terminal de negociação noBiblioteca de estratégiasda conta FMZ atual será exibido na lista automaticamente, encontrar o plugin a ser adicionado e clique em Add.

    img

  • Executar o plugin Clique em Execute, e o plugin do terminal de negociação começará a ser executado.

  • Tempo de execução do plugin O tempo máximo de execução do plug-in é de 3 minutos; e ele vai parar de funcionar automaticamente após exceder 3 minutos.

Ferramenta de Análise de Fatores Alfa

Introdução

A fórmula de análise refere-se ao método de cálculo da cotação de mercado no mercado públicoalpha101deworldquant: http://q.fmz.com/chart/doc/101_Formulaic_Alphas.pdf, que é basicamente compatível com sua gramática (com explicações para características não implementadas), e foi aprimorada. É utilizado para realizar rapidamente cálculos sobre séries temporais e validar ideias,Use o endereço.

Página Introdução:

img

Funções e operadores

"{}" abaixo representa o espaço reservado, todas as expressões não são sensíveis a minúsculas e minúsculas, e x representa séries temporais de dados

  • abs(x), log(x), sign(x)literalmente significa valor absoluto, logaritmo e função de sinal, respectivamente.

Os seguintes operadores, incluindo:+, -, *, /, >, <, também cumprem os significados das suas normas;==representa igual ou não;||significa ou;x? y: zIndica o operador ternário.

  • rank(x): a classificação das secções transversais, devolvendo a percentagem da localização; é necessário especificar múltiplos grupos-alvo candidatos, que não podem ser calculados para um mercado único e retornarão diretamente o resultado original.
  • delay(x, d): o valor anterior ao período d da sequência.
  • sma(x, d): a média móvel simples do período d da sequência.
  • correlation(x, y, d): o coeficiente de correlação das séries temporais x e y durante os últimos períodos d.
  • covariance(x, y, d): a covariância das séries temporais x e y nos últimos d períodos.
  • scale(x, a): normaliza os dados, de modo quesum(abs(x)) = a(a predefinido para 1).
  • delta(x, d): o valor corrente da série temporal x menos o valor anterior a d períodos.
  • signedpower(x, a): x^a.
  • decay_linear(x, d): média móvel ponderada do período d da série temporal x, com ponderações d, d-1, d-2... 1 (normalizada).
  • indneutralize(x, g): o processamento neutro para classificação industrial g, atualmente não suportado.
  • ts_{O}(x, d): executar operações O na série temporal x nos períodos d passados (O pode representar especificamente min e max, etc., introduzidos mais tarde), d será convertido em um número inteiro.
  • ts_min(x, d): o valor mínimo dos últimos períodos d.
  • ts_max(x, d): o valor máximo dos ú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): classificação dos valores das séries temporais x dos últimos d períodos (classificação por percentagem).
  • min(x, d): ts_min(x, d).
  • max(x, d): ts_max(x, d).
  • sum(x, d): a soma dos últimos d períodos.
  • product(x, d): o produto dos últimos d períodos.
  • stddev(x, d): o desvio-padrão dos últimos d períodos.

Dados de entrada

Os dados de entrada não são sensíveis às maiúsculas e minúsculas; os dados padrão são o símbolo selecionado na página web, ou podem ser especificados diretamente, comobinance.ada_bnb

  • returns: retorno do preço de fechamento.
  • open, close, high, low, volume: ou seja, preço de abertura, preço de fechamento, preço mais alto, preço mais baixo e volume de negociação durante o período.
  • vwapO preço executado ponderado por volume, ainda não executado, que é atualmente o preço de encerramento.
  • cap: valor de mercado total, ainda não implementado.
  • IndClassClassificação da indústria, ainda não aplicada.

Outros

A saída de vários resultados (expressos por lista) de uma só vez é suportada; por exemplo,[sma(close, 10), sma(high, 30)]Além de introduzir dados de séries temporais, pode também ser utilizado como uma calculadora simples.

Anexo

Protocolo Geral

Para a plataforma FMZ Quant Trading que ainda não encapsulou a interface da API da troca, ela pode ser acessada escrevendo um plug-in de protocolo geral.

A diferença entre oFIXPrograma plug-in de protocolo e oRESTO protocolo plug-in programa é apenas a interação entre o protocolo plug-in programa e a interface de troca. O protocolo plug-in programa tem o mesmo processamento detalhado do programa docker interação e formato de dados como FMZ Quant. Para detalhes, consulte os exemplos nos links acima.

Terminal de negociação

A plataforma FMZ Quant Trading fornece uma plataforma modular e personalizávelComérciocom o seu uso altamente flexível e gratuito, também facilita muito os usuários de negociação manual e de negociação semi-programática. Vários módulos na página Trade podem ser arrastados e ampliados, as configurações dos pares de negociação e bolsas vinculadas aos módulos podem ser modificadas e vários módulos do mesmo tipo podem ser adicionados.

img

Ferramenta de depuração

Ferramenta de depuraçãopágina fornece um ambiente para testar rapidamente códigos por bot, suportando apenasJavaScript currently.

img

Edição remota

Ele suporta o editor local código de estratégia de sincronização remota para a plataforma FMZ Quant Trading e suportaSublime Text/Atom/Vim/VSCodeNa página de edição de estratégia, clique em Remote Edit para abrir o botão de download do plugin para exibir a chave de sincronização remota (token) da estratégia atual.

img

Clique em Atualizar chave para atualizar a exibição da chave atual e clique em Excluir chave para excluir a chave secreta (token) da estratégia atual.

img

Os métodos de instalação de plug-in de diferentes editores são ligeiramente diferentes. Você pode clicar no botão de download para ir para o item específico do plug-in de sincronização remota.

img

Parâmetros do bot Importação e Exportação

img

Ao executar a negociação ao vivo, você precisa salvar os dados de parâmetros da configuração real bot, você pode clicar no botão Exportar.JSONO bot pode ser importado para o bot real novamente. Clique no botão Importar para importar os parâmetros de bot da estratégia salvos para o bot real atual. Em seguida, clique em Salvar para salvar.

Arquivos de estratégia de importação e exportação

img

  • Baixe o código fonte Exportar o código fonte da estratégia, e o tipo do arquivo de exportação é baseado na linguagem de programação da estratégia.js; a estratégia python exporta os arquivos com a extensãopy; C ++ estratégia exporta os arquivos com a extensãocpp; Mylanguage estratégia exporta os arquivos com a extensãotxtObserve que apenas o código fonte da estratégia é exportado, não incluindo parâmetros de estratégia, referências de modelo, etc.

  • Estratégia de exportação Exportar a estratégia completa, incluindo todas as informações de estratégia, tais como código fonte estratégia e design de parâmetros.xml file.

  • Estratégia de importação Utilize oxmlFicheiro exportado pela função Export, e clique no botão Import na página de edição de estratégia para selecionar oxmlDepois de importar, você precisa clicar no botão Salvar para salvar a estratégia.

Apoio multilingue

Os nomes das estratégias e as descrições dos parâmetros das estratégias podem ser escritos emChinese|English, exibido automaticamente na língua reconhecida pelas páginas web.

img

img

Em outros lugares, como:Descrição da estratégia, instruções de utilizaçãoe outros textos daMarkdownformato, utilizando[trans]Chinese|English[/trans]ou[trans]Chinese||English[/trans]O efeito do exemplo acima é mostrado na figura seguinte:

  • Display da página em chinês:img

  • Exibição da página em inglês:img

Depois de mudar o idioma, ele terá efeitos após atualizar a página da web.

As funções que podem escrever strings no código estratégia também suportam a troca de linguagem, como funçãoLog, funçãoLogStatus, 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 Simulação WexApp

  • Operação 24 horas sem parar, poderoso sistema de correspondência de negociação, simulando negociação real.
  • Um robô poderoso que fornece boa liquidez e profundidade da carteira de pedidos.
  • Suporte completo de interface API, não só pode ser testado no FMZ Quant para negociação quantitativa simulada, mas também pode se conectar à interface API por si mesmo, endereço:WexApp.

Parâmetros do programa Docker

Depois de baixar o software docker, o arquivo executável após descompressão (nome do arquivo:robot) é o programa docker; os parâmetros podem ser especificados para o programa docker, ao implantar o docker.

  • -v: verificar as informações, incluindo a versão e o tempo de compilação do programa docker atual. O comando de execução completo é baseado emApple Mac System: ./robot -v.
  • -s: o endereço especificado para comunicar com a plataforma FMZ Quant Trading ao executar o programa docker. O comando de execução completo é baseado emApple Mac System: ./robot -s node.fmz.com/xxxxxxx; xxxxxxxé o ID de identificação exclusivo de cada conta na plataforma de negociação FMZ Quant; após a execução do comando, será solicitado o ingresso da senha para a conta correspondente da plataforma de negociação FMZ Quant.
  • -p: você pode especificar diretamente o parâmetro no comando run para inserir a senha, o que não é recomendado, porque o parâmetro de senha será deixado no registro do sistema atual.node.fmz.com/xxxxxxxé:abc123456- Não. O comando de execução completo é baseado emApple Mac System: ./robot -s node.fmz.com/xxxxxxx -p abc123456.
  • -n: anexar informações de rótulo ao programa docker em execução. O comando de execução completo é baseado emApple Mac System: ./robot -n macTest -s node.fmz.com/xxxxxxxHaverá ummacTestEtiqueta de texto na informação do docker na página de gestão do docker da plataforma.
  • -l: imprimir a lista de troca suportada pelo docker atual. O comando de execução completo é baseado emApple Mac System: ./robot -l, isto é, os nomes das trocas suportadas podem ser produzidos.

Causas comuns de erro de bot e saída anormal

  • Erros gramaticais estáticos da estratégia (tais erros são óbvios, e geralmente você pode ver a marca de erro na página de edição da estratégia), que podem ser encontrados e corrigidos durante o backtest.
  • Erros de execução de estratégia, o exemplo mais comum é o uso direto do valor de retorno da função sem fazer um julgamento legal.
  • Muito conteúdo que não pode ser coletado é armazenado em variáveis globais, resultando em uso excessivo de memória.
  • Quando se utiliza o sistema assíncronoexchange.GoFunção, não há nenhuma razão razoávelwaitpara esperar o fim da coroutina durante a operação, resultando num grande número de coroutinas.
  • Muitas camadas de chamadas de funções recursivas causam o excesso de tamanho da pilha das coroutinas.
  • Erros de negócios de interface e erros de solicitação de rede, etc.; tais mensagens de erro exibirão as informações, incluindo nomes de objetos de troca relevantes, nomes de funções, mensagens e razões relacionadas a erros e outras informações.exceções do programa causadas pelo uso direto sem o interfaz retornar valor para julgar a legalidade).
  • Erros de subcamada da plataforma, o exemplo comum éDecrypt: Secret key decrypt failedA razão para o erro é que a modificação da senha da conta FMZ causa todos osAPI KEYPara resolver o problema, oAPI KEYprecisa ser reconfigurado, e o docker precisa ser reiniciado.
  • Ao alugar uma estratégia Python, um erro é relatado devido à incompatibilidade de versão entre o Python criptografado pela plataforma e o Python no tempo de execução da estratégia:ValueError: bad marshal data (unknown type code). Atualizar ou instalar o ambiente Python executado pela estratégia para uma das versões suportadas pela estratégia:Python 2.7, Python 3.5ePython 3.6.
  • interrupterro; o erro é porque o utilizador clica noPare o bot.bot na página Bot quando o programa executa uma operação (como acessar a interface da plataforma), e o bot para e interrompe a mensagem de erro impressa pela operação atual.

Bot & Grupo de Estratégia

Na página Bot e Strategy da plataforma de negociação FMZ Quant, você pode clicarConfiguração do grupoO sistema de gestão de estratégias e negociação real em grupos, por exemplo, para a definição de estratégias em grupo,Modelo, Estratégia JavaScripteEstratégia para testes de retrocessopodem ser divididas em três grupos, respectivamente.

Sub-Conta e Bot Vivo

Subconta Depois de entrar na plataforma, clique em Dashboard e Account para ir para a conta FMZ [página de gestão] (https://www.fmz.com/m/accountPara ver a página de criação da sub-conta, selecione o bot que a sub-conta adicionada pode acessar nopermissões disponíveisO controlo e a definição das subcontasnome de utilizadoreSenha de login da subcontaemInformações do utilizadorcontrole. Clique no botão Adicionar sub-membro para criar uma sub-conta. A sub-conta adicionada será exibida na página atual e pode ser modificada, bloqueada/desbloqueada e apagada.

As sub-contas têm permissões limitadas; apenas os bots autorizados nas configurações dopermissões disponíveisO montante da contribuição para o exercício de 2000 pode ser visto nas subcontas. O bot autorizado tem autoridade para modificar parâmetros, parar e reiniciar negociação ao vivo, mas não pode modificar o objeto de troca configurado pelo bot.

  • A. É conveniente iniciar sessão e gerenciar quando a equipe quantitativa gerencia várias estratégias de bots.
  • B. Debugging quando a estratégia está para alugar.

Visualização de negociação ao vivo Na lista de bots da plataforma FMZPágina do bot, clique no botão Público para exibir os bots da linha atual publicamente.

    1. Mostrar os bots no [Live View] (https://www.fmz.com/live) publicada na plataforma FMZ, após clicar no botão Público e selecionarParticipação do público.
    1. Crie uma ligação privada para visualização. Depois de clicar no botão Público e selecionarParticipação interna, você pode definir um período de validade para gerar um link privado para entrar na página de visualização privada do bot de estratégia.

Compartilhamento e aluguel de estratégias

EmEstratégiapágina, depois de clicar no botão Ação no lado direito da estratégia, o menu que aparece tem opções para compartilhamento e aluguel.

Compartilhamento de estratégias

  • Compartilhamento público Depois de clicar no botão Compartilhamento, uma caixa de diálogo aparecerá, e você pode escolher Compartilhamento Público, para que a estratégia seja completamente compartilhada nas plataformas mais estratégias, e qualquer usuário possa copiar a estratégia.

  • Partilha interna Após clicar no botão Compartilhamento, uma caixa de diálogo aparecerá e você poderá escolher Compartilhamento interno.endereço da página de cópiaeCódigo de cópiaOs utilizadores que necessitam desta estratégia só precisam de utilizar a plataforma FMZ.endereço da página de cópialigação, para entrar nopágina de cópiaDepois de obter a estratégia, ela aparecerá na página Estratégia automaticamente.

Estratégia de aluguer

  • Venda pública Após clicar no botão Rent, uma caixa de diálogo aparecerá, e você pode escolher Public Sale.

  • Venda interna Após clicar no botão Rent, uma caixa de diálogo aparecerá, e você pode escolher Internal Sale.Endereço da página de registoetoken de estratégiaOs utilizadores que necessitam desta estratégia só precisam de utilizar oEndereço da página de registolink, para entrar noPágina de registo. Em seguida, insira o token da estratégia para obter o direito de usar a estratégia. A estratégia também será exibida na página Strategy, mas apenas com o direito de usar o backtest e o bot. As informações como o código fonte da estratégia são inacessíveis.

Nota importante: Ao criar e distribuir otoken de estratégia, certifique-se de confirmar cuidadosamente se é um token de estratégia ou um código de cópia, para não compartilhar a estratégia por engano.

Algoritmo Sharpe no sistema 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
    }
}

Instruções especiais de troca

  • Futures_Binance Ele suporta o modo de posição dupla de futuros Binance; você pode usarexchange.IOpara trocar:

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

    Suporta a troca entre posição cruzada/posição isolada

    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 Ele suporta a modificação do endereço de Huobi Futures que participam da assinatura, que não é trocado por padrão.exchange.IO("signHost", "")para definir uma cadeia vazia. Utilizaçãoexchange.IO("signHost", "https://aaa.xxx.xxx")Para alterar o endereço de base da Huobi Futures que participa na verificação da assinatura. Utilizaçãoexchange.IO("base", "https://bbb.xxx.xxx")ouexchange.SetBase("https://bbb.xxx.xxx")para alterar o endereço de base da interface da plataforma. Quando o par de negociação estiver definido emXXX_USDT, usar a funçãoexchange.SetContractType("swap")para definir o código do contrato paraswapContrato perpétuo, utilizandoexchange.IO("cross", true)pode mudar paraUSDT- contrato perpétuo com margem no modo de posição cruzada.exchange.IO("cross", false)O padrão inicial é o modo de posição isolada.

  • Huobi Ele suporta tokens de alavancagem spot da Huobi, como:LINK*(-3); o código definido pela bolsa é:link3susdt, que é escrito quando a FMZ define o par de negociaçãoLINK3S_USDT- Não. Também é possível trocar pares de negociação na estratégia:

    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());
    }
    
  • OKX A interface OKX pode mudar para o ambiente de teste de robôs de simulação do OKX; usandoexchange.IO("simulate", true)Se você quiser mudar para o ambiente de negociação real, useexchange.IO("simulate", false)O padrão inicial é o ambiente comercial real. Suporta a troca de modos de margem da conta;exchange.IO("cross", true)para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)para mudar para o modo de posição isolada, o padrão inicial é o modo de posição cruzada.

  • Futures_Bibox Utilizaçãoexchange.IO("cross", true)para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)para mudar para o modo de posição isolada; o padrão inicial é o modo de posição cruzada. A troca não suporta a consulta de ordens pendentes atuais e a interface para consulta dos registos históricos de negociação do mercado, de modo que oGetOrderseGetTradesfunções não são suportadas.

  • Futuros_Bitget Utilizaçãoexchange.IO("cross", true)para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)para mudar para o modo de posição isolada.

  • Futuros_OFEX Utilizaçãoexchange.IO("cross", true)para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)para mudar para o modo de posição isolada.

  • Futuros_MEXC Utilizaçãoexchange.IO("cross", true)para mudar para o modo de posição cruzada e utilizar` ` troca.IO("cruz",


Mais.