A simple bot for trading on cryptoburge
Hello! Today we will write our first live trading trading robot. Cryptobirge. Why cryptobirge?
a) HYIP theme;
b) they somehow everything is easier.
First, I want to immediately warn casino lovers "three axes": tomorrow you will not earn a car. The article is more about how to start writing your robots, so the algorithm will be primitive, but working.
Secondly, you will earn. Just a little.
— Этот запах, что это? Чем пахнет?
— Одеколоном?
— Нет…
— Возможностями?
— Нет. Деньгами.
— Оу….всё ясно
— Запах денег!
— Понятно.
For the most impatient, all the code on the exmo-exchange-trade-bot githaba .
Stage number 1: Exchange.
We will trade on the EXMO exchange. There are several reasons. The exchange is popular in the CIS, it is Russian-speaking and supports the input of rubles, it has the ability to create pairs to the ruble.
Among the downsides is the awkward process of entering rubles, a decent commission, few pairs of bargaining.
The main thing for us is that it has ready solutions for working with their API. This will certainly facilitate our work.
So let's get started.
Of course, on the stock exchange you need to register and make some money. For example, I made $ 5.
Further in your personal account you will receive the keys to access the API.
I will use the client for NodeJS (so I need to install nodejs and npm).
On your computer we create a new folder and a file in which our trading robot will be (for example, exmo / index.js), open the console and make the last standard preparations.
Go to the folder with our project and write - npm init, then all questions press the enter key.
Next, write
npm install exmo-api
While the packages are being installed, let's create another file, call it exmo.js and fill it with these contents.
var CryptoJS = require("crypto-js")
http = require('http'),
querystring = require('querystring'),
request = require('request'),
config = {
url: 'https://api.exmo.me/v1/'
};
functionsign(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(){
returnconfig.key;
};
This file contains the address of the API, the connection of additional libraries that we need to work with the API and the main function for requests to the API.
Everything, we have all prepared and now we can proceed directly to creating a personal “money making machine”;)
Stage 2: Code
Open our index.js and connect the exmo.js file:
const exmo = require("./exmo");
Next, go to the exchange in your account where we created our keys to access the api. Copy them and save in variables:
const apiKey = ‘ВАШ ключ’;
const apiSecret = ‘Ваш секрет’;
Now we will create two variables:
currency1 is WHAT we buy;
currency2 - the currency for which we buy.
I want to buy bitcoins for dollars:
const currency1 = 'BTC';
const currency2 = 'USD';
Next important point - we create a variable with a minimum amount of the bet. The exchange does not allow to buy less than this amount.
Go to https://api.exmo.com/v1/pair_settings/ looking for your pair (for me this is BTC_USD) and look at the first parameter - min_quantity - 0.001
const currency1MinQuantity = 0.001;
And a few more variables:
the number of minutes after which the unfulfilled purchase order will be canceled currency1
const orderLifeTime = 3;
exchange commission (0.002 = 0.2%)
const stockFee = 0.002;
period of time (in minutes) to calculate the average price (this will be needed for our algorithm)
const avgPricePeriod = 1;
the amount of currency2 for the purchase of currency1 in a one-time transaction (I threw $ 5 - and I will operate with them)
const canSpend = 5;
the desired amount of profit from each transaction (0.001 = 0.1%)
const profit = 0.001;
If the time of the exchange diverges from the current
const stockTimeOffset = 0;
For convenience, we combine our pair in _
let currentPair = currency1+'_'+currency2;
Initialize the connection.
exmo.init_exmo({key:apiKey, secret:apiSecret});
For the test, you can request information about yourself:
exmo.api_query("user_info", { }, result => console.log(result););
Go to the console and run
node index.js
If everything is done correctly, you will see information on you!
Everything works and you can proceed to the most interesting part - the function that will generate the headstock for us.
So, I have already said above that our algorithm will be stupid, now you will understand how much)
The trick is to take the history of completed deals for any period - we have the avgPricePeriod variable responsible for this - and calculate the average price for which currency1 was sold. For this average price we will place our order.
So let's get started. We write our trade () function
functiontrade(){}
First we get a list of our open orders:
1) we check if we have open orders for our pair using the user_open_orders api-method. If there are they for sale,
then we just wait for them to be fulfilled (sometimes until the end of ages). If there are purchase orders, just remember them.
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) Check if we have open buy orders.
We loop through all the orders and get the history for them using the order_trades method , passing the order id there.
There may be 3 options:
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) we can buy the necessary currency not entirely, but in parts from the orders of sellers.
Therefore, if we have already bought at the desired price, then we are waiting for we to purchase the full amount.
if(res.result !== false){
console.log('Выход, продолжаем надеяться докупить валюту по тому курсу, по которому уже купили часть');
}
2) with the second option, we need to check if our order hangs too long. Prices change quickly and perhaps the average price is no longer relevant. To do this, we have entered the orderLifeTime variable, where we indicate how much our order should hang in minutes.
If the time is out, then we cancel the order using the order_cancel method , passing it the order ID.
let timePassed = (newDate().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) if the time has not yet come out, then we just hope that we can buy at our price.
console.log(`Выход, продолжаем надеяться купить валюту по указанному ранее курсу, со времени создания ордера прошло ${timePassed} секунд`);
}
}
});
}
}else{
Everything, with open orders, we figured out, now our robot knows what to do with orders when it creates them. Half done.
So, block if we have no orders.
We get information on our account using the user_info method :
exmo.api_query('user_info',{},(result)=>{
let res = JSON.parse(result);
For convenience, we write the balance for our pairs:
let balance = res.balances[currency1];
let balance2 = res.balances[currency2];
Check if there is a currency1 that you can sell?
if(balance >= currency1MinQuantity){}
If yes, we need to calculate the selling rate.
You need to sell all the currency you bought, for the amount you bought plus the profit minus the exchange commission.
An important point! We have less currency than we bought - the exchange took a commission.
let wannaGet = canSpend + canSpend * (stockFee+profit);
console.log('sell', balance, wannaGet, (wannaGet/balance));
When creating orders, the order_create method must pass parameters:
- pair is our current trading pair;
- quantity - quantity;
- price - price;
- type - type of order being created (buy / sell);
We want to sell - we specify sell in the type .
let options = {
"pair": currentPair,
"quantity": balance,
"price": wannaGet / balance,
"type": 'sell'
};
and send the request, if everything is correct, then you will see the entry "A sell order is created"
exmo.api_query("order_create", options,(result)=>{
if(result.error) console.log(result.error);
console.log("Создан ордер на продажу", currency1, result.order_id);
});
Everybody is here. If we had a currency, we simply created an order to sell it.
Now we come to the most interesting block: the case if we do not have currency1 (btc) and we want to buy it for our currency2 (usd).
First we will check if there is enough money on the balance in currency currency2.
if(balance2 >= canSpend){}
If there is, then we need to get the average price for which currency1 (btc) is sold for the period of time that we specified in avgPricePeriod .
Some lyrics:
Exmo has a ticker method with statistics and trading volumes for currency pairs. The statistics show the average price for the last 24 hours. However, the difference between the average price and the one for which the bidding is going on now can be very different.
Because of this, we can wait for a long time to get a sell order.
We will make your bike.
Exmo has a trades method , it returns a list of deals for a currency pair.
We will take the deals made for avgPricePeriod of interest to us and from them we will calculate the average price.
This is not ideal, but it will show the real prices at which they sell and buy.
For example, at the time of writing, the average price is BTC_USD - 8314, while buying on the stock exchange is carried out at a price of 7970.
If we place an order at an average price, it will immediately be executed at the minimum price listed in the sell orders.
But having added profit and the exchange commission we, most likely, will wait very long for sale.
So, let's turn to the trades method and request statistics on our currentPair pair :
exmo.api_query("trades",{"pair":currentPair}, result => {
let res = JSON.parse(result);
let prices = [];
let summ = 0;
Let's look through all the results and leave only those that fit our time period.
for(deal in res[currentPair]){
let timePassed = (newDate().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));
}
}
And calculate the average price.
let avgPrice = summ2 / prices.length;
We have the average price, but we need to correct it a bit - deduct the stockFee exchange commission and add the desired profit. Thus, having received the price below the average price of the market, we will buy a bit more currency, since the exchange subsequently takes its part;
let needPrice = avgPrice - avgPrice * (stockFee + profit);
We get the final amount we need to buy.
let ammount = canSpend / needPrice;
console.log('Buy', ammount, needPrice);
Check whether you can buy that amount of currency (if the minimum amount of the purchase is not violated).
if(ammount >= currency1MinQuantity){}
If our amount is larger, then we form the parameters for the order_create method , only this time with the type buy .
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('Выход, не хватает денег');
}
Now we need to put our function on the timer (range - once every 5 seconds, for example) and we can start.
var timerId = setTimeout(function tick() {
trade();
timerId = setTimeout(tick, 5000);
}, 5000);
node index.js
Congratulations, you wrote your first trading robot: you can finish the algorithm and make lots of money) just kidding.
I think you have a reasonable question: "How much money can you earn?"
For one operation with $ 5, I earn about 2-3 cents. This is due to the primitiveness of the algorithm, which works in case the price fluctuates in a certain range (and this is almost always not the case with cryptobirds). During the day, there are about 10-20 operations (with good hands). You can calculate yourself;)
But we are not making a code for money)
Once again the link to the githab with the full version of the bot and comments.
https://github.com/v-florinskiy/exmo-exchange-trade-bot
This is my first article - do not judge strictly)
All profit.
PS: For those who did not work with node, your script will naturally work while the console is open.
For your robot to work 24/7, you need some vps: there you put nodejs, npm and, for example, pm2. Using this utility, the script will continue to work, even if the console is closed.