Skip to content

Latest commit

 

History

History
573 lines (412 loc) · 24.8 KB

middleware_exchange_api.md

File metadata and controls

573 lines (412 loc) · 24.8 KB

Middleware Exchange API

Чтобы использовать торгового бота с другой биржей, необходимо написать промежуточное програмное обеспечение, которое сконвертирует данные из API биржи в API торгового бота.

  • В API используется 4 публичных и 6 приватных методов от биржи.
  • Публичных методы открыты и не имеют органичений на вызов.
  • Приватные методы доступны только с помощью api ключей биржи и имеют различные ограничения, а так же счетчик nonce.

Использование

Все Middleware API должны находиться в директории build/api и называться по названию биржи.

Параметры key, secret, delayRequestApi и т.д доступны из конструктора и передоваемого в него объекта conf. При необходимости можно использовать lodash.delay или lodash.throttle c параметром conf.delayRequestApi - задержка перед выполнением запроса.

Практически все параметры из переменного окружения заданы в camelCase и доступны в объекте conf.

Если вам нужно переопределить в боте параметры разработчика из объекта conf используйте свойство getConfig.

Название торговых пар должны быть в lowercase в формате btc_usd.

Для выбора вашего middleware api необходимо установить параметр переменного окружения EXCHANGE=название

Список методов API бота:

Public:

  • getInfo
  • getTicker
  • getTrades
  • getCandles (необязательный метод)

Private:

  • ordersRequest
  • balanceRequest
  • tradeSetOrder
  • tradeCancelOrder
  • tradeGetHistory
  • setNonce (Если ваш API не подразумевает ручного изменения nonce оставьте метод пустым)

Важно!

  1. Все методы должны принимать последним параметром callback.

  2. Все методы должны возвращать объект. Кроме метода balanceRequest. Он должен вернуть цифровые значения.

При ошибке, возвращается объект с ключом error в котором должно содержаться описание ошибки.

{
  success: 0
  error: 'description of the error'
}

Описание методов:

getInfo(callback)

Данный метод предоставляет всю информацию о текущих активных парах, такую как: максимальное количество знаков после запятой при торгах, минимальную цену, минимальное количество при покупке/продаже и комиссию по паре.

Пример ответа:
{
  "pairs":{
    "btc_usd": {
      "decimal_places": 3,
      "min_price": 0.1,
      "max_price": 100,
      "max_amount": 1000000
      "min_amount": 0.01,
      "fee": 0.2
      "amount_decimal_places": 8
    }
    ...
  }
}

Ключи: Название торговой пары.
decimal_places: Количество знаков после запятой разрешенные при торгах для цены.
min_price: Минимальная цена разрешенная при торгах.
max_price: Максимальная цена разрешенная при торгах.
max-amount: Максимальное количество разрешенное для покупки/продажи.
min_amount: Минимальное количество разрешенное для покупки/продажи.
fee: Комиссия пары. (Пользовательская комиссия доступна в параметре conf.exchangeFee)
amount_decimal_places: Количество знаков для объема

getTicker(pair, callback)

Данный метод предоставляет всю информацию о торгах по паре, такую как: максимальная цена, минимальная цена, средняя цена, объем торгов, объем торгов в валюте, последняя сделка, цена покупки и продажи.

Принимает параметры:
  • pair - Торговая пара или список пар разделенные через символ '-'. Например btc_usd или btc_usd-ltc_usd.
Пример ответа:
{
  "btc_usd": {
    "last": 101.773,
    "sell": 101.773,
    "buy": 101.9,
    "avg": 100.51,
    "vol": 1632898.2249,
    "vol_cur": 16541.51969,
  }
  ...
}

last: Цена последней сделки.
sell: Цена продажи (bid стакан).
buy: Цена покупки (ask стакан).
avg: Средняя цена.
vol: Объем торгов.
vol_cur: Объем торгов в валюте.

getTrades(pair, opt, callback)

Данный метод предоставляет информацию о последних сделках.

Принимает параметры:
  • pair - Торговая пара или список пар разделенные через символ '-'. Например btc_usd или btc_usd-ltc_usd.
  • opt - Объект дополнительных опций, с параметром limit - указывает, сколько сделок нужно вывести.

Сортировка по убыванию даты, т.е последние сделки сверху.

pair: string
opt {
 limit: number
}
Пример ответа:
{
  "btc_usd": [
    {
      "type": "ask",
      "price": 103.6,
      "amount": 0.101,
      "timestamp": 1370818007
    },
    {
      "type": "bid",
      "price": 103.989,
      "amount": 1.51414,
      "timestamp": 1370817960
    },
    ...
  ]
  ...
}

type: ask - продажа, bid - покупка.
price: Цена покупки/продажи.
amount: Количество купленного/проданного.
timestamp: UNIX time сделки.

ordersRequest(pair, callback)

Возращает список ваших активных ордеров.

Принимает параметры:
  • pair - Торговая пара. Например btc_usd.
Пример ответа:
{
  "343152": {
    "type": "sell",
    "amount": 12.345,
    "rate": 485,
    "timestamp_created": 1342448420,
  },
  ...
}

Ключи: Идентификатор ордера.
type: Тип ордера buy/sell.
amount: Сколько осталось купить/продать.
rate: Цена покупки/продажи.
timestamp_created: Время когда был создан ордер.

Если активных ордеров нет, вернуть ошибку:

{
  success: 0
  error: 'no orders'
}

balanceRequest(currency, callback)

Возвращает информацию о текущем балансе пользователя.

Принимает параметры:
  • currency - Объект торговой пары. Содержит параметры name, nameTwo и pair. Например:
currency {
  name: 'btc'
  nameTwo: 'usd'
  pair: 'btc_usd'
}
Пример ответа:
callback(err, balance.name, balance.nameTwo)

err: Объект ошибки, если есть. Если нет, то null
balance.name: Баланс первой валюты (Number)
balance.nameTwo: Баланс второй валюты (Number)

tradeSetOrder(opt, callback)

Основной метод используя который можно создавать ордера и торговать на бирже.

Принимает объект (opt) с параметрами:
  • pair - Торговая пара. Например btc_usd.
  • type - Тип операции, buy/sell.
  • rate - Курс по которому необходимо купить/продать (Number).
  • amount - Количество которое необходимо купить/продать (Number).
  • variety - Тип ордера ('grid-limit', 'stop-loss', 'stop-buy', 'manual-limit', 'profit-limit', 'profit-spo-limit', 'profit-trailing')
Пример ответа:
{
  "order_id": 123456789,
  "rate": 10,
  "amount": 100,
  "funds": {
    "usd": 325,
    "btc": 2.498,
  }
}

order_id: Идентификатор созданного ордера.
rate: Цена ордера. (Необязательный)
amount: Объем ордера. (Необязательный)
funds: Баланс после запроса.

tradeCancelOrder(opt, callback)

Метод предназначен для отмены ордера.

Принимает параметры:
  • opt - Объект дополнительных опций, с параметром order_id
opt {
 order_id: string or number
 currency: object { name: 'btc', nameTwo: 'usd', pair: 'btc_usd' }
}
Пример ответа:
{
  "order_id": 343154,
  "rate": 10,
  "amount": 100,
}

order_id: Идентификатор отмененного ордера.
rate: Цена ордера. (Необязательный*)
amount: Объем ордера. (Необязательный*)
  • Если rate и amount использовались в методе tradeSetOrder, то их нужно вернуть и в tradeCancelOrder

tradeGetHistory(pair, count, callback)

Возвращает историю сделок.

Важно:

  • Сортировка по возрастанию даты, т.е последние сделки снизу. (Можете использовать сортировку _.sortBy(obj, ['timestamp']))
  • Раздробленые части одного ордера по одной цене должны групироваться в один общий ордер.
  • Ключ является id ордера, а не сделки.
Принимает параметры:
  • pair - Пара, по которой выводить сделки.
  • count - Количество сделок на вывод.
Пример ответа:
{
  "166830": {
    "id": 166830
    "type": "sell",
    "amount": 1,
    "rate": 450,
    "timestamp": 1342445793
  },
  ...
}

id: Идентификатор ордера.
type: Тип сделки, buy/sell.
amount: Количество купленного/проданного.
rate: Цена покупки/продажи.
timestamp: UNIX time сделки.

getCandles(pair, periods, after, callback)

Возвращает историю свечей.

Важно:

  • Сортировка по возрастанию даты, т.е последние сделки снизу.

  • Если метод нет возможности реализовать, то возвращается пустой массив.

    API.prototype.getCandles = function(pair, periods, after, cbk){
      return cbk(null, []);
    };
    
Принимает параметры:
  • pair - торговая пара.
  • periods - Период свечи в секундах. Варианты значений 60, 180, 300, 900 и т.д.
  • after - UNIX timestamp метка с какого времени необходимо начать отсчет свечей.
Пример ответа:
[
  [timestamp, open, high, low, close],
  [152828460000, 7648.4, 7659.5, 7648.1, 7655.3]
]

timestamp: UNIX time сделки. (в милисекундах)
open: Цена открытия.
high: Цена максимума.
low: Цена минимума
close: Цена закрытия

Обработка значений Nonce

Чтобы бот автоматически обновил nonce, если nonce по какой-то причине стало больше ожидаемого числа, необходимо в любом методе в тексте ошибки в конце предложения добавить строку: send:123456, где 123456 новое валидное значение nonce. Пример ошибки:

{
  success: 0
  error: 'nonce invalid. send:123456'
}

Для обновления nonce используется метод setNonce.

setNonce(nonce)

Данный метод может быть пустым. Если ваше Middleware API не поддерживает принудительное обновление nonce.

Принудительное обновление nonce.

Принимает параметры:
  • nonce - Идентификатор nonce
Пример ответа:

Метод ни чего не возвращает.

Telegram внутри api

setTelegram(msg, cbk-send-telegram)

Метод может использоваться когда необходимо обработать какую-то специфичную команду для вашего api, например для вашего DEBUG.

Чтобы отправить сообщение в этот метод необходимо в чате Telegram отправить боту сообщение с командой: /api ваш текст

Принимает параметры:
  • msg - текст сообщения из Telegram.
  • cbk-send-telegram - колбек, метод отправки обратно сообщения в Telegram. (Может ни чего не возвращать если вам не нужно отправлять обратно сообщение).

cbk-send-telegram имеет параметры text и opt (см. sendMessage в api telegram)(необязательный параметр).

Важно:

  • Если этот метод вам не нужен просто игнорируйте его описание.

isInspectCache(cacheOrders)

Метод вызывается каждый раз при проверки исполненных ордеров в стратегиях One Orders.

Метод принимает параметр cacheOrders, в котором содержится кеш ордеров.

Важно:

  • Если этот метод вам не нужен просто игнорируйте его описание.

isExecutedProfit(cbk-send-telegram)

Метод вызывается каждый раз при исполнении профитного ордера в стратегии One Orders.

Метод принимает параметр cbk-send-telegram - колбек, метод отправки обратно сообщения в Telegram.

Важно:

  • Если этот метод вам не нужен просто игнорируйте его описание.

Пример Middleware

module.paths = module.parent.paths;          
var exchangeApi = require('exchange-api');    - библиотека api биржи (если данное Middleware API не является самим API)

var _ = require('lodash');                    - дополнительные библиотеки (если нужны)
var moment = require('moment');
var Promise = require('bluebird');

API = (function(){
    API.displayName = 'API';
    var constructor = API;
    function API(conf) {                                            - конструктор с параметрами conf (конфиг. файл приложения)
      constructor.Exchange = new exchangeApi.api(conf.key, conf.secret);
      constructor.delayRequestApi = conf.delayRequestApi;
    }
    
    API.prototype.getConfig = {                                     - если нужно переопределить параметры разработчика из conf
      directionInverse: false,                                        укажите их значение здесь.
      isOrderCalculationBtc: false,                                   Новые параметры будут возвращены боту.
      roundMethod: 'rounded'
    };
    
    API.prototype.getInfo = function(callback) {                    - Метод Middleware API
    
      return constructor.Exchange.Info().then(function(data) {      - Метод API биржи.
        
        обработка данных data
        (Здесь вы производите конвертацию данных из API биржи в API бота)
        
        ...
        
        return callback(null, data);
        
      })['catch'](function(err){
        
        обработка ошибки err
        
        ...
      
        return callback(err);
      });
    
    };
    
    API.prototype.getTicker = function(pair, callback){};
   
    API.prototype.getTrades = function(pair, opt, callback){};
   
    API.prototype.balanceRequest = function(currency, callback){};
   
    API.prototype.ordersRequest = function(pair, callback){};
   
    API.prototype.tradeSetOrder = function(opt, callback){
        var pair, type, rate, amount, variety;
        pair = opt.pair;
        type = opt.type; 
        rate = opt.rate; 
        amount = opt.amount; 
        variety = opt.variety;
    };
    
    API.prototype.tradeCancelOrder = function(opt, callback){};
    
    API.prototype.tradeGetHistory = function(pair, count, callback){
        ....
        callback(null, _.sortBy(obj, ['timestamp']))
    };
    API.prototype.getCandles = function(pair, periods, after, cbk){
      return cbk(null, []);
    };
    
    API.prototype.setNonce = function(nonce){};
    API.prototype.setTelegram = function(msq, cbkSendTelegram){};
    
    return API;
}());
module.exports = API;

Дополнительная информация

1. Про инвертированные пары

Все биржи по разному используют расположение базовой валюты в названии торговой пары, а так же отдают данные в разных вариантах.

Для примера, возьмем базовую валюту BTC.

Биржа Wex использует прямое название торговых пар, т.е базовая валюта стоит первой, например btc_usd.

Биржа Poloniex использует обратное название торговых пар, т.е базовая валюта стоит в конце, например usdt_btc. И все оперерации по торгам проверяются по btc объему не зависимо от пары.

Правильное определение базовой валюты важно для внутренних расчетов. По этому для указания какой вариант на бирже, используется параметр переменного окружения DIRECTION_CURRENCY_INVERSE. Данный параметр переключает алгоритм расчета баланса, резерва депозита и т.д.

Для прямых пар параметр не задавать, для обратных пар его значение равно DIRECTION_CURRENCY_INVERSE=true.

Например:

  • чтобы посчитать общий депозит при прямых торговых парах: (balanceTwo / price) + balance.
  • для инвертированной торговой пары расчет будет уже: (balanceTwo * price) + balance.
  • если минимальный объем ордера должен быть эквивалентен минимальному объему btc указаному на бирже (0.001). Т.е, если у вас валюта Coin стоит 0.000041 btc, минимальный объем ордера в этой валюте будет 0.001 / 0.000041 = 24.39

2. Про расчет размера минимального ордера

Если при расчетах размера ордера необходимо учитывать эквивалентный размер в BTC используйте параметр IS_ORDER_CALCULATION_BTC (этот параметр НЕ работает с фиатными парами, т.е BTC/USD(t), LTC/USD(t) и т.д).

Если не нужно ограничение только для фиатных пар, тогда используйте IS_ORDER_CALCULATION_CURRENCY.

При использовании этих параметров расчет минимального размера ордера будет по формуле MINIMUM_ORDER_SIZE / price.

Важно

  • Одновременно использовать IS_ORDER_CALCULATION_BTC и IS_ORDER_CALCULATION_CURRENCY нельзя!
  • Приоритет параметров (в порядке уменьшения): IS_ORDER_CALCULATION_CURRENCY -> IS_ORDER_CALCULATION_BTC -> min_amount.
  • Если эти параметры не заданы тогда используется статический размер минимального ордера min_amount.

3. Про округление

Если биржа использует нестандартную длину числа в объеме ордера используйте параметр AMOUNT_DECIMAL_PLACES (для всех пар), либо же укажите нужное ограничение в методе getInfo для каждой валютной пары.

Параметр ROUND_METHOD. По умолчанию округление происходит стандартным методом rounded, который откругляет число до указаного количества знаков при этом если последняя цифра в числе больше 5 то округляется вверх, если меньше то вниз.

Если нужно не округлять число, а просто обрезать его до нужного числа знаков, то используется тип truncate.

4. Данные параметры зависят от биржи.

Важно!

  • Если параметры определены в getConfig то они будут в приоритете над переменным окружением и пользователь не сможет их изменить.
  • getConfig вызывается после вызова getInfo

Option Description Default
DIRECTION_CURRENCY_INVERSE Флаг инвертированной валюты false
IS_ORDER_CALCULATION_BTC Учитывать при расчете размера ордера его сумму в btc (только для btc пар)
Например для poloniex, bittrex, liqui - true
false
IS_ORDER_CALCULATION_CURRENCY Учитывать при расчете размера ордера его сумму для любой валюты false
MINIMUM_ORDER_SIZE Минимально допустимый размер ордера 0.001
AMOUNT_DECIMAL_PLACES Количество знаков после запятой разрешенные при торгах для объема в ордере 8
PRICE_DECIMAL_PLACES Количество знаков разрешенных в цене 8
ROUND_METHOD Тип округления rounded, gauss, truncate rounded
SUBTRACT_AMOUNT_ORDERS Объем который необходимо вычисть из финальной суммы ордера 0.0000001

5. События

События позволяют управлять определенными жизненными циклами бота.

Чтобы использовать события Gbot не обходими импортировать файл utils в ваше api.

Для вызова событий используется команда utils.gBotEvents.emit(event, [params])

Event Description Params
gbot-save-state Сохраняет текущие состояние в фаил -
cmd-close-orders Закрыть ордера
Параметр 'reopen' переоткроет сетку ордеров.
Остальные параметры закроют ордера и бот встанет на паузу
'all', 'reopen', 'grid'