Пункты:
Код скрипта для ByBit с инструкцией по установке/настройке.
Инструкция по проверке работы на тестовом ByBit.
(в связи с правилами 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)
Заранее извиняюсь за возможно излишнюю детализацию, не что бы остались вопросы :)

После установки 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, аккаунты у них разные.

Для работы с тестовым 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

Сохраняем скрипт как bybit-testnet-script.py и запускаем:
python3 bybit-testnet-script.py
В случае, если все корректно отработало, увидим результат аналогичный такому:

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

