Type/to search
3
Follow
1504
Followers
Tutorial básico de escrita de estratégia de plataforma quantitativa FMZ (leitura obrigatória)
Tutorials
Created 2019-08-13 17:47:27  Updated 2026-01-27 17:22:09
 33
 71696

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:教学/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%90/1

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。
img

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.

img

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 type。**Ao 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 dadosNome da variávelilustrar

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,closebuy。**Relações específicas:

OperaçãoParâmetros do SetDirectionFunção de encomenda
Abrir uma posiçãoexchange.SetDirection("buy")exchange.Buy()
Pinto Possãoexchange.SetDirection("closebuy")exchange.Sell()
Posições vagasexchange.SetDirection("sell")exchange.Sell()
Posições vaziasexchange.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çãoParâmetros do SetDirectionFunção de encomenda
Abrir uma posiçãoexchange.SetDirection("buy")exchange.Buy()
Pinto Possãoexchange.SetDirection("closebuy")exchange.Sell()
Posições vagasexchange.SetDirection("sell")exchange.Sell()
Posições vaziasexchange.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 intervalo de repetição da função_C para 1 segundo, recomendadoGetTicker(),exchange.GetDepth,GetTrade,GetRecords,GetAccount,GetOrders, GetOrderO C++ é uma linguagem de programação de código aberto que permite que os usuários façam o que quiserem com o C#, mas que também é tolerante a erros.

CancelOrderNão é possível usar a função_C, porque a retirada falha por várias razões, se um único foi transacionado, a retirada vai voltar a falhar, e usar a função_C vai levar a uma tentativa repetida.

_A função C também pode ser inserida em argumentos e usada em funções personalizadas.

function main(){ var ticker = _C(exchange.GetTicker) var depth = _C(exchange.GetDepth) var records = _C(exchange.GetRecords, PERIOD_D1) //传入参数 }

_D Função de data

Apelo direto_D()Retorna a sequência de caracteres do tempo atual, como:2019-08-15 03:46:14。 Se for uma chamada em retrospectiva, retorne o tempo de retrospectiva。 Pode-se usar a função _D para determinar o tempo, como: _D().slice(11) > '09:00:00':

_D(timestamp,fmt)A sequência de tempo é então transformada em uma sequência de tempo, como_D(1565855310002)O fmt é o formato de tempo, o padrãoyyyy-MM-dd hh:mm:ss

Função indicador TA

Para algumas funções de indicadores de uso comum, como MA\MACD\KDJ\BOLL, os indicadores de uso comum estão diretamente embutidos na plataforma FMZ. Os indicadores de suporte específicos podem ser consultados na documentação da API.

Antes de usar a função indicador, é melhor determinar o comprimento da linha K. Quando o comprimento da linha K anterior não atende ao período necessário para o cálculo, o resultado énullSe o comprimento da linha K é 100 e o ciclo de MA é 10, então os primeiros 9 valores são nulos e os últimos são normalmente calculados.

O JavaScript também suporta o talib completo, que é suportado por uma biblioteca de terceiros, chamadatalib.CCI(records)。 Referência http://ta-lib.org/function.html 。 Para o Python pode instalar a biblioteca talib, que não pode ser simplesmente instalada com o pip, por causa da necessidade de compilação, e pode procurar o modo de instalação.

A função de pontuação pode ser inserida em um conjunto arbitrário, além de dados de linha K.

function main(){ var records = exchange.GetRecords(PERIOD_M30) if (records && records.length > 9) { var ma = TA.MA(records, 14) Log(ma) } }

Funções usadas no JavaScript

Aqui estão algumas das funções JavaScript mais usadas em disco rígido:

  • Date.now()Regressar a barra de tempo atual
  • parseFloat()Transformar uma sequência de caracteres em um número, comoparseFloat("123.21")
  • parseInt()Transformar a sequência de caracteres num número inteiro
  • num.toString()Transformar números em strings, num em variáveis numéricas
  • JSON.parse()Formata uma string Json, comoJSON.parse(exchange.GetRawJSON())
  • A função de Math baseada em JavaScript é:Math.max(),Math.abs()Exercícios matemáticos usados com frequência, etc.
  • Baseado em uma biblioteca de matemática de terceiros em JavaScript da FMZ, em http://mathjs.org/
  • O FMZ cita a biblioteca de underscore de terceiros do JavaScript, recomendado para facilitar a operação de muitos Js, em: https://underscorejs.org/

Biblioteca de modelos

Para escrever uma estratégia de disco rígido, há muitas coisas a serem consideradas, como comprar um recurso tão simples como 5 moedas, devemos considerar: o saldo atual é suficiente? Qual é o preço do pedido? Qual é a precisão? Não é necessário dividir o pedido para evitar chocar o mercado? Como lidar com pedidos incompletos?

As bibliotecas de negociação de moedas digitais e commodity futures são incorporadas por padrão e não precisam ser copiadas. Outras bibliotecas de modelos podem ser encontradas no Policy Square em https://www.fmz.com/square/20/1 . Copiar e salvar as bibliotecas de modelos e selecionar o que você deseja usar ao criar sua própria estratégia é possível.

As funções de modelo JavaScript são$Começamos com Python.extInício.

Repositório de transações de moeda digital

O endereço do código-fonte: https://www.fmz.com/strategy/10989 , já está embutido, sem necessidade de cópia.

Acesso à conta:

$.GetAccount(e) Log($.GetAccount()); // 获取账户信息, 带容错功能 Log($.GetAcccount(exchanges[1]));

Desinscrição:

$.Buy/Sell(e, amount) $.Buy(0.3); // 主交易所买入0.3个币 $.Sell(0.2); // 主交易所卖出0.2个币 $.Sell(exchanges[1], 0.1); // 次交易所卖出0.1个币 $.CancelPendingOrders(e, orderType) $.CancelPendingOrders(); // 取消主交易所所有委托单 $.CancelPendingOrders(ORDER_TYPE_BUY); // 取消主交易所所有的买单 $.CancelPendingOrders(exchanges[1]); // 取消第二个交易所所有订单 $.CancelPendingOrders(exchanges[1], ORDER_TYPE_SELL); // 取消第二个交易所所有的卖单

O julgamento é cruzado:

$.Cross(periodA, periodB) / $.Cross(arr1, arr2); var n = $.Cross(15, 30); var m = $.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6]) 如果 n 等于 0, 指刚好15周期的EMA与30周期的EMA当前价格相等 如果 n 大于 0, 比如 5, 指15周期的EMA上穿了30周期的EMA 5个周期(Bar) 如果 n 小于 0, 比如 -12, 指15周期的EMA下穿了30周期的EMA 12个周期(Bar) 如果传给Cross不是数组, 则函数自动获取K线进行均线计算 如果传给Cross的是数组, 则直接进行比较

$.withdraw ((e, currency, address, amount, fee, password) função de retirada:

$.withdraw(exchange, "btc", "0x.........", 1.0, 0.0001, "***")

Repositório de negociação de futuros de mercadorias

A biblioteca de negociação de futuros de commodities é estável e recomendada. O código fonte está em: https://www.fmz.com/strategy/12961 . Está embutido e não precisa ser copiado.

Arquivo CTA

  • O disco rígido irá automaticamente mapear o índice para a sequência principal.
  • Automatizará a transferência.
  • A retrospectiva pode especificar um mapeamento, como rb000/rb888, que é o mapeamento de transações de índice rb para a sequência de força principal.
  • Também pode ser mapeado para outros contratos, como rb000/MA888 é ver a linha K do índice de rb para negociar a força principal de MA em uma sequência
function main() { $.CTA("rb000,M000", function(r, mp) { if (r.length < 20) { return } var emaSlow = TA.EMA(r, 20) var emaFast = TA.EMA(r, 5) var cross = $.Cross(emaFast, emaSlow); if (mp <= 0 && cross > 2) { Log("金叉周期", cross, "当前持仓", mp); return 1 } else if (mp >= 0 && cross < -2) { Log("死叉周期", cross, "当前持仓", mp); return -1 } }); }

Exemplos de chamadas de classe

function main() { var p = $.NewPositionManager(); p.OpenShort("MA609", 1); p.OpenShort("MA701", 1); Log(p.GetPosition("MA609", PD_SHORT)); Log(p.GetAccount()); Log(p.Account()); Sleep(60000 * 10); p.CoverAll("MA609"); LogProfit(p.Profit()); Log($.IsTrading("MA609")); // 多品种时使用交易队列来完成非阻塞的交易任务 var q = $.NewTaskQueue(); q.pushTask(exchange, "MA701", "buy", 3, function(task, ret) { Log(task.desc, ret) }) while (true) { // 在空闲时调用poll来完成未完成的任务 q.poll() Sleep(1000) } }

Galeria de gráficos

Uma vez que a função gráfica original é mais complexa, será apresentada no próximo tutorial, é recomendado que os iniciantes usem diretamente a biblioteca de classes de gráficos, gráficos de linha muito simples, gráficos de linha K. O FMZ possui uma biblioteca de classes simples, que pode ser vista na página de edição da política. Se não houver, o usuário precisará copiar e salvar para selecionar referências na política.

img

Reprodução do catálogo de gráficos em Javascript
Reprodução da biblioteca de linhas de desenho do Python: https://www.fmz.com/strategy/39066

Exemplos:

function main() { while (true) { var ticker = exchange.GetTicker() if (ticker) { $.PlotLine('Last', ticker.Last) //可以同时画两条线,Last是这条线的名字 $.PlotLine('Buy', ticker.Buy) } Sleep(6000) } }

Configuração de parâmetros de política

Em baixo do editor de política, há uma configuração de parâmetros de política, equivalente a uma variável global da política, que pode ser acessada em qualquer lugar do código. A configuração de parâmetros de política pode ser modificada na interface do disco rígido e entrar em vigor após o reinicio. Assim, algumas variáveis podem ser configuradas como parâmetros e podem ser alteradas sem modificar a política.
img

  • Nome da variávelPor exemplo: number, string, combox, etc. podem ser usados diretamente no grupo de estratégia.
  • descrever: o nome do parâmetro na interface de estratégia, para facilitar a compreensão do significado do parâmetro.
  • Nota:: Explicação detalhada do parâmetro, que é exibida quando o mouse fica sobre ele.
  • tipo: O tipo do parâmetro é descrito abaixo.
  • Valores por defeitoO valor padrão para este parâmetro é:

O tipo de string e o tipo de número são fáceis de entender e são os tipos mais usados. A barra abaixo exibirá uma barra abaixo com opções na interface do parâmetro. A barra abaixo pode ser definida comoBTC|USDT|ETH, USDT é selecionado na página de parâmetros, então o valor de SYMBOL na estratégia é o índice de USDT 1. A seleção é uma caixa selecionável, marcada como verdadeira ou falsa.

Os parâmetros também podem ser configurados de várias maneiras: https://www.fmz.com/bbs-topic/1306

Backtesting de estratégia

Depois de fazer o trabalho de quantificação de uma estratégia, você pode testar sua estratégia com dados históricos para ver como sua estratégia ganhou em dados históricos. Claro, os resultados de retroalimentação são apenas para referência. A plataforma de quantificação FMZ suporta retroalimentação de moedas digitais em dinheiro, futuros, BitMEX e futuros de mercadorias, dos quais as moedas digitais suportam principalmente as variedades principais.
O retorno do Javascript ocorre no navegador, o retorno do Python precisa ser feito no host, e o host público pode ser fornecido pela plataforma. O retorno da linguagem do Mac precisa de mais parâmetros, consulte o documento da linguagem do Mac.

Mecanismo de resposta

O mecanismo de retrocesso de onbar é baseado em uma linha K, ou seja, cada linha K gera um ponto de tempo de retorno, no qual as informações sobre os preços de alta e baixa da linha K atual, o volume de transações e outras informações sobre a linha K histórica antes desse ponto de tempo podem ser obtidas. O inconveniente deste mecanismo é óbvio: em uma linha K, apenas uma compra e venda pode ser produzida, geralmente o preço baseado é o preço de fechamento da linha K. E uma linha K só pode obter quatro preços de alta e baixa, de modo que não há informações sobre como os preços mudam dentro de uma linha K.

A plataforma FMZ gerará 14 pontos de tempo de retorno em cada ciclo de linha K de base, gerando um tick de simulação com base no ciclo de linha K de base.**O nível de disco real é a coleta de ticks reais, que ocorrem a cada poucos segundos, e atualmente é parcialmente suportado pela profundidade real (contém 20 arquivos), que é a coleta de ticks reais.**A quantidade de dados é grande e a velocidade de retrospecção é lenta, portanto, não é possível retrospectar um tempo particularmente longo. O mecanismo de retrospecção do FMZ pode permitir que a estratégia negocie várias vezes em uma linha K, evitando apenas a transação de preço de liquidação, com mais precisão e compatível com a velocidade de retrospecção.

O esquema de retorno é o mesmo que o do disco rígido, e é um loop morto. Como o retorno é saltado em diferentes pontos de retorno, pode não usar o Sleep, que automaticamente salta para o próximo ponto de tempo no final de um ciclo. Mas o Python, devido ao mecanismo de programação, precisa forçar umSleep(10)Para evitar a morte.

Fotografias de retratos

O mecanismo de retestamento é baseado no preço de compra do usuário e no preço de cotação do ponto de tempo de retestamento. Se o preço de compra for maior do que o preço de venda, um negócio será feito. Se não for possível negociar, uma lista de espera será gerada.

Definições da página de retorno

img

    1. As opções da página de retrospectiva, a esquerda é a página de edição de estratégias.
    1. Tempo de início e fim da retrospecção, uma vez que os dados não estão completos, a retrospecção pode começar diretamente a partir do tempo em que os dados estão disponíveis.
    1. RevisãoGetRecords()O ciclo padrão da função pode ser especificado no código como um parâmetro de ciclo.
    1. Escolha de um mecanismo de feedback.
    1. Mostrar ou ocultar as configurações de resposta múltipla.
    1. Número máximo de registros, números de ganhos, números de gráficos, etc., para evitar que o excesso de dados cause o bloqueio do navegador.
    1. Geração de tick baseada no ciclo de linha K.
    1. Ponto de transação.
    1. Tolerância a erros, simulação de erros nas solicitações da API, verificação da tolerância a erros da política.
    1. se o ícone de tendência é traçado, se a função de indicador de TA for usada na retrospectiva, ele será exibido no ícone, e a compra e venda também serão marcadas.
    1. Instalação de taxas
    1. Adição de Exchange - Pair de transação e ativos.
    1. Configuração de parâmetros de retomada, se o parâmetro for numérico, também suporta parâmetros de otimização de um botão, automaticamente percorre o retomado do parâmetro de acordo com um certo alcance.

Diferenças entre detecção e disco real

    1. O GetTicker e o GetRecords são os únicos que são válidos para o retorno, os outros não são verdadeiros (por causa da grande quantidade de dados, o retorno em disco rígido já suporta esses dados, mas apenas os dados mais recentes).
  • As trocas de retrospectiva adicionadas são contas independentes e não suportam trocas de pares. Portanto, não é possível operar dois pares de transações em uma conta.
    1. Não é possível usar as solicitações da rede no teste de resposta.
    1. A retrospectiva não pode usar extensões de IO, apenas pode operar as APIs mais básicas.
    1. A retrospectiva só pode obter dados padrão, não existem dados de disco rígido como o Info.
    1. O retorno pode não ser bem-sucedido, observe o congelamento de pedidos.
    1. O teste de futuros de mercadorias não suporta a lista de preços de mercado.

A tolerância às estratégias e os erros comuns

Como mencionado anteriormente, é possível que o acesso falhe e retorne usando a interface da API no disco rígido.nullA estratégia é ser tolerante a erros, já que o uso de dados em tais situações pode gerar erros e fazer com que o disco fique parado.

Métodos de tolerância a erros comuns

A razão mais comum para isso é:

  • Erro de acesso à rede da API, o tempo de atraso do acesso à interface será retornado como null, e o uso será compensado.
  • Erros de restrição da plataforma, como restrição de IP, precisão de pedidos, frequência de acessos, erros de parâmetros, falta de ativos, impossibilidade de negociação do mercado, cancelamento de pedidos concluídos, etc. Pode consultar o documento da API especificamente de acordo com o código de erro.
  • A bolsa retorna erros de dados, ocasionalmente, como profundidade de retorno vazio, informações de conta atrasadas, status de pedido atrasado, etc.
  • Erro de lógica do programa.

Antes de usar a API para retornar dados, é necessário julgar se eles são nulos ou não. A seguir, serão apresentados os métodos usados com frequência:

//1.判断为null进行处理 var ticker = exchange.GetTicker(); while(ticker == null){ Log('ticker 获取出错'); ticker = exchange.GetTicker(); } Log(ticker.Last); // 2.判断不为null再进行引用 var ticker = exchange.GetTicker(); if(!ticker){ Log(ticker.Last); } // 3._C()函数重试 var ticker = _C(exchange.GetTicker); Log(ticker.Last); // 4. try catch容错 try{ var ticker = exchange.GetTicker(); Log(ticker.Last); } catch(err){ Log('ticker 获取出错'); }

Se você quiser obter informações erradas, pode usar:GetLastError(), irá retornar a última string de informações de erro, que pode ser processada diferencialmente.

FAQ

Muitos erros comuns foram resumidos no tópico do fórum: https://www.fmz.com/bbs-topic/1427 。 Aqui estão alguns deles, e se tiverem dúvidas, pesquisem Ctrl+F abaixo。

Como é que os guardiões são colocados?

Para mais detalhes, veja a seção Adicionar um administrador.

O que é que eu posso fazer?

Há pessoas no https://www.fmz.com/markets que oferecem serviços de substituição ou consultas em grupo, mas você precisa entrar em contato e assumir os riscos.

Acesso a todas as interfaces com aviso de tempo de expiração

Isso significa que o tempo de atraso na interface da bolsa é um problema, se ocasionalmente ocorrer, e se a mensagem indicar que a rede local não pode ser acessada, é necessário usar um servidor no exterior.

ERR_INVALID_POSITION Erro

O sistema de detecção de erros, geralmente computação de erros para a estratégia, e a tentativa de liquidação de posições quando não há ou não há uma quantidade suficiente de posições, pode causar esse erro.

symbol not set

A rede de câmbio de futuros não tem contrato definido no código, veja o exchange.SetContractType

BITMEX 429 Erro, {"error":{"message":"Rate limit exceeded retry in 1 seconds"...}}

A frequência de acesso às interfaces das exchanges é muito alta.

{"status":6004,"msg":"timestamp is out of range"}

A barra de tempo do servidor excede o alcance e precisa de atualização do tempo do servidor.

GetOrder(455284455): Error: invalid order id or order cancelled.

As ordens canceladas por algumas exchanges não são mantidas e não podem ser obtidas.

GetOrders: 400: {"code":-1121,"msg":"Invalid symbol."}

Pair de transação inválido, verifique se o par de transação foi configurado com erro.

Secret key decrypt failed

API KEY falhou na resolução, se você alterou a senha do FMZ após a configuração do APIKEY, tente adicionar uma página de câmbio no FMZ e reconfigure o APIKEY da bolsa.

Signature not valid: Invalid submission time or incorrect time format [[Hora de envio inválida ou erro de formato de hora]

Recomenda-se o uso de um servidor Linux, ou um software de sincronização de tempo de instalação nos sistemas Windows que apresentam o problema.

Por que um agente global e um administrador não conseguem acessar a API da bolsa?

Agentes globais não possuem portos de rede de hosts de proxy, e os hosts que possuem servidores no exterior são os melhores, devido a problemas de latência.

Como é que as estratégias são mantidas localmente e não em FMZs que são postadas?

Com o Python, você pode importar arquivos locais e salvá-los como arquivos normalmente escritos de acordo com a política da API do FMZ, colocando-os no seu próprio servidor sob o caminho de execução, podendo ler diretamente a execução.

#!python2.7 def run(runfile): with open(runfile,"r") as f: exec(f.read()) def main(): run('my.py')

Como usar a rede de testes da exchange ou alterar o endereço de base da API

O uso de exchange.SetBase () para mudar diretamente para o endereço de base da API correspondente é possível, como:

exchange.SetBase("https://www.okex.me")
Related Recommendations
Comment
All comments (27)

    api

    3 years ago

    如何在本地实现策略运行呢?我写了一个简单的Log输出语句,并且按照文末的操作。
    第一步,先用一台笔记本作为服务器,运行托管者程序;
    第二步,写一个简单的Log输出信息的test.py程序(FMZ 的API接口函数);
    第三步,按文末那样,写个runfile,通过run.py调用test.py运行。 img

    4 years ago

    我买的网易云量化交易课程怎么没了,现在去哪里看

    5 years ago

    谢谢

    5 years ago

    many

    5 years ago

    hi

    5 years ago

    学习ing

    5 years ago

    有一个小的文字错误,GetAccount 获取账户 介绍中,FrozenStocks应该是冻结余额而不是可用余额吧

    5 years ago

    改了

    5 years ago

    有没有做BTB的实盘教程,

    a year ago

    大佬麻烦问下咱们有官方交流群吗?有时候遇到问题不知道该在哪提问

    5 years ago

    加首页微信,拉你入群

    5 years ago

    加我进群,我的实盘执行不起来

    a year ago

    getorder outtime 获取订单超时,okex的交易所,怎么办

    5 years ago

    再次获取

    5 years ago

    担保资产率获取不到吗,到0%会被强制平仓的担保资产率

    5 years ago

    原始信息里有,可以用GetRawJSON或者查看字段里的info信息

    5 years ago

    我是看1分钟k线图操作的,所以Python死循环的sleep time 可以设置为0.1s,也就是sleep(100)吗,我看你其中写过一个sleep(10),也就是0.1s不会超过huobi HM的API限制吗?

    6 years ago

    exchange.SetDirection("closebuy"); //如果是永续合约,直接设置exchange.SetDirection("sell")

    这儿我试了OKex的永续合约,如果设置成 sell,直接开空了,平不是平多

    6 years ago

    exchange.SetDirection("closebuy"); //如果是永续合约,直接设置exchange.SetDirection("sell")

    这儿我试了OKex的永续合约,如果设置成 sell,直接开空了,平不是平多

    6 years ago

    有些永续合约允许双向持仓的,需要设置平仓。我更新一下,原来只有bitmex

    6 years ago

    不错不错,还有管理回复。。我发现代码里好多拼写错误,哈哈

    6 years ago

    GetOrders 的代码里面有两个拼写错误。。。一个是 function写成了 fuction,另一个是for循环的条件里 ; 打成了 ,

    6 years ago

    嗯嗯,已改正,感谢指出错误

    6 years ago

    是我错了。。。
    exchange.Buy(-1, 0.5),交易对是ETH_BTC,市价单代表买入0.5BTC的ETH
    exchange.Buy(price, 0.5),如果是这种限价单,则代表用price的价格买入 0.5ETH

    6 years ago

    exchange.Buy(-1, 0.5),交易对是ETH_BTC,则代表市价买入0.5BTC的ETH

    这里应该是【代表市价买入0.5ETH】

    6 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)