Tutorial básico para a plataforma FMZ Quant

Autora:Ninabadass, Criado: 2022-03-18 09:00:46, Atualizado: 2022-04-02 11:48:15

Você pode usar o Python para escrever diretamente para o banco de dados.

function onexit(){
    _G('profit', profit)
}
function main(){
    _G("num", 1); // Set a global variable num, with a value of 1 second 
    _G("num", "ok"); // Change a global variable num, whose value is the string "ok"
    _G("num", null); // Delete the global variable num 
    _G("num"); // Return the value of the global variable num; if it does not exist, return null

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

_N

Quando se faz uma encomenda, normalmente é necessário controlar a precisão do preço e do volume; a FMZ tem a função _N integrada para determinar os lugares decimais a serem salvos; por exemplo, o resultado de_N(4.253,2)É 4,25.

_C

A chamada da API da plataforma não pode garantir que o acesso seja bem-sucedido toda vez, e _C é uma função de tentativa automática. Ele sempre chamará as funções especificadas até retornar com sucesso (a função tentará novamente se retornar nula ou falsa); por exemplo,_C(exchange.GetTicker), com o intervalo de reatendimento padrão de 3 segundos, e você pode chamar a função _CDelay para controlar o intervalo de reatendimento, como _CDelay(1000), o que significa mudar o intervalo de reatendimento da função _C para 1 segundo.GetTicker(), exchange.GetDepth, GetTrade, GetRecords, GetAccount, GetOrderseGetOrderPara evitar a interrupção do programa causada pela falha de acesso.

CancelOrdernão pode usar a função _C, porque há várias razões para o fracasso de cancelar uma ordem. Se uma ordem foi executada, então cancelar a ordem retornará um fracasso, e usar a função _C resultará em tentar novamente o tempo todo. A função _C também pode passar em parâmetros e também é usada em funções personalizadas.

function main(){
    var ticker = _C(exchange.GetTicker)
    var depth = _C(exchange.GetDepth)
    var records = _C(exchange.GetRecords, PERIOD_D1) // Pass in the parameters
}

_D

Chamo-te_D()direct devolverá a cadeia de tempo atual, como:2019-08-15 03:46:14. Se for chamado durante o backtest, o tempo de backtest será devolvido. Você pode usar a função _D para julgar o tempo, como:_D().slice(11) > '09:00:00':. _D(timestamp, fmt), converterá o carimbo de hora ms para uma cadeia de tempo, como_D(1565855310002)O parâmetro fmt é o formato de tempo, e o padrão éyyyy-MM-dd hh:mm:ss.

Funções do indicador TA

Para algumas funções de indicadores comumente utilizadas, tais como MA\MACD\KDJ\BOLL e outros indicadores comuns, que foram incorporados diretamente pela plataforma FMZ, e os indicadores específicos suportados podem ser encontrados no documento API.

Antes de utilizar as funções de indicador, é melhor julgar o comprimento da linha K. Quando o comprimento da linha K anterior não pode cumprir o período necessário para o cálculo, o resultado énullPor exemplo, se o comprimento da linha K de entrada for 100 e o período para o cálculo da MA for 10, então os primeiros 9 valores são todos nulos e o cálculo após os valores da forma 9 será feito normalmente.

O JavaScript também suporta o talib completo, como uma biblioteca de terceiros, com método de invocação comotalib.CCI(records)Por favor, consulte:http://ta-lib.org/function.htmlPara Python, você pode instalar a biblioteca talib por conta própria. Devido à necessidade de compilação, você não pode simplesmente usar pip para instalar. Você pode procurar o método de instalação por conta própria.

As funções de indicador não só podem passar os dados da linha K, mas também passar qualquer matriz

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

Funções comumente usadas no JavaScript

Aqui introduzimos algumas funções JavaScript comumente usadas nos bots.

  • Date.now()Retorna o carimbo de data e hora corrente;
  • parseFloat()transfere cadeias em números, comoparseFloat("123.21");
  • parseInt()Transfere cadeias em números inteiros;
  • num.toString()Transfere números para cadeias, com a variável num num;
  • JSON.parse()formatos de string Json, tais comoJSON.parse(exchange.GetRawJSON());
  • JavaScript tem suas próprias funções matemáticas, tais como as operações matemáticas comuns, incluindoMath.max(), Math.abs()etc.; referência:https://www.w3school.com.cn/jsref/jsref_obj_math.asp ;
  • A biblioteca matemática de terceiros utilizada pela FMZ; referência:https://mathjs.org/ ;
  • A biblioteca de ressalvas de terceiros de JavaScript usada pela FMZ, que é recomendada para ter conhecimento e que torna as tediosas operações Js mais convenientes; referência:https://underscorejs.org/.

Modelo

Há muitas situações que precisam ser consideradas ao escrever uma função de estratégia de bot. Por exemplo, uma função simples como comprar 5 moedas, precisamos considerar: O saldo atual é suficiente? Quanto é o preço da ordem? Qual é a precisão? Você precisa dividir as ordens para evitar impactar o mercado? Como lidar com ordens inacabadas? E alguns detalhes assim. Em diferentes estratégias, essas funções são as mesmas, então você pode fazê-las em um modelo. Seguindo os modelos oficiais, os usuários também podem escrever suas próprias estratégias de modelo. Aqui vamos introduzir várias bibliotecas de classes de modelos muito usadas oficialmente lançadas pela FMZ, para que os usuários possam escrever rapidamente suas próprias estratégias.

A biblioteca de negociação de criptomoedas JavaScript e a biblioteca de negociação de futuros de commodities são incorporadas por padrão e não precisam ser copiadas. Outras bibliotecas de modelos podem ser encontradas na estratégia Square (https://www.fmz.com/square/20/1) Copie e guarde a biblioteca de modelos e verifique a biblioteca a ser usada ao criar sua própria estratégia.

Todas as funções do modelo JavaScript começam com$, enquanto os Python começam todos comext.

Biblioteca de negociação de criptomoedas

Endereço do código fonte:https://www.fmz.com/strategy/10989Implementação de função específica pode se referir diretamente ao código fonte.

Obter Conta:

$.GetAccount(e)

Log($.GetAccount()); // Obtain the account information, with fault tolerance function 
Log($.GetAcccount(exchanges[1]));

Encomenda e cancelamento:

$.Buy/Sell(e, amount)
$.Buy(0.3); // The main platform buys 0.3 coin
$.Sell(0.2); // The main platform sells 0.2 coin
$.Sell(exchanges[1], 0.1); // The secondary platform sells 0.1 coin
$.CancelPendingOrders(e, orderType)

$.CancelPendingOrders(); // Cancel all entrusted orders of the main platform 
$.CancelPendingOrders(ORDER_TYPE_BUY); // Cancel all buy orders of the main platform
$.CancelPendingOrders(exchanges[1]); // Cancel all orders of the secondary platform
$.CancelPendingOrders(exchanges[1], ORDER_TYPE_SELL); // Cancel all sell orders of the secondary platforom 

Julga a Cruz:

$.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])
If n = 0, it means that the current prices of exactly 15-period EMA and 30-period EMA are equal. 
If n > 0, such as 5, it means that the 15-period EMA up-crosses the 30-period EMA by 5 periods (Bar)
If n < 0, such as -12, it means that the 15-period EMA down-crosses the 30-period EMA by 12 periods (Bar)
If it is not an array passed to the Cross, the function automatically obtains the K-line for moving average calculation.
If an array is passed to Cross, compare directly.

Função $.withdraw ((e, moeda, endereço, montante, taxa, senha):

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

Biblioteca de negociação de futuros de mercadorias

Para o uso da biblioteca de negociação de futuros de commodities é muito estável, é recomendado.https://www.fmz.com/strategy/12961Implementação de função específica pode se referir diretamente ao código fonte.

Biblioteca CTA

  • O bot irá mapear automaticamente o índice para o contrato contínuo principal;
  • Ele irá lidar automaticamente com a mudança;
  • Pode especificar o mapeamento para backtest, como rb000/rb888, que é mapear a linha k do índice rb para negociar o contrato contínuo principal;
  • Pode também ser atribuído a outros contratos; por exemplo, o rb000/MA888 deve ser analisado na linha K do índice rb para negociar o contrato principal contínuo MA.
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("Golden cross period", cross, "the moment position", mp);
            return 1
        } else if (mp >= 0 && cross < -2) {
            Log("Death cross period", cross, "the moment position", mp);
            return -1
        }
    });
}

Invocação Exemplo de biblioteca

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"));
    // Multiple varieties use the trading queue to complete the non-blocking trading task
    var q = $.NewTaskQueue();
    q.pushTask(exchange, "MA701", "buy", 3, function(task, ret) {
        Log(task.desc, ret)
    })
    while (true) {
        // Call "poll" to execute the unfinished tasks in the spare time
        q.poll()
        Sleep(1000)
    }
}

Biblioteca de desenhos

Para as funções brutas para desenho são muito complicadas, que serão introduzidas no próximo tutorial, recomendamos aos iniciantes para usar a biblioteca de desenho, para desenhar gráficos de linhas muito simples e gráficos de linhas k, etc. A biblioteca de desenho simples foi construída em FMZ, que pode ser visto na página de edição de estratégia; se a biblioteca não é construída ainda, os usuários precisam copiar e salvar, para verificar e usar a biblioteca na estratégia.

img

Endereço de cópia da biblioteca de desenhos da versão Javascript:https://www.fmz.com/strategy/27293Endereço de cópia da biblioteca de desenhos da versão Python:https://www.fmz.com/strategy/39066

Exemplo específico:

function main() {
    while (true) {
        var ticker = exchange.GetTicker()
        if (ticker) {
            $.PlotLine('Last', ticker.Last) // You can draw two lines at the samw time, "Last" is the name of the line
            $.PlotLine('Buy', ticker.Buy)
        }
        Sleep(6000)
    }
}

Configurações do Parâmetro de Estratégia

No âmbito da Edit Strategy, existem configurações de parâmetros de estratégia, que são iguais às variáveis globais da estratégia, e podem ser acessadas em qualquer local do código. Os parâmetros de estratégia podem ser modificados na página do bot, e serão válidos após a reinicialização.
img

  • Nome da variável: ou seja, o número, a cadeia e a caixa etc. na imagem acima, que podem ser utilizados directamente no grupo de estratégia.
  • Descrição: o nome de um parâmetro na interface de estratégia, mais conveniente para os utilizadores compreenderem o significado do parâmetro.
  • Observação: a explicação pormenorizada de um parâmetro, que será exibida quando o mouse estiver sobre o parâmetro.
  • Tipo: o tipo de parâmetro, que será apresentado em pormenor mais adiante.
  • Padrão: o padrão do parâmetro a.

É muito fácil de entender e tipo de string e tipo de número. que são tipos muito comumente usados. A caixa de combinação irá exibir as opções na caixa na interface do parâmetro. Por exemplo, você pode definir o parâmetro SYMBOL comoBTC|USDT|ETHna caixa de combinação; se você escolher USDT na caixa na página, o valor SYMBOL na estratégia é o índice USDT 1.

Há mais parâmetros para configurações; referene:https://www.fmz.com/api.

Estratégia Backtest

Quando a quantização de uma estratégia estiver terminada, você pode testá-la pelos dados do histórico, para verificar a situação de lucro da estratégia na data do histórico. O backtest do Javascript é executado no navegador; o backtest do Python está no docker, e nossa plataforma fornece dockers públicos para usuários.

Mecanismo Baktest

O mecanismo de backtest on-bar é baseado na linha K, ou seja, cada linha K gerará um ponto no tempo para backtest. No ponto no tempo, você pode obter as informações, incluindo os preços abertos, fechados, mais altos e mais baixos e o volume de negociação da linha K atual, bem como as informações da linha K do histórico antes do ponto. A deficiência deste tipo de mecanismo é muito óbvia: apenas uma compra pode ser gerada em uma linha K; geralmente o preço referido é o preço de fechamento da linha K. Além disso, uma linha K só pode obter quatro preços, ou seja, os preços fechados, abertos, mais altos e mais baixos; a informação, incluindo como os preços mudam em uma linha K e se o preço mais alto ou o preço mais baixo muda primeiro, não pode ser obtida. Tome o bot de teste de uma hora como exemplo.

O backtest no FMZ contém dois tipos, ou seja, o backtest de nível de simulação e o backtest de nível de mercado real.No entanto, o backtest do nível real do mercado irá realmente coletar tick, a cada vários segundos, e agora ele suporta profundidade real (incluindo 20 níveis), e real execução do comércio por tarde.O volume de data é muito grande, e a velocidade do backtest é muito lenta, então o backtest não pode ser executado em um longo tempo. FMZ mecanismo backtest pode realizar múltiplos negócios da startegy em uma linha K, para evitar a situação de que a negociação só pode ser executada pelo preço de fechamento, e também cada vez mais visando e cuidando da velocidade do backtest.https://www.fmz.com/bbs-topic/9126.

A estrutura do backtest e do bot é a mesma, ambos um loop infinito. Como o backtest é para pular para diferentes pontos de backtest, o backtest pode ser executado sem usar Sleep, e ele irá pular automaticamente para o próximo ponto de tempo quando um loop for terminado. No entanto, o Python, devido ao mecanismo do programa, precisa de uma restrição deSleep(10), para não ficarmos presos.

Coincidência do teste de retorno

O mecanismo de backtest irá combinar o preço da ordem colocado pelo usuário e o preço de mercado no momento do backtest. Se o preço de compra for maior do que o preço de venda, o preço de venda será executado. Se a negociação não puder ser executada, uma ordem pendente será gerada. O deslizamento precisa ser adicionado para garantir a negociação. Se a posição não puder ser aberta ou fechada durante o backtest, verifique se a posição está congelada devido a ordens inacabadas.

Configurações da página de backtest

img

  • 1.escolher a página do Backtest, na esquerda da qual está a página Edit Strategy;
  • 2.a hora de início e a hora de fim do backtest; para os dados que possam ser incompletos, o backtest pode começar directamente a partir do momento em que os dados existem;
  • 3.o período de imprevisibilidade do backtestingGetRecords()função; pode também especificar um parâmetro de período no código;
  • 4.a escolha do mecanismo de backtest;
  • 5.exibir ou ocultar mais configurações de backtest;
  • 6.os valores máximos dos elementos do log, dos elementos do log dos lucros e dos elementos do log dos gráficos, para evitar que o navegador se descompõe devido a uma enorme quantidade de dados;
  • 7.o período gerado pelo carrapato da camada inferior de acordo com a linha K;
  • 8.Ponto de deslizamento do treino;
  • 9.tolerância a falhas, que simulará a situação em que a solicitação de API é errada e testará a capacidade de tolerância a falhas da estratégia;
  • 10.se desejar desenhar o gráfico de mercado; se for utilizada uma função de indicador de TA no backtest, a função será automaticamente apresentada no gráfico e as compras e vendas também serão assinaladas;
  • 11.Estabelecimento das taxas de serviço;
  • 12.Plataformas adicionais - pares de negociação e activos;
  • 13.configurações dos parâmetros do backtest; se os parâmetros forem números e suportarem também a otimização de uma única tecla, os parâmetros serão automaticamente percorridos num certo intervalo no backtest.

Diferenças entre Bot e Backtest

  • 1.as únicas cotações de mercado válidas no backtest são apenas de GetTicker e GetRecords; outras como GetDepth e GetTrades não são reais (o volume de dados é enorme e, embora o backtest a nível de mercado real agora suporte os dados já existentes, só suporta os dados mais recentes);
  • 2.as plataformas adicionadas no backtest são todas contas segregadas; não é suportado o direito de trocar os pares de negociação; por conseguinte, não é possível operar dois pares de negociação numa conta;
  • 3. a solicitação de rede não pode ser utilizada no backtest;
  • 4.IOA extensão não pode ser utilizada no backtest e só podem ser operadas APIs básicas;
  • 5.só podem ser obtidos dados padrão no backtest, e os dados, como o Info que está relacionado com o bot, não existem;
  • 6.o atraso pode não ser executado no backtest e prestar atenção à situação dos pedidos congelados;
  • 7.inO backtest de futuros de commodities, a ordem de mercado não é apoiada.

Estratégia Tolerância a falhas e erros comuns

Como mencionamos anteriormente, usando uma interface API no bot pode falhar para acessar e retornarnullPor isso, as estratégias precisam funcionar bem em tolerância a falhas.

Formas comuns de tolerar falhas

Causas comuns:

  • Erro de rede de acesso à API; o timeout de acesso à interface retorna nunll e um erro será relatado.

  • Erro de limitação da plataforma, como limitação de IP, precisão de ordem, frequência de acesso, erro de parâmetro, deficiência de ativos, falha de negociação no mercado, cancelamento de ordens executadas, etc.; os detalhes podem ser consultados no documento API de acordo com os códigos errados.

  • Erro de devolução de dados da plataforma; ocorre às vezes, como devolver profundidade nula, informações de conta atrasadas e status de pedido atrasado, etc.

  • Erro lógico do programa.

Antes de usar os dados devolvidos da API, você deve julgar se os dados são nulos, e os métodos comuns são introduzidos da seguinte forma:

//1.judge the data is null and handle 
var ticker = exchange.GetTicker();
while(ticker == null){
     Log('ticker obtain error');
     ticker = exchange.GetTicker();
 }
 Log(ticker.Last);
 // 2. judge the data is not null, and use 
 var ticker = exchange.GetTicker();
 if(!ticker){
     Log(ticker.Last);
 }
 // 3.retry _C() function 
 var ticker = _C(exchange.GetTicker);
 Log(ticker.Last);
 // 4.try cache fault tolerance
 try{
     var ticker = exchange.GetTicker();
     Log(ticker.Last);
 }
 catch(err){
     Log('ticker obtain error');
 } 

Se quiser obter informações sobre erros, pode utilizarGetLastError(), e as cadeias de informações de erro da última vez serão devolvidas, e os erros podem ser processados por diferenças.

Perguntas frequentes

Resumo dos erros comuns nos posts superiores dos fóruns:https://www.fmz.com/bbs-topic/9158Aqui apresentamos brevemente; você pode usar o CTRL + F para pesquisar, quando você tem problemas.

Como é que se instala o docker?

Há uma introdução detalhada sobre isso na seção de adição de um docker.

Posso pedir a alguém para escrever estratégias para mim?

emhttps://www.fmz.com/markets, existem algumas pessoas que prestam serviços de redação de estratégias para outros, ou você pode perguntar nos grupos de bate-papo; observe que esse tipo de serviços deve ser contatado por si mesmo, e você deve estar ciente de que o risco também deve ser suportado por si mesmo.

Todas as interfaces pedem tempo de espera quando acessadas

refere-se ao timeout da interface da plataforma acedida; se o timeout ocorrer ocasionalmente, não é um problema; se o timeout for solicitado o tempo todo, isso significa que não se pode aceder a todas as redes e é necessário um servidor no estrangeiro.

ERR_INVALID_POSITION

Se o backtest relatar um erro, é geralmente um erro de escrita; quando se tenta colocar uma ordem para fechar uma posição, quando não há posição ou o volume da posição não é suficiente, será relatado um erro.

Símbolo não definido

Não existe um contrato definido no código, durante os backtests das plataformas de futuros.

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

A frequência de acesso da interface da plataforma é muito alta.

O tempo está fora de alcance.

A marca de tempo do servidor excede o intervalo de tempo de atualização do servidor e o tempo excedido não pode ser muito longo.

GetOrder ((455284455)): Erro: ID de ordem inválido ou ordem cancelada.

Se a encomenda de uma plataforma for cancelada, a plataforma não manterá mais as informações sobre a encomenda, pelo que não poderão ser obtidas.

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

Pares de negociação inválidos; verifique se a configuração do par de negociação está errada.

Descifrar chave secreta falhou

A análise do APIKEY falhou. Se a senha FMZ foi modificada após a configuração do APIKEY, tente adicionar uma página de plataforma no FMZ e reconfigure o APIKEY da plataforma.

Assinatura não válida: horário de apresentação inválido ou formato de horário incorreto

Sugiro que use o servidor Linux, ou instale software de sincronização de tempo nestes sistemas Windows onde este problema ocorre.

Por que o docker ainda não pode acessar a API da plataforma quando um proxy global está configurado?

O proxy global não tem uma porta de rede do docker proxy. Devido ao problema de atraso, é melhor implantar o docker de um servidor no exterior.

Como salvar uma estratégia localmente, não para carregá-lo para FMZ?

Usando Python, e você pode importar arquivos locais, salvar a estratégia normalmente escrito pela FMZ API como um arquivo e colocá-lo no caminho de execução em seu próprio servidor, e você pode ler diretamente e executá-lo.

#!python2.7

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

Como testar a rede de uma plataforma ou como mudar o endereço da base da API?

Use exchange.SetBase() para mudar diretamente para o endereço de base da API correspondente.

exchange.SetBase("https://www.okex.me")

Mais.