Бот для Binance с индикаторами

Время от времени мне пишут, что хотели бы использовать моего бота для бинанса с таким-то индикатором или в такой-то связке индикаторов для реализации своей стратегии. Раз уж мы закончили цикл статей про индикаторы, давайте применим их в реальной жизни?

Отличия в новой версии:

  1. Стало больше файлов. Ваши настройки нужно прописывать в файле config.py
  2. Бот совершает абсолютно все сделки по рынку.
    1. Вначале, если индикаторы позволяют (об этом ниже), бот создает ордер на покупку по рынку. После создания бот получает с биржи историю сделок и считает средневзвешенную цену (как и то, что вы видите на Binance) в истории торгов.
    2. После того, как ордер на покупку исполнен, бот проверяет текущий курс (в стакане на покупку), и, если рост превысил заданное в конфиге, то продает по рынку. После продажи опять же получает историю сделок и считает курс для истории.
    3. Если включен флаг stop-loss, то бот продает по рынку, когда цена падает на указанный процент.
  3. Бот работает в два потока, один из которых собственно бот, другой синхронизирует время с биржей. Это нужно для тех случаев, когда время постепенно расходится в процессе работы бота.
  4. Убрано всё, что связано с комиссией. Во-первых, бот покупает по рынку и ему плевать на комиссии, во вторых сейчас помимо BNB|НеBNB комиссий появились разные ставки maker/taker для разных уровней участников, и еще возможна ситуация, когда часть комиссии снята в BNB, потом монеты кончились и часть снялась в остальной валюте. Для простого бота обработку всех этих событий считаю излишней, просто держите BNB на балансе и не снимайте галочку.

Теперь собственно про индикаторы (и вообще алгоритм работы).

Рассказываю с самого начала.

  1. Нужно скачать архив с ботом. Распаковать его в любую папку по вашему выбору
  2. Вам нужен установленный python версии 3.6 и выше, скачайте его с официального сайта и установите все галочки.
  3. Запустите setup.bat в папке с ботом.
  4. Откройте файл config.py в папке с ботом и укажите настройки. 
    1. Нужно будет прописать API-ключи (откуда их взять расписано тут)
    2. Указать пары, по которым собираетесь торговать
    3. Суммы для торгов
    4. Признак active пары позволяет пропускать пару, если не хотите её использовать (по ней не будут создаваться новые ордера на покупку)
    5. KLINES_LIMITS – сколько свечей бот должен получать при построении индикаторов
    6. TIMEFRAME – по каким свечам собираетесь работать с индикаторами (в примере – с часовыми)
  5. В принципе бот готов к работе, но нужно еще настроить вашу торговую стратегию. Я думал убрать её в отдельный файл, но решил, что вас это еще больше запутает. Вот суть:

Индикаторы

В файле binance_bot.py  есть вот такой вот фрагмент кода:

log.debug("Проверяем индикаторы")
# Получаем свечи и берем цены закрытия, high, low
klines = bot.klines(
    symbol=pair_name.upper(),
    interval=TIMEFRAME,
    limit=KLINES_LIMITS
)

closes = [float(x[4]) for x in klines]
high = [float(x[2]) for x in klines]
low = [float(x[3]) for x in klines]

# Скользящая средняя
sma_5 = ta.SMA(closes, 5)
sma_100 = ta.SMA(closes, 100)

ema_5 = ta.EMA(closes, 5)
ema_100 = ta.EMA(closes, 100)

enter_points = 0

if ema_5[-1] > ema_100[-1] and sma_5[-1] > sma_100[-1]:
    # Быстрая EMA выше медленной и быстрая SMA выше медленной, считаем, что можно входить
    enter_points += 1

macd, macdsignal, macdhist = ta.MACD(closes, 12, 26, 9)
if macd[-1] > macdsignal[-1] and macdhist[-1] > 0:
    # Линия макд выше сигнальной и на гистограмме они выше нуля
    enter_points += 1.3

rsi_9 = ta.RSI(closes, 9)
rsi_14 = ta.RSI(closes, 14)
rsi_21 = ta.RSI(closes, 21)

if rsi_9[-1] < 70 and rsi_14[-1] < 70 and rsi_21[-1] < 70:
    # RSI не показывает перекупленности
    enter_points += 2

fast, slow = ta.STOCH(high, low, closes, 5, 3, 3)
if fast[-1] > slow[-1]:
    # Быстрая линия стохастика выше медленной, вход
    enter_points += 1.5

fast, slow = ta.STOCHRSI(closes, 14, 3, 3)
if fast[-1] > slow[-1]:
    # Быстрая линия STOCHRSI выше медленной, вход
    enter_points += 1.8

upper, middle, lower = ta.BBANDS(closes, ma_period=20)
if high[-1] > upper[-1]:
    # Свеча пробила верхнюю полосу Боллинджера
    enter_points += 3

log.debug("Свеча набрала {b} баллов".format(b=enter_points))
if enter_points <  POINTS_TO_ENTER:
    log.debug("Минимальный проходной балл {b}. Пропуск пары".format(b=POINTS_TO_ENTER))
    continue

Я его набросал для примера, просто что бы дать вам понимание что и как настраивается. Эта торговая стратегия не является какой-то там оптимальной или известной. Вы можете добавлять или убавлять куски кода так, как вам будет удобнее. Пробегусь по логике:

Работа с индикаторами происходит только перед созданием ордера на покупку, фактически это принятие решения, стоит ли входить в торги.

Сначала мы получаем с биржи свечи по текущей паре:

klines = bot.klines(
    symbol=pair_name.upper(),
    interval=TIMEFRAME,
    limit=KLINES_LIMITS
)

Формируем массивы с ценами закрытия (а также high и low)

closes = [float(x[4]) for x in klines]
high = [float(x[2]) for x in klines]
low = [float(x[3]) for x in klines]

Строим для начала скользящие средние SMA и EMA (это и все что дальше касается индикаторов можно смело менять и удалять).

# Скользящая средняя
sma_5 = ta.SMA(closes, 5)
sma_100 = ta.SMA(closes, 100)

ema_5 = ta.EMA(closes, 5)
ema_100 = ta.EMA(closes, 100)

Проверяем, если последнее значение SMA с периодом 5 выше последнего значения SMA с периодом 100, и если тоже самое справедливо для EMA, то присваиваем одно очко в копилку. Значения могут быть любыми.

if ema_5[-1] > ema_100[-1] and sma_5[-1] > sma_100[-1]:
    # Быстрая EMA выше медленной и быстрая SMA выше медленной, считаем, что можно входить
    enter_points += 1

Если # Линия макд выше сигнальной и на гистограмме они выше нуля, то присваиваем еще 1.3 и т.п. Там вы найдете RSI, STOCH, STOCHRSI, и Боллинджера, по тем же приницпам.

macd, macdsignal, macdhist = ta.MACD(closes, 12, 26, 9)
if macd[-1] > macdsignal[-1] and macdhist[-1] > 0:
    # Линия макд выше сигнальной и на гистограмме они выше нуля
    enter_points += 1.3

В итоге, после того как все индикаторы построены и наши веса посчитаны, можно принимать решение. В данном случае у меня в конфиге стоит проходной балл 7 (параметр POINTS_TO_ENTER), а суммарно можно набрать 10.6, если все индикаторы сработают.

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

Ваша задача подобрать индикаторы, веса и проходной балл так, что бы реализовалась ваша торговая стратегия. Например, если вы используете только MA200 и RSI, и хотите войти на рынок, когда они сработают вдвоем, удалите всё лишнее, дайте каждому из них по 1 и сделайте проходной бал 2. Если достаточно сработки хотя бы одного из них, сделайте проходной балл 1.

Все доступные индикаторы вы можете найти в файле bablofil_ta.

Надеюсь, этот бот поможет вам отлаживать/настраивать/проверять свои или чужие торговые стратегии, а также принесет прибыль при грамотной настройке.

Вы всегда можете остановить бота, поменять настройки (например прибыльности или стоп-лосса) и бот подхватит для всех пар, даже для тех, по которым есть ордера. Если хотите начать все заново, удалите файл binance.db из папки с ботом, это его база данных, он создаст новую при запуске.

В общем удачи и профита вам и вашим роботам.

Задавайте вопросы в комментариях, пишите на форуме.


Это статья из цикла "Популярно о бирже"
Все статьи цикла:

Последнее изменение:

Не забудьте рассказать друзьям об этой статье.
Чтобы поддержать ресурс Bablofil достаточно просто поделиться с друзьями этой статьей в социальных сетях. Каждый репост - это самая высокая оценка качества материала. Спасибо, что читаете этот блог.



Комментарии
23.06.2019 22:16:02
после запуска и остановки в линуксе через ctrl+C и последующего перезапуска после изменения настроек - постоянно выходит ошибка

2019-06-23 23:12:25,782 [DEBUG] Получаем все неисполненные ордера по БД
2019-06-23 23:12:25,782 [DEBUG] Получены неисполненные ордера из БД: [('319031353', 'ETHUSDT'), ('78903358', 'TRXUSDT'), ('59534674', 'ETCUSDT')]
2019-06-23 23:12:25,785 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-06-23 23:12:31,366 [DEBUG] https://api.binance.com:443 "GET /api/v3/order?symbol=ETHUSDT&orderId;=319031353&timestamp;=1561320744000&signature;=ххххххххх HTTP/1.1" 400 None
2019-06-23 23:12:31,367 [ERROR] 'status'
Traceback (most recent call last):
  File "./binance_bot.py", line 43, in main_flow
    order_status = stock_order_data['status']
KeyError: 'status'
Проголосовать Проголосовать
0 0
24.06.2019 09:39:36
Биржа отвечает с кодом 400, это значит что она не может обработать входящий запрос. А настройки API ключей не менялись? Может там пробелы какие..
Проголосовать Проголосовать
0 0
24.06.2019 13:32:26
Разобрались, обновлен код бота в архиве
Проголосовать Проголосовать
0 0
03.07.2019 23:10:52
Добрый день! Спасибо за Ваш труд.
Протестировал бота - вход происходит в торги удачно: по маркету было куплено три монеты когда условия сложились до 7 входных баллов, однако когда курс купленных монет превысил на утро более 1 процент - продажа не осуществилась ни по одной из них. Пришлось все скидывать вручную.
Можно ли настроить чтобы на продажу выставлялся ордер?
Проголосовать Проголосовать
0 0
05.07.2019 16:52:27
Ордер должен выставляться, когда рост монеты превысит курс, указанный в настройках, может быть в настройках указан большой процент?
Или столкнулись с какой то ошибкой в логах?
Проголосовать Проголосовать
0 0
06.07.2019 02:29:30
Процент указан 1% (ваши настройки по умолчанию, кроме валютных пар и количества закупа), валюта выросла на 2 % - в логах ошибок не было. Но по маркету не продалась ни одна из закупленных пар.
Проголосовать Проголосовать
0 0
20.07.2019 14:16:02
после запуска и остановки  - постоянно выходит ошибка?????? Что делать????
C:\binance_bot_v2\binance_bot_v2>setup.bat
C:\binance_bot_v2\binance_bot_v2>pip install requests
Requirement already satisfied: requests in c:\users\admin\appdata\local\programs\python\python37\lib\site-packages (2.22
.0)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\admin\appdata\local\programs\python\python37\lib\site-p
ackages (from requests) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in c:\users\admin\appdata\local\programs\python\p
ython37\lib\site-packages (from requests) (1.25.3)
Requirement already satisfied: idna<2.9,>=2.5 in c:\users\admin\appdata\local\programs\python\python37\lib\site-packages
 (from requests) (2.8)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\admin\appdata\local\programs\python\python37\lib\site-pack
ages (from requests) (2019.6.16)

C:\binance_bot_v2\binance_bot_v2>pause
Для продолжения нажмите любую клавишу . . .

C:\binance_bot_v2\binance_bot_v2>run.bat
Traceback (most recent call last):
  File "./binance_bot.py", line 11, in <module>
    from config import (bot, pairs, log, TIMEFRAME, KLINES_LIMITS, POINTS_TO_ENTER, USE_OPEN_CANDLES)
  File "C:\binance_bot_v2\binance_bot_v2\config.py", line 24
    'active': True,
           ^
SyntaxError: invalid syntax
Для продолжения нажмите любую клавишу . . .

C:\binance_bot_v2\binance_bot_v2>run.bat
Traceback (most recent call last):
  File "./binance_bot.py", line 11, in <module>
    from config import (bot, pairs, log, TIMEFRAME, KLINES_LIMITS, POINTS_TO_ENTER, USE_OPEN_CANDLES)
  File "C:\binance_bot_v2\binance_bot_v2\config.py", line 24
    'active': True,
           ^
</module></module>
Проголосовать Проголосовать
0 0
29.07.2019 15:39:55
Что то не так указано в настройках, предлагаю скачать бота по новой и аккуратно заменить настройки нужных пар
Проголосовать Проголосовать
0 0
22.07.2019 22:08:49
Еще было бы прикольно реализовать нечто вроде дельта-функции для МА и ЕМА, что бы бот закупался при условии, что длинная скользящая идет наверх. А так работа выше всяких похвал)
Проголосовать Проголосовать
0 0
31.07.2019 07:34:19
Добрый день!
Бот работает (покупает, продает, пишет в логфайл) минут 20 потом останавливается. После перезапуска все опять работает минут 20 -25. В чем проблема может быть?
Проголосовать Проголосовать
0 0
31.07.2019 12:47:57
Может быть у вас другие какие то процессы к бирже тоже обращаются, и биржа вас блокирует? Редкий конечно случай, но бывает
Проголосовать Проголосовать
0 0
01.08.2019 03:25:58
Во время работы бота заходили через браузер на сайт Binance. Проверка баланса, просмотр графиков. 
А можно ли в самом боте установить проверку на блокировку сайтом? То есть если сайт нас заблокировал то бот перезапустится  через указанное время.
Проголосовать Проголосовать
0 0
03.08.2019 13:05:28
Блокируется доступ к API в первую очередь, причем не биржей, а проксирующим сервером, наподобие CloudFront, проверять доступность лучше сразу по ссылкам к апи, например https://api.binance.com/api/v1/exchangeInfo

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

Думаю, стоит начать именно с запуска бота на сервере (https://bablofil.ru/kak-zapustit-bota-na-servere), что бы исключить варианты, что сбоит ващ WiFi, роутер, провайдер интернета и т.п.
Проголосовать Проголосовать
0 0
02.08.2019 07:07:41
Или как прописать в боте запрос через каждые 15 сек?
Проголосовать Проголосовать
0 0
03.08.2019 13:07:09
В файле binance_api пропишите time.sleep(15), тогда пока один запрос к бирже не отработает второй не будет запускаться.
Но если будете несколько ботов в параллели запускать, то это не поможет
Проголосовать Проголосовать
0 0
02.08.2019 13:55:21
Выходит ошибка:
2019-08-02 18:55:17,380 [ERROR] 'status'
Traceback (most recent call last):
  File "./binance_bot.py", line 43, in main_flow
    order_status = stock_order_data['status']
KeyError: 'status'
Проголосовать Проголосовать
0 0
03.08.2019 13:08:25
Проверьте синхронизацию времени, правильность написания пары, апи ключей и т.п.
Там еще может отображаться ошибка в консоли, которая не попадает в лог, посмотрите, пишется ли там что то
Проголосовать Проголосовать
0 0
04.08.2019 03:29:10
ради научного интереса решил поиграться с кодом: попытался сделать так чтоб бот продавал по анализу свечей:

# Если ордер уже исполнен
                        if order_status == 'FILLED':
                            got_qty = float(stock_order_data['executedQty'])
                            log.info("""
                                Ордер {order} выполнен, получено {exec_qty:0.8f}.
                                Проверяем, не стоит ли создать ордер на продажу
                            """.format(
                                order=order, exec_qty=got_qty
                            ))
                            # смотрим, какие ограничения есть для создания ордера на продажу
                            for elem in limits['symbols']:
                                if elem['symbol'] == orders_info[order]['order_pair']:
                                    CURR_LIMITS = elem
                                    break
                            else:
                                raise Exception("Не удалось найти настройки выбранной пары " + pair_name)
                            got_qty = adjust_to_step(got_qty, CURR_LIMITS['filters'][2]['stepSize'])
                            #p_g_q = got_qty - (got_qty // 1000)
                            prices = bot.tickerBookTicker(
                                symbol=orders_info[order]['order_pair']
                            )

                            # Берем цены покупок (нужно будет продавать по рынку)
                            curr_rate = float(prices['bidPrice'])

                            price_change = (curr_rate/orders_info[order]['buy_price']-1)*100
                            
                            log.debug("Цена изменилась на {r:0.8f}%".format(r=price_change))

                            log.debug("По пути проверяем свечи")
                            # Получаем свечи и берем цены закрытия, high, low
                            klines = bot.klines(
                            symbol=orders_info[order]['order_pair'].upper(),
                            interval=TIMEFRAME,
                            limit=KLINES_LIMITS
                            )
                            klines = klines[:len(klines)-int(USE_OPEN_CANDLES)]

                            closes = [float(x[4]) for x in klines]
                            high = [float(x[2]) for x in klines]
                            low = [float(x[3]) for x in klines]

                            # Скользящая средняя
                            sma_2 = ta.SMA(closes, 2)
                            sma_3 = ta.SMA(closes, 3)

                            ema_2 = ta.EMA(closes, 2)
                            ema_3 = ta.EMA(closes, 3)

                            enter_points = 0

                            if ema_2[-1] > ema_3[-1] and sma_2[-1] > sma_3[-1]:
                                # Быстрая EMA выше медленной и быстрая SMA выше медленной, считаем, что можно входить
                                enter_points += 1


                            fast, slow = ta.STOCHRSI(closes, 14, 4, 2)
                            if fast[-1] > slow[-1]:
                                # Быстрая линия STOCHRSI выше медленной, вход
                                enter_points += 2

                            log.debug("Свеча {b} баллов".format(b=enter_points))
                            if enter_points <  POINTS_TO_ENTER:
                                log.debug("Продаём")
                            
                                # Отправляем команду на создание ордера с рассчитанными параметрами
                                new_order = bot.createOrder(
                                    symbol=orders_info[order]['order_pair'],
                                    recvWindow=5000,
                                    side='SELL',
                                    type='MARKET',
                                    quantity="{quantity:0.{precision}f}".format(
                                        quantity=orders_info[order]['buy_amount'], precision=CURR_LIMITS['baseAssetPrecision']
                                    ),
                                    newOrderRespType='FULL'
                                )


но выскакивает такая вот ошибка: {"code":-2010,"msg":"Account has insufficient balance for requested action."}
Я так понимаю это связано с расчетом  комиссии, вернее с его отсутствием.
В программировании  мало опыта, подскажите пожалуйста на мои недочеты. Заранее благодарю
Проголосовать Проголосовать
0 0
04.08.2019 04:30:23
И еще в консоли пишет "получено 0.00986200", а на самой бирже смотрю там баланс 0.00985234
Проголосовать Проголосовать
0 0
04.08.2019 13:28:27
У вас видимо комиссия берется не в BNB
Купите немного BNB, закиньте на баланс, тогда количество полученного будет совпадать, а уменьшаться будут монеты BNB
Так вроде все ок
Проголосовать Проголосовать
0 0
04.08.2019 17:17:24
благодарю! разобрался)
Проголосовать Проголосовать
0 0
12.08.2019 08:31:51
Еще раз здравствуйте. 
Теперь такой вопрос: как сделать запись логирования в разные файлы? То есть в первый файл записывать все в подробностях, с полями debug. В другой файл  только с полями info. Или может можно сразу краткую статистику по сделкам записывать в файл xls?
Проголосовать Проголосовать
0 0
13.08.2019 08:18:28
Посмотрите как в начале создается объект log - как вариант можно можно создать еще один и использовать его при необходимости. В эксель вы можете писать используя соответствующие модули, например openpyxl, пример можете посмотреть тут https://bablofil.ru/birja-excel/
Проголосовать Проголосовать
0 0
04.11.2019 19:15:50
Задался этим же вопросом. Погуглив и почитав инфу о модуле logging в питоне немного переписал функцию логов. Бот будет выводить два файла: BotErrors (включает записи уровня ERROR и CRITICAL), BotTradingInfo (INFO и WARNING). 
Если хотите, можете изменить переменную debugLog = True. Тогда добавится 3-й файл с записями только уровня DEBUG. Данная переменная так же откл./вкл. вывод сообщений отладки (DEBUG) в консоль (остальные уровни транслируются). 

Как сделать: в файле config.py заменить код отвечающий за логирование на мой (ниже). P.S. Возможно где то написано коряво, но у меня все работает, только учусь.
Статистику по сделкам можно получить из базы данных с помощью программы SQ-Lite. Либо с бинанса экспортировать историю торгов. 

# Подключаем логирование
#DEBUG имеет низкий уровень - выводятся все сообщения. 
#Доступны INFO, WARNING, ERROR, CRITICAL

#Вкл./Выкл. лог сообщений отладки а так же, вывод этих сообщений в консоль 
#Cообщения уровня INFO, WARNING, ERROR, CRITICAL будут записаны в файл и транслироваться в консоль
debugLog = False

#Шаблон вывода сообщения лога
format_string = '%(asctime)s [%(levelname)s] %(message)s'
formatter = logging.Formatter(fmt=format_string)

#Фильтр уровней сообщений лога
class logFilter(object):
    def __init__(self, level):
        self.__level = level

    def filter(self, logRecord):
        if self.__level <= 10:
            return logRecord.levelno == self.__level
        if self.__level > 10:
            return logRecord.levelno == self.__level or logRecord.levelno == self.__level+10

log = logging.getLogger('')

#Хандлер вывода уровня отладки только DEBUG (используется фильтр) - в файл
if debugLog == True:
    handler1 = logging.FileHandler("{path}/logs/{fname}.log".format(path=os.path.dirname(os.path.abspath(__file__)), fname="BotDebug"))
    handler1.setLevel(logging.DEBUG)
    handler1.addFilter(logFilter(logging.DEBUG))
    handler1.setFormatter(fmt=formatter)
    log.addHandler(handler1)
#Хандлер вывода уровней INFO и WARNING (используется фильтр) - в файл
handler2 = logging.FileHandler("{path}/logs/{fname}.log".format(path=os.path.dirname(os.path.abspath(__file__)), fname="BotTradingInfo"))
handler2.setLevel(logging.INFO)
handler2.addFilter(logFilter(logging.INFO))
handler2.setFormatter(fmt=formatter)
log.addHandler(handler2)
#Хандлер вывода уровней error и critical (используется фильтр) - в файл
handler3 = logging.FileHandler("{path}/logs/{fname}.log".format(path=os.path.dirname(os.path.abspath(__file__)), fname="BotErrors"))
handler3.setLevel(logging.ERROR)
handler3.setFormatter(fmt=formatter)
handler3.addFilter(logFilter(logging.ERROR))
log.addHandler(handler3)

#Хандлер вывода сообщений в консоль 
handler4 = logging.StreamHandler()
if debugLog == True:
    handler4.setLevel(logging.DEBUG)
else:
    handler4.setLevel(logging.INFO)
handler4.setFormatter(fmt=formatter)
log.addHandler(handler4)

log.setLevel(logging.DEBUG)
Проголосовать Проголосовать
0 0
18.08.2019 22:50:47
Часть лога работы бота:

2019-08-19 01:42:32,217 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-08-19 01:42:32,560 [DEBUG] https://api.binance.com:443 "GET /api/v3/ticker/bookTicker?symbol=BTCUSDT HTTP/1.1" 200 None
2019-08-19 01:42:32,560 [DEBUG] Цена изменилась на -0.50432951%, процент для продажи 1.00000000
2019-08-19 01:42:32,560 [DEBUG] Цена не изменилась до нужного %
2019-08-19 01:42:32,560 [DEBUG] Получаем из настроек все пары, по которым нет неисполненных ордеров
2019-08-19 01:42:32,560 [DEBUG] Найдены пары, по которым нет неисполненных ордеров: ['USDTBTC']
2019-08-19 01:42:32,560 [DEBUG] Работаем с парой USDTBTC
2019-08-19 01:42:32,560 [ERROR] Пропускаем пару USDTBTC
Traceback (most recent call last):
  File "./binance_bot.py", line 208, in main_flow
    raise Exception("Не удалось найти настройки выбранной пары " + pair_name)
Exception: Не удалось найти настройки выбранной пары USDTBTC
2019-08-19 01:42:32,560 [DEBUG] Получаем все неисполненные ордера по БД
2019-08-19 01:42:32,560 [DEBUG] Получены неисполненные ордера из БД: [('593822071', 'BTCUSDT')]
2019-08-19 01:42:32,576 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-08-19 01:42:32,904 [DEBUG] https://api.binance.com:443 "GET /api/v3/order?symbol=BTCUSDT&orderId;=593822071&timestamp;=1566168151000&signature;=6330fbd980f7a786af20edbc447766d85eb5c196b31b4ac3b705553aaa503650 HTTP/1.1" 200 None
2019-08-19 01:42:32,904 [DEBUG] Состояние ордера 593822071 - FILLED
2019-08-19 01:42:32,904 [INFO ] 
                                Ордер 593822071 выполнен, получено 0.00482500.
                                Проверяем, не стоит ли создать ордер на продажу
                            
2019-08-19 01:42:32,920 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-08-19 01:42:33,264 [DEBUG] https://api.binance.com:443 "GET /api/v3/ticker/bookTicker?symbol=BTCUSDT HTTP/1.1" 200 None
2019-08-19 01:42:33,264 [DEBUG] Цена изменилась на -0.52537139%, процент для продажи 1.00000000
2019-08-19 01:42:33,264 [DEBUG] Цена не изменилась до нужного %
2019-08-19 01:42:33,264 [DEBUG] Получаем из настроек все пары, по которым нет неисполненных ордеров
2019-08-19 01:42:33,264 [DEBUG] Найдены пары, по которым нет неисполненных ордеров: ['USDTBTC']
2019-08-19 01:42:33,264 [DEBUG] Работаем с парой USDTBTC
2019-08-19 01:42:33,264 [ERROR] Пропускаем пару USDTBTC
Traceback (most recent call last):
  File "./binance_bot.py", line 208, in main_flow
    raise Exception("Не удалось найти настройки выбранной пары " + pair_name)
Exception: Не удалось найти настройки выбранной пары USDTBTC
2019-08-19 01:42:33,264 [DEBUG] Получаем все неисполненные ордера по БД
2019-08-19 01:42:33,264 [DEBUG] Получены неисполненные ордера из БД: [('593822071', 'BTCUSDT')]
2019-08-19 01:42:33,279 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-08-19 01:42:33,623 [DEBUG] https://api.binance.com:443 "GET /api/v3/order?symbol=BTCUSDT&orderId;=593822071&timestamp;=1566168152000&signature;=95845e41305002bb8ce52a58113b6b99a4ce8bec76d4bd985f358b1559092aba HTTP/1.1" 200 None
2019-08-19 01:42:33,623 [DEBUG] Состояние ордера 593822071 - FILLED
2019-08-19 01:42:33,623 [INFO ] 
                                Ордер 593822071 выполнен, получено 0.00482500.
                                Проверяем, не стоит ли создать ордер на продажу
                            
2019-08-19 01:42:33,623 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443


Вот эта запись о чём говорит: 
Traceback (most recent call last):
  File "./binance_bot.py", line 208, in main_flow
    raise Exception("Не удалось найти настройки выбранной пары " + pair_name)
Exception: Не удалось найти настройки выбранной пары USDTBTC

 Подскажите пожалуйста...
Проголосовать Проголосовать
0 0
19.08.2019 11:57:15
Добрый день
Такой пары на бирже нет https://www.binance.com/en/trade/USDT_BTC
Есть такая https://www.binance.com/en/trade/BTC_USDT
Поменяйте местами названия монет
Проголосовать Проголосовать
0 0
19.08.2019 21:15:04
Андрей, простите меня пожалуйста, но тогда я не понимаю конфиг, а именно эту часть:

pairs = [
   {
        'base': 'ETH',
        'quote': 'ADA',
        'spend_sum': 0.02,  # Сколько тратить base каждый раз при покупке quote
        'profit_markup': 1, # Какой навар нужен с каждой сделки? (1=1%)
        'use_stop_loss': False, # Нужно ли продавать с убытком при падении цены
        'stop_loss': 1, # 1% - На сколько должна упасть цена, что бы продавать с убытком
        'active': True,
    }, {
        'base': 'USDT',
        'quote': 'NEO',
        'spend_sum': 11,  # Сколько тратить base каждый раз при покупке quote
        'profit_markup': 1, # Какой навар нужен с каждой сделки? (0.001 = 0.1%)
        'use_stop_loss': False, # Нужно ли продавать с убытком при падении цены
        'stop_loss': 2, # 2%  - На сколько должна упасть цена, что бы продавать с убытком
        'active': False,
    }
]

Первая часть от ['base': 'ETH',] до ['active': True,] это настройки работы бота по первой паре только по покупке? Или и по покупке и по продаже? Это разные пары валют и бот может работать по двум разным парам?
Если это разные пары? то почему настройка пары ETH-ADA отличаются от настроек пары USDT-NEO? А именно 'profit_markup' в одном примере вы указываете 1=1% во втором 0.001 = 0.1%?

Я думал что первый блок есть операция продажи и ставил BTC-USDT, вторую операцию USDT-BTC это обратная операция....
Проголосовать Проголосовать
0 0
22.08.2019 07:29:39
Это разные пары, можно и больше двух пар, он покупает и продает сам, обратную пару прописывать не нужно
Вообще обратной пары не существует, он по какой купил по той и продает, меняется тип операции
Проголосовать Проголосовать
0 0
18.09.2019 10:57:45
Здравствуйте Андрей! Скажите пожалуйста как сделать цикл запросов к бирже каждые 5-10 секунд , а не мгновенно на всех стадиях работы бота?
Проголосовать Проголосовать
0 0
24.09.2019 08:52:53
Здравствуйте, 
Самое простое в классе binance_api добавить time.sleep(5) в методе call_api
Проголосовать Проголосовать
0 0
18.09.2019 11:57:25
Traceback (most recent call last):
  File "./binance_bot.py", line 43, in main_flow
    order_status = stock_order_data['status']
KeyError: 'status'
2019-09-18 14:52:34,080 [DEBUG] Получаем все неисполненные ордера по БД
2019-09-18 14:52:34,080 [DEBUG] Получены неисполненные ордера из БД: [('26470100
6', 'BNBBTC')]
2019-09-18 14:52:34,080 [DEBUG] Starting new HTTPS connection (1): api.binance.c
om:443
2019-09-18 14:52:34,502 [DEBUG] https://api.binance.com:443 "GET /api/v3/order?s
ymbol=BNBBTC&orderId;=264701006&timestamp;=1568807553000&signature;=729edd9f910e17b
f202984b04604f78c8fb72096d4bda248fb8254d84172288d HTTP/1.1" 400 None
{"code":-1021,"msg":"Timestamp for this request was 1000ms ahead of the server's
 time."}
2019-09-18 14:52:34,502 [ERROR] 'status'
Traceback (most recent call last):
  File "./binance_bot.py", line 43, in main_flow
    order_status = stock_order_data['status']
KeyError: 'status'
2019-09-18 14:52:34,517 [DEBUG] Получаем все неисполненные ордера по БД
2019-09-18 14:52:34,517 [DEBUG] Получены неисполненные ордера из БД: [('26470100
6', 'BNBBTC')]
2019-09-18 14:52:34,517 [DEBUG] Starting new HTTPS connection (1): api.binance.c
om:443
Такая ошибка проскакивает довольно часто . Возможно меня блокирует сторонний прокси сервер или сама биржа. После смены API некоторое время этого не происходит, но потом опять начинается. Вот я думаю если уменьшить частоту запросов в минуту этого можно будет избежать?
Проголосовать Проголосовать
0 0
24.09.2019 08:54:06
Не думаю, у вас синхронизация времени страдает, нужно выставить настройки, причем не на сервера майкрософта, они сбойные (и идут в Windows по умолчанию)
Проголосовать Проголосовать
0 0
18.09.2019 21:10:50
Андрей, доброго здравия. Не подскажите как через Ваше API для Binance выставлять их OCO Ордера, содержащие в себе и тейк-профит и стоп-лосс. По лимитникам и маркет все четко расписано, а по  OCO Ордерам инфы нет. Я думаю это новшество полезно будет, т.к. боту нет необходимости после купли и расстановки OCO  ордера постоянно мониторить рынок, чтоб продать по маркету, если цена не пошла, учитывая что зачастую связь с биржей рвется в течении суток. Спасибо.
Проголосовать Проголосовать
0 0
24.09.2019 08:58:26
Здравствуйте, нужно по образцу добавить что то вроде

'newOCO': {'url': 'api/v3/order/oco', 'method':'POST', 'private':True},

и потом вызывать его
bot.newOCO(symbol="BNBUSDT", side="BUY", quantity=10, price=19, stopPrice=20)
Проголосовать Проголосовать
0 0
03.10.2019 21:22:08
Добавил, попробовал на паре BTCUSDT:
    new_order_buy = bot.newOCO( # Создаем ордер на покупку
    symbol='BTCUSDT',
    recvWindow=5000,
    side='BUY',
    quantity='0.001',
    price='7750.12',
    stopPrice='8300.01',
    newOrderRespType='FULL'
    )

 При попытке выставить пишет:
{"code":-1013,"msg":"Stop loss orders are not supported for this symbol."}
Проголосовать Проголосовать
0 0
03.10.2019 21:23:45
Весьма сомнительно, что стоп-лосс ордера не поддерживаются на данной паре через API.
Проголосовать Проголосовать
0 0
05.10.2019 11:37:33
Ну так это же не бот пишет, а биржа, бот просто пытается выставить ордер, и транслирует ответ биржи, в данном случае биржа сообщает об ошибке
Все актуальные настройки пар тут https://api.binance.com/api/v1/exchangeInfo
Для BNBUSDT сейчас OCO включен, насколько я вижу, мб на тот момент не поддерживалось..
Вы точно прописали
'newOCO': {'url': 'api/v3/order/oco', 'method':'POST', 'private':True},
А не скопировали строку с создания ордера?
Проголосовать Проголосовать
0 0
05.10.2019 21:52:29
Да, Андрей, прописал в binance_api.py:
# private methods
            'createOrder':      {'url': 'api/v3/order', 'method': 'POST', 'private': True},
            'testOrder':        {'url': 'api/v3/order/test', 'method': 'POST', 'private': True},
            'orderInfo':        {'url': 'api/v3/order', 'method': 'GET', 'private': True},
            'cancelOrder':      {'url': 'api/v3/order', 'method': 'DELETE', 'private': True},
            'openOrders':       {'url': 'api/v3/openOrders', 'method': 'GET', 'private': True},
            'allOrders':        {'url': 'api/v3/allOrders', 'method': 'GET', 'private': True},
            'account':          {'url': 'api/v3/account', 'method': 'GET', 'private': True},
            'myTrades':         {'url': 'api/v3/myTrades', 'method': 'GET', 'private': True},
            'newOCO':           {'url': 'api/v3/order/oco', 'method':'POST', 'private':True},
Посмотрел по актуальным настройкам биржы, что OCO включен, но ошибку ту же присылает, блин. Вы пробовали подобное проворачивать? В чем может быть проблема? Официальный мануал по API Бинанса с Гитхаб читал по теме OCO ордеров. Вроде все правильно, но не работает...
Проголосовать Проголосовать
0 0
02.10.2019 12:49:52
Выставил стоп-лосс 1%, однако при подходе к этой цене продажи не было.

        'base': 'USDT',
        'quote': 'EOS',
        'spend_sum': 15,  # Сколько тратить base каждый раз при покупке quote
        'profit_markup': 0.5, # Какой навар нужен с каждой сделки? (0.001 = 0.1%)
        'use_stop_loss': True, # Нужно ли продавать с убытком при падении цены
        'stop_loss': 1, # 2%  - На сколько должна упасть цена, что бы продавать с убытком
        'active': True,

2019-10-02 15:39:58,023 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-10-02 15:39:58,756 [DEBUG] https://api.binance.com:443 "GET /api/v3/ticker/bookTicker?symbol=EOSUSDT HTTP/1.1" 200 None
2019-10-02 15:39:58,779 [DEBUG] Цена изменилась на -1.02450039%, процент для продажи 0.50000000
2019-10-02 15:39:58,783 [DEBUG] Цена не изменилась до нужного %
2019-10-02 15:39:58,822 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-10-02 15:39:59,600 [DEBUG] https://api.binance.com:443 "GET /api/v3/ticker/price?symbol=EOSUSDT HTTP/1.1" 200 None
2019-10-02 15:39:59,625 [DEBUG] Получаем из настроек все пары, по которым нет неисполненных ордеров
2019-10-02 15:39:59,639 [DEBUG] По всем парам есть неисполненные ордера
2019-10-02 15:40:59,664 [DEBUG] Получаем все неисполненные ордера по БД
2019-10-02 15:40:59,671 [DEBUG] Получены неисполненные ордера из БД: [('103771620', 'ADAUSDT'), ('120860536', 'TRXUSDT'), ('298700813', 'EOSUSDT')]
Проголосовать Проголосовать
0 0
05.10.2019 11:48:20
Бот в процессе работы несколько раз запрашивает текущие курсы.
Сначала он проверил, не пора ли продавать с профитом, запросил курсы, получил эту строку
2019-10-02 15:39:58,779 [DEBUG] Цена изменилась на -1.02450039%, процент для продажи 0.50000000
После этого выяснил, что с профитом продавать рано, и переключился на ветку продажи по стоплоссу.
Там заново запросил курсы, и, полагаю, ситуация уже была другой. Тут, к сожалению, лог не пишется (хотя стоило бы), но если бы курс был по прежнему на 1%, то он продал бы и написал в лог
Проголосовать Проголосовать
0 0
30.10.2019 09:25:46
Андрей, подскажите, пожалуйста. Смутила вот эта часть кода, не могу понять:
upper, middle, lower = ta.BBANDS(closes, ma_period=21)
                        if high[-1] > upper[-1]:
                            # Свеча пробила верхнюю полосу Боллинджера

Как сделать, чтобы очки в enter_points добавлялись тогда, когда боллинджер показывает, что цена вышла из зоны перепроданности? Это ведь нижняя полоса, насколько я понимаю?
Проголосовать Проголосовать
0 0
10.11.2019 10:09:13
Вы можете манипулировать этими значениями тоже, например:
 if low[-2] > lower[-2] and  low[-1] < lower[-1] :

Вторая с конца (текущего момента) свеча была выше нижней линии Боллинджера, а последняя свеча нырнула ниже
Проголосовать Проголосовать
0 0
Пожалуйста, авторизуйтесь, что бы оставить свой комментарий
Крипто-кошельки для помощи и благодарности проекту:

Bitcoin адрес проекта: [[address]]

Перевод на сумму [[value]] BTC получен. Спасибо!.
[[error]]

Ethereum адрес проекта: [[address]]