Giter Site home page Giter Site logo

ccxt / ccxt Goto Github PK

View Code? Open in Web Editor NEW
31.5K 941.0 7.3K 2.86 GB

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading API with support for more than 100 bitcoin/altcoin exchanges

Home Page: https://docs.ccxt.com

License: MIT License

JavaScript 16.48% PHP 13.95% Python 27.07% Shell 0.03% Dockerfile 0.01% HTML 0.01% TypeScript 17.03% Handlebars 0.01% C# 25.35% Batchfile 0.01% Cython 0.03% C 0.05% C++ 0.02%
altcoin api arbitrage bitcoin bot cryptocurrency crypto e-commerce ethereum exchange

ccxt's Issues

Decoupling python/php code from transpiler

I'd like contributing to python codebase, however, am unable to since it's heavily coupled with js one, without good reason.

Most APIs differ by URL endpoints and regex substitution for pairs. I suggest having API definition folder, for example /API_def/kraken.json where API specific configuration is provided. Market than would load this file and know everything needed to perform its unified API duties.

Most APIs have json responses, thus JSON path can be configured in the configuration file. For example let's take kraken ticker for example:

"kraken":{
    "ticker":{
        "api_endpoint": "https://api.kraken.com/0/public/Ticker/{pair_name}",
        "last": "{pair_name}.c[0]"
        ...
    }
}

Since you've spent more time looking at API configuration you're more familiar what's needed. {pair_name} and other serve as substitution points in the API. How does this look to you?

Morning report

After your latest update kraken was fixed.Seems to work OK now.I will post if i ecnounter a problem,

Unfortunately poloniex private api now doesn't work.

This is the error i get when i try to access private api.It worked in the last version of ccxt.

Traceback (most recent call last):
  File "C:\oop\novi ws\Crypto\TransactionFees.py", line 8, in get_transaction_fee
    response = self.request(command, type='private', method='POST')
  File "C:\oop\novi ws\Crypto\ccxt.py", line 8600, in request
    'Sign': self.hmac (self.encode (body), self.secret, hashlib.sha512),
  File "C:\oop\novi ws\Crypto\ccxt.py", line 373, in hmac
    h = hmac.new (secret, request, algorithm)
  File "C:\Program Files (x86)\Python36-32\lib\hmac.py", line 144, in new
    return HMAC(key, msg, digestmod)
  File "C:\Program Files (x86)\Python36-32\lib\hmac.py", line 42, in __init__
    raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'

Furthermore when i try to access GDAX and its private api this is what I get:

Traceback (most recent call last):
  File "C:\oop\novi ws\Crypto\TransactionFees.py", line 50, in get_transaction_fee
    response = self.request(command, type='private', method='GET')
  File "C:\oop\novi ws\Crypto\ccxt.py", line 6373, in request
    'CB-ACCESS-PASSPHRASE': self.password,
AttributeError: 'gdax' object has no attribute 'password'

So the problem here seems to be in the request of gdax

else:
            nonce = str (self.nonce ())
            if query:
                body = self.json (query)
            what = nonce + method + request + (body or '')
            secret = base64.b64decode (self.secret)
            signature = self.hmac (self.encode (what), secret, hashlib.sha256, 'binary')
            headers = {
                'CB-ACCESS-KEY': self.apiKey,
                'CB-ACCESS-SIGN': base64.b64encode (signature),
                'CB-ACCESS-TIMESTAMP': nonce,
                'CB-ACCESS-PASSPHRASE': self.password,
            }
        return self.fetch (url, method, headers, body)

there is no password.Tried changing it to secret but that's not it.

And I tried a few other and the problem from poloniex is repeated.

I m sorry for bothering you too much I will be more than happy to do the test once you find the problem.
Let me know if you need anything else.

Issue with 'crypto' Module

Hey,

I'm currently using the ccxt library with a Meteor application I'm developing - it's a brilliant library and has been a great help, so thank you! The issue is the use of Node's crypto module, which causes confusion with NPM over an old, deprecated package of the same name, from what I gather. As a result I get a conflict error when compiling my app.

Uncaught Error: Cannot find module 'crypto'

I can bypass the issue during development by simply deleting the deprecated crypto module from my node_modules folder, however when I go to deploy I don't have control over this. Do you know anyway around this, or would it be possible to implement another cryptographic module like crypto-js? Or is the only option to fork & make the ammendment myself?

Thanks for any advice you can offer.

EOrder:Trading agreement required

Hi,
I'm getting the Error: EOrder:Trading agreement required when I try to add a Order on kraken.
In the API Doc it says:
If you receive the error "EOrder:Trading agreement required", refer to your API key management page for further details.
and then API key management says:
To indicate your agreement to the above statement and enable the orders in the API, set trading_agreement = agree in the AddOrder API.

Is it possible to accept the agreement with your code or do I have to find another way?

Thanks

Bitstamp missing pairs

Hi, when loading products for bitstamp exchange I only get 6 out of 9 available pairs. The following are missing: "ltc/usd", "ltc/eur" and "ltc/btc".

yunbi private api not work

yunbi public api is fine. private api not work.

const yunbi = new ccxt.yunbi ({
apiKey: 'xxx',
secret: 'xxx',
verbose: true
})
// var info2 = await yunbi.privateGetMembersMe()
var info2 = await yunbi.privateGetOrders()
private api give 401
yunbi https://yunbi.com/api/v2/orders.json?access_key=8NnHFhLaXt42CqnquZCfCtdkQUq1bfeu89bhj3jm&tonce=1501038669&signature=6e2347aeaa6bb7a5e44161ef408747f41d875b2ad86cce2af9aa2123fefed385 { method: 'GET',
headers: { 'User-Agent': 'ccxt/1.1.83 (+https://github.com/kroitor/ccxt) Node.js/7.10.0 (JavaScript)' },
body: undefined }
catch... { Error: yunbi GET https://yunbi.com/api/v2/orders.json?access_key=8NnHFhLaXt42CqnquZCfCtdkQUq1bfeu89bhj3jm&tonce=1501038669&signature=6e2347aeaa6bb7a5e44161ef408747f41d875b2ad86cce2af9aa2123fefed385 401 Unauthorized
at AuthenticationError.CCXTError (/mnt/d/workspace/bts-arbitrage/node_modules/_ccxt@1.1.83@ccxt/ccxt.js:13:27)
at new AuthenticationError (/mnt/d/workspace/bts-arbitrage/node_modules/_ccxt@1.1.83@ccxt/ccxt.js:41:27)
at /mnt/d/workspace/bts-arbitrage/node_modules/_ccxt@1.1.83@ccxt/ccxt.js:422:27
at process._tickDomainCallback (internal/process/next_tick.js:135:7) constructor: [Function: AuthenticationError] }

i double checked my key/secret to make sure they are correct.
do you have a test case to check ?

Liqui -- missing ask/bids should be NaN, not a zero

                ask       bid
LTC/BTC    0.019752  0.019598
STEEM/BTC  0.000000  0.000000
SBD/BTC    0.000000  0.000000
DASH/BTC   0.079651  0.078987
ANS/BTC    0.000000  0.000000
Liqui

It's unexpected to get a number 0, where there shouldn't be any. I'd expect nan or an error if there were no bids (nan is nicer a bit IMO). And here is similar ro #10 with ask greater than bid.

Cex issue

Same thing unfortunately.
Private api for cex.io

   response = self.request(command, type='private', method='POST')
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 4647, in request
    'signature': self.hmac (self.encode (auth), self.secret).upper (),
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 389, in hmac
    h = hmac.new (secret, request, algorithm)
  File "C:\Program Files (x86)\Python36-32\lib\hmac.py", line 144, in new
    return HMAC(key, msg, digestmod)
  File "C:\Program Files (x86)\Python36-32\lib\hmac.py", line 42, in __init__
    raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'

Consistency issues

DSH/BTC pair has problems across exchanges (HitBTC and BTC-e). There are also some other problematic pairs I've seen over the time with big differences between exchanges. Could you please investigate closer into problematic pairs?

I suggest testing each pair across all exchanges and see if there's big bid/ask/last fluctuation between exchanges.

CryptoCompare API

Hey,

This is more a suggestion than anything, but have you considered implementing the CryptoCompare API, found here?

It provides a good amount of data on the cryptomarket; including daily, hourly and minutely price data. Beyond that there's good 'coin snapshots' which also provide good stats on various products. The PriceHistorical endpoint could also allow for a good currency conversion implementation.

Thanks for taking the time to read.

Python fetch_trades not working on GDAX

Using

market = ccxt.gdax()
market.load_products()

for symbol in market.products:
    print (market.fetch_trades(symbol))

Throws error

Traceback (most recent call last):
('gdax', 'GET', 'https://api.gdax.com/products/{id}/trades?symbol=LTC-USD', 404, 'Not Found', {u'message': u'NotFound'})
  File "/Users/admin/workspace/test-ccxt/test-ccxt.py", line 35, in <module>
    main()
  File "/Users/admin/workspace/test-ccxt/test-ccxt.py", line 27, in main
    print (market.fetch_trades(symbol))
  File "/usr/local/lib/python2.7/site-packages/ccxt/__init__.py", line 4000, in fetch_trades
    'symbol': self.product_id (product),
  File "/usr/local/lib/python2.7/site-packages/ccxt/__init__.py", line 4035, in request
    return self.fetch (url, method, headers, body)
  File "/usr/local/lib/python2.7/site-packages/ccxt/__init__.py", line 99, in fetch
    response = opener.open (request, timeout = self.timeout).read ().decode('utf-8')
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 435, in open
    response = meth(req, response)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 548, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 473, in error
    return self._call_chain(*args)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 407, in _call_chain
    result = func(*args)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 556, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 404: Not Found

It's working on other exchanges I tried.

BTC-e bid/ask issues

                   ask            bid
BTC/USD    2491.415039    2500.556885
BTC/RUR  151700.093750  152509.546875
BTC/EUR    2219.315430    2230.996094
LTC/BTC       0.019770       0.019830
LTC/USD      49.184013      49.369999
BTC-e

                 ask         bid
DASH/EUR  175.500000  174.024246
DASH/USD  203.567596  198.500397
DASH/BTC    0.079478    0.078675
EOS/ETH     0.009471    0.009383
EOS/EUR     2.012830    1.988080
Kraken


                 ask          bid
LTC/EUR    44.200001    44.000000
LTC/BTC     0.019780     0.019770
BTC/GBP  1985.239990  1980.010010
BTC/EUR  2234.840088  2234.830078
ETH/EUR   213.000000   212.570007
GDAX

There's something wrong with BTC-e data, ask should be bigger than the bid. I'm using fetch_ticker() from your library.

Problems with fetchBalances() for Three Out of Five Exchanges

I'm attempting to use five exchanges right now, all of which work fine except for Poloniex, Bitfinex, and Kraken when it comes to fetchBalances(). I get these errors:

poloniex: Error: poloniex POST https://poloniex.com/tradingApi 422 Unprocessable Entity
bitfinex: Error: bitfinex POST https://api.bitfinex.com/v1/balances 400 Bad Request Possible reasons: invalid API keys, market down or offline, on maintenance, DDoS protection, rate-limiting in effect
kraken: TypeError: Cannot convert undefined or null to object

They all return loadProducts() just fine, and I know have the correct credentials. Is there something special about these exchanges I might be missing when it comes to fetching balances? So far, GDAX and Bitstamp work fine.

DASH on hitbtc

In class hitbtc and in its method fetch_products()

                base = 'DASH'

I dont understand this two lines.
DASH is DASH and DSH is DASHCOIN they are two separate coins I've double checked.

Kraken issues

krk = ccxt.kraken()
krk.load_products()
krk.fetch_order_book("ETHEUR.d")
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-19-7d4936c22644> in <module>()
      1 krk = ccxt.kraken()
      2 krk.load_products()
----> 3 krk.fetch_order_book("ETHEUR.d")

/usr/lib/python3.6/site-packages/ccxt/__init__.py in fetch_order_book(self, product)
   7308             'pair': p['id'],
   7309         })
-> 7310         orderbook = response['result'][p['id']]
   7311         timestamp = self.milliseconds ()
   7312         result = {

KeyError: 'result'

Poloniex and Kraken Private API

Error when calling private methods for Poloniex and Kraken exchanges.
(Using Python 3.6.0 with latest ccxt commit)

When calling Poloniex private api getting an error:

"poloniex POST https://poloniex.com/tradingApi 422 b'{"error":"Nonce must be greater than 15001320050000. You provided 1500132345."}'"

No problems after editing ccxt init.py to increase nonce value:
query['nonce'] = self.nonce () * 10000
(in request function for poloniex)

When calling Kraken private api getting an error:

File "C:\Users\username\AppData\Local\Programs\Python\Python36-32\lib\site-packages\ccxt\__init__.py", line 7178, in fetch_balance return self.privatePostBalance () File "C:\Users\username\AppData\Local\Programs\Python\Python36-32\lib\site-packages\ccxt\__init__.py", line 7203, in request query = url + self.hash (nonce + body, hashlib.sha256, 'binary') File "C:\Users\username\AppData\Local\Programs\Python\Python36-32\lib\site-packages\ccxt\__init__.py", line 344, in hash h = hashlib.new (hash, request) File "C:\Users\username\AppData\Local\Programs\Python\Python36-32\lib\hashlib.py", line 149, in __hash_new return _hashlib.new(name, data) TypeError: name must be a string

Tried fixing it but no luck. Hopefully these are actually issues, not just on my end.

Liqui issues

krk = ccxt.liqui()
pair = "GNO/USDT"
print (pair in krk.load_products())
krk.fetch_order_book(pair)
True
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-21-ab12fbccc45f> in <module>()
      2 pair = "GNO/USDT"
      3 print (pair in krk.load_products())
----> 4 krk.fetch_order_book(pair)

/usr/lib/python3.6/site-packages/ccxt/__init__.py in fetch_order_book(self, product)
   3410             'pair': p['id'],
   3411         })
-> 3412         orderbook = response[p['id']]
   3413         timestamp = self.milliseconds ()
   3414         result = {

KeyError: 'gno_usdt'

error: ['EAPI:Invalid key'] doing fetchBalance for Kraken

Using Node.JS 8.1.4 I receive this error after instantiation with the api key and private key from Kraken.

const market = new ccxt[key]({
  apiKey: data.apiKey,
  secret: data.secret
})

console.log(await market.fetchBalance())

Public functions seem to work fine.

Quadrigacx

The same thing is happening with quadrigacx and its private api

    signature = self.hmac (self.encode (request), self.secret)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 389, in hmac
    h = hmac.new (secret, request, algorithm)
  File "C:\Program Files (x86)\Python36-32\lib\hmac.py", line 144, in new
    return HMAC(key, msg, digestmod)
  File "C:\Program Files (x86)\Python36-32\lib\hmac.py", line 42, in __init__
    raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'

And just in case you didnt see it I'l post it again.
I have a problem with signature in cex.
Not sure from which side is it.Mine or yours.
Im testing for method: get_myfee/ in cex
This is what i get as a response
{'e': 'get_myfee', 'error': 'Invalid signature', 'ok': 'error'}
Api key and secret should be correctly inputed.I have checked.Might be a problem with computing the signature?

Gdax trying to put limit or market trade

Having a lot of trouble making trade on gdax.

When trying to call your own method for gdax create_limit_buy this happens

    return self.create_limit_buy_order (product, amount, price, params)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 504, in create_limit_buy_order
    return self.create_order (product, 'limit', 'buy', amount, price, params)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 6416, in create_order
    return self.privatePostOrder (self.extend (order, params))
AttributeError: 'gdax' object has no attribute 'privatePostOrder'

When trying to write my own method

response = gdax.request('orders', 'private', 'POST', params={'type': 'limit',
                                                             'side': 'buy',
                                                             'product_id': product,
                                                             'price': 3000,
                                                             'size': 1.0})   

this happens

https://api-public.sandbox.gdax.com/orders POST {'CB-ACCESS-KEY': 'ba6e6e102338f6e66244d804984bdc1e', 'CB-ACCESS-SIGN': b'pMfi9OUiCJX9YqFktaVXycNqD7MFpbEWIYgWRvwD0nI=', 'CB-ACCESS-TIMESTAMP': '1500374457', 'CB-ACCESS-PASSPHRASE': '**********', 'User-Agent': 'ccxt/1.0.158 (+https://github.com/kroitor/ccxt) Python/3.6.1'} {"type":"limit","side":"buy","product_id":"BTC/USD","price":3000,"size":1.0}
Traceback (most recent call last):
gdax POST https://api-public.sandbox.gdax.com/orders 400 Bad Request b'{"message":"invalid signature"}'
  File "C:\oop\novi ws\Crypto\testGdax.py", line 23, in <module>
    'size': 1.0})
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 6441, in request
    return self.fetch (url, method, headers, body)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 207, in fetch
    response = opener.open (request, timeout = int (self.timeout / 1000))
  File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 532, in open
    response = meth(req, response)
  File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 570, in error
    return self._call_chain(*args)
  File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 504, in _call_chain
    result = func(*args)
  File "C:\Program Files (x86)\Python36-32\lib\urllib\request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

Inconsistent naming across exchange markets

HitBTC exchange has both DASH/BTC and DSH/BTC pairs with different prices. I'd expect naming pair would be consistent across various markers, however following code proves me otherwise:

import ccxt
h = ccxt.bitfinex()
h.load_products()
pp.pprint(h.fetch_ticker("DSH/BTC"))

k = ccxt.hitbtc()
k.load_products()
pp.pprint(k.fetch_ticker("DSH/BTC"))

Output:

{'ask': 0.081222,
 'average': 0.080965,
 'baseVolume': None,
 'bid': 0.080708,
 'change': None,
 'close': None,
 'datetime': '2017-07-06T15:21:00.000Z',
 'first': None,
 'high': 0.087383,
 'info': {'ask': '0.081222',
          'bid': '0.080708',
          'high': '0.087383',
          'last_price': '0.080573',
          'low': '0.07499',
          'mid': '0.080965',
          'timestamp': '1499354460.27357124',
          'volume': '11299.25037405'},
 'last': 0.080573,
 'low': 0.07499,
 'open': None,
 'percentage': None,
 'quoteVolume': 11299.25037405,
 'timestamp': 1499354460273.5713,
 'vwap': None}
{'ask': 1.2085e-05,
 'average': None,
 'baseVolume': 11216.0,
 'bid': 1.2023e-05,
 'change': None,
 'close': None,
 'datetime': '2017-07-06T15:21:00.000Z',
 'first': None,
 'high': 1.2999e-05,
 'info': {'ask': '0.000012085',
          'bid': '0.000012023',
          'high': '0.000012999',
          'last': '0.000012085',
          'low': '0.000012023',
          'open': '0.000012015',
          'timestamp': 1499354460429,
          'volume': '11216',
          'volume_quote': '0.000000000'},
 'last': 1.2085e-05,
 'low': 1.2023e-05,
 'open': 1.2015e-05,
 'percentage': None,
 'quoteVolume': 0.0,
 'timestamp': 1499354460429,
 'vwap': None}

Also with HitBTC I get a lot of internal server errors when querying their API via this library.

From/to unified pair name/exchange specific name

I'd like in unified API having two functions which map from unified names (e.g. BTC/EUR) to market specific name and back (e.g. BTCEUR for kraken IIRC).

This will help me test your library further and detect subtle errors.

I recommend names:

to_market_api_name(self, symbol)
to_unified_name(self, symbol)

They should throw exception of not found in the exchange load products. It should use cached load_products()

This functionality is implemented somewhere anyhow, it's only about exposing it.

Issue about data type casting in ANXPRO python code

Hello~

When I was using python fetch ticket from ANXPRO, I faced a problem

In [31]: anxpro.fetch_ticker('BTC/USD')
TypeError Traceback (most recent call last)
in ()
----> 1 anxpro.fetch_ticker('BTC/USD')

C:\Users***\Desktop\ccxt\ccxt_init_.pyc in fetch_ticker(self, product)

811         ticker = response['data']
*812        timestamp = int (ticker['dataUpdateTime'] / 1000)
813         return {
814             'timestamp': timestamp,

TypeError: unsupported operand type(s) for /: 'unicode' and 'int'

There was an error in line 812

It seemed like there's some problem in casting. Therefore, I had checked the source code init.py
and I think I found the bug.

*original version

812 timestamp = int (ticker['dataUpdateTime'] / 1000)

*modified version

812 timestamp = int (ticker['dataUpdateTime']) / 1000

Besides, there's still a bug in line 819

817             'low': float (ticker['low']['value']),
818             'bid': float (ticker['buy']['value']),
*819             'ask': float (ticker['sell'])['value'],
820             'vwap': float (ticker['vwap']['value']),
821             'open': None,

Original version
'ask': float (ticker['sell'])['value']
modified version
'ask': float (ticker['sell']['value'])

The problem wave solved after I remove these two bugs.

Thank you very much :)

Gdax function request

Check method request in python code in class GDAX.
Your latest version.
Im using python 3.6.
You called your function hash with 4 parameters.It takes only 3.

I have tried sending what+ secret.decode() as first parameter but it just sends another error.

https://pastebin.com/RDRaFqsr

Easily select all implemented markets in python

I don't have the reliable method to select implemented APIs in python.

Suggestion: Can you implement function/constant which returns all available APIs. Something like:

import ccxt
ccxt.available_APIs()
# Returns ['kraken', 'gdax', ...
# Then this should work
eval('ccxt.kraken()')  # This gives me kraken API implementation from ccxt

Btw, your python module is missing __all__ marker which modules should be imported with * import.

https://docs.python.org/3/tutorial/modules.html#importing-from-a-package

Load products

I was testing some exhanges and i found some inconsistencies.

When you call poloniex.fetchProducts() you get products with symbols such as BTC/DASH and when you call hitbtc.fetchProducts() the same product has symbol DASH/BTC .

Batch fetch operations

I see following three unified API operations which would ideally have their batch equivalent:

  • fetchOrderBook (symbol): Fetch an order book for a particular product trading symbol.
  • fetchTrades (symbol): Fetch recent trades for a particular trading symbol.
  • fetchTicker (symbol): Fetch latest ticker data by trading symbol.

I'm using python syntax

Thus for example istead of:

ex = some_exchange
ex.fetchTicker("BTC/ETH"), ex.fetchTicker("DSH/BTC")

I could write (executor would be instace of https://docs.python.org/3/library/concurrent.futures.html):

ex.batchFetchTicker(["BTC/ETH", "DSH/BTC"], executor=exec)

Or by using asyncio and python3.5+ syntax:

await ex.batchFetchTicker(["BTC/ETH", "DSH/BTC"])

Some markets implement batch REST API, for example kraken uses comma separated symbol lists. Others like GDAX have no such option, and this method could be implemented in fallback mode using fetchX functions (with taking care of concurrent HTTP request, and not executing them sequentially).

Yobit issues

yo = ccxt.yobit()
yo.load_products()
yo.fetch_order_book("F16/BTC")
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-15-1ad1d615e328> in <module>()
----> 1 yo.fetch_order_book("F16/BTC")

/usr/lib/python3.6/site-packages/ccxt/__init__.py in fetch_order_book(self, product)
   9987         timestamp = self.milliseconds ()
   9988         result = {
-> 9989             'bids': orderbook['bids'],
   9990             'asks': orderbook['asks'],
   9991             'timestamp': timestamp,

KeyError: 'bids'

Bter issues

krk = ccxt.bter()
print ("TIX/LTC" in krk.load_products())
krk.fetch_order_book("TIX/LTC")
True
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-20-6e30f99be8e3> in <module>()
      1 krk = ccxt.bter()
      2 print ("TIX/LTC" in krk.load_products())
----> 3 krk.fetch_order_book("TIX/LTC")

/usr/lib/python3.6/site-packages/ccxt/__init__.py in fetch_order_book(self, product)
   4082                 amount = order[1]
   4083                 result[side].append ([ price, amount ])
-> 4084         result['asks'] = self.sort_by (result['asks'], 0)
   4085         return result
   4086 

/usr/lib/python3.6/site-packages/ccxt/__init__.py in sort_by(l, key, descending)
    244     @staticmethod
    245     def sort_by (l, key, descending = False):
--> 246         return sorted (l, key = lambda k: k[key], reverse = descending)
    247 
    248     @staticmethod

Gemini issue

Latest version of ccxt used and python 3.6.

When calling private post method on gemini.
This pops out:

 File "C:\oop\novi ws\Crypto\TransactionFees.py", line 120, in get_transaction_fee
    response = self.request(command, type='private', method='POST')
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\ccxt\__init__.py", line 6557, in request
    payload = base64.b64encode (self.json (request))
  File "C:\Program Files (x86)\Python36-32\lib\base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'

Bitfinex nonce

Trying to get balances on btifinex.

   response = self.request(command, type='private', method='POST')
bitfinex POST https://api.bitfinex.com/v1/balances 400 Bad Request b'{"message":"Nonce is too small."}

Might be a problem from my end.
Any ideas?

Unified API for accessing order books

Each exchange return order books in different formats. Can we have unified API for parsing and accessing bids/ask price, size, etc?
GDAX
{u'bids': [[u'2588.41', u'1.09', 1]], u'asks': [[u'2588.83', u'0.09597', 3]], u'sequence': 3496680051}

Okcoin

{u'bids': [[2688.93, 0.03], [2688.92, 0.044], [2686.46, 0.02], [2686.22, 0.03], [2682.72, 0.21], [2682.19, 0.01], [2682.01, 0.9], [2681.17, 1.894], [2680.52, 0.8], [2679.16, 1.5], [2676, 0.01], [2674.42, 0.6], [2674.41, 1.47], [2674.14, 0.3], [2673.93, 15], [2673.92, 2.823], [2673.45, 1.884], [2666.69, 0.566], [2666.68, 2.831], [2666, 0.294], [2663.73, 0.566], [2663.03, 0.114], [2660.96, 1.884], [2660, 4.037], [2659.43, 2.839], [2655, 0.2], [2652, 0.207], [2651, 0.01], [2650, 7.784], [2648.85, 0.948], [2646.43, 0.547], [2644, 0.2], [2641.55, 0.555], [2641, 0.272], [2640, 5.164], [2638.98, 4.04], [2637.22, 0.344], [2633, 0.2], [2632.43, 0.522], [2631.52, 2.48], [2631.05, 0.32], [2630.83, 15], [2630, 2.005], [2625.22, 0.214], [2624.48, 64.9], [2622, 0.2], [2621.35, 0.474], [2616.25, 0.588], [2611.87, 0.01], [2611, 0.2], [2610, 0.618], [2605, 0.4], [2603, 0.05], [2600, 7.855], [2599, 0.2], [2598, 1.5], [2590, 5.078], [2588, 0.6], [2577, 0.2], [2576, 0.3], [2570, 0.191], [2566, 0.2], [2563, 1.5], [2558, 0.118], [2555, 7.2], [2551, 1], [2550.44, 80], [2550, 4.705], [2548, 0.12], [2546, 1.5], [2544, 0.2], [2539, 0.11], [2530, 2], [2520, 1], [2510, 0.285], [2503, 0.05], [2501, 5], [2500, 4.968], [2475, 1.5], [2474, 0.499], [2471.02, 0.133], [2470, 0.186], [2458.39, 5], [2458, 1.5], [2455, 0.03], [2453, 3], [2452, 5], [2450, 46.988], [2444, 1.5], [2443, 2], [2434, 1.5], [2430, 2], [2428.39, 7.571], [2426.88, 5], [2425, 5.025], [2422, 5], [2420.11, 1], [2420, 8], [2416.88, 5], [2416, 4], [2412, 5.021], [2401, 0.03], [2400, 13.363], [2390, 1.5], [2387, 0.222], [2380, 0.06], [2370, 3], [2368.88, 5], [2351.01, 0.05], [2351, 0.6], [2350.88, 3], [2350, 18], [2340, 2], [2333.44, 0.13], [2311, 0.3], [2301, 1], [2300, 18.018], [2280, 0.08], [2260, 0.06], [2250, 3.03], [2242, 0.106], [2222.22, 2], [2222, 41.991], [2220.11, 1], [2220.01, 14.66], [2220, 0.07], [2218.01, 10], [2217.01, 10], [2215.01, 10], [2212.01, 10], [2209.01, 10], [2207.01, 10], [2205.01, 10], [2202, 0.098], [2201.01, 0.1], [2200, 25.873], [2190, 2], [2188, 0.2], [2180, 0.22], [2165, 0.124], [2158.58, 1], [2155, 0.125], [2146, 0.01], [2145, 0.125], [2140, 0.09], [2135, 0.126], [2132.07, 0.072], [2125, 0.126], [2120, 0.127], [2110, 0.127], [2101.01, 0.1], [2100, 33.306], [2095, 0.5], [2090, 0.128], [2080, 0.129], [2075, 23.379], [2065, 20], [2060, 0.11], [2058.58, 1], [2055, 0.5], [2050.88, 3.561], [2050, 1.01], [2020, 0.12], [2004, 10], [2001.12, 0.22], [2000, 32.875], [1993.96, 0.065], [1993, 0.301], [1958.58, 1], [1952.52, 25], [1928, 0.021], [1925.52, 25], [1916, 0.021], [1912, 2], [1907.56, 20], [1907.53, 0.058], [1904, 0.021], [1900, 4.056], [1892, 0.022], [1889.28, 0.08], [1888, 0.2], [1886.61, 0.033], [1880, 0.022], [1875.78, 0.132], [1875.44, 0.045], [1874.53, 0.035], [1874.16, 0.113], [1868, 0.022], [1866, 0.143], [1858.58, 1], [1856, 0.022], [1852.52, 25], [1850, 0.01], [1844, 0.022], [1838.53, 4], [1832, 0.022], [1820, 0.022], [1818.18, 0.04], [1808, 0.022], [1807.56, 20]], u'asks': [[3175.01, 0.02], [3175, 0.5], [3173.85, 0.02], [3173.27, 0.02], [3169.68, 0.02], [3167.91, 86.5], [3164.35, 0.02], [3164.29, 0.036], [3159.02, 0.02], [3155.86, 0.02], [3155, 0.013], [3153.69, 0.02], [3150, 0.02], [3149.39, 0.02], [3148.36, 0.02], [3143.03, 0.02], [3143, 0.05], [3141.06, 86], [3140.64, 0.036], [3138, 10], [3137.7, 0.02], [3132.37, 0.02], [3129, 15.81], [3127.04, 0.02], [3126.37, 0.02], [3123.43, 0.108], [3121.71, 0.02], [3120, 0.01], [3116.38, 0.02], [3114.22, 85.5], [3113.35, 0.02], [3100.7, 0.02], [3100, 0.345], [3095.49, 0.037], [3093, 0.05], [3089, 0.1], [3087.37, 85], [3072.6, 0.037], [3068, 0.02], [3060.52, 84.5], [3050, 0.05], [3049.59, 0.037], [3047.12, 0.551], [3044, 0.023], [3043, 0.05], [3038, 0.5], [3033.68, 84], [3028, 0.196], [3026.8, 0.038], [3020, 0.993], [3010, 0.014], [3006.83, 83.5], [3000, 21.305], [2999.95, 2], [2999.85, 0.08], [2997.34, 0.02], [2994.49, 0.02], [2993, 0.05], [2989.9, 1.996], [2988, 5], [2986.53, 0.02], [2985.85, 1.996], [2985.49, 0.02], [2983.37, 0.02], [2980, 1.255], [2979.98, 83], [2978.15, 1.996], [2975.15, 0.988], [2973, 0.05], [2970.03, 1.81], [2970, 0.247], [2958, 0.029], [2953.14, 82.5], [2951, 0.15], [2950.1, 2.074], [2950, 0.14], [2943, 0.05], [2940, 0.116], [2938, 0.099], [2934.99, 0.03], [2934.98, 0.03], [2930, 0.027], [2926.29, 82], [2925, 0.019], [2923, 0.05], [2920, 2.243], [2918.87, 5], [2917.17, 1.996], [2916.36, 0.03], [2915.15, 1.996], [2913.88, 40], [2911.11, 1.936], [2910, 0.27], [2903, 1.068], [2902, 1.852], [2900, 63.792], [2899.44, 81.5], [2899, 2], [2893, 0.05], [2891.56, 0.03], [2888, 5.13], [2886.94, 0.01], [2884.49, 1.189], [2882, 2], [2880.08, 1.996], [2879.79, 3.593], [2877, 0.378], [2875.75, 1.996], [2875, 0.21], [2873, 0.05], [2872.6, 81], [2870.7, 4.535], [2869.69, 4.99], [2868, 30], [2865, 0.01], [2862, 2], [2859.59, 3.992], [2852, 2], [2850, 6.508], [2849.49, 7.984], [2848, 0.03], [2845.75, 80.5], [2843, 0.05], [2842, 2], [2840, 0.31], [2839.99, 0.301], [2832, 2], [2830, 35], [2825, 0.01], [2822, 2], [2820, 1.75], [2818.9, 80], [2802, 2], [2800, 29.929], [2799, 0.2], [2798.88, 2.583], [2793, 0.05], [2790, 0.089], [2788, 0.229], [2785, 4.162], [2779, 0.104], [2777, 0.237], [2775, 2.235], [2772.3, 0.03], [2772.28, 5.03], [2770.54, 0.03], [2770.52, 0.03], [2770, 0.107], [2769.41, 0.03], [2767.47, 0.03], [2766, 0.2], [2764.31, 0.03], [2760.18, 0.03], [2760.16, 0.03], [2760.15, 0.03], [2760, 0.324], [2759.86, 0.203], [2755, 0.2], [2753.62, 4.141], [2750, 2.085], [2746.61, 0.32], [2745, 0.299], [2744.36, 0.022], [2744, 0.2], [2742.09, 0.433], [2740, 1.488], [2739.99, 0.025], [2736.65, 0.196], [2735.11, 0.566], [2735, 0.169], [2733, 0.2], [2732.78, 0.103], [2730.5, 0.5], [2730, 0.1], [2728.52, 0.5], [2727.97, 0.32], [2725.62, 0.089], [2725, 1.32], [2724.62, 2.771], [2723.78, 0.04], [2723.56, 0.8], [2722, 0.2], [2720, 0.021], [2719, 0.779], [2718.55, 0.03], [2717.94, 2.204], [2717.37, 2.778], [2717.36, 6], [2715.87, 0.03], [2713.46, 0.02], [2711, 0.2], [2710.13, 2.785], [2710.12, 0.13], [2707, 0.59], [2705.4, 0.035], [2705.39, 0.03], [2705.38, 0.5], [2702.88, 1.473], [2702, 2.914], [2701.99, 0.16]]}

Kraken

{u'result': {u'XXBTZUSD': {u'bids': [[u'2578.00600', u'0.254', 1499207743], [u'2578.00500', u'2.897', 1499207737], [u'2578.00200', u'0.014', 1499207737], [u'2578.00000', u'1.678', 1499207368], [u'2577.62000', u'0.500', 1499207348], [u'2576.99900', u'2.000', 1499206268], [u'2575.23000', u'0.150', 1499207735], [u'2574.09100', u'0.232', 1499207699], [u'2573.43900', u'0.046', 1499205868], [u'2572.41100', u'3.096', 1499207631], [u'2570.21100', u'13.140', 1499207635], [u'2570.21000', u'3.300', 1499207623], [u'2570.00000', u'0.330', 1499206264], [u'2568.37100', u'3.235', 1499205983], [u'2566.72900', u'3.276', 1499205249], [u'2566.61000', u'0.022', 1499202772], [u'2566.18300', u'1.010', 1499207647], [u'2565.00100', u'2.881', 1499205207], [u'2564.41800', u'1.010', 1499207679], [u'2563.00000', u'3.000', 1499202410], [u'2561.00600', u'17.770', 1499207710], [u'2561.00400', u'8.250', 1499207628], [u'2561.00200', u'13.824', 1499207319], [u'2561.00000', u'2.000', 1499204974], [u'2560.92800', u'3.000', 1499202395], [u'2559.14600', u'3.160', 1499202180], [u'2558.84000', u'0.391', 1499203976], [u'2558.00000', u'0.001', 1499206996], [u'2557.22800', u'27.272', 1499207736], [u'2557.22700', u'3.200', 1499202119], [u'2556.00000', u'2.000', 1499206994], [u'2555.86800', u'0.137', 1499207595], [u'2555.54800', u'1.514', 1499207738], [u'2555.54700', u'2.567', 1499201892], [u'2555.01000', u'0.001', 1499204835], [u'2553.38400', u'11.946', 1499207575], [u'2553.38300', u'3.467', 1499199894], [u'2552.00000', u'2.000', 1499202831], [u'2551.86500', u'2.930', 1499207229], [u'2550.12000', u'3.000', 1499207432], [u'2550.00000', u'3.536', 1499205047], [u'2547.91900', u'3.450', 1499207474], [u'2546.72900', u'0.643', 1499199617], [u'2546.72000', u'0.211', 1499127357], [u'2546.20900', u'3.050', 1499207508], [u'2545.90400', u'0.689', 1499187364], [u'2545.90200', u'0.671', 1499126461], [u'2545.01000', u'0.010', 1499196001], [u'2544.99500', u'0.100', 1499201899], [u'2543.25200', u'0.500', 1499164477], [u'2541.28100', u'0.636', 1499111623], [u'2541.12500', u'0.186', 1499197706], [u'2539.70300', u'0.003', 1499207517], [u'2538.51900', u'1.000', 1499126223], [u'2538.10000', u'0.071', 1499205598], [u'2536.01000', u'0.011', 1499199771], [u'2535.22000', u'0.300', 1499194601], [u'2535.01000', u'0.010', 1499196019], [u'2535.00000', u'5.000', 1499182179], [u'2534.02600', u'0.501', 1499196849], [u'2530.00000', u'0.384', 1499185278], [u'2527.48188', u'0.005', 1499199652], [u'2527.19300', u'0.003', 1499207506], [u'2527.05600', u'0.013', 1499165821], [u'2526.59000', u'15.000', 1499204561], [u'2525.01000', u'0.010', 1499134102], [u'2525.00000', u'0.015', 1499188622], [u'2521.00000', u'16.995', 1499200655], [u'2520.00000', u'1.100', 1499202149], [u'2516.12500', u'0.016', 1499206782], [u'2515.00000', u'0.028', 1499111422], [u'2514.82900', u'0.006', 1499207516], [u'2514.69121', u'0.005', 1499199679], [u'2514.52377', u'0.010', 1499106411], [u'2514.33500', u'0.002', 1499181775], [u'2513.10000', u'0.200', 1499100372], [u'2506.45900', u'0.213', 1499186589], [u'2503.00000', u'0.040', 1499187040], [u'2502.12000', u'0.040', 1499114854], [u'2501.92432', u'0.005', 1499199691], [u'2501.00000', u'2.197', 1499198447], [u'2500.01000', u'0.010', 1499102950], [u'2500.00000', u'27.780', 1499207667], [u'2493.07000', u'0.803', 1499195595], [u'2490.31000', u'2.000', 1499127857], [u'2490.14100', u'0.053', 1499082715], [u'2490.00000', u'0.035', 1499179757], [u'2487.88898', u'0.005', 1499199708], [u'2485.00000', u'0.001', 1499202858], [u'2480.00000', u'0.102', 1499158154], [u'2475.58000', u'0.013', 1499094813], [u'2475.50000', u'2.000', 1499103622], [u'2475.01000', u'0.010', 1499103015], [u'2475.00000', u'2.000', 1499195384], [u'2474.30000', u'0.170', 1499177423], [u'2474.09700', u'0.100', 1499131334], [u'2472.00000', u'0.632', 1499107284], [u'2470.00000', u'0.154', 1499116856], [u'2464.84800', u'1.010', 1499075419], [u'2464.00000', u'0.010', 1499092255]], u'asks': [[u'2579.48800', u'0.315', 1499207740], [u'2580.57000', u'7.731', 1499207685], [u'2582.18900', u'0.120', 1499207620], [u'2582.50100', u'0.527', 1499207603], [u'2582.52700', u'2.791', 1499207597], [u'2584.49100', u'16.622', 1499207742], [u'2584.49500', u'2.655', 1499207593], [u'2586.25400', u'2.911', 1499207459], [u'2588.12900', u'2.495', 1499207308], [u'2588.60800', u'1.010', 1499207672], [u'2588.88000', u'1.662', 1499206824], [u'2589.33500', u'0.003', 1499207739], [u'2589.49000', u'1.010', 1499207657], [u'2589.62300', u'1.010', 1499207688], [u'2590.00000', u'1.000', 1499207498], [u'2590.08600', u'3.000', 1499207166], [u'2591.68500', u'3.100', 1499200958], [u'2592.79000', u'0.110', 1499194437], [u'2593.05800', u'0.228', 1499193856], [u'2593.37300', u'0.005', 1499207537], [u'2593.98600', u'3.000', 1499202124], [u'2595.84200', u'3.180', 1499202136], [u'2596.00000', u'10.000', 1499193251], [u'2597.21700', u'2.810', 1499202185], [u'2598.39800', u'0.010', 1499196915], [u'2599.44800', u'3.000', 1499202388], [u'2600.00000', u'13.591', 1499207439], [u'2601.23700', u'2.900', 1499202414], [u'2602.75000', u'0.001', 1499192881], [u'2603.19900', u'2.900', 1499205250], [u'2604.05000', u'0.063', 1499184963], [u'2604.74400', u'3.250', 1499205972], [u'2605.54900', u'3.000', 1499207569], [u'2605.81010', u'0.005', 1499192921], [u'2607.00400', u'3.000', 1499205987], [u'2608.94400', u'3.400', 1499207664], [u'2609.70000', u'0.013', 1499187779], [u'2610.00000', u'0.984', 1499204729], [u'2611.97000', u'30.000', 1499204764], [u'2612.00000', u'0.125', 1499194024], [u'2614.00000', u'0.015', 1499180761], [u'2615.00000', u'0.384', 1499202759], [u'2616.00000', u'0.039', 1499198457], [u'2616.87000', u'0.010', 1499196949], [u'2617.85000', u'2.029', 1499207734], [u'2618.00000', u'10.000', 1499179708], [u'2618.71015', u'0.005', 1499192935], [u'2620.00000', u'0.398', 1499203330], [u'2621.21100', u'1.000', 1499181763], [u'2623.07700', u'13.620', 1499207743], [u'2623.07800', u'2.029', 1499207564], [u'2623.81400', u'0.100', 1499207561], [u'2625.00000', u'5.077', 1499202732], [u'2627.75000', u'0.001', 1499190931], [u'2628.00000', u'3.016', 1499189890], [u'2629.93300', u'1.010', 1499175364], [u'2630.00000', u'0.525', 1499201495], [u'2631.61020', u'0.005', 1499192949], [u'2632.90500', u'0.002', 1499207512], [u'2633.65700', u'5.005', 1499176934], [u'2633.66800', u'5.003', 1499162010], [u'2634.98700', u'0.086', 1499155251], [u'2635.00000', u'0.760', 1499160981], [u'2638.00000', u'0.264', 1499154974], [u'2639.00000', u'2.550', 1499203452], [u'2640.00000', u'1.460', 1499186692], [u'2640.08300', u'0.002', 1499207561], [u'2643.95700', u'0.011', 1499204398], [u'2644.00000', u'0.020', 1499149134], [u'2644.09700', u'0.014', 1499206785], [u'2644.51127', u'0.005', 1499192973], [u'2645.00000', u'5.761', 1499160995], [u'2646.32000', u'0.010', 1499196977], [u'2647.00000', u'0.500', 1499172159], [u'2647.34900', u'0.001', 1499152154], [u'2647.65000', u'3.791', 1499184940], [u'2648.52800', u'0.014', 1499206790], [u'2648.64000', u'0.080', 1498317415], [u'2648.92100', u'2.050', 1499206699], [u'2649.00000', u'0.025', 1499193820], [u'2649.10000', u'0.100', 1499154672], [u'2649.49100', u'0.250', 1499174609], [u'2649.75200', u'0.310', 1499187820], [u'2650.00000', u'33.033', 1499186804], [u'2650.02800', u'0.020', 1499194054], [u'2651.60000', u'0.014', 1499183996], [u'2651.75000', u'0.001', 1499011296], [u'2652.84400', u'0.018', 1498332536], [u'2652.95900', u'0.024', 1499206797], [u'2653.52300', u'0.013', 1499204402], [u'2653.59400', u'0.002', 1499206972], [u'2655.00000', u'0.755', 1499161028], [u'2655.01500', u'15.000', 1499204752], [u'2655.11900', u'0.012', 1499146444], [u'2658.55200', u'0.040', 1498415795], [u'2658.97400', u'0.004', 1499207507], [u'2660.00000', u'2.153', 1499205186], [u'2660.30100', u'0.012', 1499198703], [u'2660.44300', u'0.040', 1498360813], [u'2661.82000', u'0.028', 1499206801]]}}, u'error': []}```

Make certain unified API methods private/delete them

I'm looking at unified API and see many ways to shoot yourself in the foot using it. This is the current approach:

order (symbol, side, amount[, price[, params]])
trade (symbol, side, amount[, price[, params]])
buy (symbol, amount[, price[, params]])
sell (symbol, amount[, price[, params]])
createOrder (symbol, side, amount[, price[, params]])
createBuyOrder (symbol, amount[, price[, params]])
createSellOrder (symbol, amount[, price[, params]])
createLimitOrder (symbol, side, amount, price, params])
createMarketOrder (symbol, side, amount[, params])
createLimitBuyOrder (symbol, amount, price[, params])
createLimitSellOrder (symbol, amount, price[, params])
createMarketBuyOrder (symbol, amount[, params])
createMarketSellOrder (symbol, amount[, params])

I instead recommend the following:

createLimitBuyOrder (symbol, amount, price[, params])
createLimitSellOrder (symbol, amount, price[, params])
createMarketBuyOrder (symbol, amount[, params])
createMarketSellOrder (symbol, amount[, params])

Everything else should be private or non-existing (in python private methods begin with single _ ; Double underscore __ are also private but not inherited IIRC, since I remember having a bug with those)

It's explicit in what it's doing and does one single thing well. (SRP -- single responsibility principle)

What's the difference between this two?

order (symbol, side, amount[, price[, params]])
trade (symbol, side, amount[, price[, params]])

Eventually, keep those (or one of these..not sure what's the difference)

Also is there any reason for keeping camelCase in python, instead of using only underscores? PEP8 standard defines how python code should look like, and I assume your users are using it; it's trivial converting camelCase to underscore in the head; much less trivial if there's a typo somewhere and you accidentally call the wrong function.

Python 3.4.5 issues

Hi,

Many thanks for your efforts. Not sure what particular python 3 version you tried this with but this does not work with Python 3.4.5 out of the box:

  File "/home/ccxt/ccxt-master/ccxt/__init__.py", line 335, in hmac
    h = hmac.new (secret, request, hash)
  File "/usr/lib64/python3.4/hmac.py", line 144, in new
    return HMAC(key, msg, digestmod)
  File "/usr/lib64/python3.4/hmac.py", line 42, in __init__
    raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'

Here is a quick fix for this:

--- ccxt-master/ccxt/__init__.py        2017-07-10 05:05:45.000000000 +0300
+++ ccxt-master.bak/ccxt/__init__.py    2017-07-11 22:08:37.627994125 +0300
@@ -157,6 +157,8 @@
         headers.update ({ 'User-Agent': userAgent })
         if self.verbose:
             print (url, method, headers, data)
+        if data:
+            data = data.encode ()
         request = _urllib.Request (url, data, headers)
         request.get_method = lambda: method
         response = None
@@ -332,7 +334,7 @@

     @staticmethod
     def hmac (request, secret, hash = hashlib.sha256, digest = 'hex'):
-        h = hmac.new (secret, request, hash)
+        h = hmac.new (secret.encode(), request.encode(), hash)
         if digest == 'hex':
             return h.hexdigest ()
         elif digest == 'base64':

Calling unified methods

Would it be possible to get a the consistent format when getting the result of unified methods such as
fetchOrderBook (symbol)
or
fetchBalance ()

At the moment a few orderbooks still include timestamps (e.g. from kraken) with each order, and the result of calling fetchBalance() is obviously very different between exchanges; I'm guessing it would be a big task to change this?

Streaming (WS, Websocket support): Orderbooks, Trades, Balances...

I would like to see a new market property called balances, that would function the same way as symbols. When you call fetchBalances(), then the balances property would get filled with an associative array of currencies with balances (free, used, total, available, etc.).

Balances would also be updated via websocket (when available) or by repeated calls to the API, depending on rate limits.

Ultimately, we could do something like:

kraken.fetchBalances();
let myAvailableBTC = kraken.balance.available['BTC'];
let myTotalBTC = kraken.balance.total['BTC'];

Bitfinex private api

Im using python 3.6 and im using your latest version.

https://pastebin.com/VkNzP8s5

print(bitfinex.get_transaction_fee())

you can initialize a bitfinex variable with this
'apiKey' : '
'secret' :

When I try to call method request in class bitfinex for a private post method it fails with an error:
TypeError: a bytes-like object is required, not 'str' in line
1705 : payload = base64.b64encode (self.json (query))

I hvae tried encoding it and then in
'X-BFX-SIGNATURE': self.hmac (payload.decode(), self.secret, hashlib.sha384),`
putting decode in payload and it works.

Bittrex fetchBalance() fails

Using a fresh API key pair:

const balance = await market.fetchBalance()

produces

bittrex https://bittrex.com/api/v1.1/account/getbalances?nonce=1501049737&apikey=[redacted] { method: 'GET',
  headers:
   { 'User-Agent': 'ccxt/1.1.83 (+https://github.com/kroitor/ccxt) Node.js/8.1.4 (JavaScript)',
     apisign: [redacted] },
  body: undefined }
(node:22773) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'length' of undefined
(node:22773) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.