Работа с API Binance: описание, код и примеры

Вступление

Биржа binance, как и многие другие биржи, предоставляет API - программный интерфейс для автоматизации торговли. В этой статье рассмотрены методы и приведены примеры кода для работы с ними.
Официальное описание API (на английском) - здесь. Бот для Binance - здесь. Как получить API ключи - тут.


Вводная информация


В отличии от многих других бирж, Binance лимитирует не только количество запросов к API, но и "вес" запросов. Причем, это не какие-то фиксированные единицы, но целый комплекс (как они заявляют, англ). Например, если вы постоянно запрашиваете свечи но не торгуете, то ваш вес накапливается и вас могут забанить. И вообще они суровые - если вы постоянно перебиваете лучшую цену на минимальную ставку, или создаете/отменяете ордера но не покупаете и продаете и т.п. то вас настигнут санкции. Так что будьте аккуратны при тестировании ботов. Впрочем, пока я тестировал, ничего плохого не случилось, хотя я порой и жестил.


Если биржа захочет вам намекнуть, что пора бы снизить пыл, она вернет 429 ответ сервера. Если вы будете игнорировать этот ответ и ломиться в закрытую дверь, то вас забанят по IP на срок от 2 минут до 3 дней.


Подключение к API биржи идет через https://api.binance.com, для авторизованных запросов нужно отправлять ключ в заголовке X-MBX-APIKEY, и подписывать тело запроса SHA256.


Что бы вы не заморачивались с этим, я написал код, который позволяет все указанные запросы выполнять. Для его работы нужно установить Python версии 3.6+ с официального сайта, потом в командной строке выполнить pip install requests. Создайте папку (для удобства), создайте новый файл binance_api.py, и вставьте туда этот код:

import time
import json
import urllib
import hmac, hashlib
import requests

from urllib.parse import urlparse, urlencode
from urllib.request import Request, urlopen

class Binance():

    methods = {
            # public methods
            'ping':             {'url':'api/v1/ping', 'method': 'GET', 'private': False},
            'time':             {'url':'api/v1/time', 'method': 'GET', 'private': False},
            'exchangeInfo':     {'url':'api/v1/exchangeInfo', 'method': 'GET', 'private': False},
            'depth':            {'url': 'api/v1/depth', 'method': 'GET', 'private': False},
            'trades':           {'url': 'api/v1/trades', 'method': 'GET', 'private': False},
            'historicalTrades': {'url': 'api/v1/historicalTrades', 'method': 'GET', 'private': False},
            'aggTrades':        {'url': 'api/v1/aggTrades', 'method': 'GET', 'private': False},
            'klines':           {'url': 'api/v1/klines', 'method': 'GET', 'private': False},
            'ticker24hr':       {'url': 'api/v1/ticker/24hr', 'method': 'GET', 'private': False},
            'tickerPrice':      {'url': 'api/v3/ticker/price', 'method': 'GET', 'private': False},
            'tickerBookTicker': {'url': 'api/v3/ticker/bookTicker', 'method': 'GET', 'private': False},
            # 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},
            # wapi
            'depositAddress':   {'url': '/wapi/v3/depositAddress.html', 'method':'GET', 'private':True},
            'withdraw':   {'url': '/wapi/v3/withdraw.html', 'method':'POST', 'private':True},
            'depositHistory': {'url': '/wapi/v3/depositHistory.html', 'method':'GET', 'private':True},
            'withdrawHistory': {'url': '/wapi/v3/withdrawHistory.html', 'method':'GET', 'private':True},
            'withdrawFee': {'url': '/wapi/v3/withdrawFee.html', 'method':'GET', 'private':True},
            'accountStatus': {'url': '/wapi/v3/accountStatus.html', 'method':'GET', 'private':True},
            'systemStatus': {'url': '/wapi/v3/systemStatus.html', 'method':'GET', 'private':True},
    }
    
    def __init__(self, API_KEY, API_SECRET):
        self.API_KEY = API_KEY
        self.API_SECRET = bytearray(API_SECRET, encoding='utf-8')
        self.shift_seconds = 0

    def __getattr__(self, name):
        def wrapper(*args, **kwargs):
            kwargs.update(command=name)
            return self.call_api(**kwargs)
        return wrapper
    
    def call_api(self, **kwargs):

        command = kwargs.pop('command')
        api_url = 'https://api.binance.com/' + self.methods[command]['url']

        payload = kwargs
        headers = {}
        
        payload_str = urllib.parse.urlencode(payload)
        if self.methods[command]['private']:
            payload.update({'timestamp': int(time.time() + self.shift_seconds - 1) * 1000})
            payload_str = urllib.parse.urlencode(payload).encode('utf-8')
            sign = hmac.new(
                key=self.API_SECRET,
                msg=payload_str,
                digestmod=hashlib.sha256
            ).hexdigest()

            payload_str = payload_str.decode("utf-8") + "&signature="+str(sign) 
            headers = {"X-MBX-APIKEY": self.API_KEY}

        if self.methods[command]['method'] == 'GET':
            api_url += '?' + payload_str

        response = requests.request(method=self.methods[command]['method'], url=api_url, data="" if self.methods[command]['method'] == 'GET' else payload_str, headers=headers)
        if 'code' in response.text:
            print(response.text)
        return response.json()

 

Для тестирования методов, создайте в этой же папке второй файл, например, binance_test.py, туда вставьте вот такой код (подставьте свои API ключи):

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('account', bot.account())


После этого код можно запускать. К примеру, если вы только установили Python и не знаете, что делать, найдите редактор Idle (он устанавливается вместе с питоном), в нем File -> Open, откройте файл binance_test.py и нажмите F5. Код, представленный выше, вернет информацию по вашему аккаунту - подробности ниже.


Еще немного общей информации: практически во всех подписанных запросах необходимо указывать параметр timestamp - это текущее unix-время в милиосекундах. Но, так как некоторые сети бывают перегружены, то ваш запрос может заблудиться и придти позже. Поэтому биржа предоставляет вам временное окно (по умолчанию 5000 милисекунд). Если у вас запросы не успевают придти в это окно, вы можете его расширить с помощью параметра recvWindow. Но, думаю, это мало кому понадобится.


Реклама



Публичные запросы


Проверка связи - /api/v1/ping 


Метод для проверки работы API. 
Возвращает пустой словарь

{}


Ссылка для просмотра в браузере https://api.binance.com/api/v1/ping.
Вес - 1
Код для проверки:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print(bot.ping())

 


Получение времени биржи - /api/v1/time


Ссылка для просмотра в браузере https://api.binance.com/api/v1/time
Вес - 1
Возвращает словарь с текущим временем:

{
  "serverTime": 1499827319559
}


Код для проверки:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print(bot.time())

 


Настройки и лимиты биржи - /api/v1/exchangeInfo


Ссылка для просмотра в браузере https://api.binance.com/api/v1/exchangeInfo
Вес - 1
Возвращает структуру данных:

{
  "timezone": "UTC",
  "serverTime": 1508631584636,
  "rateLimits": [{
      "rateLimitType": "REQUESTS",
      "interval": "MINUTE",
      "limit": 1200
    },
    {
      "rateLimitType": "ORDERS",
      "interval": "SECOND",
      "limit": 10
    },
    {
      "rateLimitType": "ORDERS",
      "interval": "DAY",
      "limit": 100000
    }
  ],
  "exchangeFilters": [],
  "symbols": [{
    "symbol": "ETHBTC",
    "status": "TRADING",
    "baseAsset": "ETH",
    "baseAssetPrecision": 8,
    "quoteAsset": "BTC",
    "quotePrecision": 8,
    "orderTypes": ["LIMIT", "MARKET"],
    "icebergAllowed": false,
    "filters": [{
      "filterType": "PRICE_FILTER",
      "minPrice": "0.00000100",
      "maxPrice": "100000.00000000",
      "tickSize": "0.00000100"
    }, {
      "filterType": "LOT_SIZE",
      "minQty": "0.00100000",
      "maxQty": "100000.00000000",
      "stepSize": "0.00100000"
    }, {
      "filterType": "MIN_NOTIONAL",
      "minNotional": "0.00100000"
    }]
  }]
}


Ключ rateLimits ведет на массив с лимитами - сколько запросов в секунду/минуту/день можно делать. 
Ключ symbols содержит настройки для каждой пары - рассмотрим одну, ETHBTC

{
  "symbol": "ETHBTC",
  "status": "TRADING",
  "baseAsset": "ETH",
  "baseAssetPrecision": 8,
  "quoteAsset": "BTC",
  "quotePrecision": 8,
  "orderTypes": [
    "LIMIT",
    "LIMIT_MAKER",
    "MARKET",
    "STOP_LOSS_LIMIT",
    "TAKE_PROFIT_LIMIT"
  ],
  "icebergAllowed": true,
  "filters": [
    {
      "filterType": "PRICE_FILTER",
      "minPrice": "0.00000100",
      "maxPrice": "100000.00000000",
      "tickSize": "0.00000100"
    },
    {
      "filterType": "LOT_SIZE",
      "minQty": "0.00100000",
      "maxQty": "100000.00000000",
      "stepSize": "0.00100000"
    },
    {
      "filterType": "MIN_NOTIONAL",
      "minNotional": "0.00100000"
    }
  ]
}


symbol - непосредственно пара
status - TRADING  -разрешена торговля
baseAsset - базовая валюта
baseAssetPrecision - требуемое количество символов базовой валюты после запятой при создании ордера (для цены и количества)
quoteAsset - квотируемая валюта
quotePrecision - требуемое количество символов квотируемой валюты после запятой при создании ордера (для цены и количества)
"orderTypes": [
    "LIMIT",
    "LIMIT_MAKER",
    "MARKET",
    "STOP_LOSS_LIMIT",
    "TAKE_PROFIT_LIMIT"
  ] - допустимые виды ордеров по паре
icebergAllowed - разрешено ли создание айсбергов (ордеров с невидимой частью)
filters - ограничение ордеров
    PRICE_FILTER - ограничение цены создаваемого ордера. Цена ордера должна быть в диапазоне min_price и max_price, и шаг торговли должен быть кратен tickSize. Да да, тут нельзя ставить ордера с произвольной ценой.
    LOT_SIZE - ограничение объема создаваемого ордера. Объем должен быть в диапазоне minQty и maxQty, и быть кратен stepSize.
    MIN_NOTIONAL - итоговая сумма ордера (объем*цена) должна быть выше minNotional.
Код для проверки:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print(bot.exchangeInfo())

 


Открытые ордера на бирже - /api/v1/depth


Метод позволяет получить книгу ордеров. 
Принимает параметры:
Обязательные:
symbol - пара 
Необязательные:
limit - кол-во возвращаемых записей от 5 до 1000 (по умолчанию 100). Допустимые значения: 5, 10, 20, 50, 100, 500, 1000. Еще можно указать 0, но он может вернуть большое кол-во данных.
Вес зависит от параметра limit. При лимите от 5 до 100 вес будет равен 1. Для параметра 500 вес составит 5. Для параметра 1000 вес будет 10.
Ссылка для просмотра в браузере: https://api.binance.com/api/v1/depth?symbol=ETHBTC
Возвращает значения:

{
  "lastUpdateId": 1027024,
  "bids": [
    [
      "4.00000000",     // PRICE
      "431.00000000",   // QTY
      []                // Ignore.
    ]
  ],
  "asks": [
    [
      "4.00000200",
      "12.00000000",
      []
    ]
  ]
}


bids - это списки цен/объемов на покупку, asks - на продажу.
Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('depth', bot.depth(
    symbol='BNBBTC',
    limit=5
))

 


Последние (чужие) сделки - /api/v1/trades


Принимает параметры:
Обязательные:
symbol - пара 
Необязательные:
limit - кол-во возвращаемых записей (максимум 500, по умолчанию 500).
Вес - 1
Ссылка для просмотра в браузере: https://api.binance.com/api/v1/trades?symbol=ETHBTC
Пример ответа:

[
  {
    "id": 28457,
    "price": "4.00000100",
    "qty": "12.00000000",
    "time": 1499865549590,
    "isBuyerMaker": true,
    "isBestMatch": true
  }
]


id - id сделки
price - цена
qty - количество
time - время сделки
isBuyerMaker - была ли покупка по указанной покупателем цене, 
isBestMatch - была ли встречная сделка
Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('trades', bot.trades(
    symbol='BNBBTC',
    limit=1
))

 


Сжатая история сделок - /api/v1/aggTrades


Метод позволяет получить суммарную историю сделок. Сделки, выполненные в одно время по одному ордеру и по одной цене будут представлены одной строкой с объединенным количеством.
Вес - 1
Ссылка для просмотра в браузере: https://api.binance.com/api/v1/aggTrades?symbol=ETHBTC
Принимает параметры:
Обязательные:
symbol - пара
Необязательные:
fromID - показывать начиная со сделки № (включительно)
startTime - начиная с какого времени (включительно)
endTime - заканчивая каким временем (включительно)
limit - Кол-во записей (максимум 500, по умолчанию 500)
Возвращает данные:

[
  {
    "a": 26129,         //  tradeId строки
    "p": "0.01633102",  // Цена
    "q": "4.70443515",  // Количество
    "f": 27781,         // Первая tradeId
    "l": 27781,         // Последняя tradeId
    "T": 1498793709153, // Время
    "m": true,          // Was the buyer the maker?
    "M": true           // Was the trade the best price match?
  }
]


Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('aggTrades', bot.aggTrades(
    symbol='BNBBTC',
    limit=1
))

 


Данные по свечам – /api/v1/klines


Вес – 1
Ссылка для просмотра в браузере https://api.binance.com/api/v1/klines?symbol=LTCBTC&interval=5m
Параметры:
Обязательные:
symbol – пара
interval – период свечи
    Допустимые интервалы:
    •    1m     // 1 минута
    •    3m     // 3 минуты
    •    5m    // 5 минут
    •    15m  // 15 минут
    •    30m    // 30 минут
    •    1h    // 1 час
    •    2h    // 2 часа
    •    4h    // 4 часа
    •    6h    // 6 часов
    •    8h    // 8 часов
    •    12h    // 12 часов
    •    1d    // 1 день
    •    3d    // 3 дня
    •    1w    // 1 неделя
    •    1M    // 1 месяц

Необязательные:
limit – кол-во свечей (максимум 500, по умолчанию 500)
startTime – время начала построения
endTime – окончание периода
Если не указаны параметры startTime и endTime, то возвращаются самые последние свечи.
Пример ответа:

[
  [
    1499040000000,      // Время открытия
    "0.01634790",       // Цена открытия (Open)
    "0.80000000",       // Максимальная цена (High)
    "0.01575800",       // Минимальная цена (Low)
    "0.01577100",       // Цена закрытия (Close)
    "148976.11427815",  // Объем
    1499644799999,      // Время закрытия
    "2434.19055334",    // Объем квотируемой валюты
    308,                // Кол-во сделок
    "1756.87402397",    // Taker buy base asset volume
    "28.46694368",      // Taker buy quote asset volume
    "17928899.62484339" // Ignore
  ]
]

 

Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('klines', bot.klines(
    symbol='BNBBTC',
    interval='5m',
    limit=1
))

 


Статистика за 24 часа - /api/v1/ticker/24hr


Вес – 1, если указана пара, иначе вес равен (количеству всех торгуемых пар)/2.
Ссылка для просмотра в браузере: https://api.binance.com/api/v1/ticker/24hr?symbol=BNBBTC
Параметры:
Необязательные:
symbol – пара
Если symbol не указан, возвращаются данные по всем парам. В этом случае, считается, что вы сделали столько запросов к бирже, сколько вернулось пар.
Пример ответа:

{
  "symbol": "BNBBTC", // пара
  "priceChange": "-94.99999800", // изменение цены за сутки 
  "priceChangePercent": "-95.960", // изменение цены за сутки %
  "weightedAvgPrice": "0.29628482", //Средневзвешенная цена
  "prevClosePrice": "0.10002000", // Предыдущая цена закрытия
  "lastPrice": "4.00000200",     // Последняя цена
  "lastQty": "200.00000000",    // Последний объем
  "bidPrice": "4.00000000",    // Цена покупки
  "askPrice": "4.00000200",    // Цена продажи
  "openPrice": "99.00000000",    // Цена открытия
  "highPrice": "100.00000000",    // Самая высокая цена
  "lowPrice": "0.10000000",    // Самая низкая цена
  "volume": "8913.30000000",    // Объем торгов базовой валюты
  "quoteVolume": "15.30000000",    // Объем торгов квотируемой
  "openTime": 1499783499040,    // Время открытия
  "closeTime": 1499869899040,    // Время закрытия
  "fristId": 28385,   // Id первой сделки
  "lastId": 28460,    // Id последней сделки
  "count": 76         // Кол-во сделок
}

 

Если пар несколько, то такие словари вкладываются в массив, вот так:

[
  {
    "symbol": "BNBBTC",
    
  },
  {
    "symbol": "LTCBTC",
    
  },
]

 

Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('ticker/24hr', bot.ticker24hr(
    symbol='BNBBTC'
))

 


Последняя цена по паре (или парам) - /api/v3/ticker/price


Вес - 1
Параметры:
Необязательные:
symbol – пара
Если параметр symbol не указан, то возвращаются цены по всем парам.
Ссылка для просмотра в браузере: https://api.binance.com/api/v3/ticker/price?symbol=BNBBTC
Пример ответа:

{
  "symbol": "LTCBTC",
  "price": "4.00000200"
}


Или (если не указан параметр)

[
  {
    "symbol": "LTCBTC",
    "price": "4.00000200"
  },
  {
    "symbol": "ETHBTC",
    "price": "0.07946600"
  }
]

 

Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('ticker/price', bot.tickerPrice(
    symbol='BNBBTC'
))

 


Лучшие цены покупки/продажи - /api/v3/ticker/bookTicker


Вес 1
Параметры:
Необязательные:
symbol – пара
Если параметр symbol не указан, возвращаются данные по всем парам.
Ссылка для просмотра в браузере: https://api.binance.com/api/v3/ticker/bookTicker?symbol=BNBBTC
Пример ответа:

{
  "symbol": "LTCBTC",
  "bidPrice": "4.00000000", //Лучшая цена покупки
  "bidQty": "431.00000000", // Кол-во к покупке
  "askPrice": "4.00000200", // Лучшая цена продажи
  "askQty": "9.00000000"       // Кол-во к продаже    
}

 

Или (если не указан параметр):

[
  {
    "symbol": "LTCBTC",
    "bidPrice": "4.00000000",
    "bidQty": "431.00000000",
    "askPrice": "4.00000200",
    "askQty": "9.00000000"
  },
  {
    "symbol": "ETHBTC",
    "bidPrice": "0.07946700",
    "bidQty": "9.00000000",
    "askPrice": "100000.00000000",
    "askQty": "1000.00000000"
  }
]


Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('ticker/bookTicker', bot.tickerBookTicker(
    symbol='BNBBTC'
))

Реклама


 


Реклама


Авторизованные запросы:

 


Создание ордера - /api/v3/order

Для тех, кто будет писать свою библиотеку – обратите внимание, что адрес один и тот же /api/v3/order, но отличается метод – если отправлять данные через POST, это будет создание ордера, через GET – получение информации об ордере, DELETE – отмена ордера. Параметры, соответственно, разные.


Вес – 1
Метод: POST
Параметры:
Обязательные:
symbol – пара
side – тип ордера (BUY либо SELL)
type – тип ордера (LIMIT, MARKET, STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT, LIMIT_MAKER) 
quantity – количество к покупке
timestamp – текущее время в миллисекундах (в коде, выложенном здесь, проставляется автоматически, указывать не надо. 
Необязательные:
timeInForce – (GTC, IOC, FOK). По умолчанию GTC. Расшифрую.
    GTC (Good Till Cancelled) – ордер будет висеть до тех пор, пока его не отменят.
    IOC (Immediate Or Cancel) – Будет куплено то количество, которое можно купить немедленно. Все, что не удалось купить, будет отменено.
   FOK (Fill-Or-Kill) – Либо будет куплено все указанное количество немедленно, либо не будет куплено вообще ничего, ордер отменится.

price – цена
newClientOrderId – Идентификатор ордера, который вы сами придумаете (строка). Если не указан, генерится автоматически.
stopPrice – стоп-цена, можно указывать если тип ордера STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, или TAKE_PROFIT_LIMIT.
icebergQty – кол-во для ордера-айсберга, можно указывать, если тип ордера LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT
recvWindow – кол-во миллисекунд, которое прибавляется к timestamp и формирует окно действия запроса (см. выше). По умолчанию 5000.
newOrderRespType –какую информацию возвращать, если удалось создать ордер. Допустимые значения ACK, RESULT, или FULL, по умолчанию RESULT. Подробности ниже.


В зависимости от типа ордера, некоторые поля становятся обязательными:

Тип ордера                    Обязательные поля
LIMIT                         timeInForce, quantity, price
MARKET                        quantity
STOP_LOSS                     quantity, stopPrice
STOP_LOSS_LIMIT               timeInForce, quantity, price, stopPrice
TAKE_PROFIT                   quantity, stopPrice
TAKE_PROFIT_LIMIT             timeInForce, quantity, price, stopPrice
LIMIT_MAKER                   quantity, price


Ордера типа LIMIT_MAKER – это ордера типа обычного LIMIT, но они отклонятся, если ордер при выставлении может выполниться по рынку. Другими словами, вы никогда не будете тейкером, ордер либо выставится выше/ниже рынка, либо не выставится вовсе.
Ордера типа STOP_LOSS и TAKE_PROFIT исполнятся по рынку (ордер типа MARKET), как только будет достигнута цена stopPrice.
Любые ордера LIMIT или LIMIT_MAKER могут формировать ордер-айсберг, установив параметр icebergQty.
Если установлен параметр icebergQty, то параметр timeInForce ОБЯЗАТЕЛЬНО должен иметь значение GTC.

Для того, что бы выставлять цены, противоположные текущим для ордеров типов MARKET и LIMIT:
Цена выше рыночной: STOP_LOSS BUY, TAKE_PROFIT SELL
Цена ниже рыночной: STOP_LOSS SELL, TAKE_PROFIT BUY


При создании ордера вернется ответ, в зависимости от параметра newOrderRespType:


newOrderRespType == ACK:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595
}


newOrderRespType == RESULT:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595,
  "price": "0.00000000",
  "origQty": "10.00000000",
  "executedQty": "10.00000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "MARKET",
  "side": "SELL"
}


newOrderRespType == FULL:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595,
  "price": "0.00000000",
  "origQty": "10.00000000",
  "executedQty": "10.00000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "MARKET",
  "side": "SELL",
  "fills": [
    {
      "price": "4000.00000000",
      "qty": "1.00000000",
      "commission": "4.00000000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3999.00000000",
      "qty": "5.00000000",
      "commission": "19.99500000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3998.00000000",
      "qty": "2.00000000",
      "commission": "7.99600000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3997.00000000",
      "qty": "1.00000000",
      "commission": "3.99700000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3995.00000000",
      "qty": "1.00000000",
      "commission": "3.99500000",
      "commissionAsset": "USDT"
    }
  ]
}


Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
# Создать отложенный ордер на покупку 0.1 LTC за BTC
# По курсу 0.1
print('createOrder', bot.createOrder(
    symbol='LTCBTC',
    recvWindow=5000,
    side='BUY',
    type='LIMIT',
    timeInForce='GTC',
    quantity=0.1,
    price=0.1
))

 


Тестирование создания ордера: /api/v3/order/test


Вес: 1
Метод: POST
Метод позволяет протестировать создание ордера – например, проверить, правильно ли настроены временные рамки. По факту такой ордер никогда не будет исполнен, и средства на его создание затрачены не будут.
Параметры такие же, как при создании ордера.
Возвращает пустой словарь:

{}


Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
# Протестировать отложенный ордер на покупку 0.1 LTC за BTC
# По курсу 0.1
print('testOrder', bot.testOrder(
    symbol='LTCBTC',
    recvWindow=5000,
    side='BUY',
    type='LIMIT',
    timeInForce='GTC',
    quantity=0.1,
    price=0.1
))

 


Получить информацию по созданному ордеру - /api/v3/order


Вес – 1
Метод – GET
Параметры:
Обязательные:
symbol – пара
orderId – ID ордера, назначенный биржей
ИЛИ origClientOrderId – ID ордера, назначенный пользователем или сгенерированный (см. создание ордера)
Либо orderId либо origClientOrderId необходимо предоставить.
timestamp – текущее время (в представленном коде проставляется автоматически, указывать не надо)
Необязательные:
recvWindow – окно валидности запроса.

Возвращаемое значение:

{
  "symbol": "LTCBTC",
  "orderId": 1,
  "clientOrderId": "myOrder1",
  "price": "0.1",
  "origQty": "1.0",     // исходное указанное кол-во на покупку/продажу
  "executedQty": "0.0",  // текущее исполненное кол-во
  "status": "NEW",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.0",
  "icebergQty": "0.0",
  "time": 1499827319559,
  "isWorking": true
}

Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('orderInfo', bot.orderInfo(
    orderId=123123,
    symbol='LTCBTC',
))

 


Отмена ордера - /api/v3/order


Вес – 1
Метод – DELETE
Параметры:
Обязательные:
symbol – пара

orderId – ID ордера, назначенный биржей
ИЛИ origClientOrderId – ID ордера, назначенный пользователем или сгенерированный (см. создание ордера)
Либо orderId либо origClientOrderId необходимо предоставить.

timestamp – текущее время (в представленном коде проставляется автоматически, указывать не надо)
Не обязательные:
 
newClientOrderId – позволяет однозначно определить отмену, если не указано, генерируется автоматически
recvWindow – окно валидности запроса.
Возвращает:

{
  "symbol": "LTCBTC",
  "origClientOrderId": "myOrder1",
  "orderId": 1,
  "clientOrderId": "cancelMyOrder1"
}

 

Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
print('cancelOrder', bot.cancelOrder(
    orderId=123123,
    symbol='LTCBTC',
))

 


Текущие открытые пользователем ордера - /api/v3/openOrders


Вес – 1 если указана пара, либо (количество всех открытых для торгов пар) / 2.
Метод – GET
Параметры:
Обязательные:
timestamp – текущее время (в представленном коде проставляется автоматически, указывать не надо)
Не обязательные:
Не обязательные:
symbol – пара
recvWindow – окно валидности запроса.

Если параметр symbol не указан, возвращаются все открытые ордера по всем парам в массиве. В этом случае количество запросов к API считается равным количеству открытых для торговли пар.
Возвращает:

[
  {
    "symbol": "LTCBTC",
    "orderId": 1,
    "clientOrderId": "myOrder1",
    "price": "0.1",
    "origQty": "1.0",
    "executedQty": "0.0",
    "status": "NEW",
    "timeInForce": "GTC",
    "type": "LIMIT",
    "side": "BUY",
    "stopPrice": "0.0",
    "icebergQty": "0.0",
    "time": 1499827319559,
    "isWorking": trueO
  }
]


Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)

# Все открытые ордера по паре
print('openOrders', bot.openOrders(
    symbol='LTCBTC',
))

# Все открытые ордера по всем парам
print('openOrders', bot.openOrders())

 


Все ордера пользователя вообще - /api/v3/allOrders


Метод позволяет получить вообще все ордера пользователя – открытые, исполненные или отмененные.
Вес – 5
Метод – GET
Параметры:
Обязательные:
symbol – пара
timestamp – текущее время (в представленном коде проставляется автоматически, указывать не надо)
Не обязательные:
orderId – Если указан, то вернутся все ордера, которые >= указанному. Если не указан, вернутся самые последние.
limit – кол-во возвращаемых ордеров (максимум 500, по умолчанию 500)
recvWindow – окно валидности запроса.
Возвращает:

[
  {
    "symbol": "LTCBTC",
    "orderId": 1,
    "clientOrderId": "myOrder1",
    "price": "0.1",
    "origQty": "1.0",
    "executedQty": "0.0",
    "status": "NEW",
    "timeInForce": "GTC",
    "type": "LIMIT",
    "side": "BUY",
    "stopPrice": "0.0",
    "icebergQty": "0.0",
    "time": 1499827319559,
    "isWorking": true
  }
]

 

Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)

# Все ордера по паре
print('allOrders', bot.allOrders(
    symbol='LTCBTC',
))

 


Информация по аккаунту - /api/v3/account


Вес – 5
Метод – GET
Параметры:
Обязательные:
timestamp – текущее время (в представленном коде проставляется автоматически, указывать не надо)
Не обязательные:
recvWindow – окно валидности запроса.
Возвращает:

{
  "makerCommission": 15,
  "takerCommission": 15,
  "buyerCommission": 0,
  "sellerCommission": 0,
  "canTrade": true,
  "canWithdraw": true,
  "canDeposit": true,
  "updateTime": 123456789,
  "balances": [
    {
      "asset": "BTC",
      "free": "4723846.89208129",
      "locked": "0.00000000"
    },
    {
      "asset": "LTC",
      "free": "4763368.68006011",
      "locked": "0.00000000"
    }
  ]
}


Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)

print('account', bot.account())

 


Список сделок пользователя - /api/v3/myTrades


Метод позволяет получить историю торгов авторизованного пользователя по указанной паре.
Вес – 5.
Параметры:
Обязательные:
symbol – пара
timestamp – текущее время (в представленном коде проставляется автоматически, указывать не надо)
Не обязательные:
limit – кол-во возвращаемых сделок (максимум 500, по умолчанию 500)
fromId – с какой сделки начинать вывод. По умолчанию выводятся самые последние.
recvWindow – окно валидности запроса.
Возвращает:

[
  {
    "id": 28457,
    "orderId": 100234,
    "price": "4.00000100",
    "qty": "12.00000000",
    "commission": "10.10000000",
    "commissionAsset": "BNB",
    "time": 1499865549590,
    "isBuyer": true,
    "isMaker": false,
    "isBestMatch": true
  }
]


Пример кода:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)

print('myTrades', bot.myTrades(
    symbol='LTCBTC'
))

Реклама


WAPI

Ввод и вывод средств

Подробное описание будет чуть позже, пока что примеры с комментариями

from binance_api import Binance
bot = Binance(
    API_KEY='D7F...Ejj',
    API_SECRET='gwQ...u3A'
)

# Получение адреса для депозита
print(bot.depositAddress(asset='BTC'))

# Вывод средств
print(bot.withdraw(asset='XRP', address='1wsdsr234234242', amount=12))

# История пополнений
print(bot.depositHistory(asset='BTC'))
print(bot.depositHistory())

# История выводов
print(bot.withdrawHistory())
print(bot.withdrawHistory(asset='ETH'))

# Узнать комиссию за вывод
print(bot.withdrawFee(asset='BTC'))

# Состояние аккаунта
print(bot.accountStatus())

# Состояние биржи
print(bot.systemStatus())

 

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

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



Комментарии
15.02.2018 22:40:34
Здравствуйте! Что-то у меня не в порядке с первым примером. Выдает ошибку : {'msg',: 'Invalid API-key, IP, or permission for action.', 'code': -2015}. API ключ я взял настоящий действующий.
Проголосовать Проголосовать
0 0
16.02.2018 02:01:54
Временами выдает {'code': -1022, 'msg': 'Signature for this request is not valid.'}". Прочел что это связано с recWindow. Непонятно как этого избегать.
Проголосовать Проголосовать
0 0
16.02.2018 05:03:13
Проверьте настройки безопасности - возможно, нужно добавить IP в белый список. Так же убедитесь, что стоят нужные галки в настройках ключа - для первого примера нужен флаг Read Info, но вообще поставьте Enable Trading тоже - что бы можно было выставлять ордера
Проголосовать Проголосовать
0 0
16.02.2018 05:07:04
Это значит, что пакет данных от вас до Binance идет долго, дольше чем 5000 мс. 
Просто увеличьте это окно, например

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)

print('account', bot.account(recvWindow=15000))

Этот параметр можно в любом приватном методе использовать
Проголосовать Проголосовать
1 0
16.02.2018 16:13:44
Я поробовал добавит IP в белый список н это не помогло. Впрочем это видимо вопрос не к Вам, а к админам биржи. Спасибо за ответ!
Проголосовать Проголосовать
0 0
16.02.2018 16:12:09
print('account', bot.account(recvWindow=15000)) выдает ошибку 
{'msg',:"Not all sent parameters were read; 'read' '2' parameter(s) but was sent '3'.", 'code': -1104}
Проголосовать Проголосовать
0 0
18.02.2018 13:00:13
Увеличил параметр до 25000 - и все равно. Насколько надо его увеличить? Работает примерно в половине случаев...
Проголосовать Проголосовать
0 0
16.02.2018 17:48:44
Проверил только что, взял код с сайта и вашего примера, отлично отработало.
Проверьте свой код - такая ошибка говорит о том, что какой-то параметр не распознался, возможно написан с опечаткой
Проголосовать Проголосовать
0 0
18.02.2018 13:08:55
Скорее всего, вам стоит проверить синхронизацию времени на своем компьютере, мне кажется у вас расхождение с мировым на несколько секунд, отсюда все проблемы. 25000 это и так довольно много.
Проголосовать Проголосовать
0 0
18.02.2018 12:56:40
Вы правы, опечатка!
Проголосовать Проголосовать
0 0
18.02.2018 14:26:14
Прошу прощения за глупый вопрос : а как это проверить и какое время должно быть? (Ubuntu 16.04 LTS). Вроде секунды в порядке...
Проголосовать Проголосовать
0 0
18.02.2018 17:52:04
Начните с  команды timedatectl
Вот, можете по шагам пройти, установить ntp и всё, что надо https://www.digitalocean.com/community/tutorials/how-to-set-up-time-synchronization-on-ubuntu-16-04
Проголосовать Проголосовать
0 0
18.02.2018 19:35:12
Спасибо за ссылку, я все это проделал и лучше не стало. Опытным путем видно что где-то 55000 оптимальное число,но все равно 1 раз из десяти происходит сбой. Меньше и больше - сбоев больше : 2 - 3 из 10.
Проголосовать Проголосовать
0 0
04.03.2018 12:26:19
Здравствуйте!  При попытке выставить ордер на покупку по паре 'ADABTC' получаю ответ биржи:        {'code': -1100, 'msg': "Illegal characters found in parameter 'price'; legal range is '^([0-9]{1,20})(\\.[0-9]{1,20})?$'."}
возможно это связано с тем, что цена ADA низкая в  BTC? Кусок кода :
    #цену приводим к требованиям биржи о кратности
    my_need_price = adjust_to_step(bid_price, data_big[pair][1]['filters'][0]['tickSize'])
 # Рассчитываем кол-во, которое можно купить, и тоже приводим его к кратному значению
    my_amount = adjust_to_step(amount/ my_need_price, data_big[pair][1]['filters'][1]['stepSize'])
    my_need_price = float(my_need_price)
    my_need_price = round(my_need_price,8)
    print ('my_need_price =',my_need_price , 'my_amount=',my_amount)
    with open(CURR_DIR+'/SL/LOG/'+'log_buy.txt', 'a') as f:
        print(datetime.now(),'***338РЕШЕНИЕ О ПОКУПКЕ***', pair)
        print(datetime.now(),'***339РЕШЕНИЕ О ПОКУПКЕ***', pair,'data_big[pair][0]=',data_big[pair][0], file=f)
        print(datetime.now(),'my_need_price =',my_need_price , 'my_amount=',my_amount, file=f)        
        print(datetime.now(),'***Ордер на покупку***', pair, 'bid_price=', bid_price, 'amount=', amount, file=f)    
 # Отправляем команду на бирже о создании ордера на покупку с рассчитанными параметрами
    new_order = bot.createOrder(
                                symbol=pair,
                                recvWindow=15000,
                                side='BUY',
                                type='LIMIT',
                                timeInForce='GTC',  # Good Till Cancel
                                quantity=my_amount,
                                price=my_need_price,
                                newOrderRespType='FULL'
                               )
    time.sleep(1)
     # Если удалось создать ордер на покупку
    if 'orderId' in new_order:
        print("Создан ордер на покупку", new_order) 
        print ('orderId=', new_order['orderId'])
        data_big[pair][0] = 1    
        data_big[pair].append(new_order['orderId'])

        with open(CURR_DIR+'/SL/LOG/'+'log_buy.txt', 'a') as f:
            print(datetime.now(), pair,'362создан ордер на покупку', new_order, file=f)
            print(datetime.now(), pair,'создан ордер на покупку data_big[pair] =', data_big[pair], file=f)
        
    else :
        data_big[pair][0] = 0 
        with open(CURR_DIR+'/SL/LOG/'+'log_buy.txt', 'a') as f:
            print(datetime.now(), pair,'368ОШИБКА не создан ордер на покупку', new_order, file=f)
            print(datetime.now(), pair,'ОШИБКА не создан ордер на покупку data_big[pair] =', data_big[pair], file=f)
    with open(CURR_DIR+'/SL/LOG/'+'log_buy.txt', 'a') as f:
        print(datetime.now(), pair,'318 Выход call_buy data_big[pair] =', data_big[pair], file=f)
А дальше лог, который выдает этот код:
2018-03-04 21:24:08.254604 ***339РЕШЕНИЕ О ПОКУПКЕ*** ADABTC data_big[pair][0]= 0
2018-03-04 21:24:08.254604 my_need_price = 2.3e-05 my_amount= 52.0
2018-03-04 21:24:08.254604 ***Ордер на покупку*** ADABTC bid_price= 2.3e-05 amount= 0.0012
2018-03-04 21:24:09.431604 ADABTC 368ОШИБКА не создан ордер на покупку {'code': -1100, 'msg': "Illegal characters found in parameter 'price'; legal range is '^([0-9]{1,20})(\\.[0-9]{1,20})?$'."}
2018-03-04 21:24:09.431604 ADABTC ОШИБКА не создан ордер на покупку data_big[pair] = [0, {'symbol': 'ADABTC', 'status': 'TRADING', 'baseAsset': 'ADA', 'baseAssetPrecision': 8, 'quoteAsset': 'BTC', 'quotePrecision': 8, 'orderTypes': ['LIMIT', 'LIMIT_MAKER', 'MARKET', 'STOP_LOSS_LIMIT', 'TAKE_PROFIT_LIMIT'], 'icebergAllowed': True, 'filters': [{'filterType': 'PRICE_FILTER', 'minPrice': '0.00000001', 'maxPrice': '100000.00000000', 'tickSize': '0.00000001'}, {'filterType': 'LOT_SIZE', 'minQty': '1.00000000', 'maxQty': '90000000.00000000', 'stepSize': '1.00000000'}, {'filterType': 'MIN_NOTIONAL', 'minNotional': '0.00100000'}]}]
2018-03-04 21:24:09.431604 ADABTC 318 Выход call_buy data_big[pair] = [0, {'symbol': 'ADABTC', 'status': 'TRADING', 'baseAsset': 'ADA', 'baseAssetPrecision': 8, 'quoteAsset': 'BTC', 'quotePrecision': 8, 'orderTypes': ['LIMIT', 'LIMIT_MAKER', 'MARKET', 'STOP_LOSS_LIMIT', 'TAKE_PROFIT_LIMIT'], 'icebergAllowed': True, 'filters': [{'filterType': 'PRICE_FILTER', 'minPrice': '0.00000001', 'maxPrice': '100000.00000000', 'tickSize': '0.00000001'}, {'filterType': 'LOT_SIZE', 'minQty': '1.00000000', 'maxQty': '90000000.00000000', 'stepSize': '1.00000000'}, {'filterType': 'MIN_NOTIONAL', 'minNotional': '0.00100000'}]}]

Т.е. значения   my_need_price = 2.3e-05    my_amount= 52.0  приводят к такому результату, я уже думал что дело в букве е в цене, но как победить это я не знаю, может подскажите?
Проголосовать Проголосовать
0 0
05.03.2018 20:27:38
Добрый день!
Вам нужно отправлять как-то так:
price="{price:0.8f}".format(price=my_need_price)

Так же они лимитируют precision - сколько знаков после запятой для пары допускается, советую посмотреть эту статью и взять код оттуда https://bablofil.ru/bot-dlya-binance/ - там эти моменты решены
Проголосовать Проголосовать
0 0
06.03.2018 13:38:16
Спасибо, просто я не профессиональный программист, а самоучка и не понимаю всего кода из https://bablofil.ru/bot-dlya-binance/ , но теперь я примерно понял, а вообще я делал на основе этой вашей статьи, просто те моменты где я не понимал код я не использовал, сделаю отпишусь.
Проголосовать Проголосовать
0 0
07.03.2018 11:59:59
Спасибо, просто вставил вашу строку        price="{price:0.8f}".format(price=my_need_price)
и все заработало, просто как чудо, до этого неделю голову ломал
Проголосовать Проголосовать
0 0
12.03.2018 19:05:22
Добрый день. Обнаружил, что в API отсутствует возможность связать заявку и сделку. Через WebSocket в режиме активных торгов эта информация поступает, но есть сценарий, когда возникает проблема. Пример. Робот выставил заявку, она выставилась, висит активная. Я записал ID транзакции и Id заявки у себя. Все нормально. Далее, закрываю робота и на бирже моя заявка срабатывает. Я открываю робота, вызываю "GetAccountTrades" (в API возможно по-другому называется, я использую C# и BinanceDotNet), получаю список сделок, но в нем нет OrderId. Получается, робот не может понять, что произошло с заявкой. Тем более, она может пройти частично или несколько сделок будут входить в одну заявку. Я не первый, кто заметил этот недочет, люди советуют обратиться к разработчикам биржи. Вам не приходилось обходить подобный момент?
Проголосовать Проголосовать
0 0
14.03.2018 12:08:26
Метод API myTrades возвращает ID ордера 
[
  {
    "id": 28457,
    "orderId": 100234,
    "price": "4.00000100",
    "qty": "12.00000000",
    "commission": "10.10000000",
    "commissionAsset": "BNB",
    "time": 1499865549590,
    "isBuyer": true,
    "isMaker": false,
    "isBestMatch": true
  }
]
Видимо, библиотека которой вы пользуетесь это игнорирует, или нужно использовать другой метод
Проголосовать Проголосовать
0 0
14.03.2018 13:34:38
Действительно, в API есть такое поле. Видимо наткнулся на устаревшую информацию (месячной давности) и не перепроверил сам. Благодарю за наводку!
Проголосовать Проголосовать
0 0
15.03.2018 06:06:10
Добрый день, Андрей
Можно попросить вас, выложить код бота  binance с индикатором MACD 
В заранее благодарю.
Проголосовать Проголосовать
0 0
17.03.2018 19:35:48
Всем доброго времени суток. Пишу бота, который собирает открытую статистику (без API KEY) агрегированных сделок на бирже через websocket. Создаю количество потоков равное количеству валютных пар, например XXXETH. Но через несколько часов работы сервер биржи перестает предоставлять статистику по некоторым валютам (примерно половина) или даже в момент пампа. При этом на клиентском сокете не могу отловить этот момент, чтобы пересоздать соединение. Кто как решает эту проблему?
Проголосовать Проголосовать
0 0
18.03.2018 10:42:04
Пробую получить свечки за большой промежуток времени и не получается - отдаются только свечи за последнее время, остальное игнорируется.
Это ограничение бинанса?
Есть вариант обойти?
Проголосовать Проголосовать
0 0
18.03.2018 17:28:15
Ограничение бинанса - последние 500 записей. Поэтому приходиться собирать статистику через websocket (свечи, агрегированные сделки) и хранить у себя.
Проголосовать Проголосовать
0 0
21.03.2018 17:26:15
Добры вечер всем! Подскажите пожалуйста как по API узнать цену ордера исполненного по маркету? В "orderInfo" не нашел значения.
Проголосовать Проголосовать
0 0
21.03.2018 18:32:53
Спасибо! Решился вопрос.
Проголосовать Проголосовать
0 0
27.03.2018 14:09:33
Здравствуйте. Подскажите из-за чего возникает эта ошибка?
Traceback (most recent call last):
  File "C:\1\binance_test.py", line 6, in <module>
    print('account', bot.account())
  File "C:\1\binance_api.py", line 43, in wrapper
    return self.call_api(**kwargs)
  File "C:\1\binance_api.py", line 70, in call_api
    return response.json()
  File "C:\Program Files\Python36\lib\site-packages\requests\models.py", line 892, in json
    return complexjson.loads(self.text, **kwargs)
  File "C:\Program Files\Python36\lib\json\__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "C:\Program Files\Python36\lib\json\decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Program Files\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)</module>
Проголосовать Проголосовать
0 0
27.03.2018 17:23:05
Биржа на что-то ругается, может быть время не синхронизировано, или сетевой сбой какой то. Попробуйте передать и указать параметр recvWindow побольше
Проголосовать Проголосовать
0 0
27.03.2018 19:21:25
Роман, такая же ошибка. Вчера все нормально работало. Если нашли в чем причина отпишитесь пожалуйста.
Проголосовать Проголосовать
0 0
27.03.2018 19:23:19
Не помогает(
Проголосовать Проголосовать
0 0
28.03.2018 08:06:46
Да, изменился немного механизм работы API
Я изменил код в статье, можно дальше пользоваться
Проголосовать Проголосовать
1 0
28.03.2018 20:34:19
Спасибо!
Проголосовать Проголосовать
0 0
28.03.2018 18:03:24
Здравствуйте, подскажите пожалуйста, почему не можно API Binance https://api.binance.com/api/v1/ticker/24hr?symbol=BNBBTC отредактировать в программе http://jsoneditoronline.org/,  как API exmo? Урок брал в Вашей статьи https://bablofil.ru/exmo-api/#add_comment_form
Проголосовать Проголосовать
0 0
16.04.2018 14:45:07
Здравствуйте.
Если вы откроете ссылку  https://api.binance.com/api/v1/ticker/24hr?symbol=BNBBTC в браузере, скопируете текст и вставите в jsoneditoronline, то все получится. Но если вы попробуете ссылку открыть в самом jsoneditoronline, то он не сможет её скачать т.к. бинанс будет думать что это какой-то робот ломится
Проголосовать Проголосовать
0 0
02.04.2018 13:39:34
Здравствуйте, подскажите пожалуйста. Как одним запросом извлечь 4 разных пар свечь c API Binance. я могу извлечь только одну пару
Проголосовать Проголосовать
0 0
16.04.2018 14:54:20
Добрый день.
Так, к сожалению, нельзя, но можно вытащить что-то похожее, за сутки, отсюда - https://api.binance.com/api/v1/ticker/24hr?symbol=BNBBTC
Проголосовать Проголосовать
0 0
07.04.2018 18:00:11
Здравствуйте, а как получить текущую свечу одной пары?
Проголосовать Проголосовать
0 0
16.04.2018 14:56:45
Добрый день,
Что, в вашем понимании, текущая - вы же можете строить свечи за любой период - минута, сутки, 11 секунд, год... 
Вы можете брать последние свечи методом klines, можете брать последние сделки по паре и строить свою свечу, можете брать тикер (https://api.binance.com/api/v1/ticker/24hr?symbol=BNBBTC) и получать самые последние данные + объемы за сутки
Проголосовать Проголосовать
0 0
09.04.2018 05:54:53
Добрый день. Подскажите, как получить с Бинансе информацию о имеющихся парах? Нужно что-то типа https://wex.nz/api/3/info
Проголосовать Проголосовать
0 0
16.04.2018 14:57:54
Добрый день,
я беру отсюда - https://api.binance.com/api/v1/exchangeInfo
В цикле по symbols, берем symbol
Проголосовать Проголосовать
1 0
24.04.2018 12:17:41
спасибо,
Ещё вопросик проясните пожалуйста-
можно ли публичные запросы (depth, например) сделать на несколько пар одновременно?
например на Yobite: Depth: https://yobit.net/api/3/depth/ltc_btc-nmc_btc
а то как бы не нарушить их лимиты, при обновлении цен на все пары...(интересует при сравнении бирж - 30-40 пар обычно)
Проголосовать Проголосовать
0 0
26.04.2018 08:31:38
Можно, смотря какая информация нужна
Например, вот последняя цена по каждой паре
https://api.binance.com/api/v3/ticker/price
Везде, где symbol необязательное поле, просто убирайте его, и получите полный список.
Вообще можно 1200 запросов в минуту, если не превышать то не банят
Проголосовать Проголосовать
1 0
26.04.2018 08:58:52
спасибо. прайс использую. просто когда арбитражную ситуацию оцениваешь нужны стаканы. Но если 1200 запросов... вопросов нет. На некоторых биржах столкнулся на 1-2 запроса в секунду и менее. Там этот вопрос актуален.
Проголосовать Проголосовать
0 0
25.04.2018 04:01:51
Андрей, поменялось похоже еще что-то на Бинансе( Такая ошибка вылетает на bot.account():
{'code': -1021, 'msg': "Timestamp for this request was 1000ms ahead of the server's time."}
Проголосовать Проголосовать
0 0
26.04.2018 08:32:52
Это означает, что у вас время опережает мировое
Нужно настроить синхронизацию времени на вашем устройстве, боты сейчас работают, я проверил
Проголосовать Проголосовать
0 0
26.04.2018 17:32:29
Спасибо! Я видел сообщение ошибки, но подумал что что-то другое) Синхронизация не помогала, пока не поменял сервер синхронизации. А не подскажите из Питона нельзя запускать синхронизацию времени винды? А то у меня сутки нормально все было. Опять эта ошибка. Синхронизировался-хорошо все.
Проголосовать Проголосовать
0 0
28.04.2018 12:00:58
Из питона можно вызывать команды командной строки, один способ это модуль subprocess, второй - os.system(..), можно вызывать команды синхронизации
Но посмотрите код бота https://bablofil.ru/bot-dlya-binance/ - там я беру время сервера binance, текущее время, беру разницу и в дальнейшем отправляю запросы за учетом этой разницы, ничего синхронизировать не надо.
Проголосовать Проголосовать
0 0
06.05.2018 11:21:27
простите, а как из сжатой истории чужих сделок (/api/v1/aggTrades) определить была ли это покупка или продажа?
  {
    "a": 26129,         //  tradeId строки
    "p": "0.01633102",  // Цена
    "q": "4.70443515",  // Количество
    "f": 27781,         // Первая tradeId
    "l": 27781,         // Последняя tradeId
    "T": 1498793709153, // Время
    "m": true,          // Was the buyer the maker?
    "M": true           // Was the trade the best price match?
  }
если "m" true, то сделка Sell, а если false, то Buy?
Проголосовать Проголосовать
0 0
15.05.2018 11:07:16
Если один купил а другой продал, то это buy или sell?
Отвечу так: в истории торгов binance зеленым подсвечиваются сделки, у которых isBuyerMaker == false, и маджентой - у кого true
Проголосовать Проголосовать
0 0
16.05.2018 15:27:34
ну это понятно, что для кого-то Buy, а для кого-то Sell ))
имел ввиду, конечно, отображение на бирже ... спасибо за ответ
Проголосовать Проголосовать
0 0
15.05.2018 06:33:17
Возник вопрос, а как достать баланс доступный для определённой валюты и в дальнейшем без проблем использовать его для рассчётов ?
Проголосовать Проголосовать
0 0
15.05.2018 11:14:22
Добрый день!
Как то так:

from binance_api import Binance
bot = Binance(
    API_KEY='D7...Ejj',
    API_SECRET='gwQ...u3A'
)
NEED_ASSET = "BTC"

need_balance = 0
for struct in bot.account()["balances"]:
    if struct["asset"] == NEED_ASSET:
        need_balance = float(struct["free"])
        break

print(need_balance)
Проголосовать Проголосовать
1 0
17.05.2018 08:30:46
Здравствуйте, с  неделю начала вылазить ошибка.
/ $
/ $ cd '/data/user/0/ru.iiec.pydroid3/files/project/binance_calc_invest' ; export PYTHTraceback (most recent call last):           File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 31, in <module>                                 start(fakepyfile,mainpyfile)             File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 30, in start                                    exec(open(mainpyfile).read(),  __main__.__dict__)                                   File "<string>", line 12, in <module>      File "/data/user/0/ru.iiec.pydroid3/files/project/binance_calc_invest/binance_api.py", line 46, in wrapper                         return self.call_api(**kwargs)           File "/data/user/0/ru.iiec.pydroid3/files/project/binance_calc_invest/binance_api.py", line 73, in call_api                        return response.json()
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.6/site-packages/requests/models.py", line 892, in json
    return complexjson.loads(self.text, **kwargs)
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.6/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)

[Program finished]</module></string></module>
Проголосовать Проголосовать
0 0
17.05.2018 08:55:13
Добрый день, видимо не может подключиться к бирже по какой то причине (связь? ростелеком?) или получает какой то неожиданный ответ.

добавьте перед 
return response.json()
строку
print response.text
и посмотрите, что там возвращается

А так код у меня, например, по прежнему работает
Проголосовать Проголосовать
0 0
17.05.2018 12:23:08
<title>ERROR: The request could not be satisfied</title>

403 ERROR

The request could not be satisfied.


Bad request.

Generated by cloudfront (CloudFront) Request ID: rgfqfSbdvbhh_m2xQZHBQ146vm1UvVzMnLx4ZV6ACkQZTQvl8k9Nsw==
Проголосовать Проголосовать
0 0
17.05.2018 14:18:15
Я такое правил уже, когда трафик бинанса пошел через сервера амазона...
Вам нужно скачать обновленную версию либо с этой статьи, либо с этой: https://bablofil.ru/bot-dlya-binance/, должно все работать
Проголосовать Проголосовать
1 0
21.05.2018 09:47:47
Добрый день, у меня при работе моего самописного бота тоже такая ошибка появляется, подскажите как вы решили эту проблему?
Проголосовать Проголосовать
0 0
21.05.2018 09:54:07
В общем если запрос идет через GET и через сервера CloudFront то тело запроса должно быть пустым (только заголовки)
Проголосовать Проголосовать
1 0
21.05.2018 10:37:08
ok, спасибо.
Проголосовать Проголосовать
0 0
17.05.2018 12:16:43
Да кстати это началось после ковровых блокировок роскомпозора
Проголосовать Проголосовать
0 0
17.05.2018 15:43:22
Спасибо все заработало
Проголосовать Проголосовать
0 0
23.05.2018 12:17:22
ДОбрый день. Подскажите пожалуйста, как через апи бинанс получать данные о пополнении баланса и выводе средств с биржи? По идее должна быть такая возможность, но у Вас тут я к сожалению, не нашел. Заранее спасибо
Проголосовать Проголосовать
0 0
23.05.2018 20:43:16
Добрый день
Обновил статью: код binance_api (вначале) и в конце статьи добавил несколько примеров.
Более подробно распишу позже, но вроде бы и так всё наглядно
Если что спецификацию можно почитать на английском https://github.com/binance-exchange/binance-official-api-docs/blob/master/wapi-api.md
Проголосовать Проголосовать
0 0
23.05.2018 12:41:51
Здравствуйте.

Подскажите пожалуйста, как можно скачать историю котировок криптовалют с биржи Binance для создания своей базы данных?
Проголосовать Проголосовать
0 0
01.06.2018 08:34:36
Здравствуйте, непосредственно бинанс дает скачать максимум 500 записей, если нужна история торгов за длительный период лучше поискать сторонние аггрегаторы
Проголосовать Проголосовать
0 0
28.05.2018 20:29:39
Здравствуйте.
подскажите как подключиться в Binance с использованием вебсокета ?
Проголосовать Проголосовать
0 0
10.06.2018 10:55:24
Здравствуйте, вообще есть такое (чье-то) решение https://github.com/sammchardy/python-binance
pip install python-binance
Умеет коннектиться из коробки
А я попозже постараюсь выложить простой способ работы с сокетами
Официальное описание API - тут https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md
Имейте в виду, что сокеты отправляют информацию раз в секунду, в то время как rest запросы отвечают за 0.3 - 0.8 секунды
Проголосовать Проголосовать
0 0
08.06.2018 12:48:48
Здравствуйте Андрей. Большая благодарность Вам за качественное объяснение и примеры. Очень понятно и доходчиво!
Есть вопрос - не могу найти информацию по купленным и проданным ордерам за единицу времени, например за последнюю секунду (имею ввиду не пользователя а вообще по бирже по определённому токену). Знаю что бинанс предоставляет эту информацию, но не могу найти как это сделать, Вы не интересовались этим вопросом?
Проголосовать Проголосовать
0 0
10.06.2018 10:59:14
Добрый день.
Посмотрите метод aggTrades - можно указать период с разницей в секунду, получите до 500 сделок
Так же можно просто trades - последние 500 сделок, но там придется самому время выбирать из полученных данных
Проголосовать Проголосовать
1 0
17.06.2018 12:46:20
Андрей, спасибо большое!
Проголосовать Проголосовать
0 0
13.06.2018 17:51:36
Добрый вечер! Спасибо за подробный разбор работы апи биржи. 
Подскажите, есть ли способ скачать историю движения цен в orderbook (стакане) ? Или же остаётся только подписываться на вэбсокет и сохранять инфо в БД?
Проголосовать Проголосовать
0 0
18.06.2018 07:53:01
Добрый день
Боюсь, что именно придется собирать самому (или обращаться к тем, кто уже собирает)
Проголосовать Проголосовать
0 0
26.06.2018 04:25:31
Добрый день Андрей, большая просьба подсказать как определить объёмы покупок и объёмы продаж за 1 час методом trades. 
Просто не совсем понимаю описание этого метода.

{
  "e": "trade",     // Event type
  "E": 123456789,   // Event time
  "s": "BNBBTC",    // Symbol
  "t": 12345,       // Trade ID
  "p": "0.001",     // Price
  "q": "100",       // Quantity
  "b": 88,          // Buyer order Id
  "a": 50,          // Seller order Id
  "T": 123456785,   // Trade time
  "m": true,        // Is the buyer the market maker?
  "M": true         // Ignore.
}

Запутался в терминологии.
Судя по описанию с github https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md (Trade Streams)
за это отвечает значение "isBuyerMaker" ("m": true,        // Is the buyer the market maker?). 
Т.е. если это значение true, то это покупка (покупатель создал ордер на покупку), и соответственно если false то это продажа?
isBestMatch ("M": true         // Ignore.) тоже не понятен - имеется ввиду что сделка выполнена?

Заранее благодарю, Иван.
Проголосовать Проголосовать
0 0
26.06.2018 20:54:24
Добрый день
Насчет isBuyerMaker - по сути это означает, что тот, кто хотел купить, выставил по ценам ниже рынка, и тот, кто продавал, откликнулся на это (покупатель - мейкер, продавец - тейкер). А вот покупка это или продажа - это как посмотреть. Обсуждали в комментариях в комментариях выше, биржа подсвечивает зеленым, если isBuyerMaker - false. 
Сделка в любом случае выполнена, если попала в историю сделок.
isBestMatch - они писали на реддит, кажется, что это поле никогда не меняется и оставлено для совместимости.
Проголосовать Проголосовать
1 0
27.06.2018 05:37:33
Андрей, благодарю.
Проголосовать Проголосовать
0 0
30.06.2018 23:25:59
Здравствуйте, Андрей. Вы пишете "Да да, тут нельзя ставить ордера с произвольной ценой.", я зашёл на https://api.binance.com/api/v1/exchangeInfo, и там можно увидеть по всем парам такую картину: 

[{"filterType":"PRICE_FILTER","minPrice":"0.00000100","maxPrice":"100000.00000000","tickSize":"0.00000100"}

то есть фактически максимальная и минимальная цена не ограничены (пока), просто в теории эти значения могут быть изменены биржей до каких-то более узких значений. Я правильно понимаю?
Проголосовать Проголосовать
0 0
01.07.2018 10:13:25
Здравствуйте
Под невозможностью произвольной цены я имел в первую очередь не мин/макс, а именно шаг - tickSize.
Если он, например равен 0.01000000, то нельзя поставить 0.01100000 или 0.01000001 или еще как-то, все цены, которые вы ставите по этой паре, должны быть кратны 0.01000000. Биржа не даст поставить ордера ни руками, ни через апи, если не выполняется это условие.
Ну, и если посмотреть внимательнее, не у всех пар значения одинаковые, хотя большей частью совпадают
BTCUSDT
,"minPrice":"0.01000000","maxPrice":"10000000.00000000","tickSize":"0.01000000"
NEOUSDT
,"minPrice":"0.00100000","maxPrice":"10000000.00000000","tickSize":"0.00100000"
LSKBNB
"minPrice": "0.00010000", "maxPrice":"100000.00000000","tickSize": "0.00010000"
Ну и да, биржа в любой момент может изменить эти ограничения, особенно когда (и если) цены начнут скакать и изменяться в несколько раз.
Проголосовать Проголосовать
1 0
06.07.2018 13:00:30
Спасибо за уточнение! :)
Проголосовать Проголосовать
0 0
28.07.2018 14:41:35
Здравствуйте, Андрей! При запуске print(bot.withdraw(asset='XRP', address='адресс моего кошелька', amount='точное кол-во')) выходит эта ошибка: {'msg': 'Name is empty.', 'success': False}.  Не могли бы Вы подсказать в чём может быть проблема?
Проголосовать Проголосовать
0 0
01.08.2018 10:01:02
Добрый день, странно, поле name необязательно к заполнению, это описание обычное
Вы можете его указать, например 
print(bot.withdraw(asset='XRP', address='адресс моего кошелька', amount='точное кол-во', name='for_me')) 
Ну и еще для XRP можно указать addressTag, если требуется
Проголосовать Проголосовать
0 0
01.08.2018 17:39:36
Благодарю, эту проблему уже решил) Техподдержка ничего дельного не отвечала, в итоге в "Withdrawal Address Management" я подключил "Whitelist", добавил кошель, намеренно создал имя, уже его вписал и бинго: эта ошибка пропала (если просто указать имя в коде - увы не работает). Только вот заместо одной ошибки появилась другая: {'msg': 'Address verification failed.', 'success': False}. Я начал тестировать на другой валюте что бы исключить возможные проблемы с "addressTag", но пока не могу понять в связи с чем выходит ошибка. Все остальные функции прекрасно работают с API ключами, а на указанный в коде адрес кошелька через браузер средства выводятся без намёка на какую либо проблему. Техподдержка сейчас просит прислать им код в формате "POST 'https://www.binance.com/wapi/v3/withdraw.html?asset=waves&address;=0x**************** -d 'amount=1&recvWindow;=5000&name;=addressName&timestamp;=1510903211000&signature;=************************", только вот не совсем понимаю зачем в таком формате, да ещё и с "timestamp" "recvWindow", а что такое "signature" и где этот показатель брать, так и вообще не знаю. Возможно если эти параметры вписать - эта ошибка так же как и предыдущая пропадёт :D
Проголосовать Проголосовать
0 0
07.08.2018 10:50:44
Добавьте в моем коде перед

response = requests.request(method=self.methods[command]['method'], url=api_url, data="" if self.methods[command]['method'] == 'GET' else payload_str, headers=headers)

print(api_url)
print("" if self.methods[command]['method'] == 'GET' else payload_str)
print(headers)

там будут все эти параметры, они рассчитываются
Проголосовать Проголосовать
0 0
20.08.2018 04:59:35
Как поставить ордер понятно а как сделать что бы при его срабатывании ставился TAKE_PROFIT по определенной цене и объему
Проголосовать Проголосовать
0 0
17.10.2018 12:05:56
Отслеживать его состояние и выставлять новый при срабатывании.
Можете посмотреть, как это сделано здесь: https://bablofil.ru/bot-dlya-binance
Проголосовать Проголосовать
0 0
16.09.2018 14:49:47
кто нибудь знает какой вес имеет запрос /api/v3/ticker/price если не указывать конкретную пару ?
Проголосовать Проголосовать
0 0
17.10.2018 12:08:39
Увы.. Техподдержка наверное только. Да и то, они эксперементируют с машинным обучением, если вы торгуете то ничего не будет, а если только лишнюю нагрузку создаете, то будет.
Проголосовать Проголосовать
0 0
03.10.2018 13:55:57
Существует ли опция получить список всех ордеров в стакане?
Проголосовать Проголосовать
0 0
17.10.2018 12:10:07
Нет, и более того - то, что вы видите в стакане не всегда является истинным. Есть ордера айсберги - в стакане отображается только видимая (мелкая часть), а при покупке всплывает остальное.
Проголосовать Проголосовать
0 0
07.10.2018 05:17:24
Вылетает ошибка раз в день примерно:
Exception: {"code":-1021,"msg":"Timestamp for this request is outside of the recvWindow."}

Помогите пожалуйста синхронизировать время. Сейчас пробую делать так:
        subprocess.call("net start w32time", shell=True)
        subprocess.call("w32tm /resync", shell=True)
        # Настраиваю синхронизацию времени
        limits = bot.exchangeInfo()
        local_time = int(time.time())
        server_time = int(limits['serverTime'])//1000
        shift_seconds = server_time-local_time
        bot.set_shift_seconds(shift_seconds)

Не помогает(
Проголосовать Проголосовать
1 0
07.10.2018 16:24:45
Эту настройку через каждую минуту делаю. Для надежности и время синхронизирую на компьютере и устанавливаю как в боте Андрея поправку.
Проголосовать Проголосовать
0 0
17.10.2018 12:13:19
Может пакет какой-то сетевой заблудился, может оборудование провайдера на чердаке барахлит или еще что-то, бывает такое.. 
Можете попробовать в этой строке payload.update({'timestamp': int(time.time() + self.shift_seconds - 1) * 1000})
убрать единичку или увеличить её, может быть пореже будет вылетать ошибка
Проголосовать Проголосовать
1 0
15.11.2018 18:39:46
когда от сервера приходит 429 ответ, на сколько времени нужно отправить бота в сон? и можно ли обойти это с помощью прокси?
Проголосовать Проголосовать
0 0
16.11.2018 13:55:50
и ещё вопросы:
ограничения идут на IP или на 1 ключ? если я например сделаю бота в котором будет несколько людей торговать
и если вылетает 429 ответ, он вылетает на IP или на аккаунт
Проголосовать Проголосовать
0 0
17.11.2018 17:12:13
Сначала возвращается 429 код несколько раз, потом, если не успокоиться и продолжать долбить, банят по IP на несколько минут и возвращают код 418, если и тут не успокоиться то увеличивают срок бана.
Я бы советовал после получения 429 использовать замедление с увеличением - т.е. грубо говоря на 1 сек сделать паузу, если опять вернулось 429 то уже паузу на 3 сек, потом на 9 например.. При получении 418 сразу минут на 5 тормозить.
Прокси могут помочь, но до этого проще не доводить, все же 1200 запросов в минуту допускается, причем можно всякие курсы и свечи получать по сокетам без ограничений вообще - остается только управлять выставлением ордеров. Более того, по сокетам можно и обновления по своим ордерам получать. В общем, при грамотной архитектуре взаимодейтсвия бана не будет и при сотне клиентов с одного IP
Проголосовать Проголосовать
0 0
16.11.2018 10:11:54
Доброго времени суток!
У меня при выполнении:
new_order = bot.createOrder(
                                       symbol=pair,
                                       recvWindow=15000,
                                       side='SELL',
                                       type='LIMIT',
                                       quantity="{quantity:0.{precision}f}".format(quantity=my_amount, precision=CURR_LIMITS['baseAssetPrecision']),
                                       price="{price:0.{precision}f}".format(price=0.01, precision=CURR_LIMITS['baseAssetPrecision']),
                                       newOrderRespType='FULL')

Вылетает ошибка:
2018-11-16 13:16:48,274 [ERROR] Timeout value connect was quantity=0.16000000&price;=0.01000000&recvWindow;=15000&newOrderRespType;=FULL&side;=SELL&symbol;=LTCBTC&timestamp;=1542363406000&type;=LIMIT&signature;=8d859dc16d56a4de0c60c14dd2a7860ded374f7d5724838793b72c6f4063cbec, but it must be an int, float or None.
Traceback (most recent call last):
  File "C:\Python35\lib\site-packages\urllib3\util\timeout.py", line 124, in _validate_timeout
    float(value)
ValueError: could not convert string to float: 'quantity=0.16000000&price;=0.01000000&recvWindow;=15000&newOrderRespType;=FULL&side;=SELL&symbol;=LTCBTC&timestamp;=1542363406000&type;=LIMIT&signature;=8d859dc16d56a4de0c60c14dd2a7860ded374f7d5724838793b72c6f4063cbec'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\uia\Desktop\infoB\MACD_bot.py", line 882, in <module>
    newOrderRespType='FULL')
  File "C:\Users\uia\Desktop\infoB\binance_api.py", line 52, in wrapper
    return self.call_api(**kwargs)
  File "C:\Users\uia\Desktop\infoB\binance_api.py", line 82, in call_api
    response = requests.request(method=self.methods[command]['method'], url=api_url, data="", timeout=30 if self.methods[command]['method'] == 'GET' else payload_str, headers=headers)
  File "C:\Python35\lib\site-packages\requests\api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python35\lib\site-packages\requests\sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python35\lib\site-packages\requests\sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python35\lib\site-packages\requests\adapters.py", line 435, in send
    timeout = TimeoutSauce(connect=timeout, read=timeout)
  File "C:\Python35\lib\site-packages\urllib3\util\timeout.py", line 94, in __init__
    self._connect = self._validate_timeout(connect, 'connect')
  File "C:\Python35\lib\site-packages\urllib3\util\timeout.py", line 127, in _validate_timeout
    "int, float or None." % (name, value))
ValueError: Timeout value connect was quantity=0.16000000&price;=0.01000000&recvWindow;=15000&newOrderRespType;=FULL&side;=SELL&symbol;=LTCBTC&timestamp;=1542363406000&type;=LIMIT&signature;=8d859dc16d56a4de0c60c14dd2a7860ded374f7d5724838793b72c6f4063cbec, but it must be an int, float or None.

Уже всю голову сломал - в чём может быть проблема?</module>
Проголосовать Проголосовать
0 0
16.11.2018 10:40:25
Разобрался
Проголосовать Проголосовать
0 0
Пожалуйста, авторизуйтесь, что бы оставить свой комментарий
Крипто-кошельки для помощи и благодарности проекту:

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

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

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