3
focar em
1444
Seguidores

Tutorial básico de escrita de estratégia de plataforma quantitativa FMZ (leitura obrigatória)

Criado em: 2019-08-13 17:47:27, atualizado em: 2021-08-06 10:29:46
comments   33
hits   69033

[TOC] Este tutorial inclui o conhecimento básico de estratégias de programação, incluindo introdução, feedback, gráficos e outros conteúdos da API. Após o aprendizado deste tutorial básico, o usuário será capaz de usar com habilidade as APIs básicas e escrever estratégias de disco rígido.Introdução à plataforma de quantificação dos inventores da FMZ 。

A versão anterior do tutorial:Inventor Quantificar (FMZ.COM) Estratégia de Criação de Manual de Uso Completo 2.0 (Tutorial)Este tutorial tem uma lista de muitos posts indexados, e é recomendável que você os veja.

Instruções para a elaboração da estratégia

Introdução à API

A negociação programada é a ligação de um programa através de uma API e uma bolsa, para realizar a compra e venda automática de acordo com a intenção projetada ou para realizar outras funções. A API é conhecida como Application Programming Interface (API).

Atualmente, existem dois principais protocolos de interface para as exchanges de moedas digitais: REST e Websocket. O protocolo REST requer um acesso para cada acesso de dados.

{"data:{"buy":"11351.73","high":"11595.77","last":"11351.85","low":"11118.45","open":"11358.74","quoteVol":"95995607137.00903936","sell":"11356.02","time":1565593489318,"vol":"3552.5153"}}

Isso permite que você veja o que está acontecendo com o par BTC_USDT, que é atualizado a cada atualização.market=Os parâmetros de pares de negociação específicos são seguidos, que podem ser modificados para obter outros dados de pares de negociação. Para interfaces públicas, como o mercado, todos podem acessar, portanto, não é necessário autenticar, enquanto algumas interfaces, como as encomendas e as contas de acesso, precisam identificar o usuário, que precisa ser assinado usando o API-KEY. O Websocket é um modelo de assinatura, após o envio do conteúdo que precisa ser assinado, a bolsa envia os dados atualizados para o programa, sem a necessidade de voltar a acessar cada vez, portanto, é mais eficiente.

A plataforma de negociação quantitativa FMZ embala as interfaces REST de todas as exchanges, usando uma forma unificada de chamadas e formatos de dados, tornando a programação de estratégias mais simples e generalizada. A plataforma FMZ pode facilmente suportar o Websocket, que será detalhado no próximo tutorial.

Diferentes linguagens de programação

A documentação da API do FMZ é baseada principalmente em JavaScript, mas, devido ao encapsulamento, as diferenças entre as línguas são quase iguais, basta prestar atenção aos problemas gramaticais. C ++ é um pouco especial, e os tutoriais posteriores terão uma introdução especializada. Como o Js é relativamente simples e sem problemas de compatibilidade, recomendamos que os iniciantes o usem. A plataforma de quantificação do FMZ suporta o Python completo, pode ser instalada livremente em vários pacotes e é recomendado o uso de uma base de programação. Para usuários que não querem aprender a linguagem de programação e apenas querem escrever estratégias rapidamente, a plataforma do FMZ também suporta o Mac, compatível com as estratégias de finanças do Mandarim, com recomendações de uso de experiência, a desvantagem é que não há linguagem de programação ativa.

Como existem diferentes versões do Python, pode ser especificado no início do programa, como#!Python2,#!Python3O JavaScript foi recentemente atualizado para a linguagem ES6, e os interessados podem aprender mais sobre isso. A seguir, o código do Python e do Javascript para as mesmas funções é mostrado, apenas com diferenças gramaticais, portanto, o documento da API fornece apenas exemplos do Javascript, e este tutorial também irá combinar casos de uso especiais do Python.

#python代码
def main():
    while True:
        Log(exchange.GetAccount().Balance)
        Sleep(2000)
#相应的Js代码
function main(){
    while(true){
        Log(exchange.GetAccount().Balance)
        Sleep(2000)
    }
}

Recomendações de recursos

  • A documentação da API da plataforma FMZ, que não é detalhada em cada interface, pode ser consultada neste documento: https://www.fmz.com/api
  • Se você quiser receber sinais de tradingview, faça uma compra no FMZ, consulte este artigo: https://www.fmz.com/digest-topic/5533
  • Javascript, Python introdução rápida, escrever estratégias simples não precisa de gramática complexa, basta dominar alguns conceitos básicos, pode aprender a programar enquanto aprende este tutorial: https://www.fmz.com/bbs-topic/382 https://www.fmz.com/bbs-topic/417
  • Documentação em Mac, muito útil para estratégias de tendências.
  • Um exemplo de chamada em C++ para quem estiver interessado em C++ pode ver, mas como não é uma linguagem interpretável, é difícil de debug e não é recomendado: https://www.fmz.com/strategy/61533
  • Curso de negociação quantitativa de moedas digitais no curso NetEase Cloud Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociação quantitativa de moedas digitais no Curso de negociaçãoLinks para o curso
  • Algumas estratégias de ensino, apropriadas para o início da fase inicial, estratégias básicas de marginalização enquanto se aprende:https://www.fmz.com/square/s:tag:%E6%95%99%E5%AD%A6/1
  • A estratégia é explicada em detalhes pelo código-fonte: https://www.fmz.com/bbs/s:tag: %E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%901

Ferramentas de depuração

A plataforma de quantificação FMZ fornece uma ferramenta de debug para a interface de API de debug, https://www.fmz.com/m/debug 。 A ferramenta de debug só suporta JavaScript, pode ser executada apenas por um período de tempo, e a interface de troca pode ser debugada sem a criação de um disco rígido。 Os dados de retorno serão retornados como resultado, e o código da ferramenta de debug não será armazenado。 Durante o aprendizado deste tutorial, você pode testar simultaneamente usando a ferramenta de debug。 Tutorial básico de escrita de estratégia de plataforma quantitativa FMZ (leitura obrigatória)

Arquitetura de procedimentos estratégicos

A excepção é que, tal como os procedimentos normais, os procedimentos de estratégia devem ser executados em sequência de código. Uma vez que a estratégia precisa ser executada sem interrupção, geralmente é necessário um ciclo mais um tempo de repouso.

Outras funções com funções especiais são:

  • onexit ((() é uma função de varredura de cauda de saída normal, com um tempo máximo de execução de 5 minutos, que pode ser declarada sem que seja declarado, e que, se ultrapassar o tempo, irá apresentar um erro de interrupção. Pode ser usado para salvar alguns resultados ao sair do processo.
  • onerror() Função de saída para exceção, com duração máxima de 5 minutos, não declarável.
  • init() Como função de inicialização, a política é chamada automaticamente no início da execução, sem declaração.
function onTick(){
   var ticker = exchange.GetTicker()
   var account = exchange.GetAccount()
    //在这里写策略逻辑,将会每6s调用一次
}
function main(){
    while(true){
        onTick()
        Sleep(6000)
    }
}

O exemplo anterior mostra que, se um erro de acesso à rede pode causar a interrupção direta da política, se você quiser uma política semelhante à reinicialização automática que não é interrompida, você pode usar a estratégia em disco rígido com o ciclo principal tolerante a erros de try catch (não use try). Naturalmente, recomende-se essa operação apenas quando a política for estável, caso contrário, todos os erros não serão relatados e será difícil descartar os problemas da política.

function onTick(){
   var ticker = exchange.GetTicker()
   var account = exchange.GetAccount()
    //在这里写策略逻辑,将会每6s调用一次
}
function main(){
    try{
        while(true){
           onTick()
           Sleep(6000)
       }
    }catch(err){
        Log(err)
    }
}

Introdução à API da bolsa

Plataformas de negociação e configuração de pares de negociação

Quando se invoca qualquer API relacionada a uma bolsa, é necessário especificar a bolsa e o par de transações. Se apenas uma bolsa-par de transações for adicionada ao criar o disco virtual, o par de transações será eliminado.exchangeA representação do objeto, comoexchange.GetTicker()O que é obtido é o ticker de mercado da casa de câmbio.

A plataforma FMZ suporta a adição simultânea de vários pares de transação, como BTC e ETH que podem ser operados simultaneamente na mesma conta de transação, mas também BTC e ETH de outra conta. Note que diferentes contas na mesma conta também podem ser adicionadas simultaneamente, de acordo com a distinção de rótulos adicionados ao site da FMZ.exchangesOs conjuntos são representados pela ordem em que foram criados os discos rígidos:exchanges[0]exchanges[1]… e assim por diante. O formato do par de transações é:BTC_USDTO BTC é a moeda de troca e o USDT é a moeda de conta.

Tutorial básico de escrita de estratégia de plataforma quantitativa FMZ (leitura obrigatória)

Obviamente, se nós operamos com muitos pares de transações, esse método pode ser problemático, mas podemos usar o SetCurrency para trocar pares de transações, comoexchange.SetCurrency("BTC_USDT")Neste momento,exchangeO par de transações vinculadas torna-seBTC_USDTA partir de agora, a nova parcela de transações será válida até a próxima chamada para alterar o par.Observe que a retrospectiva atualizada suporta trocas de pares de transaçõesAqui está um exemplo concreto.

var symbols = ["BTC_USDT", "LTC_USDT", "EOS_USDT", "ETH_USDT"]
var buyValue = 1000
function main(){
  for(var i=0;i<symbols.length;i++){
      exchange.SetCurrency(symbols[i])
      var ticker = exchange.GetTicker()
      var amount = _N(buyValue/ticker.Sell, 3)
      exchange.Buy(ticker.Sell, amount)
      Sleep(1000)
  }
}

Acesso a uma interface aberta

Como o exemplo acima, as interfaces de negociação geralmente são interfaces abertas e acessíveis a todos. As interfaces de negociação comuns incluem: ticker de negociação, profundidade de negociação, registros de linha K e registros de negociação. A negociação é a base da estratégia de julgamento de negociação.

As interfaces geralmente têmInfoCampo, que representa a sequência de dados originais retornados pela exchange, que pode ser usada para complementar informações adicionais que precisam ser analisadas anteriormente, usando JavaScriptJSON.parse()O Python usa a biblioteca json.TimeOs campos indicam o tempo de solicitação e podem ser usados para determinar o atraso.

É possível acessar e retornar com falhas usando a interface da API no disco rígidonullPython de volta.NonePor isso, a tolerância a erros é muito importante. Este tutorial irá abordá-la separadamente.

GetTicker

Obter a tendência atual do mercado, é provavelmente a interface mais usada, você pode consultar o último preço de transação, preço de compra e venda, volume de transação recente, etc. Você pode determinar o preço da transação com base na informação do ticker antes de fazer outro pedido. Um exemplo de retorno em disco{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}

function main() {
    var ticker = exchange.GetTicker()
    Log(ticker) //在调试工具中 return ticker 。可以看到具体的结果。
    Log('上次成交价: ',ticker.Last, '买一价: ', ticker.Buy)
}

GetDepth

Obter informações sobre a profundidade da lista de pendências. Embora o GetTicker contenha uma lista de compra e venda, se você quiser pesquisar mais profundamente, você pode usar esta interface, geralmente pode consultar as 200 seguintes listas de pendências. Você pode usar esta interface para calcular o preço de impacto. Abaixo está um retorno real.

{
    "Info":null,
    "Asks":[
        {"Price":5866.38,"Amount":0.068644},
        {"Price":5866.39,"Amount":0.263985},
        ......
        ]
    "Bids":[
        {"Price":5865.13,"Amount":0.001898},
        {"Price":5865,"Amount":0.085575},
        ......
        ],
    "Time":1530241857399
}

Exemplos de compra e venda de tickets com acesso profundo:

function main() {
    var depth = exchange.GetDepth()
    Log('买一价个: ', depth.Bids[0].Price, '卖一价格: ', depth.Asks[0].Price)
}

GetRecords

Obter uma linha K, uma das interfaces mais usadas, que retorna informações de preços por um longo período de tempo, para calcular a base de vários indicadores. O ciclo da linha K não pode ser especificado se não for especificado o ciclo padrão que será usado ao adicionar o disco rígido. O comprimento da linha K não pode ser especificado, aumentando com o tempo, até 2000 raízes, sendo que a primeira chamada é de aproximadamente 200 raízes (diferentes trocas retornam diferentes).

exchange.SetMaxBarLen(Len)Pode-se definir o número de linhas K que serão obtidas pela primeira vez (suportado por algumas exchanges) e o número máximo de linhas K que serão obtidas.Exemplos:exchange.SetMaxBarLen(500)

O GetRecords pode especificar períodos: PERIOD_M1:1 minutos, PERIOD_M5:5 minutos, PERIOD_M15:15 minutos, PERIOD_M30:30 minutos, PERIOD_H1:1 horas, PERIOD_D1:1 dias.exchange.GetRecords(PERIOD_M1)Depois de atualizar o mais recente host, será suportado o ciclo de personalização, o número de segundos do ciclo de transmissão direta será usado como parâmetro, a personalização em nível de minuto será sintetizada com base na linha K de 1 minuto, a linha K abaixo de 1 minuto será sintetizada através do GetTrades (), os futuros de mercadorias serão sintetizados com base em tick, etc.O que é que se passa aqui?PERIOD_M1Estas variáveis são as variáveis globais padrão do FMZ, e os interessados podem logar seus próprios valores específicos, normalmente usados diretamente.

Exemplo de retorno de dados:

[
    {"Time":1526616000000,"Open":7995,"High":8067.65,"Low":7986.6,"Close":8027.22,"Volume":9444676.27669432},
    {"Time":1526619600000,"Open":8019.03,"High":8049.99,"Low":7982.78,"Close":8027,"Volume":5354251.80804935},
    {"Time":1526623200000,"Open":8027.01,"High":8036.41,"Low":7955.24,"Close":7955.39,"Volume":6659842.42025361},
    ......
]

Exemplo de linha K iterativa:

function main(){
    var close = []
    var records = exchange.GetRecords(PERIOD_H1)
    Log('total bars: ', records.length)
    for(var i=0;i<records.length;i++){
        close.push(records[i].Close)
    }
    return close
}

GetTrades

Obter dados de transação de um determinado período de tempo (e não os seus próprios dados de transação), algumas casas de câmbio não suportam. É menos comum, pode consultar a documentação da API para obter informações detalhadas.

Obter uma conta para negociar

Estas interfaces são associadas às contas e não podem ser obtidas diretamente, sendo necessário o uso de assinaturas API-KEY. A plataforma FMZ já foi tratada automaticamente em um ambiente de fundo e pode ser usada diretamente.

Obter uma conta no GetAccount

Obter informações sobre a conta. Uma das interfaces mais usadas, que precisa ser chamada antes de fazer o pedido, para evitar o saldo insuficiente.{"Stocks":0.38594816,"FrozenStocks":0,"Balance":542.858308,"FrozenBalance":0,"Info":{}}。 em que Stocks é o saldo disponível em moeda de transação do par negociado, FrozenStocks é o saldo congelado de ordens pendentes, Balance é o saldo disponível em moeda de contabilização, FrozenBalance é o saldo congelado. Se o par negociado éBTC_USDTO Bitcoin (BTC) é o Bitcoin (BTC) e o Bitcoin (BTC) é o Bitcoin (BTC).

Observe que o resultado retornado é o resultado de um par de transações especificado, que as informações de outras moedas da conta de transação estão no campo Info, e que a operação de múltiplos pares de transações não precisa ser chamada várias vezes.

Um disco rígido com o valor total das transações atuais:

function main(){
    while(true){
        var ticker = exchange.GetTicker()
        var account = exchange.GetAccount()
        var price = ticker.Buy
        var stocks = account.Stocks + account.FrozenStocks
        var balance = account.Balance + account.FrozenBalance
        var value = stocks*price + balance
        Log('Account value is: ', value)
        LogProfit(value)
        Sleep(3000)//sleep 3000ms(3s), A loop must has a sleep, or the rate-limit of the exchange will be exceed
        //when run in debug tool, add a break here
    }
}

Compra com o Buy

O preço é o seguinte:exchange.Buy(Price, Amount)ouexchange.Buy(Price, Amount, Msg), Price é o preço, Amount é a quantidade, Msg é uma string adicional que pode ser exibido no registro do disco, não é obrigatório. Esta forma é para pendurar pedidos, se não for possível imediatamente a transação completa, gerará pedidos não realizados, o pedido será devolvido com o resultado de sucesso para a ordem id, e o resultado de falha seránull, para consultar o status das encomendas.

Se você quer comprar um preço de venda, Price é 1, e Amount é o valor da compra, comoexchange.Buy(-1, 0.5)O negócio está certo.ETH_BTC, que representa o preço de mercado para comprar ETH de 0,5 BTC. Algumas casas de câmbio não suportam a lista de preços de mercado, nem a retrospectiva de futuros.

Todos os preços e quantidades de precisão requisitados para transações em partes, disponíveis_N()A função de precisão é usada para controlar. Para a negociação de futuros, Buy e Sell têm outros significados, que serão apresentados separadamente.

Um exemplo de compra a um preço razoável:

function main(){
    while(true){
        var ticker = exchange.GetTicker()
        var price = ticker.Sell
        if(price >= 7000){
            exchange.Buy(_N(price+5,2), 1, 'BTC-USDT')
            break
        }
        Sleep(3000)//Sleep 3000ms
    }
    Log('done')
}

Vender e vender abaixo

O preço de venda é o mesmo que o preço de compra. O preço de mercado é o preço de venda.exchange.Sell(-1, 0.2)O preço de venda é de 0,2 ETH.

GetOrder para obter pedidos

Obter informações de pedidos com base no ID de pedido. Interface comum, modo de chamadaexchange.GetOrder(OrderId),OrderId é a identificação da encomenda, que é devolvida quando a encomenda é feita.Atenção ao tipo de pedidoTypeCampos e status do pedidoStatusOs valores reais são numéricos, representando diferentes significados, mas não são favoráveis à memória, sendo representados pela FMZ com constantes globais, como os de pedidos não realizados.StatusO valor de 0 é igual aORDER_STATE_PENDINGTodas estas constantes globais podem ser consultadas na documentação.◦ Retorna o resultado:

{
    "Id":125723661, //订单id
    "Amount":0.01, //订单数量
    "Price":7000, //订单价格
    "DealAmount":0, //已成交数量
    "AvgPrice":0, //成交均价
    "Status":0, // 0:未完全成交, 1:已成交, 2:已撤单
    "Type":1,// 订单类型,0:买单, 1:卖单
    "ContractType":"",//合约类型,用于期货交易
    "Info":{} //交易所返回原始信息
    }
}

Uma estratégia para comprar um determinado número de moedas:

function main(){
    while(true){
        var amount = exchange.GetAccount().Stocks
        var ticker = exchange.GetTicker()
        var id = null
        if(5-amount>0.01){
            id = exchange.Buy(ticker.Sell, Math.min(5-amount,0.2))
        }else{
            Log('Job completed')
            return //return the main function, bot will stop
        }
        Sleep(3000) //Sleep 3000ms
        if(id){
            var status = exchange.GetOrder(id).Status
            if(status == 0){ //这里也可以用 status == ORDER_STATE_PENDING 来判断。
                exchange.CancelOrder(id)
            }
        }
    }
}

GetOrders não entregou o pedido

Obtenha a lista de todos os pedidos pendentes com a transação atual. Se não houver pedidos pendentes, retorne uma matriz vazia. Obtenha o resultado específico da lista de pedidos, como o GetOrder.

Exemplo de cancelamento de transação atual para todos os pedidos:

function CancelAll(){
    var orders = exchange.GetOrders()
    for(var i=0;i<orders.length;i++){
        exchange.CancelOrder(orders[i].Id) // cancel order by orderID
    }
}
function main(){
    CancelAll()
    while(true){
        //do something
        Sleep(10000)
    }
}

CancelOrder (Cancelar ordem)

Cancelar um pedido de acordo com o pedido id.exchange.CancelOrder(OrderId)。 cancelamento de sucesso retorna true, caso contrário retorna false。 observe que o pedido já foi totalmente transacionado e o cancelamento de falha。

Contratos a prazo e a perpetuidade

A negociação de futuros de moeda digital é um pouco diferente da negociação de caixa, a função de negociação de caixa acima também se aplica à negociação de futuros, a negociação de futuros de moeda digital tem uma função exclusiva. Antes de realizar a negociação de futuros de moeda digital, é necessário familiarizar-se com as operações manuais no site e entender os conceitos básicos, como abertura de posição, baixa de posição, total de posição, baixa de posição, alavancagem, perda de posição, lucro flutuante e garantia, bem como as fórmulas de cálculo correspondentes.

Os contratos de perpetuidade são semelhantes aos contratos de futuros, mas não possuem o conceito de posse simultânea de uma quantidade de espaço.

Se a bolsa simultaneamente suportar futuros em dinheiro, como OKEX e Huobi Futures, é necessário selecionar separadamente na interface da bolsa a barra de futuros OKEX e a barra de futuros Huobi adicionada, sendo considerada na FMZ como uma bolsa diferente da caixa.

SetContractType Configuração do contrato

O primeiro passo para a negociação de futuros é configurar o contrato a ser negociado, por exemplo, com futuros OKEX, escolha o par de negociação de BTC para criar um disco rígido ou um retrospectivo. Também é necessário configurar no código o contrato da semana atual, da próxima semana ou trimestral.invalid contract typeAo contrário de pares de negociação em dinheiro, os contratos de futuros geralmente são garantidos por moedas de negociação como o BTC. O par de negociação adicionado ao BTC geralmente representa o par de negociação BTC_USD garantido pelo BTC. Se houver futuros garantidos pelo USDT, é necessário criar um par de negociação BTC_USDT adicionado ao disco.Depois de configurar o par de transações, também é necessário configurar o tipo de contrato específico, como permanente, semanal, quinzenal, etc. Depois de configurar o contrato, é possível realizar operações de compra e venda, entre outras.

A existência de contratos de base de moeda e base de USDT, como Binance, OKEX, HuobiDM, etc., exige uma distinção ao adicionar contratos de configuração de disco rígido. As configurações específicas são as seguintes:

//OKEX期货
exchange.SetContractType("swap")        // 设置为永续合约
exchange.SetContractType("this_week")   // 设置为当周合约
exchange.SetContractType("next_week")   // 设置为次周合约
exchange.SetContractType("quarter")     // 设置为季度合约

//HuobiDM
exchange.SetContractType("this_week")   // 设置为当周合约 
exchange.SetContractType("next_week")   // 设置为次周合约
exchange.SetContractType("quarter")     // 设置为季度合约
exchange.SetContractType("swap")        // 设置为永续合约

//币安期货
exchange.SetContractType("swap")   // 设置为永续合约,注意币本位和USDT本位都存在永续
exchange.SetContractType("quarter")   // 设置为当季合约
exchange.SetContractType("next_quarter")  // 设置为次季合约

//BitMEX
exchange.SetContractType("XBTUSD")    // 设置为永续合约
exchange.SetContractType("XBTM19")  // 具体某个时间结算的合约,详情登录BitMEX查询各个合约代码

//GateIO
exchange.SetContractType("swap")      // 设置为永续合约,不设置默认为swap永续合约。 

//Deribit
exchange.SetContractType("BTC-27APR18")  // 具体某个时间结算的合约,详情参看Deribit官网。

GetPosition é uma posição

Obter a lista de informações sobre a posição atual, OKEX ((OKCOIN) futuros podem ser transmitidos em um parâmetro, especificando o tipo de contrato a ser obtido. Se não houver uma posição, retornará a lista vazia[]A informação sobre as posições retorna como segue: há muita informação específica que precisa ser combinada com uma análise específica sobre a transação.

Tipo de dados Nome da variável ilustrar

A estrutura original retornada pela exchange de objetos “Number”, “MarginLevel”, “Bar Size”, “OKCoin”, “10” ou “20”, “OK Futures”, “Full-Stock Mode”, “Return to Fixed 10”, porque a API nativa não o suporta. O OKCoin representa a quantidade de contratos que a OKCoin possui. O OKCoin representa o número de contratos que a OKCoin possui. Número de unidades congeladas “Price de um número” “Price de um número” Numerologia Marginal Marginal “number” “Profit” “adjustable” “number” “Profit” “adjustable” “number” “number” “Profit” “adjustable” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “number” “num “const “adjustable” PD_LONG para a posição “closebuy_today” em CTP, “PD_SHORT” para a posição “closesell_today” em CTP, “PD_LONG_YD” para a posição “yesterday” em CTP, “PD_SHORT_YD” para a posição “closesell” em CTP string DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType DATAContractType

function main(){
    exchange.SetContractType("this_week");
    var position = exchange.GetPosition();
    if(position.length>0){ //特别要注意引用前要先判断position长度再引用,否则会出错
        Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:",
            position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type,"ContractType:", position[0].ContractType)
    }
}

O que é que eu tenho a dizer?

A primeira coisa a fazer é definir o tamanho da alavanca e a forma como ela será chamada:exchange.SetMarginLevel(10)O 10 representa 10 vezes o nível de alavancagem, e o tamanho de alavancagem apoiado pode ser visto nas casas de câmbio correspondentes.Atenção: o Leverage deve ser configurado em uma bolsa e o código deve ser compatível com a configuração da bolsa, caso contrário, será um erro│ ou não configurado, usando a alavanca padrão │ A seguir, define a direção da transação e o modo de chamada:exchange.SetDirection(Direction)A partir de agora, o que vai acontecer é que os investidores vão ter que pagar.Diferentemente dos futuros, se o contrato de permanência não tiver o conceito de posse simultânea de hipoteca, ou seja, não é permitido manter uma posição individual, a hipoteca será automaticamente liquidada, e tudo o que precisa ser configuradobuyesellDisponível. Se for suportado, configuração necessáriaclosebuy,closebuyRelações específicas:

Operação Parâmetros do SetDirection Função de encomenda
Abrir uma posição exchange.SetDirection(“buy”) exchange.Buy()
Pinto Possão exchange.SetDirection(“closebuy”) exchange.Sell()
Posições vagas exchange.SetDirection(“sell”) exchange.Sell()
Posições vazias exchange.SetDirection(“closesell”) exchange.Buy()

Por fim, o código específico de posição aberta e parada, o volume de encomendas variam de acordo com a bolsa, como os futuros de huobi são por número de tiras, uma de US $ 100. Tenha em atenção que o retorno de futuros não suporta o preço de mercado.

function main(){
    exchange.SetContractType("this_week")    // 举例设置 为OKEX期货 当周合约
    price = exchange.GetTicker().Last
    exchange.SetMarginLevel(10) //设置杠杆为10倍 
    exchange.SetDirection("buy") //设置下单类型为做多 
    exchange.Buy(price+10, 20) // 合约数量为20下单 
    pos = exchange.GetPosition()
    Log(pos)
    Log(exchange.GetOrders()) //查看是否有未成交订单
    exchange.SetDirection("closebuy"); //如果是永续合约,直接设置exchange.SetDirection("sell")
    exchange.Sell(price-10, 20)
}

Aqui está um exemplo de uma estratégia específica para um total de posições vazias.

function main(){
    while(true){
        var pos = exchange.GetPosition()
        var ticker = exchange.GetTicekr()
        if(!ticker){
            Log('无法获取ticker')
            return
        }
        if(!pos || pos.length == 0 ){
            Log('已无持仓')
            return
        }
        for(var i=0;i<pos.length;i++){
            if(pos[i].Type == PD_LONG){
                exchange.SetContractType(pos[i].ContractType)
                exchange.SetDirection('closebuy')
                exchange.Sell(ticker.Buy, pos[i].Amount - pos[i].FrozenAmount)
            }
            if(pos[i].Type == PD_SHORT){
                exchange.SetContractType(pos[i].ContractType)
                exchange.SetDirection('closesell')
                exchange.Buy(ticker.Sell, pos[i].Amount - pos[i].FrozenAmount)
            }
        }
        var orders = exchange.Getorders()
        Sleep(500)
        for(var j=0;j<orders.length;j++){
            if(orders[i].Status == ORDER_STATE_PENDING){
                exchange.CancelOrder(orders[i].Id)
            }
        }
    }
}

Levação de moeda digital

A troca no código para uma conta de alavancagem é necessária, o resto é o mesmo que a transação em dinheiro.

Ao usar o exchange.IO (“trade_margin”) para mudar para o modo de conta de depósito, os ativos da conta de depósito e aquisição serão acessados na interface de alavancagem da bolsa. Utilize exchange.IO ((“trade_normal”) para mudar para o modo de conta normal.

Bolsas compatíveis:

  • OKEX V3: O modelo de conta de alavancagem é diferente do padrão, e alguns pares de transação podem não existir.
  • Bitcoin: O modelo de conta de alavancagem é diferente do padrão, e alguns pares podem não existir.
  • ZB: Os fundos só podem ser transferidos como QCs, setor de negociação alavancado, independência de fundos entre os diferentes pares de negociação, ou seja, o número de moedas QC sob o par de negociação ETH_QC, não visto no BTC_QC
  • FCoin
  • Binance (em inglês)

Negociação de futuros de mercadorias

A negociação de futuros de commodities e a negociação de futuros de moedas digitais têm uma grande diferença. Primeiro, o tempo de negociação de futuros de commodities é curto, as moedas digitais são negociadas 24 horas; o protocolo de futuros de commodities também não é uma REST API comum; a frequência de negociação de futuros de commodities e os limites de quantidade de encomendas, as moedas digitais são muito flexíveis, etc. Portanto, a negociação de futuros de commodities tem muitas áreas que requerem atenção especial e recomenda uma experiência de operação manual de operação.

A plataforma de negociação quantitativa FMZ, como um provedor de negociação programada, solicitou a licença do software para os vários servidores de negociação de futuros, o usuário pode usá-lo sem a necessidade de solicitar diretamente, adicionando a lista de solicitações da FMZ à lista de solicitações da FMZ. Referência específica: https://www.fmz.com/bbs-topic/3860 ❚ Se o seu fornecedor de futuros não estiver mais na lista, ele só pode se candidatar ou voltar a apoiar a abertura de negociação, geralmente leva 2 dias.

Devido às vantagens da arquitetura da plataforma FMZ, os usuários também podem adicionar várias contas de comerciantes de futuros e implementar algumas funções que outros softwares de negociação programada de futuros de mercadorias não conseguem, como a síntese de ticks de alta frequência. Referência: https://www.fmz.com/bbs-topic/1184

Quadro de Políticas

Em primeiro lugar, uma vez que não é uma transação de 24 horas e requer uma operação de login, é necessário avaliar o status do link antes de fazer a transação.exchange.IO("status")paratrueIndica que a conexão foi iniciada. Se a conexão não for bem sucedida, a API não será chamada e não será solicitado o ‘not login’. Pode dormir após o início da estratégia ((2000), dar um certo tempo para o login. Também pode tentar a assinatura novamente._C(exchange.SetContractType,"MA888")A primeira parte do vídeo mostra uma imagem de um avião a desembarcar em uma ilha.

Os códigos de compra e negociação dos futuros de mercadorias são os mesmos que os futuros de moedas digitais, e aqui serão apresentados os pontos em que eles são diferentes e precisam de atenção.

function main(){
    _C(exchange.SetContractType,"MA888") //没登陆成功是无法订阅合约的,最好重试一下
    while(true){
        if(exchange.IO("status")){
            var ticker = exchange.GetTicker()
            Log("MA888 ticker:", ticker)
            LogStatus(_D(), "已经连接CTP !")//_D获取事件
        } else {
            LogStatus(_D(), "未连接CTP !")
            Sleep(1000)
        }
    }
}

Recomenda-se o uso de commodity futures (mais adiante), o código é muito simples e não precisa lidar com detalhes tediosos. Código de cópia: https://www.fmz.com/strategy/57029

function main() {
    // 使用了商品期货类库的CTA策略框架
    $.CTA(Symbols, function(st) {
        var r = st.records
        var mp = st.position.amount
        var symbol = st.symbol
        /*
        r为K线, mp为当前品种持仓数量, 正数指多仓, 负数指空仓, 0则不持仓, symbol指品种名称
        返回值如为n: 
            n = 0 : 指全部平仓(不管当前持多持空)
            n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓,如果n大于当前持仓, 则反手开多仓
            n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓,如果-n大于当前持仓, 则反手开空仓
            无返回值表示什么也不做
        */
        if (r.length < SlowPeriod) {
            return
        }
        var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod));
        if (mp <= 0 && cross > ConfirmPeriod) {
            Log(symbol, "金叉周期", cross, "当前持仓", mp);
            return Lots * (mp < 0 ? 2 : 1)
        } else if (mp >= 0 && cross < -ConfirmPeriod) {
            Log(symbol, "死叉周期", cross, "当前持仓", mp);
            return -Lots * (mp > 0 ? 2 : 1)
        }
    });
}

Modo de obtenção de dados do CTP

Os futuros de mercadorias usam o protocolo CTP, todos os movimentos e transações de pedidos são notificados somente quando há mudanças, enquanto a consulta de pedidos, contas e posições é uma consulta ativa. Portanto, é adequado para a estratégia de alta freqüência orientada a eventos de escrita.GetTickerGetDepthGetRecordsTodos os dados são armazenados em cache para obter os dados mais recentes, e quando não há dados, eles esperam por dados, então a estratégia pode não usar o Sleep. Quando a situação muda, ticker, profundidade e registros são atualizados, enquanto a chamada de qualquer interface é retornada imediatamente, o estado da interface chamada é colocado em modo de atualização em espera, a próxima vez que a mesma interface é chamada, espera que novos dados sejam retornados. Algumas situações de fechamento de portas frias ou paralisação de contratos ocorrem por um longo tempo sem negociação, o que é normal para a estratégia ser carregada por muito tempo.

Se você quiser obter dados de cada vez que você acessa um evento, você pode mudar para o modo de atualização imediata do evento, mesmo que seja um evento antigo.exchange.IO("mode", 0)A estratégia não pode ser escrita como um evento-driven, sendo necessário adicionar um evento SLeep para evitar um rápido ciclo de morte. Algumas estratégias de baixa frequência podem usar este modo, sendo a estratégia simples de usar.exchange.IO("mode", 1)Pode-se reverter o modo de cache padrão.

Para operar um único contrato, pode-se usar o modo padrão. No entanto, se houver vários contratos, é possível que um contrato não seja atualizado, resultando em um bloqueio na interface de atualização de atualização, e que as atualizações de atualização de outros contratos também não sejam obtidas. Para resolver este problema, pode-se usar o modo de atualização imediata, mas sem escrever uma estratégia de alta frequência.exchange.IO("wait")◦ Se você adicionar vários objetos de câmbio, o que é raro em futuros de commodities, você pode usarexchange.IO("wait_any")O índice retornado é o índice da bolsa de valores retornada.

A mudança de tick foi enviada por:{Event:"tick", Index:交易所索引(按实盘上交易所添加顺序), Nano:事件纳秒级时间, Symbol:合约名称} Envio de encomendas:{Event:"order", Index:交易所索引, Nano:事件纳秒级时间, Order:订单信息(与GetOrder获取一致)}

Neste ponto, a estrutura da estratégia pode ser escrita como:

function on_tick(symbol){
    Log("symbol update")
    exchange.SetContractType(symbol)
    Log(exchange.GetTicker())
}

function on_order(order){
    Log("order update", order)
}

function main(){
    while(true){
        if(exchange.IO("status")){ //判断链接状态
            exchange.IO("mode", 0)
            _C(exchange.SetContractType, "MA888")//订阅MA,只有第一次是真正的发出订阅请求,接下来都是程序切换,不耗时间。
            _C(exchange.SetContractType, "rb888")//订阅rb
            while(true){
                var e = exchange.IO("wait")
                if(e){
                    if(e.event == "tick"){
                        on_tick(e.Symbol)
                    }else if(e.event == "order"){
                        on_order(e.Order)
                    }
                }
           }
        }else{
            Sleep(10*1000)
        }
    }
}

Diferenças entre futuros de mercadorias e moedas digitais

Além disso, observe a diferença entre os futuros de mercadorias e as exchanges de moeda digital. Como o GetDepth, na verdade, só tem uma profundidade (a cobrança de 5 profundidades é cara), o GetTrades também não tem acesso ao histórico de transações (são simulados com base na mudança de posse, sem registro real de transações). Os futuros de mercadorias têm restrições de queda e queda, quando o preço de venda é o preço de parada, a quantidade de pedidos é 0, quando o preço de compra é o preço de parada, a quantidade de pedidos é 0.

Configurar um contrato

exchange.IO ((“instruments”): retorna a lista de todos os contratos da exchange em formato de dicionário, apenas com suporte a disco rígido. exchange.IO ((“products”): retorna a lista de todos os produtos da exchange em formato de dicionário, apenas com suporte a disco rígido. exchange.IO ((“subscribed”): retorna um contrato de subscrição, no mesmo formato, apenas com suporte a disco físico.

Os futuros tradicionais da CTPContractTypeÉ o contrato de identificação, que é separado por maiúsculas.exchange.SetContractType("au1506")O contrato é configurado com sucesso e retorna detalhes do contrato, como o mínimo de compra, taxas, horário de entrega, etc. Quando se inscreve em vários contratos, apenas a primeira é a solicitação de assinatura de envio real, e depois é apenas para trocar o par de transações no nível do código, sem perder tempo. O contrato contínuo principal é o código 888 como MA888, o contrato de índice contínuo 000 como MA000, 888 e 000 são apenas suportados para negociação de contratos virtuais.No entanto, a linguagem Mac pode operar o contrato de domínio, e o programa troca de posição automaticamente, ou seja, elimina a posição não dominante e abre uma nova posição na posição dominante.

O contrato não pode ser configurado sem login bem sucedido, mas também será retornado imediatamente, então você pode tentar novamente com o _C, sabendo que o login do CTP está concluído. Após o login bem sucedido, a configuração do contrato não é demorada e não gerará acesso real à rede.

Abrir e fechar posições

SetDirectionDireçãobuy, closebuy, sell, closesellQuatro parâmetros, mais commodity futuresclosebuy_todayeclosesell_todayO que você acha que está acontecendo?closebuy/closesellPara a posição de equilíbrio, apenas a variedade do período anterior é dividida em equilíbrio entre hoje e ontem, o que pode afetar os honorários, portanto, é necessário priorizar o equilíbrio entre ontem e hoje. Para os futuros tradicionais da CTP, pode-se configurar um segundo parâmetro de 1 ou 2 ou 3, referindo-se respectivamente a caixa especulativa, caixa de lucro e caixa de segurança, sem configuração de especulação por defeito.As operações específicas de compra e venda, obtenção de posições, obtenção de ordens, cancelamento de instruções e obtenção de contas são as mesmas que as transações de futuros de moedas digitais, consulte o capítulo anterior.

Operação Parâmetros do SetDirection Função de encomenda
Abrir uma posição exchange.SetDirection(“buy”) exchange.Buy()
Pinto Possão exchange.SetDirection(“closebuy”) exchange.Sell()
Posições vagas exchange.SetDirection(“sell”) exchange.Sell()
Posições vazias exchange.SetDirection(“closesell”) exchange.Buy()

O exemplo a seguir é uma função de posição parada específica, note que este exemplo é muito simples, mas também deve considerar se está em tempo de negociação, não está totalmente transacionado como colocar um teste pesado, qual é o volume máximo de baixa, a frequência é muito alta, especificamente, o preço de desvio ou de liquidação e uma série de outras questões.A criação de um armazém em disco rígido é recomendada para usar um armazém de classes embalado na plataforma. https://www.fmz.com/strategy/12961。 A página de bibliotecas tem uma descrição detalhada, e é recomendável que você aprenda o código fonte das bibliotecas 。

function Cover(contractType, amount, slide) {
    for (var i = 0; i < positions.length; i++) {
        if (positions[i].ContractType != contractType) {
            continue;
        }
        var depth = _C(e.GetDepth);
        if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) {
            exchange.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");
            exchange.Sell(depth.Bids[0]-slide, amount, contractType, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]);
        } else {
            exchange.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
            exchange.Buy(depth.Asks[0]+slide, amount, contractType, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]);
        }
    }
}

Commodity Futures suporta tipos de ordens personalizadas (suporta disco rígido, retrocesso não é suportado), especifica o modo de colagem posterior, adicionado em colagem_A parte de trás da caixa, por exemplo.

exchange.SetDirection("buy_ioc");
exchange.SetDirection("sell_gtd-20170111")

O sufixo específico é:

  • ioc concluído imediatamente, ou THOST_FTDC_TC_IOC revogado
  • gfs Esta secção é válida THOST_FTDC_TC_GFS
  • gfd válido no dia THOST_FTDC_TC_GFD
  • gtd válido até a data especificada THOST_FTDC_TC_GTD
  • gtc válido antes da revogação THOST_FTDC_TC_GTC
  • gfa O conjunto de lances é válido THOST_FTDC_TC_GFA

Interface fácil de usar

Por padrão, o CTP é o interface aberto no Commodity Futures Trading, podendo ser alterado para o Etsy, se solicitado. O encapsulamento do FMZ é o mesmo. A diferença é que a conta, o pedido e o depósito são em modo de envio, portanto, o custodiante mantém esses dados localmente e retornam imediatamente quando o interface correspondente é chamado, sem efetivamente enviar o pedido.

Os tipos de ordens personalizadas do iShares são os seguintes:

  • gfd válido no dia TAPI_ORDER_TIMEINFORCE_GFD
  • TAPI_ORDER_TIMEINFORCE_GTC válido antes da revogação do gtc
  • gtd válido até a data especificada TAPI_ORDER_TIMEINFORCE_GTD
  • TAPI_ORDER_TIMEINFORCE_FAK
  • ioc concluído imediatamente, caso contrário revogado TAPI_ORDER_TIMEINFORCE_FAK
  • TAPI_ORDER_TIMEINFORCE_FOK falha na entrega completa, cancelação total

Funções globais de uso comum

Log Logs e transmissão via WeChat

No disco rígido, um registro de logs, seguido de uma sequência de caracteres com o @, a mensagem é enviada para a fila de envio, sendo enviada diretamente após o envio do WeChat ou do telegram.Log('推送到微信@')

A cor do log também pode ser personalizadaLog('这是一个红色字体的日志 #ff0000')#ff0000A representação de 16 dígitos para a cor RGB

Todos os arquivos de log existem no banco de dados sqlit em disco no diretório do host, que pode ser baixado e aberto com o software do banco de dados, ou pode ser usado para copiar a recuperação de backup (o nome do banco de dados e o disco físico são idênticos).

LogProfit imprime receitas

Registre os ganhos e trace a curva de ganhos na interface do disco, que pode ser mantida após o reinicio do disco.LogProfit(1000)Atenção.LogProfitOs parâmetros não são necessariamente o lucro, podem ser quaisquer números e precisam ser preenchidos por si mesmos.

A barra de status do LogStatus é mostrada (incluindo a tabela)

O estado do disco rígido, como os logs são guardados e atualizados constantemente, pode ser usado se for necessário exibir apenas informações não guardadas.LogStatusfunção.LogStatusOs parâmetros são strings, que também podem ser usados para representar a informação da tabela.

Um exemplo de tabela que mostra a localização do estado do disco rígido:

var table = {type: 'table', title: '持仓信息', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}; 
LogStatus('`' + JSON.stringify(table) + '`'); // JSON序列化后两边加上`字符, 视为一个复杂消息格式(当前支持表格) 
LogStatus('第一行消息\n`' + JSON.stringify(table) + '`\n第三行消息'); // 表格信息也可以在多行中出现 
LogStatus('`' + JSON.stringify([table, table]) + '`'); // 支持多个表格同时显示, 将以TAB显示到一组里 
LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`\n'); // 上下排列显示多个表

Dormir

Parâmetros em milissegundos, comoSleep(1000)Um segundo para hibernar. Devido à restrição de frequência de acesso a todas as transações, a estratégia geral é adicionar tempo de hibernação ao ciclo de morte.

_G Salvar dados

O programa reinicia quando o disco rígido é reiniciado e, se você quiser salvar alguma informação permanente, você pode fazer isso._GÉ muito prático e fácil de usar, pois permite que o conteúdo seja sequenciado em JSON._GA função é escrita emonexit()Assim, cada vez que a estratégia é interrompida, a informação necessária é automaticamente guardada. O que é necessário é que o usuário tenha um sistema de armazenamento de arquivos que permita que o arquivo seja armazenado._A função G não é muito útil e pode ser escrita diretamente no banco de dados usando o Python.

function onexit(){
    _G('profit', profit)
}
function main(){
    _G("num", 1); // 设置一个全局变量num, 值为1 s
    _G("num", "ok"); // 更改一个全局变量num, 值为字符串ok 
    _G("num", null); // 删除全局变量 num 
    _G("num"); // 返回全局变量num的值,如果不存在返回null

    var profit = 0
    if(_G('profit')){
        profit = _G('profit')
    }
}

_Função de precisão N

Na hora de fazer um pedido, muitas vezes para controlar o preço e a precisão da quantidade, o FMZ tem a função _N embutida, que determina a preservação de dígitos de pontos mínimos, como_N(4.253,2)O resultado é 4,25.

_C. Reinicialização automática

A API de chamadas de exchanges não é uma garantia de sucesso em todos os acessos._C é uma função que reinicia automaticamente. Continuará a chamar a função especificada até retornar o sucesso (a função que retorna null ou false será reiniciada), como_C(exchange.GetTicker), o intervalo de repetição padrão é de 3 segundos, pode ser chamado a função_CDelay para controlar o intervalo de repetição, por exemplo, _CDelay(1000), indicando a mudança de int