Бот для Bittrex - продолжаем продолжать

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

Продолжаем развлекаться - соорудим бота для биржи Bittrex.com.

Регистрацию я расписывать не буду, она довольно тривиальна, а вот с подключением через API «есть нюанс» (с). Дело в том, что биржа параноидальна серьезно относится к безопасности пользователей и сохранности их средств, так что приготовьтесь к многочисленным подтверждениям того, что вы это вы. Так вот.

Подключаем API на Bittrex.com

В меню выбираем Settings – API Keys, и с грустью тоской смотрим на надпись:

To use API Keys, you must have Two-Factor Authentication enabled.

Для использования API необходимо подключить двуфакторную авторизацию. Круто, ну давайте включим. Там же, в Settings, переходим в раздел Two-Factor Authentication и с еще большей болью в сердце видим, что Bittrex использует только и исключительно Google Authenticator.

Пару слов о Google Authenticator: Первый раз я столкнулся с Google Authenticator, когда подключал двуфакторную авторизацию на btc-e.nz. Тогда я подумал, ух ты, как здорово, ставишь приложение на телефон и авторизуешься когда тебе надо, можно симки менять.. Прошло несколько лет, мой телефон давно сломался, я давно купил новый, и вот мне потребовалось зайти на эту биржу и авторизоваться под старым акканутом.. И разверзся ад! Сначала Google меня допрашивал, я ли это, требовал всевозможных подтверждений, гонял по кругу, не верил мне.. Потом вроде заработало. Я попытался авторизоваться на бирже, но теперь биржа начала ругаться на то, что код неправильный. Я сдался, удалил приложение, и пошел делать то, что хотел, на другую биржу. Через несколько месяцев владельца btc-e арестовали, а биржу на месяц прикрыли, потом вроде как перекупили, так что вся эта канитель по сути спасла меня от потери денег. Но Google Authenticator мне все равно с тех пор не нравится.

Так вот. Для двуфакторной авторизации нам нужно установить на телефон Google Authenticator. Это официальное приложение, его можно найти в Play Market и iTunes. После установки приложение попросит вас добавить аккаунт.

Отсканируйте в приложении QR-код с сайта, введите цифры с приложения на сайт, потом перейдите на почту и подтвердите, что вы действительно решили подключить авторизацию. После этого можно работать с ключами API.

Возвращаемся в Settings – API Keys, запускаем Google Authenticator, указываем на странице цифры из приложения, и указываем права доступа – я не стал включать вывод средств, ибо вроде бы незачем. Но вот описание:

  • Read Info – Можно получать информацию о балансе и других свойствах аккаунта
  • Withdraw – Вывод средств на указанный вами адрес. Эта опция может быть полезной для проведения арбитража или переводе средств в cold storage.
  • Trade Limit – Позволяет выставлять отложенные ордера по лимиту
  • Trade Market – Позволяет выставлять отложенные ордера по рынку. ПРЕДУПРЕЖДЕНИЕ (так на сайте написано): Не включайте эту опцию, если точно не уверены, что делаете. Покупки по рынку чрезвычайно опасны!

В общем я включил первые две опции. Насчет предупреждения не понял, т.к. в API нет метода, что бы торговать по рынку. Ну да ладно.

После выставления настроек вводим новые цифры из Google Authenticator, нажимаем Update Keys и ура! Получилось.

Совет – сразу эти ключи сохраните куда-нибудь. Тут строго относятся к безопасности, если забудете, придется новые создавать.


Реклама


Проверяем работу через API

Методы для работы API биттрекса расписаны тут. Изменим немного функцию из бота для эксмо, и попробуем что-то сделать.

Я закинул на баланс немного LTC и создал ордер на продажу по завышенной цене. Проверим, видно ли это через API запросы:

import time
import json
import urllib, http.client
import hmac, hashlib

API_KEY = '...'
# обратите внимание, что добавлена 'b' перед строкой
API_SECRET = b'...'

API_URL = 'bittrex.com'
API_VERSION = 'v1.1'

# Свой класс исключений
class ScriptError(Exception):
    pass

# все обращения к API проходят через эту функцию
def call_api(**kwargs):
    http_method = kwargs.get('http_method') if kwargs.get('http_method', '') else 'POST'
    method = kwargs.get('method')

    nonce = str(int(round(time.time())))
    payload = {
            'nonce': nonce
    }

    if kwargs:
        payload.update(kwargs)

    uri = "https://" + API_URL + "/api/" + API_VERSION +  method + '?apikey=' + API_KEY  + '&nonce=' + nonce
    uri += urllib.parse.urlencode(payload)

    payload = urllib.parse.urlencode(payload)

    H = hmac.new(key=API_SECRET, digestmod=hashlib.sha512)
    H.update(uri.encode())
    sign = H.hexdigest()
    apisign = hmac.new(API_SECRET,
                       uri.encode(),
                       hashlib.sha512).hexdigest()

    headers = {"Content-type": "application/x-www-form-urlencoded",
               "Key": API_KEY,
               "apisign": apisign}

    conn = http.client.HTTPSConnection(API_URL, timeout=60)
    conn.request(http_method, uri, payload, headers)
    response = conn.getresponse().read()

    conn.close()

    try:
        obj = json.loads(response.decode('utf-8'))

        if 'error' in obj and obj['error']:
            raise ScriptError(obj['error'])
        return obj
    except json.decoder.JSONDecodeError:
        raise ScriptError('Ошибка анализа возвращаемых данных, получена строка', response)

print(call_api(method='/account/getbalances'))
print(call_api(method='/market/getopenorders', market='USDT-LTC'))

На выходе получаем:

Баланс: {'success': True, 'message': '', 'result': [{'Currency': 'LTC', 'Balance': 0.48107406, 'Available': 0.47107406, 'Pending': 0.0, 'CryptoAddress': 'LMGJrSr37DYpZGiWEpLzTEz7my6PUu48KP'}]}

Открытые ордера: {'success': True, 'message': '', 'result': [{'Uuid': None, 'OrderUuid': '07dd349c-936f-426e-be6a-c3ad6d6d0bf4', 'Exchange': 'USDT-LTC', 'OrderType': 'LIMIT_SELL', 'Quantity': 0.01, 'QuantityRemaining': 0.01, 'Limit': 56.90798125, 'CommissionPaid': 0.0, 'Price': 0.0, 'PricePerUnit': None, 'Opened': '2017-11-05T08:47:53.18', 'Closed': None, 'CancelInitiated': False, 'ImmediateOrCancel': False, 'IsConditional': False, 'Condition': 'NONE', 'ConditionTarget': None}]}

Отлично, всё работает, можно начинать делать бота.


Реклама


Получаем данные для индикаторов

В официальном API нет метода, который позволил бы получить значения для свечей. Тем не менее, существует неофициальный API v2.0, который используется самим биттрексом, и о котором они никому ничего не рассказывают. Я обнаружил это, изучая запросы между моим браузером и биржей в панели разработчика (F12 - Network), позже, погуглив, обнаружил что люди уже повытаскивали все запросы и даже их расписали. Эту информацию вы можете найти в гугле, мне же нужна одна функция – получение данных свечей.

 Вот как выглядит запрос:

https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=USDT-LTC&tickInterval=fiveMin

Если требуется интервал по полчаса, то fiveMin меняем на thirtyMin, и т.п.

У этих данных, впрочем, есть недостаток – они возвращают данные за прошедшие периоды.. Т.е. если строить по минутам, то отставание составит 3 минуты, если по 5 минут, то как минимум 5 минут и т.п. Для оперативного принятия решений этого мало, поэтому недостающий набор данных я планирую брать с публичного метода getmarkethistory:

https://bittrex.com/api/v1.1/public/getmarkethistory?market=USDT-LTC.

Т.е. последние несколько минут торгов я буду брать с истории торгов, и дополнять ими то, что недополучил вначале – так я соберу наиболее полную картину. Более того, как раз последние несколько секунд и минут могут как раз оказаться решающими. Напишем код, проверим:

import time
import json
import requests
from datetime import datetime

MARKET = 'USDT-BTC'

def get_ticks():
    chart_data = {}
    # Получаем готовые данные свечей
    res = requests.get("https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=" + MARKET + "&tickInterval=fiveMin")
    for item in json.loads(res.text)['result']:
        try:
            dt_obj = datetime.strptime(item['T'], '%Y-%m-%dT%H:%M:%S.%f')
        except ValueError:
            dt_obj = datetime.strptime(item['T'], '%Y-%m-%dT%H:%M:%S')
        ts = int(time.mktime(dt_obj.timetuple()))
        if not ts in chart_data:
            chart_data[ts] = {'open': float(item['O']), 'close': float(item['C']), 'high': float(item['H']), 'low': float(item['L'])}

    # Добираем недостающее
    res = requests.get("https://bittrex.com/api/v1.1/public/getmarkethistory?market=" + MARKET)
    for trade in reversed(json.loads(res.text)['result']):
        try:
            dt_obj = datetime.strptime(trade['TimeStamp'], '%Y-%m-%dT%H:%M:%S.%f')
        except ValueError:
            dt_obj = datetime.strptime(item['T'], '%Y-%m-%dT%H:%M:%S')
            
        ts = int((time.mktime(dt_obj.timetuple())/300))*300 # округляем до 5 минут
        if not ts in chart_data:
            chart_data[ts] = {'open': 0, 'close': 0, 'high': 0,'low': 0}

        chart_data[ts]['close'] = float(trade['Price'])

        if not chart_data[ts]['open']:
            chart_data[ts]['open'] = float(trade['Price'])

        if not chart_data[ts]['high'] or chart_data[ts]['high'] < float(trade['Price']):
            chart_data[ts]['high'] = float(trade['Price'])

        if not chart_data[ts]['low'] or chart_data[ts]['low'] > float(trade['Price']):
            chart_data[ts]['low'] = float(trade['Price'])

    return chart_data

# Выведем результат, посмотрим - работаем по времени биржи
chart_data = get_ticks()
for item in sorted(chart_data):
    print(datetime.fromtimestamp(item),chart_data[item])

Результат:

2017-11-05 11:10:00 {'open': 54.75500015, 'close': 54.75500015, 'high': 54.75500015, 'low': 54.75500015}
2017-11-05 11:15:00 {'open': 54.87745003, 'close': 54.89744999, 'high': 54.89744999, 'low': 54.87745003}
2017-11-05 11:20:00 {'open': 54.87755003, 'close': 55.03567601, 'high': 55.03567601, 'low': 54.87755003}
2017-11-05 11:25:00 {'open': 55.03567601, 'close': 55.0, 'high': 55.03567601, 'low': 55.0}
2017-11-05 11:30:00 {'open': 55.00668, 'close': 55.0, 'high': 55.00668, 'low': 55.0}
2017-11-05 11:35:00 {'open': 55.0, 'close': 55.0, 'high': 55.0, 'low': 55.0}
2017-11-05 11:40:00 {'open': 55.0, 'close': 55.0, 'high': 55.0, 'low': 55.0}
2017-11-05 11:45:00 {'open': 55.0, 'close': 55.0, 'high': 55.0, 'low': 55.0}
2017-11-05 11:50:00 {'open': 54.8975, 'close': 54.79500025, 'high': 55.0, 'low': 54.79500025}
2017-11-05 11:55:00 {'open': 54.915338, 'close': 54.79500001, 'high': 54.915338, 'low': 54.79500001}

Для анализа этих данных мы будем использовать MACD, как и в предыдущей статье, потому что, во-первых, это сэкономит время и размер статьи, а во-вторых, потому что мы будем в этот раз использовать значения по другому.

Итак, принцип алгоритма расписан здесь, сделаем небольшую функцию, которая будет возвращать нам тренд и совет, пора или не пора торговать. Я подразумеваю, что тренд растет (growing),  если это либо бык в активной фазе, либо медведь в затухающей. Код выглядит вот так:

def get_macd_advice(chart_data):
    macd, macdsignal, macdhist = talib.MACD(numpy.asarray([chart_data[item]['close'] for item in sorted(chart_data)]),
                                            fastperiod=12, slowperiod=26, signalperiod=9)
    idx = numpy.argwhere(numpy.diff(numpy.sign(macd - macdsignal)) != 0).reshape(-1) + 0

    trand = 'BULL' if macd[-1] > macdsignal[-1] else 'BEAR'

    max_v = 0

    activity_time = False
    growing = False

    for offset, elem in enumerate(macdhist):

        growing = False

        curr_v = macd[offset] - macdsignal[offset]
        if abs(curr_v) > abs(max_v):
            max_v = curr_v
        perc = curr_v / max_v

        if ((macd[offset] > macdsignal[offset] and perc * 100 > BULL_PERC)  # восходящий тренд
            or (
                macd[offset] < macdsignal[offset] and perc * 100 < (100 - BEAR_PERC)
            )
            ):
            activity_time = True

            growing = True

        if offset in idx and not numpy.isnan(elem):
            # тренд изменился
            max_v = curr_v = 0  # обнуляем пик спреда между линиями

    return ({'trand':trand, 'growing':growing})

Соответственно, при работе мы будем вызывать эту функцию, передавать ей полученные ранее данные и узнавать, пора ли покупать/продавать и т.п.


Реклама


Стратегия

В этот раз предлагаю поступить так – бот будет закупать на падении графика, когда MACD все уже падает, но тренд уже начал разворот, и будет продавать купленное на росте тренда, пока он все еще растет, но уже начинает спад.

Таким образом, он будет стараться купить дешевле, но продать как можно дороже, а если курс вырастет недостаточно и пойдет на спад, то будет выставлять по минимально допустимой цене (с учетом комиссии при покупке, при продаже и требуемого навара).

И это, вроде бы и относительно безопасно, но, как выяснилось, работает оочень долго – сначала бот ждет покупки на спаде, потом ждет роста. С другой стороны, значительно уменьшается шанс залезть на самый пик и никогда ничего не продать.

Но, тем не менее, предусмотрена опция отключения такого поведения - USE_MACD = True заставит бота думать, USE_MACD = False включит ковбойский режим. Если режим MACD включен, управлять настройками задумчивости можно через переменные BEAR_PERC и BULL_PERC (подробнее рассмотрено тут) – выставляйте каждую от 0 и до 101 и смотрите, как лучше.

В общем-то вот код, скачивайте, пользуйтесь, может еще какие-то идеи придут. Удачи вам)

P.S. Если вы раньше не запускали ботов с моего сайта, то знайте, вам нужно установить Python с модулями (описано тут) и ta-lib (описано тут). О всяких других аспектах, таких как работа с API или комиссиями, читайте в статьях цикла, ссылки под этой статьёй. 


Реклама


Статистика по результатам тестирования

Через 6 суток непрерывной работы бота я снял статистику - выкачал историю сделок с биттрекса, и посчитал чистый доход за вычетом комиссий.

Играл на 8 пар, каждой выделял по 2 доллара. Из-за политики биржи, еще 0.25% прибавлялись к платежам, так что каждый ордер на покупку обходился примерно в 2,00499762 доллара.

Профитность ставил 0.1% с каждой сделки.

В итоге за 6 дней было совершено 144 сделки (72 цикла покупки/продажи), прибыль с каждой составила большей частью 0.1%, в некоторых случаях больше (иногда на пару порядков больше).

Итоговый доход с 16 долларов, заряженных в игру, составил 1,23 - или 7.6%.

Зависших пар (купленных на пике) - не обнаружено.

Продолжаем наблюдение..

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

Комментарии: (92)
07.11.2017 08:11
Ув. Андрей, спасибо вам за ваш труд и вашу помощь в освоении автоматизации торговли. Скажите пожалуйста, а для биржи bitfinex планируется написание бота?
08.11.2017 15:21
День добрый ! Для двухфакторки использую FreeOTP Authenticator вместо Google Authenticator , на всякий случай делаю скрин ключа и сохраняю на флешку.

Также интересует бот для биржи WEX.nz (бывшая реанимированная BTCe)
Заранее благодарен !
08.11.2017 15:42
Добрый день.
Вообще пока не планировал ботов для других бирж, но подумаю. За FreeOTP спасибо)
08.11.2017 17:11
На здоровье )
С нетерпением буду ждать робота для WEX, если что )
11.11.2017 13:46
Traceback (most recent call last):
  File "C:\Users\Admin\Downloads\bittrex_macd.py", line 68, in <module>
    chart_data = get_ticks()
  File "C:\Users\Admin\Downloads\bittrex_macd.py", line 39, in get_ticks
    res = requests.get("https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=" + MARKET + "&tickInterval=fiveMin")
NameError: name 'MARKET' is not defined

имя 'рынок' не определен ?</module>
12.11.2017 15:21
Точно, точно. Обновил статью
14.11.2017 09:57
Андрей подскажите как с Bittrex.com выгрузить в Excel историю торгов.
14.11.2017 19:37
Заходите в раздел Orders - https://bittrex.com/History, там кнопка "Load All" со стрелочкой. Нажимаете, разгадываете капчу и  получаете Excel-файл со всеми торгами
14.11.2017 21:46
Это я понял а как скрипто python вытащить в эксель?
14.11.2017 23:02
1. Берем код из первого примера
2. В конце добавляем 

trades = call_api(method='/account/getorderhistory')['result']

import os
from openpyxl import Workbook
# Создадим Excel файл
wb = Workbook()
ws = wb.active

for trade in trades:

    ws.append(
        [
            trade['OrderUuid'],
            trade['Exchange'],
            trade['OrderType'],
            trade['Price']
        ]
    )
    
wb.save(os.path.dirname(os.path.abspath(__file__)) + "/bittrex_excel.xlsx")
    
3. Запускаем. Рядом с ботом появляется эксель. Дополнительные поля можно добавить, описаны тут https://bittrex.com/home/api, метод /account/getorderhistory
17.02.2018 10:29
Андрей, спасибо за бота, не могли бы вы подсказать кода пытаюсь через API вытащить историю своих торгов он выдает только последние 10 сделок..как взять всю хорнологию?не подскажете?
15.11.2017 14:18
Андрей, подскажи пожалуйста как подобрать наиболее подходящую пару для торгов данным ботом на Bittrex?
17.11.2017 13:03
Если именно этим ботом - то я бы рекомендовал бы разбить депозит на небольшие суммы и торговать сразу на максимально возможное количество пар. Не так часто меняется macd, особенно на непопулярных парах, так что по каждой паре количество сделок в день будет небольшим. Соответственно, чем больше пар - тем больше сделок. Если вложить все в одну пару, она может уйти в даун на несколько часов или дней, а так пока одна пара ждет другие работают.
21.11.2017 10:11
Получается нужно запустить к примеру 10 ботов если мы хотим торговать на 10-ти парах, но не рискуем ли мы быть забанеными по ip, ведь количество запросов может превысить лимит?
21.11.2017 12:13
Зачем 10 ботов - тут в одном боте можно прописать 50 пар например.
А про лимиты на битрексе ничего не сказано, только общее - не более 500 открытых ордеров и не более 200 000 ордеров в сутки.
У меня неделю работал на 8 пар (в одном боте), не забанили
22.11.2017 13:30
Я код сразу не смотрел, думал он написан так же как для ексмо. Подозреваю для ексмо можно так же прикрутить, что бы сразу на нескольких парах работало?
19.11.2017 22:37
Доброго времени суток, Андрей, робот работает исправно, большое спасибо. Но столкнулся с такой проблемой, после покупки ботом крипты, я решил изменить параметры кода и продать валюту в ручную (т.к. думал что с новыми параметрами он не исполнит ордера созданные со старыми параметрами). Но бот все еще берет из БД неисполненные ордера которых нет и пытается создать ордер на продажу. Можно ли обнулить эту БД чтобы начать с чистого листа или что можно сделать?
20.11.2017 00:12
Можно удалить файл local.db из папки с ботом, он начнет вообще все с чистого листа.
Можно внутри базы удалить записи по конкретным ордерам, но наверное вам не так нужна история, её можно и с биржи скачать.
25.11.2017 14:28
Добрый день. Бот запускается, несколько минут работает, а потом возникает ошибка. Что за ошибка видно на скрине. В чем может быть причина
25.11.2017 14:28
http://pastenow.ru/3d09f2c861e9a9910e5c531677b7cd52
Ссылка скрина не прикрепилась)
25.11.2017 21:14
Добрый день!
Обновил код, скачайте и запустите новый
26.11.2017 18:28
Все в одну строку, нереально отредактировать https://bablofil.ru/static/macd_bots/bittrex_macd.py
26.11.2017 22:14
Плюс еще синтаксическая ошибка.
27.11.2017 14:04
Всё в одну строку, нереально отредактировать https://bablofil.ru/static/macd_bots/bittrex_macd.py

Плюс еще синтаксическая ошибка.
27.11.2017 14:45
А вы перейдите по своей ссылке и нажмите CTRL+U ;)
27.11.2017 15:40
Андрей, в связи с неоднозначными заявлениями Битрекс, планируете ли вы переписать этот бот для другой биржи? Изюминка этого бота от других представленных на этом сайте в том, что он торгует сразу несколькими парами, если у вас есть такие мысли, то хочу обратить ваше внимание на биржу hitbtc, особенность комиссия 0.1%, а при покупке по рынку на сколько я понял 0.01%, плюс от той же ексмо (на которой я завис), начисляют все форки, тотже голд и кеш появились раньше, чем его начисляли, как бы торговля фьючерсом получалась
08.12.2017 18:08
Очень интересный бот, спасибо за его бесплатное предоставление. Очень часто, к сожалению, закупает под самым пиком на альтах=(, хотя скорее, это он поздно закупает после начала подъема. Что в нем можно подредактировать, чтобы покупка происходила раньше ? Еще раз спасибо за бота, иногда он реально умудряется зарабатывать)
10.12.2017 03:16
Присоединяюсь, покупает почти на пике и пока создает ордер падение уже настолько большое, что ордер зависает. запускал на 2 дня по 8 парам по 10 долларов на бай, бот заработал 50 центов, и на этом все, 5 ордеров повисло наглухо и потери практически 1 доллар на ордер
12.12.2017 10:54
BULL_PERC можно поставить побольше, 99.5 например
09.12.2017 22:26
Прочитал все статьи. Очень много ценной информации для начинающего. Спасибо огромное. Напишите, пожалуйста, простецкого бота под binance, чтоб было от чего отталкиваться и допиливать.
12.12.2017 09:31
есть такая биржа hitbtc.com возможно ли под нее переделать этот бот, если да то каким образом?
18.12.2017 15:56
Возможно все, если приложить немного времени, я все хочу хочу но некогда)
13.12.2017 18:08
Приветствую.

Андрей, поясните, пожалуйста, почему в описанных примере и тесте на бирже Вы использовали параметр tickInterval=fiveMin, а в полном коде бота по умолчанию обозначено 30 минут?
18.12.2017 15:55
Потому что я сначала написал код, протестировал и выложил статью. Потом неделю его гонял, там-сям что-то подстраивал и выложил последнюю версию ) Ну и потом еще обновлял код после комментариев.
18.12.2017 19:44
Понятно.
Я уж подумал, что есть какой-то хитрый план.
Спасибо за ответ.

Кстати, я изменил параметр на пятиминутку, слегка модифицировал код, чтобы бот закупался по одним параметрам MACD, а продавал по другим. Торговля побойчее пошла. Вроде...
21.12.2017 01:35
Можете выложить код с этими параметрами очень интересно?!
23.12.2017 20:44
Весь код выкладывать нет смысла, там изменения минимальные. Просто перечислю.
1. BEAR_PERC = 70
    BULL_PERC = 99.5
Пробовал с BULL_PERC = 30, затем 90. Зависали пары. Пришлось продавать с минус, хоть и не большой. Причина - если бы не зависли, несколько раз бот зависшие токены закупил и снова продал.
2. Создал отдельную процедуру на покупку. В ней прописал параметры fastperiod=8, slowperiod=17. Типа как создатель индикатора завещал. Правда он эти параметры рекомендовал внутри дня использовать, ну да ладно... Да, и код основного цикла изменил так, чтобы в нужный момент, вызывалась нужная процедура.
3. Изменил интервал запрашиваемых данных с биржи на tickInterval=fiveMin (как у автора в примере). Решился на этот шаг, после эксперимента  двумя ботами на разных интервалах. Пятиминутный отрабатывал чаще.
17.12.2017 16:17
Андрей, добрый день! 
Большое спасибо за бота! 
Подскажите, пожалуйста, почему может возникать ошибка при создании ордера -  "certificate verify failed"
17.12.2017 16:47
Вопрос снимается, разобрался)
22.12.2017 11:26
Андрей, добрый день!
При запуске бота с учетом тренда по MACD выдает:

2017-12-22 15:17:36.606197 USDT-BTC Получаем все неисполненные ордера по БД
2017-12-22 15:17:36.617198 USDT-BTC Неисполненных ордеров в БД нет, пора ли создать новый?
'NoneType' object is not iterable

При запуске бота без учета тренда по MACD выдает:

2017-12-22 03:17:51.338694 USDT-BTC Получаем все неисполненные ордера по БД
2017-12-22 03:17:51.354695 USDT-BTC Неисполненных ордеров в БД нет, пора ли создать новый?
2017-12-22 03:17:51.377696 USDT-BTC Создаем ордер на покупку
2017-12-22 03:17:51.388697 USDT-BTC Создаем ордер на покупку
2017-12-22 03:17:51.401698 USDT-BTC Получаем текущие курсы
2017-12-22 03:17:51.690714 USDT-BTC 
        Текущая цена - 15200.00000000
        На сумму 3.00000000 USDT можно купить 0.00019737 BTC
        Создаю ордер на покупку
        
2017-12-22 03:17:51.999732 USDT-BTC 
            Не удалось создать ордер: NONCE_NOT_PROVIDED

Где и что в коде подправить? Спасибо...
22.12.2017 17:10
Проверьте, правильно ли прописаны API ключи.. Пока что других причин не вижу
23.12.2017 21:00
Андрей, как Вам более оперативно вопрос можно задать?
Понимаю, что для Вас этот бот скорее хобби, и врятли Вы уделяете теме большое внимание, но все же.

На всякий случай задам вопросы здесь. Если повезет, через пару дней ответы получу ;)
1. Анализируя работу бота заметил, что бот покупает на падении. Сильном. Без какого-либо признака разворота. Т.е. линии сходятся, но разворота не намечается. На растущем рынке такие его действия не особо болезненны для депозита, рано или поздно курс вырастет, но все же. К тому же он покупает, когда обе скользящие пересекаются находясь ниже нулевой линии, что, в принципе, не логично, ведь курс в этот момент все еще может падать. Подозреваю, что виновата сравнение значений переменных по модулю в процедуре MACD. Или я не прав? Может я какой параметр перекрутил?

2. На сайте есть видео с описанием еще одного индикатора - стохастического RSI. Как я понял, с его помощью можно предотвратить закупку бота в момент перекупленности, когда скользящие сходятся и вроде можно закупиться, а через мгновение цена улетает вниз. Не ради праздного интереса спрашиваю. Удалось "прикрутить" второй индикатор к боту. Если да, его результативность увеличилась?
27.12.2017 05:02
Спасибо за материал. Хороший повод приступить к знакомству с Python. Есть проблемка. В коде есть функция проверки buy ордера по возрасту. Если не исполнен - снять заявку на покупку. Обратил внимание, что это условие не срабатывает.
Так же, по аналогии с этим вариантом, пытался закрывать уже открытый ордер по достижении заданного возраста. Это условие так же не срабатывало.
Может в коде какая-то заморочка, не очевидная на первый взгляд?
17.02.2018 10:51
Разве что разница в часовых поясах. Выведите в консоль текущее время, время создания ордера и сравните
26.08.2019 15:17
Спасибо за подсказку, а то я запаниковал, когда три ордера зависли, хотя в коде есть условие автоотмены через полминуты.
27.08.2019 05:40
Хотя нет, там в коде проверяются только зависшие ордера на покупку, а на продажу - нет. Очень странно, ведь прибыль-то идет от ордеров на продажу, и если ордер завис, то потом чтобы от него избавиться, приходится сильно сбивать цену, что уводит в минус. В общем, странный скрипт.
27.08.2019 06:21
Ух ты, а там даже не проверяется, готов ли кто-то купить у меня по цене, которую я предлагаю

Текущий курс продажи 187.99597746
Создаю ордер на продажу по курсу 191.67569321

То есть, ордер на продажу создается даже тогда, когда нет подходящих ордеров на покупку. Вполне естественно, что ордер зависает:)

Вообще, конечно, не скрипт виноват, что так происходит, а сам инструмент MACD - он сигнализирует, что пора продавать, а цена-то стала еще меньше, чем была при покупке. Эх, не наварить мне миллионы:)
27.12.2017 07:06
Ещё вопрос. На примере для полоникс с MACD бот рисовал графики с динамикой. Возможно ли сделать так, чтобы при принятии решения о buy или shell, бот сохранял график этого момента ф файл jpg? Это помогло бы в анализе. Ну и ещё. Я нафантазировал параллельно с торговым ботом запустить телеграм бота, который бы уведомлял меня об активности трейдера. Телебот мог бы присылать картинку с графиками прямо в телефон
17.02.2018 10:53
Вы можете взять код для рисования графиков из статьи https://bablofil.ru/macd-python-stock-bot/, у mathplotlib есть возможность программно сохранять итоговое изображение. Так же отсюда можно взять код для отправки картинки в телеграм https://bablofil.ru/telegram-bot/
29.01.2018 08:54
Андрей дня доброго,

Подскажите пожалуйста по готовым данным для свечей в процедуре get_ticks:
В коде готового бота для биттрекс Вы берете данные за довольно длительный промежуток -
    res = requests.get("https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=" + market + "&tickInterval=thirtyMin") ~ 1 месяц
и дополняете их потом 5 минутными свечками за крайний период. 
В коде бота для poloniex же вы берете данные только за последние 15 часов -
    start_time = time.time() - 15*60*60
    resource = requests.get("https://poloniex.com/public?command=returnChartData&currencyPair=%s&start=%s&end=9999999999.=300" % (pair, start_time))

У меня пара вопросов связанных с этим - 
1. Можно ли миксовать данные в chart_data 30 и 5 минутных свечей для анализа?
2. Имеет ли смысл увеличить так же до месяца chart_data в боте полоникса?

Спасибо
29.01.2018 12:17
В коде биттрекса комментарий старый оставался, сейчас я его поправил - свечки добивались по 30 минут (1800 секунд).
Если вы про бота с macd, то прям уж большого смысла не имеет увеличение до месяца- тут важнее всего, что бы бот получил последние 2-3 пересечения линий macd, и понимал, в какую сторону движется. По факту нужно только последнее пересечение, но оно могло произойти как полчаса назад, так и неделю, поэтому берем с запасом. Но если сделаете месяц, чуть-чуть подстрахуетесь. Вообще зависит от динамики выбранной пары
29.01.2018 17:37
Понял спасибо.
01.02.2018 08:58
Добрый день. У меня первый пример запускается в черном окошке и через секунду гаснет. Так и должно быть? Сам файл с заключительным кодом тоже запускается и гаснет. второй пример, который без апи и ключа, бежит в окошке нормально
01.02.2018 09:26
Вполне возможно, смотря как вы запускаете (вы же прописали API ключи?).
Только что проверил первый код, он отработал и вывел мне информацию. 
Попробуйте, к примеру, запустить так:
Win+R -> cmd -> python путь_к_файлу.py

или запустите Idle (устанавливается вместе с питоном), там File->Open, откройте ваш файл и нажмите F5. 
Если и будет какая-то ошибка, вы её увидите.

У вас может быть тоже работает, выводит информацию и закрывает окно, и это тоже правильно, смотря как запускать
02.02.2018 08:18
Сердечно Вас благодарю, Андрей! Все запустилось по первому Варианту! Работает мой первый в жизни скрипт! Супер. Вы Молодцы!
Есть еще один вопрос, но скорее по самому биттрексу. Где у меня не хватает? На каком счету и какая сумма должна быть изначально?
Пишет USDT-BTC
Не удалось создать ордер: недостаточно средств
02.02.2018 08:53
В данном случае на балансе должны быть USDT, лучше штук 10-20, но и 2-5 может пойти, если ничего не ужесточили
02.02.2018 17:47
Благодарю Вас. Закинула 4. Теперь жду, появится ли хоть одна сделка. Программный файл теперь включается без использования командной строки. Счастливых выходных Вам!
04.02.2018 13:04
благодарю. все работает в консоли
14.02.2018 06:11
бот перестал совершать операции. хотя на счету 18 криптодолларов. уже 2 дня висит просто так. пишет что условия рынка не подходят. или пишет по английски. что минимальные требования не соблюдены.
15.02.2018 07:49
Биттрикс любит повышать минимальные ставки без предупреждения..
Надо подстраиваться, увеличивать..
Мне в свое время понравился биттрикс именно тем, что можно было ставить любую ставку, включая самые копеечные. Я перенес скрипты с полоникса на битрикс, и через неделю ставки изменились и я не смог играть так, как задумавал. Увы (
24.02.2018 21:25
было бы неплохо подтягивать ордера на продажу совместно с профитом, так можно больше заработать, почти на пике разворота
25.02.2018 17:34
индикатор Параболик "SAR" к примеру
05.04.2018 07:35
Здравствуйте, а для форекса Вы не пробовали боты мастерить? например, для аккаунтов на сайте форекс4ю ?
16.04.2018 15:42
Добрый день,
Когда-то давно писал скрипты для мета-трейдера, кажется, но вся эта идея с торговлей через брокера сводит любые скрипты на нет
05.04.2018 08:02
Кстати, у ехмо слабая защита. Через вывод на доге у меня запросто слили все деньги без моего участия. Это возможно даже без видимого взлома аккаунта и емайла. Следите за точками входа в ящик по айпи
11.05.2018 17:24
Занятно, может вирус какой адреса подменяет?
Я слышал, некоторые VPN этим грешат )
01.05.2018 10:45
Добрый день, Андрей. Спасибо огромное вам за проделанную работу. Подскажите, возможно ли добавить функцию усреднения? Чтоб, при падении, бот открывал ордера на покупку, на определенном расстоянии и переставлял ордер на продажу. К примеру, мы купили крипты на 5$ и продолжилось падение. При падении на 1%, открывался еще один ордер на покупку и отменялся ордер на продажу и на отскоке мы получили бы свой профит. Думаю это было бы мего круто. Спасибо большое.
11.05.2018 17:33
Да не за что, можно, может попозже выложу
Зачастую люди выставляют сразу заказов 5 с некоторым шагом от текущей цены, и при исполнении каждого (отменяют и) выставляют ордер на продажу
Думаю, вы можете и сами немного модифицировать код - создавать ордера на покупку в цикле, при исполнении продажи отменять все открытые ордера на покупку, при исполнении покупки отменять продажу и на всё создавать новую...
02.05.2018 17:48
Добрый день, при запуске кода получаю вот такое сообщение

Traceback (most recent call last):
  File "C:\ta-lib\bittrex_macd.py", line 10, in <module>
    import talib
ModuleNotFoundError: No module named 'talib'
>>> </module>
03.05.2018 01:16
Я не эксперт, но по моему ta - lib не установлен. читаем тут: https://bablofil.ru/python-indicators/
11.05.2018 17:34
Да, почитайте тут и установите всё, что надо
https://bablofil.ru/python-indicators/
09.06.2018 22:22
а можно такое только для exmo?
27.07.2018 19:46
Добрый вечер, Андрей!
Что значит "'NoneType' object is not iterable" при запуске c USE_MACD = True?
Аналогично, как в сообщении Сергея В. от 22.12.2017 11:26:25
Если USE_MACD = False - все прекрасно работает.
01.08.2018 09:56
Добрый вечер!
Такое может быть, если, например, рынок указан не правильно
В боте у меня стояла пара USDT-BCC, а такой, оказывается, уже нет..
Я внес пару дополнений в код, что бы было видно сообщение если что, скачайте по новой
20.08.2018 09:30
Добрый день!
BTC-XMR Создаем ордер на покупку
BTC-XMR Создаем ордер на покупку и на этом все, ордера не открываются, баланс подходит, в чем может быть причина?
23.08.2018 11:32
Добрый день!
Может быть суммы торгов запредельные?
Например, CAN_SPEND = 2 будет означать 2 BTC...
Может быть что-то с апи ключами.. И в логе еще что-то должно быть, мне кажется
18.09.2018 11:05
2018-09-18 13:25:57.103594 BTC-XRP Создаем ордер на покупку
2018-09-18 13:25:57.108598 BTC-XRP Создаем ордер на покупку
2018-09-18 13:25:57.112601 BTC-XRP Получаем текущие курсы
2018-09-18 13:25:57.117603 BTC-BCH Получаем все неисполненные ордера по БД
2018-09-18 13:25:57.122606 BTC-BCH Неисполненных ордеров в БД нет, пора ли создать новый?
2018-09-18 13:25:57.842943 BTC-BCH Условия рынка не подходят для торговли {'trand': 'BEAR', 'growing': False}
2018-09-18 13:25:57.847947 BTC-ETC Получаем все неисполненные ордера по БД
2018-09-18 13:25:57.852951 BTC-ETC Неисполненных ордеров в БД нет, пора ли создать новый?
2018-09-18 13:25:58.372373 BTC-ETC Условия рынка не подходят для торговли {'trand': 'BULL', 'growing': False}
2018-09-18 13:25:58.377376 BTC-PART Получаем все неисполненные ордера по БД
2018-09-18 13:25:58.382381 BTC-PART Неисполненных ордеров в БД нет, пора ли создать новый?
2018-09-18 13:25:58.915580 BTC-PART Условия рынка не подходят для торговли {'trand': 'BEAR', 'growing': False}
2018-09-18 13:25:58.920583 BTC-XRP Получаем все неисполненные ордера по БД
2018-09-18 13:25:58.925588 BTC-XRP Неисполненных ордеров в БД нет, пора ли создать новый?
2018-09-18 13:25:59.435452 BTC-XRP Создаем ордер на покупку
2018-09-18 13:25:59.439785 BTC-XRP Создаем ордер на покупку
2018-09-18 13:25:59.444787 BTC-XRP Получаем текущие курсы
2018-09-18 13:25:59.449790 BTC-BCH Получаем все неисполненные ордера по БД
2018-09-18 13:25:59.460798 BTC-BCH Неисполненных ордеров в БД нет, пора ли создать новый?
Ордера не создаются, не понятно почему, апи вроде работает хорошо, баланс и размер ордера соотвествуют, пытается купить в цикле, но не покупает..
18.09.2018 11:40
а можно штатными средствами сократить инфу которая пишется в лог? что бы писались только ошибки и сделки... лог раздувает быстро от однотипной информации
25.09.2018 02:55
Здравствуйте. В последние несколько дней бот перестал работать. При запросе балансов  (call_api(method='/account/getbalances')) Выдает ошибку: 

Traceback (most recent call last):
  File "E:/Питон/KryptoShop/TestConection1.py", line 53, in call_api
    obj = json.loads(response.decode('utf-8'))
  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\json\__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "E:/Питон/TestConection1.py", line 61, in <module>
    print(call_api(method='/account/getbalances'))
  File "E:/Питон/TestConection1.py", line 59, in call_api
    raise ScriptError('Ошибка анализа возвращаемых данных, получена строка', response)
ScriptError: ('Ошибка анализа возвращаемых данных, получена строка', b'Bad Request')
>>> 

До этого несколько месяцев все работало отлично. У себя ничего не менял. Не подскажите, в чем может быть причина? 
Спасибо.
</module>
28.09.2018 16:13
Да и меня перестал торговать. Выяснилось, что https запрос содержит ненужные параметры.
29.09.2018 05:46
Андрей видимо в функции запроса к бирже что то изменилось?? такая же ошибка 'Ошибка анализа возвращаемых данных, получена строка', b'Bad Request'...
18.11.2018 07:25
Друзья, обновил код для коннекта, должно всё работать
12.03.2019 19:46
Здравствуйте, Андрей.

Может подскажите, не знаю в чем проблема.
Не удается получить баланс по счету. Попробовал Ваш код, ошибок не выдает.

{'success': False, 'message': 'This endpoint does not accept request bodies.', 'result': None}
14.03.2019 12:34
Добрый день,

Попробуйте вот эту строку
params=payload if http_method == 'POST' else [],

заменить на
params=payload if http_method == 'POST' else None,

Или вообще изменить код так, что бы для проверки баланса этой строки не существовало
14.03.2019 18:52
Андрей, Добрый Вечер.

К сожалению, не могу найти таких строк в коде.
Возможно у меня не актуальная версия (брал с этого сайта).

Естественно key/secret поставил свои, остальное ничего не менял. Если была бы ошибка, то проще было бы.

Не уверен, что это играет роль, но разный хэш при отправке запроса.
H 2: <hmac.hmac 0x00000000056****="" at="" object="">
<http.client.httpsconnection 0x00000000057****="" at="" object="">

{'success': False, 'message': 'This endpoint does not accept request bodies.', 'result': None}

Спасибо.</http.client.httpsconnection></hmac.hmac>
18.03.2019 13:31
По симптомам похоже, что вы видите сообщение кеширующего прокси, который настроен немного не так, как апи самой биржи, этим грешит CloudFront от Амазона. Можно попробовать ходить через разные VPN, возможно в какой то стране коннект пойдет по другому пути.
Можно скачать последнюю версию с этого сайта и попробовать поменять строки
Кстати говоря, не так давно я выкладывал на форум нового ботя для биттрекса, более продвинутого
https://forum.bablofil.ru/topic/95-%D0%B1%D0%BE%D1%82-%D0%B4%D0%BB%D1%8F-bittrex-macdrsi/
20.08.2019 20:41
Здравствуйте! Подскажите, актуален ли скрипт на момент времени август 2019 года. Заинтересовался темой криптовалют, закинул на биттрекс сумму, которую не жаль потерять, но вот следить за курсом и торчать на бирже 24 часа в сутки, само собой, нереально, а так как я по профессии программист (пэхэпэшник, правда), то почти сразу стрельнула мысль об автоматизации торговли. Спасибо.
20.08.2019 21:56
Оказалось, что для PHP тоже есть библиотека Technical Analysis for Traders, возможно, напишу свой скрипт на пыхе когда-нибудь:)
22.08.2019 07:33
Актуален, еще посмотрите вот этого бота

https://forum.bablofil.ru/files/file/3-bittrexmacdrsi/

https://forum.bablofil.ru/topic/95-%D0%B1%D0%BE%D1%82-%D0%B4%D0%BB%D1%8F-bittrex-macdrsi/page/2/#comments
22.08.2019 07:30
Конечно, нет большой разницы на каком языке писать )
02.11.2019 10:39
Не срабатывают запросы. Выдает {'success': False, 'message': 'This endpoint does not accept request bodies.', 'result': None}
Думаю запрос поменялся. Как лечить?
10.11.2019 10:13
Добрый день,
У меня сейчас нет настроенной среды для проверки, попробуйте заменить
params=payload if http_method == 'POST' else [],
на 
params=payload if http_method == 'POST' else "",
или 
params=payload if http_method == 'POST' else None,
Пожалуйста, Авторизуйтесь что бы оставить свой комментарий