Hola a todos! Hoy escribiremos nuestro primer robot de comercio de combate para jugar en la bolsa de valores. Cryptoexchange. ¿Por qué el intercambio de criptomonedas?
a) tema publicitario;
b) son de alguna manera más simples.
En primer lugar, quiero advertir de inmediato a los fanáticos del casino Three Axes: mañana no ganarán un automóvil. El artículo trata más sobre cómo comenzar a escribir sus robots, por lo que el algoritmo será primitivo, pero funcionará.
En segundo lugar, ganarás. Solo un poquito.
C / f "El juego por una caída" (2015)- Este olor, ¿qué es? ¿A qué huele?
- Colonia?
- no ...
- Oportunidades?
- No Dinero
- Oh ... todo está claro
- El olor del dinero!
- Ya veo.
Para los más impacientes, todo el código en el github exmo-exchange-trade-bot .
Etapa 1: Intercambio.
Negociaremos en el intercambio EXMO. Hay varias razones El intercambio es popular en la CEI, es de habla rusa y admite la entrada de rublos, tiene la capacidad de crear pares para el rublo.
Entre las desventajas están el proceso inconveniente de depositar rublos, una comisión decente, pocos pares negociados.
Para nosotros, lo principal es que tiene soluciones listas para trabajar con su API. Esto sin duda facilitará nuestro trabajo.
Entonces comencemos.
Por supuesto, debe registrarse en la bolsa de valores y depositar algo de dinero. Por ejemplo, aporté $ 5.
Además en su cuenta, recibirá claves para acceder a la API.
Usaré el cliente para NodeJS (por lo que deberá instalar nodejs y npm).
En su computadora, cree una nueva carpeta y un archivo en el que estará nuestro robot comercial (por ejemplo, exmo / index.js), abra la consola y realice los últimos preparativos estándar.
Vamos a la carpeta con nuestro proyecto y escribimos - npm init, luego presionamos enter para todas las preguntas.
Luego escribimos
npm install exmo-api
Mientras se instalan los paquetes, cree otro archivo, llámelo exmo.js y llénelo con este contenido.
con estos contenidos 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 archivo contiene la dirección de la API, la conexión de bibliotecas adicionales que necesitamos para trabajar con la API y la función principal para las solicitudes a la API.
Eso es todo, hemos preparado todo y ahora podemos comenzar directamente a crear una "máquina de hacer dinero" personal;)
Etapa 2: Código
Abra nuestro index.js y conecte el archivo exmo.js:
const exmo = require("./exmo");
Luego, vaya al intercambio en su cuenta personal al lugar donde creamos nuestras claves para acceder a la API. Los copiamos y los guardamos en variables:
const apiKey = ' '; const apiSecret = ' ';
Ahora cree dos variables:
moneda1 es lo que compramos;
moneda2: moneda para la que estamos comprando.
Quiero comprar bitcoins por dólares:
const currency1 = 'BTC'; const currency2 = 'USD';
A continuación, un punto importante: creamos una variable con un monto mínimo de apuesta. El intercambio no permite comprar menos de esta cantidad.
Vamos a la dirección https://api.exmo.com/v1/pair_settings/ buscamos su par (para mí es BTC_USD) y miramos el primer parámetro - min_quantity - 0.001
const currency1MinQuantity = 0.001;
Y algunas variables más:
el número de minutos después de los cuales se cancelará una orden de compra no cumplida
const orderLifeTime = 3;
comisión de cambio (0.002 = 0.2%)
const stockFee = 0.002;
período de tiempo (en minutos) para calcular el precio promedio (esto será necesario para nuestro algoritmo)
const avgPricePeriod = 1;
la cantidad de moneda2 para comprar moneda1 en una transacción única (arrojé $ 5, operaré con ellos)
const canSpend = 5;
la cantidad deseada de ganancias de cada transacción (0.001 = 0.1%)
const profit = 0.001;
Si el tiempo de intercambio difiere del actual
const stockTimeOffset = 0;
Para mayor comodidad, combinamos nuestro par a través de _
let currentPair = currency1+'_'+currency2;
Inicializa la conexión.
exmo.init_exmo({key:apiKey, secret:apiSecret});
Para la prueba, puede solicitar información sobre usted:
exmo.api_query("user_info", { }, result => console.log(result););
Ve a la consola y corre
node index.js
Si todo se hace correctamente, ¡verá información sobre usted!
Todo funciona y puedes pasar a la parte más interesante: la función que las abuelas generarán para nosotros.
Entonces, ya dije anteriormente que nuestro algoritmo será estúpido, ahora entenderás cuánto)
El truco consiste en tomar el historial de transacciones completadas para cualquier período (tenemos la variable avgPricePeriod responsable de esto) y calcular el precio promedio por el cual se vendió la moneda1. Por este precio promedio, realizaremos nuestro pedido.
Entonces comencemos. Escribimos nuestra función trade ()
function trade(){}
Primero obtenemos una lista de nuestros pedidos abiertos:
1) comprobamos si tenemos órdenes abiertas para nuestro par utilizando el método de la API user_open_orders. Si también hay en venta,
entonces solo esperamos que se cumplan (a veces hasta el final de los tiempos). Si hay órdenes de compra, solo recuérdelas.
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 si tenemos órdenes de compra abiertas.
Ordenamos todos los pedidos y obtenemos un historial de ellos utilizando el método order_trades , pasando la identificación del pedido allí.
Puede haber 3 opciones:
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 la moneda necesaria no en su totalidad, sino en partes de pedidos de vendedores.
Por lo tanto, si ya hemos comprado al precio deseado, estamos esperando la compra del monto total.
if(res.result !== false){ console.log(', , '); }
2) con la segunda opción, debemos verificar si nuestro pedido se demora demasiado. Los precios cambian rápidamente y quizás el precio promedio ya no sea relevante. Para hacer esto, creamos la variable orderLifeTime, donde indicamos cuánto debe colgar nuestro pedido en minutos.
Si se acabó el tiempo, cancele el pedido utilizando el método order_cancel , pasándole el ID del 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) si aún no ha llegado el momento, solo esperamos poder comprar a nuestro precio.
console.log(`, , ${timePassed} `); } } }); } }else{
Todo, descubrimos órdenes abiertas, ahora nuestro robot sabe qué hacer con las órdenes cuando las crea. La mitad del trabajo hecho.
Entonces, un bloque si no tenemos pedidos.
Obtenemos información sobre nuestra cuenta utilizando el método user_info :
exmo.api_query('user_info',{},(result)=>{ let res = JSON.parse(result);
Por conveniencia, anotamos saldos para nuestros pares:
let balance = res.balances[currency1]; let balance2 = res.balances[currency2];
¿Verifica si hay moneda1 que se puede vender?
if(balance >= currency1MinQuantity){}
Si es así, necesitamos calcular la tasa de venta.
Debe vender toda la moneda que compró, la cantidad que compró más las ganancias menos la comisión de cambio.
Un punto importante! Tenemos menos monedas de las que compramos: el intercambio tomó una comisión.
let wannaGet = canSpend + canSpend * (stockFee+profit); console.log('sell', balance, wannaGet, (wannaGet/balance));
Al crear pedidos, el método order_create necesita pasar los parámetros:
- par es nuestro par actual para el comercio;
- cantidad - cantidad;
- precio - precio;
- tipo: tipo del pedido creado (compra / venta);
Queremos vender: en el tipo que especificamos vender .
let options = { "pair": currentPair, "quantity": balance, "price": wannaGet / balance, "type": 'sell' };
y envíe una solicitud, si todo está correcto, verá la entrada "Se ha creado una orden de venta"
exmo.api_query("order_create", options,(result)=>{ if(result.error) console.log(result.error); console.log(" ", currency1, result.order_id); });
Eso es todo. Si teníamos una moneda, simplemente creamos una orden para venderla.
Ahora pasamos al bloque más interesante: el caso si no tenemos moneda1 (btc) y queremos comprarlo para nuestra moneda2 (usd).
Primero, verifique si hay suficiente dinero en el balance general en la moneda2.
if(balance2 >= canSpend){}
Si lo hay, entonces necesitamos obtener el precio promedio por el cual se vende la moneda1 (btc) durante el período de tiempo que especificamos en avgPricePeriod .
Un poco de letra:
Exmo tiene un método de teletipo con estadísticas y volúmenes de negociación para pares de divisas. Las estadísticas muestran el precio promedio de las últimas 24 horas. Sin embargo, la diferencia entre el precio promedio y el precio actual en la subasta puede ser muy diferente.
Debido a esto, podemos esperar mucho tiempo para la ejecución de una orden de venta.
Haremos nuestra bicicleta.
Exmo tiene un método de negociación , devuelve una lista de ofertas para un par de divisas.
Tomaremos el trato perfecto para el avgPricePeriod que nos interesa y de ellos calcularemos el precio promedio.
Esta no es una opción ideal, pero mostrará los precios reales a los que venden y compran.
Por ejemplo, al momento de escribir, el precio promedio de BTC_USD es 8314, mientras que la compra en el intercambio se realiza a un precio de 7970.
Si hacemos un pedido a un precio promedio, se ejecutará inmediatamente al precio mínimo indicado en los pedidos de venta.
Pero agregando ganancias y comisión de cambio, es probable que esperemos mucho tiempo para la venta.
Entonces, pasemos al método de intercambios y solicitemos estadísticas sobre nuestro par actual de pares:
exmo.api_query("trades",{"pair":currentPair}, result => { let res = JSON.parse(result); let prices = []; let summ = 0;
Revisaremos todos los resultados y dejaremos solo aquellos que sean adecuados para nuestro período de tiempo.
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)); } }
Y calcular el precio promedio.
let avgPrice = summ2 / prices.length;
Tenemos un precio promedio, pero necesitamos fijarlo un poco: reste la comisión de intercambio stockFee y agregue la ganancia deseada. Por lo tanto, habiendo recibido un precio por debajo del precio promedio de mercado, compraremos un poco más de dinero, ya que el intercambio posteriormente forma parte de él;
let needPrice = avgPrice - avgPrice * (stockFee + profit)
Obtenemos la cantidad final que necesitamos comprar.
let ammount = canSpend / needPrice; console.log('Buy', ammount, needPrice);
Verificamos si es posible comprar tal cantidad de moneda (es la cantidad mínima de compra no violada).
if(ammount >= currency1MinQuantity){}
Si nuestra cantidad es mayor, entonces formamos los parámetros para el método order_create , solo que esta vez con el 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(', '); }
Ahora tenemos que poner nuestra función en el temporizador (el rango es una vez cada 5 segundos, por ejemplo) y podemos ejecutarlo.
var timerId = setTimeout(function tick() { trade(); timerId = setTimeout(tick, 5000); }, 5000);
node index.js
Felicitaciones, escribió su primer robot comercial: puede terminar el algoritmo y ganar mucho dinero) es broma .
Creo que tiene una pregunta razonable: "¿Cuánto dinero puede ganar de esta manera?"
Por una operación con $ 5, gano alrededor de 2-3 centavos. Esto se debe a la primitividad del algoritmo, que funciona si el precio fluctúa en un cierto rango (y este no es casi siempre el caso en los intercambios de criptomonedas). Alrededor de 10-20 operaciones tienen lugar por día (con buenas manos). Puedes contar contigo mismo;)
Pero no estamos dominando el código por dinero)
Una vez más, un enlace al github con la versión completa del bot y comentarios.
https://github.com/v-florinskiy/exmo-exchange-trade-bot
Este es mi primer artículo, no juzgues estrictamente)
Todas las ganancias.
PD: Para aquellos que no trabajaron con el nodo, su script funcionará naturalmente mientras la consola esté abierta.
Para que su robot funcione 24/7, necesita algún tipo de vps: allí coloca nodejs, npm y, por ejemplo, pm2. Con esta utilidad, el script continuará funcionando, incluso si la consola está cerrada.