Olá pessoal! Hoje vamos escrever nosso primeiro robô comercial de combate para jogar na bolsa de valores. Troca de criptografia. Por que troca de criptomoeda?
a) tema de hype;
b) são de alguma forma mais simples.
Em primeiro lugar, quero avisar imediatamente os fãs do cassino dos Três Machados: você não ganhará um carro amanhã. O artigo é mais sobre como começar a escrever seus robôs, para que o algoritmo seja primitivo, mas funcione.
Em segundo lugar, você ganhará. Só um pouquinho.
C / f “O jogo da queda” (2015)- Esse cheiro, o que é? Como cheira?
Colônia?
- Não ...
- Oportunidades?
- não. Dinheiro
- Oh ... está tudo claro
- O cheiro de dinheiro!
Entendo.
Para os mais impacientes, todo o código no github exmo-exchange-trade-bot .
Etapa 1: Troca.
Vamos negociar na bolsa EXMO. Existem várias razões. A troca é popular na CEI, é de língua russa e suporta a entrada de rublos, tem a capacidade de criar pares para o rublo.
Entre as desvantagens estão o inconveniente processo de depositar rublos, uma comissão decente, poucos pares negociados.
Para nós, o principal é que ele possui soluções prontas para trabalhar com sua API. Isso certamente facilitará nosso trabalho.
Então, vamos começar.
Obviamente, você precisa se registrar na bolsa de valores e depositar algum dinheiro. Por exemplo, eu contribuí com US $ 5.
Além disso, em sua conta, você receberá chaves para acessar a API.
Usarei o cliente para o NodeJS (portanto, você precisará instalar o nodejs e o npm).
No seu computador, crie uma nova pasta e um arquivo no qual nosso robô de negociação será (por exemplo, exmo / index.js), abra o console e faça os últimos preparativos padrão.
Nós vamos para a pasta com o nosso projeto e escrevemos - npm init, depois pressione enter para todas as perguntas.
Em seguida, escrevemos
npm install exmo-api
Enquanto os pacotes estão sendo instalados, crie outro arquivo, chame-o de exmo.js e preencha-o com este conteúdo.
com esses conteúdos var CryptoJS = require("crypto-js") http = require('http'), querystring = require('querystring'), request = require('request'), config = { url: 'https://api.exmo.me/v1/' }; function sign(message){ return CryptoJS.HmacSHA512(message, config.secret).toString(CryptoJS.enc.hex); } exports.init_exmo = function (cfg) { config.key = cfg.key; config.secret = cfg.secret; config.nonce = Math.floor(new Date().getTime()*1000); }; exports.api_query = function(method_name, data, callback){ data.nonce = config.nonce++; var post_data = querystring.stringify(data); var options = { url: config.url + method_name, method: 'POST', headers: { 'Key': config.key, 'Sign': sign(post_data) }, form:data }; request(options, function (error, response, body) { if (!error && response.statusCode == 200) { callback(body); }else{ callback(error); } }); }; exports.api_query2 = function(method_name, data, callback){ data.nonce = config.nonce++; var post_data = querystring.stringify(data); var post_options = { host: 'api.exmo.me', port: '80', path: '/v1/' + method_name, method: 'POST', headers: { 'Key': config.key, 'Sign': sign(post_data), 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(post_data) } }; var post_req = http.request(post_options, function(res) { res.setEncoding('utf8'); res.on('data', function (chunk) { callback(chunk); }); }); post_req.write(post_data); post_req.end(); }; exports.test = function(){ return config.key; };
Este arquivo contém o endereço da API, a conexão de bibliotecas adicionais necessárias para trabalhar com a API e a principal função para solicitações à API.
É tudo, nós preparamos tudo e agora podemos começar diretamente a criar uma “máquina de fazer dinheiro” pessoal;)
Etapa 2: Código
Abra nosso index.js e conecte o arquivo exmo.js:
const exmo = require("./exmo");
Em seguida, vá para a troca em sua conta pessoal para o local em que criamos nossas chaves para acessar a API. Nós os copiamos e salvamos em variáveis:
const apiKey = ' '; const apiSecret = ' ';
Agora crie duas variáveis:
currency1 é o que compramos;
currency2 - moeda pela qual estamos comprando.
Quero comprar bitcoins por dólares:
const currency1 = 'BTC'; const currency2 = 'USD';
A seguir, um ponto importante - criamos uma variável com um valor mínimo de aposta. A troca não permite comprar menos que esse valor.
Vamos para o endereço https://api.exmo.com/v1/pair_settings/, procuramos seu par (para mim é BTC_USD) e olhamos para o primeiro parâmetro - min_quantity - 0,001
const currency1MinQuantity = 0.001;
E mais algumas variáveis:
o número de minutos após os quais um pedido não atendido será cancelado na moeda1
const orderLifeTime = 3;
comissão de câmbio (0,002 = 0,2%)
const stockFee = 0.002;
período de tempo (em minutos) para calcular o preço médio (isso será necessário para o nosso algoritmo)
const avgPricePeriod = 1;
a quantidade de moeda2 para comprar a moeda1 em uma transação única (joguei US $ 5 - operarei com eles)
const canSpend = 5;
o valor desejado de lucro de cada transação (0,001 = 0,1%)
const profit = 0.001;
Se o tempo de troca diverge do atual
const stockTimeOffset = 0;
Por conveniência, combinamos nosso par através de _
let currentPair = currency1+'_'+currency2;
Inicialize a conexão.
exmo.init_exmo({key:apiKey, secret:apiSecret});
Para o teste, você pode solicitar informações sobre si mesmo:
exmo.api_query("user_info", { }, result => console.log(result););
Vá para o console e execute
node index.js
Se tudo for feito corretamente, você verá informações sobre você!
Tudo funciona e você pode passar para a parte mais interessante - a função que as avós irão gerar para nós.
Então, eu já disse acima que nosso algoritmo será estúpido, agora você entenderá quanto)
O truque é levar o histórico de transações concluídas para qualquer período - nós temos a variável avgPricePeriod responsável por isso - e calcular o preço médio pela qual a moeda1 foi vendida. Por esse preço médio, faremos nosso pedido.
Então, vamos começar. Escrevemos nossa função trade ()
function trade(){}
Primeiro, obtemos uma lista de nossos pedidos em aberto:
1) verificamos se temos pedidos abertos para o nosso par usando o método da API user_open_orders. Se houver também à venda,
então apenas esperamos que eles sejam cumpridos (às vezes até o fim dos tempos). Se houver pedidos, lembre-se deles.
exmo.api_query("user_open_orders", { }, result => { let res = JSON.parse(result); if(res[currentPair] == undefined) console.log(' '); let buyOrders = []; for(let i in res[currentPair]){ console.log(res[currentPair][i]); if(res[currentPair][i].type == 'sell'){ console.log(', / '); }else{ buyOrders.push(res[currentPair][i]); } }
2) Verificamos se temos pedidos de compra abertos.
Classificamos todos os pedidos e obtemos um histórico deles usando o método order_trades , passando o ID do pedido para lá.
Pode haver três opções:
if(buyOrders.length > 0){ for(let key in buyOrders){ console.log(', ', buyOrders[key]['order_id']); exmo.api_query('order_trades', {"order_id": buyOrders[key]['order_id']}, result => { let res = JSON.parse(result);
1) podemos comprar a moeda necessária não no todo, mas em partes de pedidos de vendedores.
Portanto, se já compramos pelo preço desejado, aguardamos a compra de todo o valor.
if(res.result !== false){ console.log(', , '); }
2) com a segunda opção, precisamos verificar se nosso pedido está atrasado demais. Os preços mudam rapidamente e talvez o preço médio não seja mais relevante. Para isso, criamos a variável orderLifeTime, na qual indicamos quanto o nosso pedido deve demorar em minutos.
Se o tempo acabar, cancele o pedido usando o método order_cancel , passando o ID do pedido.
let timePassed = (new Date().getTime() / 1000) + stockTimeOffset * 60 * 60 - (buyOrders[key]['created']); if(timePassed > orderLifeTime * 60){ exmo.api_query('order_cancel',{"order_id":buyOrders[key]['order_id']}, res => { let result = JSON.parse(res); if(result.error) console.log(result.error); console.log(` ${orderLifeTime} ${currency1}`); }); }else{
3) se o tempo ainda não chegou, esperamos que possamos comprar pelo nosso preço.
console.log(`, , ${timePassed} `); } } }); } }else{
Tudo, descobrimos pedidos em aberto, agora o nosso robô sabe o que fazer com os pedidos quando os cria. Metade do trabalho feito.
Então, um bloco se não tivermos pedidos.
Obtemos informações sobre nossa conta usando o método user_info :
exmo.api_query('user_info',{},(result)=>{ let res = JSON.parse(result);
Por conveniência, anotamos saldos para nossos pares:
let balance = res.balances[currency1]; let balance2 = res.balances[currency2];
Verifique se existe uma moeda1 que possa ser vendida?
if(balance >= currency1MinQuantity){}
Nesse caso, precisamos calcular a taxa de venda.
Você precisa vender toda a moeda que comprou, o valor que comprou mais lucro menos a comissão de câmbio.
Um ponto importante! Temos menos moedas do que compramos - a bolsa levou uma comissão.
let wannaGet = canSpend + canSpend * (stockFee+profit); console.log('sell', balance, wannaGet, (wannaGet/balance));
Ao criar pedidos, o método order_create precisa receber os parâmetros:
- par é o nosso par atual para negociação;
- quantidade - quantidade;
- preço - preço;
- tipo - tipo do pedido criado (compra / venda);
Queremos vender - do tipo que especificamos vender .
let options = { "pair": currentPair, "quantity": balance, "price": wannaGet / balance, "type": 'sell' };
e enviar uma solicitação, se tudo estiver correto, você verá a entrada "Uma ordem de venda foi criada"
exmo.api_query("order_create", options,(result)=>{ if(result.error) console.log(result.error); console.log(" ", currency1, result.order_id); });
Só isso. Se tivéssemos uma moeda, simplesmente criamos um pedido para vendê-la.
Agora, passamos ao bloco mais interessante: o caso, se não tivermos a moeda1 (btc) e quisermos comprá-lo para a nossa moeda2 (usd).
Primeiro, verifique se há dinheiro suficiente no balanço na moeda2.
if(balance2 >= canSpend){}
Se houver, precisamos obter o preço médio pelo qual a moeda1 (btc) é vendida pelo período especificado em avgPricePeriod .
Um pouco de letra:
Exmo tem um método de ticker com estatísticas e volumes de negociação para pares de moedas. As estatísticas mostram o preço médio nas últimas 24 horas. No entanto, a diferença entre o preço médio e o preço em que o leilão está sendo realizado pode ser muito diferente.
Por esse motivo, podemos esperar muito tempo pela execução de uma ordem de venda.
Nós vamos fazer a nossa bicicleta.
Exmo tem um método de negociação , retorna uma lista de transações para um par de moedas.
Tomaremos a oferta perfeita para o avgPricePeriod do qual estamos interessados e, a partir deles, calcularemos o preço médio.
Esta não é uma opção ideal, mas mostrará os preços reais pelos quais eles vendem e compram.
Por exemplo, no momento da redação deste artigo, o preço médio do BTC_USD é 8314, enquanto a compra na bolsa é realizada ao preço de 7970.
Se fizermos um pedido a um preço médio, ele será imediatamente executado pelo preço mínimo indicado nas ordens de venda.
Mas, adicionando lucro e comissão de câmbio, é provável que esperemos muito tempo pela venda.
Então, vejamos o método de negociação e solicitamos estatísticas sobre nosso par atual de pares:
exmo.api_query("trades",{"pair":currentPair}, result => { let res = JSON.parse(result); let prices = []; let summ = 0;
Examinaremos todos os resultados e deixaremos apenas aqueles adequados ao nosso período de tempo.
for(deal in res[currentPair]){ let timePassed = (new Date().getTime() / 1000) + stockTimeOffset * 60 * 60 - res[currentPair][deal].date; if(timePassed < avgPricePeriod * 60){ summ += parseInt(res[currentPair][deal].price); prices.push(parseInt(res[currentPair][deal].price)); } }
E calcule o preço médio.
let avgPrice = summ2 / prices.length;
Temos um preço médio, mas precisamos corrigi-lo um pouco - subtraia a comissão de câmbio da stockFee e adicione o lucro desejado. Assim, tendo recebido um preço abaixo do preço médio de mercado, compraremos um pouco mais de moeda, uma vez que a bolsa posteriormente faz parte dela;
let needPrice = avgPrice - avgPrice * (stockFee + profit)
Recebemos o valor final que precisamos comprar.
let ammount = canSpend / needPrice; console.log('Buy', ammount, needPrice);
Verificamos se é possível comprar uma quantia dessa moeda (o valor mínimo de compra não é violado).
if(ammount >= currency1MinQuantity){}
Se nossa quantidade for maior, formaremos os parâmetros para o método order_create , somente desta vez com o tipo de compra .
let options = { "pair": currentPair, "quantity": ammount, "price": needPrice, **"type": 'buy'** }; exmo.api_query('order_create', options, res => { let result = JSON.parse(res); if(result.error) console.log(result.error); console.log(' ', result.order_id); }); }else{ console.log(', '); } }); }else{ console.log(', '); }
Agora precisamos colocar nossa função no cronômetro (o intervalo é uma vez a cada 5 segundos, por exemplo) e podemos executá-lo.
var timerId = setTimeout(function tick() { trade(); timerId = setTimeout(tick, 5000); }, 5000);
node index.js
Parabéns, você escreveu seu primeiro robô de negociação: você pode terminar o algoritmo e ganhar muito dinheiro) brincando .
Eu acho que você tem uma pergunta razoável: "Quanto dinheiro você pode ganhar dessa maneira?"
Para uma operação com US $ 5, ganho cerca de 2-3 centavos. Isso se deve à primitividade do algoritmo, que funciona se o preço flutuar em um determinado intervalo (e isso quase sempre não é o caso nas trocas de criptomoedas). Cerca de 10 a 20 operações ocorrem por dia (com boas mãos). Você pode contar a si mesmo;)
Mas não estamos dominando o código por uma questão de dinheiro)
Mais uma vez, um link para o github com a versão completa do bot e comentários.
https://github.com/v-florinskiy/exmo-exchange-trade-bot
Este é o meu primeiro artigo - não julgue estritamente)
Todo o lucro.
PS: Para aqueles que não trabalharam com o nó, seu script funcionará naturalmente enquanto o console estiver aberto.
Para o seu robô funcionar 24/7, você precisa de algum tipo de vps: lá você coloca nodejs, npm e, por exemplo, pm2. Usando esse utilitário, o script continuará funcionando, mesmo se o console estiver fechado.