Pull to refresh

Моя реализация Java библиотеки для биржи BTC-e

Reading time 5 min
Views 15K
После начала торговли на BTC-e я заметил довольно удачное API. Его возможности вполне можно направить на благое дело. А именно — на создание торговых ботов и мобильные клиенты. Про ботов понятно, а вот клиент под Android понадобился довольно скоро, но на маркете тогда их вообще не нашлось. А когда библиотека была дописана (да да, кода в ней мало, но получился долгострой), приложения хоть и появились, но были все равно какие-то не такие. Итак, если вам интересно узнать, что же у меня получилось и насколько это может быть полезно вам — прошу под кат.

Перед написанием я поставил перед собой ряд задач, а именно:
  • реализовать в библиотеке все возможности api;
  • название методов и возвращаемые значения должны точно соответствовать методам из официальной документации;
  • сделать её удобной для модификации, в том числе другими людьми;
  • возвращаемые значения должны быть, по возможности, готовыми к употреблению;
  • добавить дополнительную функциональность, основанную на методах api;
  • сделать её совместимой с Andoid.

Для хостинга был выбран GitHub, ссылки вы можете найти в конце статьи.

Размышления о том, как все это скомпоновать привели к следующей иерархии классов:

image

Две основные группы классов, это PrivateBaseClass и PublicBaseClass, для приватного и публичного раздела api, соответственно. PrivateBaseClass разделен на методы, возвращающие итерируемые результаты и неитерируемые. В их основе лежит CommonClass, содержащий общие для всех вещи. Private Network служит для работы с ключами при отправке приватных запросов, а так же шифровки в 3DES, для хранения на устройстве. StringCrypter ему в этом как раз и помогает. А завершает композицию класс TradeApi, вобравший в себя все их возможности и служащий точкой взаимодействия с пользователем. Правда, никто не запрещает использовать отдельно классы вродe Ticker или Info, если кроме их функциональности вам больше ничего и не нужно.
Для работы с json была выбрана Jackson library, а для всего остального Apache Commons Codec.
А теперь на примере, что же из всего этого получилось и как с этим бороться этим пользоваться.
Алгоритм будет примерно следующим: выбираем из официальной документации нужный нам метод, устанавливаем ему параметры, запускаем, получаем результаты.
Самое первое что вам, возможно, захочется — узнать цены любимых пар. И сделать это будет довольно просто:

TradeApi tradeApi = new TradeApi();
tradeApi.ticker.addPair("btc_usd");//добавляем пары
tradeApi.ticker.addPair("ltc_usd");
tradeApi.ticker.addPair("nmc_usd");
tradeApi.ticker.runMethod();//запускаем метод
while (tradeApi.ticker.hasNextPair()) {//если есть следующая пара
	tradeApi.ticker.switchNextPair();//переключаемся на следующую пару
	System.out.println(tradeApi.ticker.getCurrentLast());//выводим на экран
}

Результатом будет:
368.98
4.216
1.02

Следующим на очереди у нас будет получение баланса, ключи можно взять в личном кабинете (эти, естественно, не валидны):

String aKey = "TK8HD88A-ENLZZBCW-P4L5JYVR-18K9NZZP-CYQ7WKKH";//API-ключ
String aSecret = "b7738a9f4d62da1b6ebdcd7ff2d7b5ddb93de88b71f017ae600b7ab3ed5b7015";//SECRET
TradeApi tradeApi = new TradeApi(aKey,aSecret);//передаем их конструктору
tradeApi.getInfo.runMethod();//запускаем метод, который возвращает нужную информацию
System.out.println(tradeApi.getInfo.getBalance("usd"));//выводим долларовый баланс на экран

Результатом будет:
0.25

В случае, если вы не хотите в своей конечной реализации вводить ключи каждый раз, но и хранить в открытом виде их тоже не хотите, возможно использовать встроенное шифрование. Код будет тем же за исключением передачи ключей. В этом случае конструктору нужно будет передать зашифрованный api-ключ, секрет а так же пароль для их расшифровки:

String aKey = "TK8HD88A-ENLZZBCW-P4L5JYVR-18K9NZZP-CYQ7WKKH";//API-ключ
String aSecret = "b7738a9f4d62da1b6ebdcd7ff2d7b5ddb93de88b71f017ae600b7ab3ed5b7015";//SECRET
String password = "12345";// пароль
String encryptedKey = tradeApi.encodeString(aKey, password);// шифруем ключ
String encryptedSecret = tradeApi.encodeString(aSecret, password);// шифруем секрет
tradeApi.setKeys(encryptedKey, encryptedSecret, password);//передаем конструктору зашифрованные ключ, секрет и пароль для их расшифровки

В случае если пароль неверен, будет выброшено исключение. В случае если были установлены валидные ключ и секрет, но после была попытка установить зашифрованные ключи с неправильным паролем, исключение будет так же выброшено, но прежние ключи останутся работать дальше.

А теперь, возможно, самое интересное: дополнительные фичи, созданные с помощью официального API.
Начнем с торговли. Кроме родного метода Trade, описанного в документации, мною был добавлен метод немного умнее. В нем используются сразу два метода: Trade и Info. Он автоматически округляет цену до допустимых пределов и выбрасывает исключения с разными сообщениями для быстрой диагностики причины ошибки:

String aKey = "TK8HD88A-ENLZZBCW-P4L5JYVR-18K9NZZP-CYQ7WKKH";//API-ключ
String aSecret = "b7738a9f4d62da1b6ebdcd7ff2d7b5ddb93de88b71f017ae600b7ab3ed5b7015";//SECRET
TradeApi tradeApi = new TradeApi(aKey,aSecret);//передаем их конструктору
Trade trade = tradeApi.extendedTrade("btc_usd", false, "600", "0.01");//false - продажа, true - покупка :)
if (trade.isSuccess()){
		System.out.println(trade.getReceived());//выводим полученное
}

Результат: 0
то есть мы ничего не получили т. к. продать сейчас 0.01 биткоина за 600 долларов на момент написания статьи было нельзя.

Следующий на очереди приятный для использования во всяческих будильниках метод priceDifference:

TradeApi tradeApi = new TradeApi();
for (int i = 0; i < 3; i++) {
	System.out.println(tradeApi.priceDifference("btc-usd", 600.0, 10000));
}

Результат:
233.39
233.39
233.103

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

А напоследок остаются tryMaximumBuy(String pairName, long reuseAgeMillis) и tryMaximumSell(String pairName). Наиболее интересен из этих двоих метод tryMaximumBuy. Он пытается выполнить максимально возможную покупку валюты по выбранной паре. Вторым параметром является время, через которое данные, используемые в методе, считаются устаревшими и подлежат обновлению. Показать пример работы, к сожалению не смогу, по причине того что это будет не бесплатно для меня.
Разумеется, на этом возможности данной бибилиотеки не ограничены и, возможно, вы найдете в ней ещё какие-то полезные мелочи для себя, например, округление чисел до выбранного знака после запятой, полезно при работе с количеством и ценами при покупке. С библиотекой вы так же можете скачать Javadoc, описывающий многие методы.

В заключение надеюсь, что эта библиотека окажется вам полезна и послужит дальнейшему развитию криптовалютного сообщества, а так же снимет проблему поддержания вашего набора классов для работы с API биржи в актуальном состоянии т.к. этим буду заниматься я.

Обещанные в начале статьи ссылки


Ссылка на репозиторий с библиотекой: github.com/alexandersjn/btc_e_assist_api
Ссылка на документацию по приватной части API: btc-e.com/tapi/docs#Trade
Ссылка на документацию по публичной части API: btc-e.com/api/3/docs
Так же в качестве примера использования, вы можете найти ссылку на мой андроид клиент для btc-e в описании репозитория библиотеки. Его исходный код вы тоже найдете в моём репозитории.

Благодарю за внимание.
Tags:
Hubs:
+21
Comments 9
Comments Comments 9

Articles