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

Андрей К…
Последнее изменение:
101
2
0

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

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

  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 из папки с ботом, это его база данных, он создаст новую при запуске.

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

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

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

Комментарии: (101)
23.06.2019 22:16
после запуска и остановки в линуксе через 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'
24.06.2019 09:39
Биржа отвечает с кодом 400, это значит что она не может обработать входящий запрос. А настройки API ключей не менялись? Может там пробелы какие..
21.04.2021 19:05
Не тратьте время на это дерьмо, ничего серьезного не добиться от этого бота, Только в учебных целях, научится питону не более:
111) и самое главное бот не стабильный, пропускает стоп-лосси лимиты на продажу, даже если его допилить чтоб он после продажи не покупал снова, бот будет пропускать то что должен делать.
24.06.2019 13:32
Разобрались, обновлен код бота в архиве
03.07.2019 23:10
Добрый день! Спасибо за Ваш труд.
Протестировал бота - вход происходит в торги удачно: по маркету было куплено три монеты когда условия сложились до 7 входных баллов, однако когда курс купленных монет превысил на утро более 1 процент - продажа не осуществилась ни по одной из них. Пришлось все скидывать вручную.
Можно ли настроить чтобы на продажу выставлялся ордер?
05.07.2019 16:52
Ордер должен выставляться, когда рост монеты превысит курс, указанный в настройках, может быть в настройках указан большой процент?
Или столкнулись с какой то ошибкой в логах?
06.07.2019 02:29
Процент указан 1% (ваши настройки по умолчанию, кроме валютных пар и количества закупа), валюта выросла на 2 % - в логах ошибок не было. Но по маркету не продалась ни одна из закупленных пар.
20.07.2019 14:16
после запуска и остановки  - постоянно выходит ошибка?????? Что делать????
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>
29.07.2019 15:39
Что то не так указано в настройках, предлагаю скачать бота по новой и аккуратно заменить настройки нужных пар
22.07.2019 22:08
Еще было бы прикольно реализовать нечто вроде дельта-функции для МА и ЕМА, что бы бот закупался при условии, что длинная скользящая идет наверх. А так работа выше всяких похвал)
31.07.2019 07:34
Добрый день!
Бот работает (покупает, продает, пишет в логфайл) минут 20 потом останавливается. После перезапуска все опять работает минут 20 -25. В чем проблема может быть?
31.07.2019 12:47
Может быть у вас другие какие то процессы к бирже тоже обращаются, и биржа вас блокирует? Редкий конечно случай, но бывает
01.08.2019 03:25
Во время работы бота заходили через браузер на сайт Binance. Проверка баланса, просмотр графиков. 
А можно ли в самом боте установить проверку на блокировку сайтом? То есть если сайт нас заблокировал то бот перезапустится  через указанное время.
03.08.2019 13:05
Блокируется доступ к API в первую очередь, причем не биржей, а проксирующим сервером, наподобие CloudFront, проверять доступность лучше сразу по ссылкам к апи, например https://api.binance.com/api/v1/exchangeInfo

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

Думаю, стоит начать именно с запуска бота на сервере (https://bablofil.ru/kak-zapustit-bota-na-servere), что бы исключить варианты, что сбоит ващ WiFi, роутер, провайдер интернета и т.п.
02.08.2019 07:07
Или как прописать в боте запрос через каждые 15 сек?
03.08.2019 13:07
В файле binance_api пропишите time.sleep(15), тогда пока один запрос к бирже не отработает второй не будет запускаться.
Но если будете несколько ботов в параллели запускать, то это не поможет
02.08.2019 13:55
Выходит ошибка:
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'
03.08.2019 13:08
Проверьте синхронизацию времени, правильность написания пары, апи ключей и т.п.
Там еще может отображаться ошибка в консоли, которая не попадает в лог, посмотрите, пишется ли там что то
04.08.2019 03:29
ради научного интереса решил поиграться с кодом: попытался сделать так чтоб бот продавал по анализу свечей:

# Если ордер уже исполнен
                        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."}
Я так понимаю это связано с расчетом  комиссии, вернее с его отсутствием.
В программировании  мало опыта, подскажите пожалуйста на мои недочеты. Заранее благодарю
04.08.2019 04:30
И еще в консоли пишет "получено 0.00986200", а на самой бирже смотрю там баланс 0.00985234
04.08.2019 13:28
У вас видимо комиссия берется не в BNB
Купите немного BNB, закиньте на баланс, тогда количество полученного будет совпадать, а уменьшаться будут монеты BNB
Так вроде все ок
04.08.2019 17:17
благодарю! разобрался)
12.08.2019 08:31
Еще раз здравствуйте. 
Теперь такой вопрос: как сделать запись логирования в разные файлы? То есть в первый файл записывать все в подробностях, с полями debug. В другой файл  только с полями info. Или может можно сразу краткую статистику по сделкам записывать в файл xls?
13.08.2019 08:18
Посмотрите как в начале создается объект log - как вариант можно можно создать еще один и использовать его при необходимости. В эксель вы можете писать используя соответствующие модули, например openpyxl, пример можете посмотреть тут https://bablofil.ru/birja-excel/
04.11.2019 19:15
Задался этим же вопросом. Погуглив и почитав инфу о модуле 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)
18.08.2019 22:50
Часть лога работы бота:

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

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

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 это обратная операция....
22.08.2019 07:29
Это разные пары, можно и больше двух пар, он покупает и продает сам, обратную пару прописывать не нужно
Вообще обратной пары не существует, он по какой купил по той и продает, меняется тип операции
18.09.2019 10:57
Здравствуйте Андрей! Скажите пожалуйста как сделать цикл запросов к бирже каждые 5-10 секунд , а не мгновенно на всех стадиях работы бота?
24.09.2019 08:52
Здравствуйте, 
Самое простое в классе binance_api добавить time.sleep(5) в методе call_api
14.02.2021 11:19
В таком случае будет задержка между принятием решения и http запросом, за которую может измениться цена. Лучше поставить sleep в начале циклов по ордерам и оставшимся парам.
18.09.2019 11:57
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 некоторое время этого не происходит, но потом опять начинается. Вот я думаю если уменьшить частоту запросов в минуту этого можно будет избежать?
24.09.2019 08:54
Не думаю, у вас синхронизация времени страдает, нужно выставить настройки, причем не на сервера майкрософта, они сбойные (и идут в Windows по умолчанию)
18.09.2019 21:10
Андрей, доброго здравия. Не подскажите как через Ваше API для Binance выставлять их OCO Ордера, содержащие в себе и тейк-профит и стоп-лосс. По лимитникам и маркет все четко расписано, а по  OCO Ордерам инфы нет. Я думаю это новшество полезно будет, т.к. боту нет необходимости после купли и расстановки OCO  ордера постоянно мониторить рынок, чтоб продать по маркету, если цена не пошла, учитывая что зачастую связь с биржей рвется в течении суток. Спасибо.
24.09.2019 08:58
Здравствуйте, нужно по образцу добавить что то вроде

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

и потом вызывать его
bot.newOCO(symbol="BNBUSDT", side="BUY", quantity=10, price=19, stopPrice=20)
03.10.2019 21:22
Добавил, попробовал на паре 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."}
03.10.2019 21:23
Весьма сомнительно, что стоп-лосс ордера не поддерживаются на данной паре через API.
05.10.2019 11:37
Ну так это же не бот пишет, а биржа, бот просто пытается выставить ордер, и транслирует ответ биржи, в данном случае биржа сообщает об ошибке
Все актуальные настройки пар тут https://api.binance.com/api/v1/exchangeInfo
Для BNBUSDT сейчас OCO включен, насколько я вижу, мб на тот момент не поддерживалось..
Вы точно прописали
'newOCO': {'url': 'api/v3/order/oco', 'method':'POST', 'private':True},
А не скопировали строку с создания ордера?
05.10.2019 21:52
Да, Андрей, прописал в 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 ордеров. Вроде все правильно, но не работает...
02.10.2019 12:49
Выставил стоп-лосс 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')]
05.10.2019 11:48
Бот в процессе работы несколько раз запрашивает текущие курсы.
Сначала он проверил, не пора ли продавать с профитом, запросил курсы, получил эту строку
2019-10-02 15:39:58,779 [DEBUG] Цена изменилась на -1.02450039%, процент для продажи 0.50000000
После этого выяснил, что с профитом продавать рано, и переключился на ветку продажи по стоплоссу.
Там заново запросил курсы, и, полагаю, ситуация уже была другой. Тут, к сожалению, лог не пишется (хотя стоило бы), но если бы курс был по прежнему на 1%, то он продал бы и написал в лог
30.10.2019 09:25
Андрей, подскажите, пожалуйста. Смутила вот эта часть кода, не могу понять:
upper, middle, lower = ta.BBANDS(closes, ma_period=21)
                        if high[-1] > upper[-1]:
                            # Свеча пробила верхнюю полосу Боллинджера

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

Вторая с конца (текущего момента) свеча была выше нижней линии Боллинджера, а последняя свеча нырнула ниже
11.03.2020 08:20
Андрей, добрый день.

При пробитии верхней границы полосы Боллинджера мы ожидаем спада цены, мы действительно там должны входить в рынок с покупкой?
Возможно нужно внести измененный индикатор, нам необходимо побитие именно нижней полосы Боллинджера?

14.02.2021 15:41
статистика показывает, что вы правы
18.11.2019 17:42
Здравствуйте! Что за ошибку бот выкидывает?
2019-11-18 16:50:08,023 [DEBUG] Свеча набрала 7.3 баллов
2019-11-18 16:50:08,023 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-11-18 16:50:08,477 [DEBUG] https://api.binance.com:443 "GET /api/v3/account?timestamp=1574085007000&signature=48733ce161bbe6ce3ad5cb943d53c59558ca5853ddcd75a39bf02863fa2c8e9b HTTP/1.1" 401 None
2019-11-18 16:50:08,477 [ERROR] Пропускаем пару TRXUSDT
Traceback (most recent call last):
  File "./binance_bot.py", line 272, in main_flow
    balance['asset']: float(balance['free']) for balance in bot.account()['balances']
KeyError: 'balances'
25.11.2019 07:49
Здравствуйте!

Проверьте апи ключи, а так же синхронизируйте время на компьютере с мировым
11.12.2019 19:34
Добрый день
Бот покупает - но не продает - по всем парам ошибка типа этой

2019-12-12 03:28:55,782 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-12-12 03:28:56,460 [DEBUG] https://api.binance.com:443 "GET /api/v3/ticker/bookTicker?symbol=ZECUSDT HTTP/1.1" 200 None
2019-12-12 03:28:56,464 [DEBUG] Цена изменилась на 0.67956903%, процент для продажи 0.00500000
2019-12-12 03:28:56,470 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-12-12 03:28:57,070 [DEBUG] https://api.binance.com:443 "POST /api/v3/order HTTP/1.1" 400 None
2019-12-12 03:28:57,078 [WARNI] Не удалось создать ордер на продажу {'code': -2010, 'msg': 'Account has insufficient balance for requested action.'}
2019-12-12 03:28:57,087 [DEBUG] Starting new HTTPS connection (1): api.binance.com:443
2019-12-12 03:28:57,714 [DEBUG] https://api.binance.com:443 "GET /api/v3/ticker/price?symbol=ZECUSDT HTTP/1.1" 200 None


Руками не торгую - пишет суммы не хватает, версия  от ноября
12.12.2019 07:31
Я так полагаю, либо у вас на балансе нет BNB, либо выключена настройка "платить комиссию в BNB". Бот в итоге покупает сумму S, но по факту получает S-fee, пытается продать S, но столько в наличии нет.
Закупите bnb для комиссий
26.12.2019 19:57
вопрос:
в файле congig.ry
для 'base': 'ETH',
        'quote': 'ADA',
'profit_markup': 1, # Какой навар нужен с каждой сделки? (1=1%)

для  'base': 'USDT',
        'quote': 'NEO',
'profit_markup': 1, # Какой навар нужен с каждой сделки? (0.001 = 0.1%)

Почему в оном случае 1=1%, а в другом уже другая зависимость? и как мне понять, что писать для других пар?
31.12.2019 19:21
Выдает ошибку:
2019-12-31 19:04:13,827 [DEBUG] "GET /api/v1/klines?symbol=ETHBTC&interval=1h&limit=200 HTTP/1.1" 200 None
2019-12-31 19:04:13,829 [DEBUG] "GET /api/v1/exchangeInfo HTTP/1.1" 200 None

Забиваю в адресную строку браузера: https://www.binance.com/api/v1/klines?symbol=ETHBTC&interval=1h&limit=200 HTTP/1.1
выдает:
code	-1100
msg	"Illegal characters found in parameter 'limit'; legal range is '^[0-9]{1,20}$'."
при этом строка https://www.binance.com/api/v1/klines?symbol=ETHBTC&interval=1h&limit=200 выдает, много данных, видимо, то что нужно.

В доках API Binance пишут, что уберут API v1 и будет API v3.
Как сделать, чтоб работало?
01.01.2020 21:12
В логе ошибки нет, это просто отчет о том, что адрес был успешно запрошен. Если все же ошибка есть, кидайте сюда.
Насчет перехода на V3 достаточно в файле binance_api поменять v1 на v3 в соответствующих методах, формат сообщений не изменился, насколько я вижу. В любом случае, еще есть почти год на переход.
02.01.2020 10:10
2019-12-31 19:04:14,102 [DEBUG] Работаем с парой HCETH
2019-12-31 19:04:14,102 [DEBUG] Проверяем индикаторы
2019-12-31 19:04:14,106 [INFO ] Starting new HTTPS connection (1): api.binance.com
2019-12-31 19:04:14,310 [DEBUG] "GET /api/v1/klines?symbol=HCETH&interval=1h&limit=200 HTTP/1.1" 200 None
2019-12-31 19:04:14,327 [ERROR] Пропускаем пару HCETH
Traceback (most recent call last):
  File "./bot/binance_bot_v2/binance_bot.py", line 249, in main_flow
    fast, slow = ta.STOCH(high, low, closes, 5, 3, 3)
  File "/root/bot/binance_bot_v2/bablofil_ta.py", line 192, in STOCH
    fastk.append(((closes[i] - curr_low) / (curr_high - curr_low)) * 100)
ZeroDivisionError: float division by zero

Последние 6 строк это ошибка? Почему пропускает на 5 строке? В других случаях, он баллы высчитывает, а тут пропускает.
02.01.2020 15:35
Последние 6 строк да, сообщения об ошибках.
Тут происходит деление на ноль, но это не из-за того, что он данные не получил, а из-за того, видимо, что текущий high по паре совпал с текущим low, если посмотрите график по паре, то так оно и есть
https://snipboard.io/1uQ52d.jpg
С такими ровными графиками теханализ работать не может.
Вообще на будущее нужно будет такое предусмотреть в коде, добавить внятное описание ошибки, и пропуск таких пар, но в целом оно так сейчас и работает. Просто подождите, пока начнется какое-то движение по паре, и снова всё заработает
03.01.2020 18:27
"Если хотите начать все заново, удалите файл binance.db из папки с ботом, это его база данных, он создаст новую при запуске."
Остановил бота, продал вручную закупленные ботом монеты, удалил файл binance.db из папки с ботом. Запустил заново, теперь пишет:
2020-01-02 10:23:48,478 [DEBUG] Цена изменилась на 3.06608884%, процент для продажи 1.00000000
2020-01-02 10:23:48,481 [INFO ] Starting new HTTPS connection (1): api.binance.com
2020-01-02 10:23:48,690 [DEBUG] "POST /api/v3/order HTTP/1.1" 400 None
2020-01-02 10:23:48,695 [WARNI] Не удалось создать ордер на продажу {'code': -2010, 'msg': 'Account has insufficient balance for requested action.'}
Типа пытается продать, то что купил ранее, а нету монет уже.
Смотрю в папку с ботом, а там нет, вновь созданного binance.db. Нашел такой файл в папке - выше в root. т.е. бот при первом запуске создал этот файл изначально в root - не в папке с ботом. Сами файлы бота лежат типа в root/papka/papka/(файлы бота). Как ему задать рабочую папку текущую, где лежит бот?
03.01.2020 19:51
Бот запускаю на удаленном сервере Ubuntu 16, python 3.6. Удалил binance.db из root, перезапустил бота. Файл создался, снова в root. Но не сразу, хотя закупился бот давно уже.
04.01.2020 07:29
Бот создает файл в той папке, откуда запущен интерпретатор питон

Самое простое это перейти сразу в папку с ботом и запускать оттуда
cd /root/papka/papka
python3.8 ./binance_bot.py

Можно в файле binance_bot.py поменять строку
conn = sqlite3.connect('binance.db')
на
conn = sqlite3.connect('/root/papka/papka/binance.db')

Тогда будет неважно, откуда запускать
07.01.2020 19:20
Индикаторы это хорошо:) А вы можете добавить режим тестирования индикаторов по истории свечей? С выдачей результата торгов: кол-во прибыльных/убыточных сделок. Чтоб можно было настроить стратегию, включить режим теста и бот, вместо торгов, сперва протестировал и выдал процент удачных сделок по истории. Затем режим теста в False, и торгуем в нормальном режиме. Так можно проверить правильность настройки и подобрать стратегию с наибольшим процентом удачных сделок не теряя время на длительные тесты. И видно будет четкие результаты в цифрах.
11.01.2020 12:44
Это называется backtesting, он может дать примерную ретроспективную картину, вообще можно найти уже готовые решения, я когда-то брал свечи с Полоникса (тогда не было Бинанса), и эмулировал по ним. Думаю, для Бинанса сейчас вполне можно так сделать, я подумаю как лучше это оформить.
09.01.2020 13:47
Подскажите, пожалуйста, как добавить в лог запись о том, какие индикаторы сработали и прибавили баллов.
Чтоб было примерно так:
2020-01-09 13:00:16,345 [DEBUG] Свеча набрала 2 баллов = macd(1) + BB(1).
или так:
2020-01-09 13:00:16,345 [DEBUG] Свеча набрала 2 баллов = 1 балл (macd) + 1 балл (BB).

Чтоб видно было какой индикатор сработал и сколько баллов добавил. Потом легче сравнивать с графиком на бирже и понятно будет, срабатывает как было задумано или нет.
11.01.2020 12:40
Самое простое это везде добавить вывод в лог, вот так например

if rsi_9[-1] < 70 and rsi_14[-1] < 70 and rsi_21[-1] < 70:
    # RSI не показывает перекупленности
    enter_points += 2
    log.debug("Сработал RSI, текущее значение " + str(enter_points))

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

ну и т.п.
12.01.2020 13:05
Настроил на бирже в TradingView те же индикаторы, с одинаковыми параметрами, как в боте. Минутный график. Бот совершал сделки, время входа точное до минуты. Смотрю по истории, а свеча не дотягивает до нижней линии Боллинджера. А по условиям настроенного индикатора, свеча должна пробить нижнюю линию BB. Получается эти линии смещаются, после того, как появляется последующая история. Уже после точки входа в сделку. Чтоб проверять по истории, надо как-то ухищряться
Еще заметил, крипта, которой торгуют за доллары имеет примерно одинаковые графики. И входят в рынок почти в одно и то же время, т.к. индикаторы на все пары настроены одинаковые. Нет смысла торговать на разных валютных парах со схожими графиками, если точки входа в торги одинаковы. В таких парах, только проценты роста и падения разные. Как настроить для каждой пары свои индикаторы, с разными параметрами, чтоб посути на одинаковых графиках, но на разных парах, тестировать разные стратегии? Или как на одну и ту же пару настроить разные стратегии:) Чтоб на низко рисковые стратегии закупаться на большую сумму, на более рискованные сделки входить с меньшими суммами.
12.01.2020 17:40
Да, всё так, центральная линия Боллинджера это скользящая средняя, она меняется при поступлении новых данных, таковы свойства индикатора и средних чисел в принципе. А т.к. верхний и нижний пояса это отклонения от средней, то меняются и они.
Вы можете запускать несколько экземпляров бота, каждого в своей папке, и менять им параметры, хотите, ставьте одинаковые пары с разными параметрами, лимит обращений вы вряд ли превысите, проблемы если и начнутся, то где то после 20 одновременных ботов
13.01.2020 21:46
Чтоб к этому боту прикрутить Trailing stop, нужно для каждой пары сохранять цену стоп лоса в базу данных. Затем при проверке, пора ли продавать - изменять этот стоп лос и записывать новое значение в базу данных, либо продавать по текущей цене. В коде на месте сверки с % продажи, вставлять Long алгоритм из Trailing stop. 
Или другой подход: значение stop_loss, изначально заданное в config.py, изменять как-то отдельным потоком, тогда binance_bot.py не нужно будет менять, главное, чтоб была включена продажа по стоплосу. Но отдельным потоком это значение будет меняться в реальном времени, а при создании новой сделки, это значение нужно возвращать к изначальному из config.py. И уже в этом модуле, можно любой алгоритм втыкать, хоть Trailing stop, хоть проверку индикаторов - если нужное условие сработало, изменить процент, так, чтоб продажа произошла прямо сейчас - сработала продажа по стоплосу. Можно без записи в базу данных обойтись. При перезапуске бота, произойдет сверка с текущей ценой, и если она выше, то стоплос изменится и продолжится отслеживание роста цены и смещение % стоплоса. В питоне же есть потоки, а у вас статей о них нет :) Вот и тема для статьи :)
14.01.2020 14:01
Почему же, статья про потоки есть https://bablofil.ru/python-multithreading/
Прикрутить трейлинг совсем не сложно, есть разные способы и разные виды трейлинга, каждому нужно по своему)
15.01.2020 15:07
Уважаемый Андрей!    Огромное спасибо за Ваш  труд и желание поделиться  своими наработками. Перечитал все  ваши статьи, благодаря им освоил( в необходимых для данных задач обьемах) программирование на Питоне, сделал свои варианты Ботов.  
Мой бот покупает на минимумах курсов продает на Максимумах. Биржа Binance.  Но проблема в том, что даже на 1минтуных таймфреймах информацию мы получаем по окончании минутного интервала, после смены  тренда  и, как правило,  цена уходит  за это время при смене локального тренда  Грубо говоря - шел рост, рост, рост курса, потом  началось падение, и через минуту пришла красная 1m свеча и фактически только в этот момент робот принимает решение о выставлении ордера на продажу, а курс уже упал  - бывает на  10-20$  - если речь про BTC-USDT

Вопрос:  Рельно ли сделать отдельным потоком  формирование своих свеч с меньшим интервалом - например,  10 сек вместо минуты.  Меня Интересует ваше мнение  о том, какие  сложности вы видите в реализации данной задачи.
   Этот поток будет работать не постоянно, и   включаться  в  опрос текущих сделок на бирже и формировать свои свечи ТОЛЬКо  в отдельные моменты, когда  идут экстремумы  в графиках тех или иных  показателей   на 1минутном  таймфрейме.
16.01.2020 06:38
Добрый день, конечно реально
Нужно получать историю сделок, группировать их время создания по нужными интервалам, соответственно low и high свечи будут наименьшей и наивысшей ценами сделок, open - цена первой сделки, close- цена последней, объем - суммарный объем сделок в периоде. Хотите, делайте 3-х секундные свечи, хотите - 11 секундные и т.п.
14.04.2021 07:25
Здравствуйте, а можно ли получать данные о сделках в реальном времени , там на графиках есть Time меньше 1m? тогда данные о сделках были бы в реальном времени и логика бота уже была актуальной в текущий момент времени?
18.04.2021 14:20
Не получается получить историю торгов, так как метод Public, 

            'historicalTrades': {'url': 'api/v3/historicalTrades', 'method': 'GET', 'private': False},

если оставляешь как есть пишет:

2021-04-18 14:09:13,265 [DEBUG] https://api.binance.com:443 "GET /api/v3/historicalTrades?symbol=BTCUSDT&limit=500 HTTP/1.1" 401 46
2021-04-18 14:09:13,279 [DEBUG] История торогов {'code': -2014, 'msg': 'API-key format invalid.'}

а если ставлю метов в Private:

            'historicalTrades': {'url': 'api/v3/historicalTrades', 'method': 'GET', 'private': True},

2021-04-18 14:03:08,856 [DEBUG] https://api.binance.com:443 "GET /api/v3/historicalTrades?symbol=BTCUSDT&limit=500&timestamp=1618754587000&signature=4824cb3fee4f5237d45b1242f3646f6bfa3ac9a56f3806829c1a9d5e919e4474 HTTP/1.1" 400 74
2021-04-18 14:03:08,968 [DEBUG] История торогов {'code': -1101, 'msg': "Too many parameters; expected '3' and received '4'."}

это от сюда:
                        history = bot.historicalTrades(
                            symbol='BTCUSDT',
                            limit=500
                            #fromId= (тут не понятно что писать, оставил 2 параметра)
                        )
                        log.debug("История торогов " + str(history))

как можно оформить код , чтобы лишние параметры не отправлялись? я так понял, что надо в request было только 3 параметра, а отправляются время (timestamp) и данные об зашифрованном ключе API (signature).

Как бы вы сами реализовали получение истории?
18.04.2021 18:14
Всё разобрался, удалось получить массив данных последних сделок.
16.01.2020 08:07
Здравствуйте. У меня вот такая проблема, раза три уже случалась:
2020-01-15 21:23:46,950 [DEBUG] "GET /аpi/v1/klines?symbol=E0SUSDTSinterva1=lm&l imit=200 HTTP/1.1" 200 None
2020-01-15 21:23:47,014 [DEBUG] Свеча набрала 0 баллов
2020-01-15 21:23:47,019 [DEBUG] Минимальный проходной балл 2. Пропуск пары 2020-01-15 21:23:47,019 [DEBUG] Работаем с парой DASHUSDT 2020-01-15 21:23:47,019 [DEBUG] Проверяем индикаторы
2020-01-15 21:23:47,038 [INFO ] Starting new HTTPS connection (1): api.binance.com
[23772812.390793] Out of memory: Kill process 22529 (python3) score 28 or sacrifice child
[23772812.394352] Killed process 22529 (python3) total-vm:229532KB, anon-rss:279 20KB, file-rss:1676KB
[36]+ Killed	python3 ./bot/binance_bot_v2/binance_bot.py
Killed
rootOubuntu-s-lvcpu-lgb-sfo2-01:`#

И бота выкидывает, все останавливается. Я так понял, память забивается чем-то, и сервак вырубает бота. Удаленный сервер Ubuntu 16, python 3.6.
16.01.2020 19:17
Снес все, поставил ubuntu18, там сразу Python 3.6.9. Поставил какую-то приблуду для мониторинга сервера - теперь показывает загруженность ОЗУ. Будем посмотреть, повторится ли ошибка снова. Есть подозрения, что виноват Proxy сервер, который раньше был на той же машине:) Он был без пароля. Злые юзеры нашли его и бесплатно пользовались. Логов на 5 Гбайт накопилось:)))
21.01.2020 18:42
Из википедии:
EUR/USD
Цена данной валютной пары показывает, какое количество долларов США (USD) можно приобрести за 1 единую европейскую валюту (EUR). Открывая ордер «buy» трейдер приобретает EUR, расплачиваясь при этом USD. При фиксировании прибыли совершается обратная операция — покупка USD за EUR. В данной паре EUR является базовой валютой. Это утверждение верно по отношению ко всем мировым валютам.

т.е. EUR является базовой валютой - первая валюта базовая, вторая котируемая, а у вас все наоборот:)
27.01.2020 00:39
Странно что никто не обратил внимания, но в программе ошибка или опечатка:
# USE_OPEN_CANDLES = True - использовать последнюю (текущую) свечу для расчетов
# USE_OPEN_CANDLES = False - Использовать только закрытые свечи
Эти комменты ошибочны

Реально все как раз наоборот - если False - то при расчетах используется  в том числе и последняя по времени свеча,  а если True   - то только закрытие свечи.
Это видно и по коду:
 klines = klines[:len(klines) - int(USE_OPEN_CANDLES)]  при значении  False - использовался весь массив , включая последнее значение

и реально проверено на практике:   брались свечи с интервалом  несколько секунд и значение closes[-1]  менялось,  только если 
USE_OPEN_CANDLES = False 

PS  если кто то не согласен, убедите , обьясните,  что я не так понимаю
31.01.2020 15:36
Да, спасибо, должно быть наоборот, обновил код
04.02.2020 17:40
Мне кажется, для RSI важнее сочетание значений на разных таймфреймах с разными периодами. А тут получается таймфрейм один, а периоды разные.
01.03.2020 08:57
Это вопрос стратегии и использовании инструмента. Код не так сложно приспособить под разные таймфреймы, кому то это нужно, кому то нет
18.02.2020 07:51
Здравствуйте! открыл файл binance_bot.py в редакторе. показал на 78 строчке кода ошибку, связанную с использованием переменной pair_name до ее объявления. и по моему там еще табуляция перед условным оператором else смещена.
18.02.2020 16:54
Вопрос снят восполнением знаний! спасибо
20.02.2020 12:38
Здравствуйе, Андрей! Подскажите. Дописал свой индикатор. Прикрутил его в bablofil_ta. Но при тестировании бота выходит ошибка NameError: name 'OSCV' is not defined. Т.е. файл binance_bot не видит индикатор который записан в bablofil_ta. Как такое возможно? Оба файла в одной папке.
20.02.2020 15:26
вопрос снят... тоже восполнением знаний. А также использованием метода научного тыка.
23.03.2020 05:19
Здравствуйте, выше было несколько вопросов но так и не последовало ни одного ответа!

В файле конфига profit_markup и stop_loss какое значение будет верным? 1 = 1% или 0,01 = 1% ?
30.03.2020 17:08
1=1% Это верно. У меня так, и отрабатывает правильно
28.03.2020 20:32
Здравствуйте, Андрей!
А можете пояснить назначение переменной (колонки в БД) buy_verified? Из названия ясно, что переменная должна подтверждать покупку, но все равно не понял как это все связывается в Вашем боте.
31.03.2020 23:02
Здравствуйте Андрей спасибо вам большое за бота,скажите пожалуйста если возможность сделать так что бы бот сам принимал решение когда продавать ориентировался исключительно по индикатором и принимал решение о продаже.то есть сейчас как я понимаю он только покупает по индикаторам,а продаёт уже с профитом какой процент ты выставляешь.А хотелось бы что бы бот сам принимал решение когда подорвать. Так к примеры ты выставляешь профит в 2% а курс бах и подскочил на 10% а индикаторы могли бы в этом случае помочь и скажем продастся не на сомом пике а к примеру не на 10 % а на 8% скажем!
Интересно узнать ваше мнение,Спасибо!
01.04.2020 12:46
Дополнения к моему отзыву: У вас в боте есть вот такая строка:
upper, middle, lower = ta.BBANDS(closes, ma_period=21)
 if high[-1] > upper[-1]:
    # Свеча пробила верхнюю полосу Боллинджера
    enter_points += 3
То есть бот ждет пробития верхней полосы и так входит.Но после побития  верхней обычно ожидается спад.Почему бы не сделать что бы бот заходил по  Боллинджеру но только после пробития нижней полосы?
25.05.2020 19:15
Андрей,  ОГРОМНОЕ тебе  СПАСИБО за то что пишешь подобные статьи!!! Правда, от всей души...  респект и уважуха тебе!!!  Твои статьи сподвигли меня на изучение Python,  хотя когда-то в детстве я и занимался программированием,  но потом успешно забросил, сейчас   вот вникаю заново. Написал на основе твоих статей бота,  использующего алгоритм кольца(внутрибиржевой арбитраж.. сделки типа RUB->BTC->USDT->RUB), правда  прибыли он не приносит,  но вопрос сейчас по другой теме.... по индикаторам:

почему-то  стохастический осцилятор  в твоей библиотеке bablofil_ta выдает значения,  не совпадающие с бинансом,  например, бот выдает:
быстр=28, медл=25   
а на бинансе индикатор Stoch показывает  %K(синяя линия) =24, %D(красная линия)=24
при всех прочих равных условиях(таймфреймы,  параметры индикатора  и пр.)

по формуле из википедии проверял - все вроде верно, но не сходятся цифры с бинансом, тот же  RSI  сходится идеально с ботом...

 и еще мне  не понятно зачем заполнять нулями(fastk.append(math.nan)) первые N строк в функциях типа STOCH,  может из-за этого несоответствие?
{code:java}
def STOCH(high, low, closes, fastk_period, slowk_period, slowd_period):
    fastk = []
    
    for i, _ in enumerate(closes):
        if (i + 1) < fastk_period:
            fastk.append(math.nan)
        else:
            lower_bound = i + 1 - fastk_period
            upper_bound = i + 1
            curr_low = min(low[lower_bound:upper_bound])
            curr_high = max(high[lower_bound:upper_bound])
            fastk.append(((closes[i] - curr_low) / (curr_high - curr_low)) * 100)

    fastk = EMA(fastk, slowk_period)
    slowd = EMA(fastk, slowd_period)
{code}
25.05.2020 19:56
кажется до меня дошло.. метод сглаживания(усреднения) бинанс использует другой, если указать без сглаживания, например (12,1,1) то цифры сходятся
07.06.2020 13:11
Добрый день, скорее всего, мой вопрос очень легкий, но знаний у меня маловато. Как получить параметры (обратиться) предыдущей свечи (мин, макс, откр, закр)?
23.06.2020 07:21
Добрый день,

Вот тут массив свечей накапливается
closes = [float(x[4]) for x in klines]
high = [float(x[2]) for x in klines]
low = [float(x[3]) for x in klines]

Соответственно high последней свечи это high[-1], предпоследней high[-2] и т.п. 
цену открытия можно также добавить по аналогии, добавить
open = [float(x[1]) for x in klines]
05.01.2021 03:49
Здравствуйте! Не подскажете, как можно реализовать индикатор Connors RSI?
13.02.2021 12:12
Андрей, спасибо за огромный труд.
Странно, что такой сложный и востребованный продукт интеллектуальной собственности Вы выкладываете в открытый доступ. Не понятна Ваша мотивация) Но программисты люди странные, знаю по себе. Сейчас не об этом.

Для расчёта оптимальных таймфреймов, и значений enter_points собрал 3х-суточную ежеминутную статистику по паре BTCUSDT по всем таймфреймам по текущим 6ти индикаторам, которые участвуют в расчёте enter_points в вашем коде. Кол-во свеч оставил 200. Загнал статистику в БД. Посчитал, для промежутков времени от текущего (1, 3, 5, 10, 30, 60, 90, 120, 180 минут) если индикатор сработал (т.е enter_points увеличилось) и цена увеличилась, значит срабатывание правильное, а если индикатор сработал, но цена стала ниже начальной, то ошибка индикатора. По формуле: "(кол-во правильных срабатываний - кол-во ошибок) / кол-во случаев роста цены" сгруппировав по таймфреймам и промежуткам времени получил таблицу (к сожалению скрин не вставить в коммент). 
По ней видно, что очень редко какой индикатор показывает результат больше 25%. И для разных индикаторов надо брать разные таймфреймы, иначе это полная рулетка. Во многих случаях результаты отрицательные, т.е ошибок больше чем правильных срабатываний. 
В общем, надо дорабатывать бота под оценки индикаторов на разных таймфреймах и кодировать ещё больше индикаторов. Вам спасибо за такой стимул разобраться в pythone.
14.02.2021 18:38
Андрей, добрый день.
Не подскажете, зачем запрашиваются данные по 200 свечам если в индикаторах используется максимум 100 (в SMA, EMA) в других ещё меньше? Или я не правильно понял?

26.03.2021 14:40
Потому что мы берем первые 100 значений, получаем одну точку, потом еще 100 с отступом в 1, получаем вторую точку и т.п.
У нас первые 100 значений будут пустыми, при агрегации в 100
15.04.2021 05:51
Привет админу, большое спасибо за труд, очень интересный проект в свободном доступе! Хотел спросить, как лучше сделать чтобы бот совершал только одну сделку и потом останавливался, до обнуления enter_points , проблема в том что на коротких заходах (микроскальпинг) бот совершает покупку уже на вершине волны, то есть по моей настройке 1 раз он покупает всегда в плюс (+0,5%) и быстро закрывает сделку, но как приостановить бота? 
к примеру (у меня всего 2 бала для входа в покупку): 
enter_points == 2 совершаем покупку, 
прошло минуты 2-3 закрепляем профит +0,5% и далее
пока enter_points  == 2 не делаем покупки 
при снижении enter_points до 0, снова начинаем вычислять баллы для входа (ловим другую волну)
16.04.2021 03:24
Разобрался, немного переделал саму логику и условия теперь бот покупает делает 1 покупку и 1 продажу и ждёт пока все баллы обнулятся на 0. Потом только начинает считать - вчера работал почти весь день, в целом показывает профит, надо смотреть дальше из 100 сделок если хотбы 60 будут верными, то бот профитный.
22.07.2021 17:57
Добрый день, Андрей! Огромное спасибо за много полезной инфы без воды! Сейчас изучаю питон, хочу потестировать бота, где его можно скачать? В статье ссылок нет, на гитхабе другие боты, а этого не нашел, можно ссылку?
18.08.2021 02:06
Andrey Доброго времени суток! Не могу авторизоваться для скачивания файлов. Спасибо
18.08.2021 02:19
все ок, разобрался (AdBlock)
05.09.2021 10:10
**Разобрался, немного переделал саму логику и условия теперь бот покупает делает 1 покупку и 1 продажу и ждёт пока все баллы обнулятся на 0.. **
подскажите как это реализовать в коде ?
Пожалуйста, Авторизуйтесь что бы оставить свой комментарий