В этой статье я покажу вам, как работает программа Qt Bitcoin Trader, и поведаю историю ее разработки.
Эта программа с открытым исходным кодом позволяет быстро делать ставки на Mt.Gox, и задавать правила для автоматической торговли.
Написана она на чистом Qt 4 с использованием OpenSSL, и, по моему мнению, в ней есть интересные особенности со стороны разработки, о которых тоже хочу рассказать.
Предыстория
Во время апрельских скачков курса Bitcoin я, и мой друг Dybik, как и многие на хабре, заинтересовались этой замечательной криптовалютой. Мы, как и, думаю, множество из тех кто читает эту статью, решили попробовать себя на бирже. Как оказалось, самой популярной биржей для торговли Bitcoin является Mt.Gox. Мы зарегистрировались там и начали делать первые ставки.
Курс постоянно рос, ажиотаж нарастал. Весь интернет гудел об этом, и помню, даже по телевизору тогда говорили о Bitcoin. Мы торговали на сайте Mt.Gox, и сайт часто подлагивал. Раздражало когда выставишь ордера, а отменить не получается. Вернее, получается, но кнопка «cancel» не давала никаких подтверждений и откликов. Было непонятно, отменился ордер или нет.
Уже тогда я подумал: «А почему нет на сайте возможности задать правила для создания ордеров?». Круглосуточно следить за курсом нельзя, было бы хорошо оставить правила на ночь. Искал программы и находил python боты и какие-то непонятные мне тогда платные клиенты для десктопа. «Редактировать файл, чтобы подправить правило? Это же неудобно», — подумал я. Нужна программа, которая не позволит сделать механических ошибок, пропустить ноль или запятую.
Курс постоянно прыгал, и мы успевали выгодно покупать и продавать. Я пытался получить выгоду на мелких скачках. В логе ордеров Mt.Gox ясно отображался отдельный пункт суммой налога на покупку, но не было пункта для продажи. «Налог только на покупку», — подумал я. А когда посчитал, то понял, что проигрываю. Налог на продажу тоже есть, он встроен в сумму. По-моему, логичнее было бы делать одинаково отображение налога и для продажи и для покупки. Но, может, Mt.Gox специально хочет нас запутать? Не знаю. Выяснил это и начал дальше торговать.
Получилась хорошая сумма и мы поняли, что не зря потратили столько времени. А дальше, ну, вы и сами помните, дальше настал полный крах курса и мы тоже попали под удар. Сайт зависал, продать Bitcoin было невозможно, а потом Mt.Gox вовсе заморозил торги на сутки. Курс стремительно упал. Так я проиграл половину вложенной суммы.
Что дальше делать? Сдаться и вывести остаток суммы? Я не на минуту не сомневался и начал думать о стратегии, она не выходила у меня из головы. Искать боты на python? Нет, мне стало интересно реализовать что-то свое. Когда только начал торговать на Mt.Gox, у меня перед глазами уже была простая программа, которую я не мог нигде найти и тогда я приступил к разработке Qt Bitcoin Trader.
Встречайте — Qt Bitcoin Trader
После первого запуска вас встретит окно создания профиля.
Надо получить API ключ с параметрами Info и Trade, вести его в программу, далее — придумать надежный пароль.
Все данные сохраняются в папке профиля пользователя, зашифрованные c помощью OpenSSL шифрованием AES256.
В окне логина можете включить проверку обновлений.
Для пользователей Mac и Windows есть автоматическое обновление.
Проверка новых версий проводится по загрузке файла с GitHub, в котором сохранена контрольная сумма бинарного файла, зашифрованного с помощью RSA2048. Поэтому, нет риска подмены файла вредоносным.
Когда выйдет новая версия, то вы увидите такое окно:
Интерфейс я старался разработать простым, и так, чтобы все было на виду. Не в обиду пользователям с низкими разрешениями экранов, но оптимизировать интерфейс для них буду позже.
Слева вы видите список открытых ордеров, обновляющихся в реальном времени.
Вы можете создавать ордера на покупку и на продажу, но, чтобы сумма их не превышала ваш баланс. С недавних пор Mt.Gox сразу удаляет ордера, которые превышают баланс.
Наконец-то можно отменить ордер, и сразу видеть его статус «Отменен», даже если он еще висит на сайте, API получает подтверждение доставки.
Все данные маркета обновляются одним запросом, кроме последней цены. Она обновляется еще и из цен последних сделок.
Калькулятор налога доступен по маленькой кнопке слева вверху. Мне приходили отзывы, и я сделал его таким, какой привыкли использовать пользователи онлайн калькуляторов.
Он работает так же, за исключением того, что автоматически загружается баланс и последние цены, что есть удобно.
Вы можете открыть сколько угодно калькуляторов на свое усмотрение.
Между групбоксами покупки и продажи есть два поля.
Если вы хотите купить Bitcoin, заполните левый групбокс, а потом заполните правый по той цене, за которую хотите продать. И в верхнем групбоксе вы увидите чистый доход с учетом налогов.
В нижнем групбоксе наоборот. Если вы сначала продаете, а потом покупаете, то он вычисляет доход в другую сторону — в Bitcoin.
Так же вы можете указать точную сумму дохода, которую хотите получить и нажать кнопку «Применить», тогда в следующем групбоксе вы получите рассчитанную цену, по которой нужно продать или купить Bitcoin.
Вы можете легко создать правило для автоматического создания ордеров:
Сейчас вы можете создавать правила в двух режимах: «По очереди» и в «Параллельном».
В параллельном режиме, при изменении значений, проверяются на сходство все правила, и любое из них может быть исполнено. В режиме «По очереди» вторая строка правила будет проверяться только, если исполнена первая. Вы можете менять порядок правил и редактировать их.
Для некоторых значений есть звуковое оповещение. Значок динамика — это кнопка-выключатель.
Для Windows пользователей есть возможность включить портабельный режим. Надо создать папку QtBitcoinTrader в той же папке что exe файл, и все зашифрованные данные будут сохраняться в ней.
Что ожидается в следующих версиях Qt Bitcoin Trader?
В первую очередь, поддержка других бирж. По возможности свободного времени, я доделаю поддержку самых популярных бирж по очереди.
Возможно работа websocket api и http api одновременно.
Далее — отображение графиков в реальном времени. Возможность отцеплять групбоксы, делая их отдельными окнами, что будет несомненно удобно с использованием нескольких мониторов.
Будет реализована возможность добавления API разных бирж и разных валют в один профиль, для одновременного мониторинга.
Скриптовый язык, как дополнение правил, которым можно будет в несколько строк написать стратегию анализирующую цены на разных биржах.
Как вы мне можете помочь в усовершенствовании Qt Bitcoin Trader?
На данный момент программа переведена на английский, русский, украинский, испанский, голландский и норвежский языки.
Вы можете помочь перевести программу на свой родной язык. В программе присутствует встроенный движок-переводчик. Нажмите кнопку «О программе», и вы увидите инструкцию:
Нажмете кнопку «Перевести программу», и увидите диалог:
Здесь есть все поля, которые надо перевести. Поля с красным текстом — это поля, совпадающие с английским переводом.
По нажатию кнопки «Применить», вы сразу увидите свой перевод в программе и сможете подкорректировать слишком длинные тексты. Когда вы закончите перевод, сохраните файл и пришлите на электронный адрес, указанный в инструкции. После проверки перевода я добавлю его в следующую версию Qt Bitcoin Trader.
И не забудьте оставить свою контактную информацию и адрес Bitcoin для донейтов в поле «Переводчик:».
Также вы можете помочь в развитии программы материально, поскольку программа живет только на донейтах.
Адрес Bitcoin для поддержки: 1d6iMwjjNo8ZGYeJBZKXgcgVk9o7fXcjc
Официальные ресурсы Qt Bitcoin Trader
Скачать для Windows и Mac (SourceForge.net)
Скачать с Softpedia для Windows
Скачать с Softpedia для Mac
BitcoinTalk RUS Форум
BitcoinTalk ENG Форум
BtcSec Форум
Фишинг
Как только моя программа появилась в интернете, сразу начали появляться дубликаты с описанием моей программы.
Но, вместо ссылок на скачку Qt Bitcoin Trader предлагается скачать вирус. Я был удивлен, почему так много фейков Qt Bitcoin Trader в интернете. И даже qtbitcointrader dоt com — это фейк с ссылкой на вирус. Если бы знал, что программа будет так популярна, то сразу бы купил этот домен. Думаю, это урок для меня и для всех, кто читает эту статью.
Будьте внимательны, если не знаете, надежная ли ссылка, то гуглите по названию.
Я рекомендую использовать встроенное в программу безопасное обновление.
Особенности разработки Qt Bitcoin Trader
Механизм встроенного переводчика
Может, вы задаетесь вопросом, почему я не выбрал для перевода программы стандартный Qt Linguist?
Мне он не нравится, может и удобно редактировать форму, но, чтобы перевести файл, нужен сам Qt Linguist, а он есть, наверное, только у 5% всех пользователей программы.
Поэтому, я решил написать свой движок, и сделать его удобным не только для разработчиков, но и для всех пользователей программы.
Можете посмотреть исходники класса JulyTranslator на GitHub. Это базовый класс, в котором сохраняются все ассоциации слов в QHash. Этот класс умеет загружать и сохранять файлы перевода, а так же переводить отдельные объекты интерфейса и загружать текст из интерфейса в файл.
Каждому объекту интерфейса, который должен переводиться, я задаю уникальный текстовый идентификатор через setAccessibleName().
Функция translateUi(QWidget *parent) класса JulyTranslator обходит все дочерние виджеты родителя из параметра функции. Каждому виджету, который надо перевести, само собой надо вызывать translateUi() в конструкторе или по сигналу.
Например, обходим все кнопки QPushButton, проверяем, есть ли значение accessibleName(), и, если да, то достаем ассоциацию этого значения из QHash класса JulyTranslator
foreach(QPushButton* curButton, par->findChildren<QPushButton*>())
if(!curButton->accessibleName().isEmpty())
curButton->setText(translateButton(curButton->accessibleName(),curButton->text()));
Получился класс, который загружает язык из файла и применяет его в интерфейс.
Поскольку мне не всегда нравится, как работает QLayout, то, после применения перевода, я прохожусь по каждому виджету, вычисляю минимальный размер, чтобы обеспечить подобающий вид виджета, и задаю ему минимальную ширину.
Пример для кнопки:
foreach(QPushButton* pushButtons, par->findChildren<QPushButton*>())
pushButtons->setMinimumWidth(qMin(pushButtons->maximumWidth(),QFontMetrics(pushButtons->font()).width(pushButtons->text())+10));
В результате, мы экономим место в интерфейсе, и при этом тексты не выходят за виджеты.
Второй этап — сделать создание перевода удобным для пользователей.
Класс TranslationDialog предназначен для генерации списка полей. Он достает весь массив текстов из JulyTranslator и генерирует QTextEdit для каждого поля.
Поскольку мне не всегда нравится то, что делает лейаут с QTextEdit, я написал виджет TranslationLine, который при изменении идеально обтекает текст для экономии места.
Вы можете это наблюдать в переводчике, когда дописываете что-нибудь или ставите энтеры в текстовые поля. Поле автоматически увеличивается и уменьшается.
Безопасное автоматическое обновление только с помощью GitHub и SourceForge
Принцип обновления прост: программа при запуске загружает файл raw.github.com/JulyIGHOR/QtBitcoinTrader/master/versions.txt, который лежит на GitHub в открытом виде.
В файле сохранена зашифрованная с помощью RSA2048 контрольная сумма бинарника SH1.
Public.key вшит в ресурс программы, а Private.key надежно сохранен и запаролен, и есть только у меня.
Программа при проверке обновления загружает файл по указаной ссылке из файла в оперативную память, если файл больше 15 мб, то закачка отменяется.
Дальше вычисляется контрольная сумма SH1 скачанных данных, и сопоставляется с расшифрованной информацией из файла обновления.
Если контрольная сумма совпадает, то программа сохраняет файл из оперативки на диск под названием QtBitcoinTrader.upd. После контрольной проверки читает его обратно, и проверяет, хорошо ли сохранился файл. После успешной проверки переименовывает себя в *.bkp, а файл *.upd — в оригинальное имя файла.
После перезапуска лишние файлы удалятся.
Этот принцип работает одинаково и для Windows, и для Mac OS X.
Послесловие
Помните, программа за вас не торгует, это лишь инструмент помогающий вам торговать.
Надеюсь, я не слишком затянул и статья была вам интересна.
Буду рад поддержке, отзывам и рекомендациям.
Автор: IGHOR