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')
}
}
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.
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
, GetOrders
eGetOrder
Para evitar a interrupção do programa causada pela falha de acesso.
CancelOrder
nã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
}
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
.
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 énull
Por 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)
}
}
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())
;Math.max()
, Math.abs()
etc.; referência:https://www.w3school.com.cn/jsref/jsref_obj_math.asp ;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
Todas as funções do modelo JavaScript começam com$
, enquanto os Python começam todos comext
.
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, "***")
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
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)
}
}
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.
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)
}
}
No âmbito da
É 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|ETH
na 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.
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.
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(10)
, para não ficarmos presos.
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.
GetRecords()
função; pode também especificar um parâmetro de período no código;Como mencionamos anteriormente, usando uma interface API no bot pode falhar para acessar e retornarnull
Por isso, as estratégias precisam funcionar bem em tolerância a 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.
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")