# Минискрипт для продажи ARB и не только, на ByBit **Published by:** [Karl](https://paragraph.com/@ifomoeverytime/) **Published on:** 2023-03-22 **URL:** https://paragraph.com/@ifomoeverytime/arb-bybit ## Content Пункты:Код скрипта для ByBit с инструкцией по установке/настройке.Инструкция по проверке работы на тестовом ByBit.Обновление от 03.05:(в связи с правилами Bybit и ограничениями) Если необходимо что бы скрипт ставил лимитные ордера, а не рыночные, нужно заменить: bybit.place_active_order(symbol=_ticker, side="Sell", type="MARKET", qty=qty) На: bybit.place_active_order(symbol=_ticker, side="Sell", type="LIMIT", qty=qty, price=_min_sell_price) Заранее извиняюсь за возможно излишнюю детализацию, не что бы остались вопросы :)Код бота для ByBit с инструкцией по установке/настройке.Для работы скрипты потребуется python. Для его установки воспользуйтесь инструкцией на скриншоте.После установки python, установим библиотеку для работы с Bybit. Для этого выполним в консоли команду: pip3 install pybit Для работы скрипта все готово. Теперь возьмем скрипт представленный ниже:from pybit import spot from datetime import datetime import time import math _min_sell_price = 1.00 _percent_to_sell = 1.00 #1 - 100% _ticker = "ARBUSDT" _coin = "ARB" _decimal = 4 _debug = False _testnet = False _keys = [ { 'api_key' : '', 'api_secret' : '', }, { 'api_key' : '', 'api_secret' : '', }, #... ] def floor_with_precision(value, precision=0): return math.floor(value * 10**precision) / 10**precision def print_with_time(msg): print(datetime.now().strftime("%H:%M:%S.%f") + ' ' + str(msg)) def check_price(msg): global _keys if _debug == True: print(msg['data']) last_price = float(msg['data']['bidPrice']) print_with_time(last_price) if (last_price >= _min_sell_price): print_with_time('Price in range.') keys_sold = [] for key_pair in _keys: amount = 0 bybit = spot.HTTP(endpoint="https://api" + ("", "-testnet")[_testnet] + ".bybit.com", api_key=key_pair['api_key'], api_secret=key_pair['api_secret']) balances = bybit.get_wallet_balance()['result']['balances'] for balance in balances: if balance['coin'] == _coin: amount = float(balance['free']) print_with_time('Balance: ' + str(amount) + ' ' + _coin) if amount > 0: qty = floor_with_precision(float(amount * _percent_to_sell), _decimal) print_with_time('Selling: ' + str(qty) + ' ' + _coin + ' for ' + str(last_price)) try: bybit.place_active_order(symbol=_ticker, side="Sell", type="MARKET", qty=qty) print_with_time('Sell ok') except Exception as e: print_with_time('Sell operation failed') keys_sold.append(key_pair) time.sleep(0.2) for key_sold in keys_sold: _keys.remove(key_sold) bybit = spot.HTTP(endpoint="https://api" + ("", "-testnet")[_testnet] + ".bybit.com", api_key=_keys[0]['api_key'], api_secret=_keys[0]['api_secret']) try: res = bybit.latest_information_for_symbol(symbol=_ticker) if res['result']: print_with_time(_ticker + " found.") else: print_with_time(_ticker + " found. But no data yet.") except Exception as e: print_with_time(_ticker + " not found.") raise SystemExit print_with_time('Waiting for price: ' + str(_min_sell_price)) ws = spot.WebSocket(test=_testnet) ws.book_ticker_v2_stream(check_price, _ticker) while len(_keys) > 0: pass print('All sold.') Отредактируем:_min_sell_price = 1.00 _percent_to_sell = 0.20 #1 - 100% _min_sell_price - это минимальная цена(last price) при которой скрипт начнет продавать. _percent_to_sell - процент от баланса который мы хотим что бы был продан. Значение 1 - это 100%, 0.5 - 50%. Все числа пишем через точку._ticker = "ARBUSDT" _coin = "ARB" _decimal = 4 _debug = False _testnet = False Тут мы вставляем нужную нам пару и монету которую будем продавать. Пример: _ticker = "BTCUSDT", _coin = "BTC" - для продажи BTC. Предустановлена пара ARBUSDT и токен ARB. _decimal - не трогаем, хз сколько ByBit у ARB знаков после запятой видит, если указать много - скрипт выдаст ошибку, если мало - то все что за последним знаком останется на балансе. _debug - вывод более полной информации о цене в логе. Значения True и False. _testnet - если работаем с тестовым Bybit True, если с реальным False._keys = [ { 'api_key' : '', 'api_secret' : '', }, { 'api_key' : '', 'api_secret' : '', }, { 'api_key' : '', 'api_secret' : '', }, { 'api_key' : '', 'api_secret' : '', }, #... ] API ключи для аккаунтов ByBit. Создать из можно тут: https://www.bybit.com/app/user/api-managementКлючам нужны права на торговлю на споте.Блоков с ключами вставляем столько сколько требуется по примеру выше. Если продажа будет с одного аккаунта, то и ключ должен быть один. В поле api_key вставляем ключ, в поле api_secret - соответственно secret. Сохраняем файл, скажем как bybit-script.py Скрипт для запуска готов, готов, запускается из консоли: python3 bybit-script.py Но до этого, настоятельно рекомендую проверить правильность работы на тестнете ByBit, о чем далее.Инструкция по про проверке работы на тестовом ByBitТестовый ByBit находится по адресу: https://testnet.bybit.com Процесс регистрации аналогичен процессу регистрации на реальном ByBit, аккаунты у них разные.Так же нужно сгенерировать отдельные API ключи.Для работы с тестовым ByBit используется следующий код.from pybit import spot from datetime import datetime import time import math _min_sell_price = 26000.00 _percent_to_sell = 0.10 #1 - 100% _ticker = "BTCUSDT" _coin = "BTC" _decimal = 4 _debug = False _testnet = True _keys = [ { 'api_key' : '', 'api_secret' : '', }, { 'api_key' : '', 'api_secret' : '', }, #... ] def floor_with_precision(value, precision=0): return math.floor(value * 10**precision) / 10**precision def print_with_time(msg): print(datetime.now().strftime("%H:%M:%S.%f") + ' ' + str(msg)) def check_price(msg): global _keys if _debug == True: print(msg['data']) last_price = float(msg['data']['bidPrice']) print_with_time(last_price) if (last_price >= _min_sell_price): print_with_time('Price in range.') keys_sold = [] for key_pair in _keys: amount = 0 bybit = spot.HTTP(endpoint="https://api" + ("", "-testnet")[_testnet] + ".bybit.com", api_key=key_pair['api_key'], api_secret=key_pair['api_secret']) balances = bybit.get_wallet_balance()['result']['balances'] for balance in balances: if balance['coin'] == _coin: amount = float(balance['free']) print_with_time('Balance: ' + str(amount) + ' ' + _coin) if amount > 0: qty = floor_with_precision(float(amount * _percent_to_sell), _decimal) print_with_time('Selling: ' + str(qty) + ' ' + _coin + ' for ' + str(last_price)) try: bybit.place_active_order(symbol=_ticker, side="Sell", type="MARKET", qty=qty) print_with_time('Sell ok') except Exception as e: print_with_time('Sell operation failed') keys_sold.append(key_pair) time.sleep(0.2) for key_sold in keys_sold: _keys.remove(key_sold) bybit = spot.HTTP(endpoint="https://api" + ("", "-testnet")[_testnet] + ".bybit.com", api_key=_keys[0]['api_key'], api_secret=_keys[0]['api_secret']) try: res = bybit.latest_information_for_symbol(symbol=_ticker) if res['result']: print_with_time(_ticker + " found.") else: print_with_time(_ticker + " found. But no data yet.") except Exception as e: print_with_time(_ticker + " not found.") raise SystemExit print_with_time('Waiting for price: ' + str(_min_sell_price)) ws = spot.WebSocket(test=_testnet) ws.book_ticker_v2_stream(check_price, _ticker) while len(_keys) > 0: pass print('All sold.') Отличия:вместо _testnet = False для тестового используем _testnet = Trueне забываем про то что у тестового ByBit используются тестовые API-ключи.На этом отличия заканчиваются. Установка и настройка полностью аналогичны описанным выше. Для теста мы можем запросить тестовые монеты, это делается здесь: https://testnet.bybit.com/user/assets/home/overviewНажимаем “Request Test Coins”Сохраняем скрипт как bybit-testnet-script.py и запускаем: python3 bybit-testnet-script.py В случае, если все корректно отработало, увидим результат аналогичный такому:Пример работы скриптаСменой пары и монеты мы можем настроить скрипт на работу с любым активом. Все вопросы по тому как скрипт работает и ответы почему выпадает та или иная ошибка ## Publication Information - [Karl](https://paragraph.com/@ifomoeverytime/): Publication homepage - [All Posts](https://paragraph.com/@ifomoeverytime/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@ifomoeverytime): Subscribe to updates - [Twitter](https://twitter.com/ifomoeverytime): Follow on Twitter