Crypto-toolbox / bitex

Crypto-currency Exchange API Framework
MIT License
483 stars 134 forks source link

Bitfinex Auth calls fail #97

Open Razorbob opened 6 years ago

Razorbob commented 6 years ago

Hello, just wanted to point out, that bitfinex auth request fail.

ERROR:bitex.utils:return_api_response: HTTPError for url https://api.bitfinex.com/v1/order/new Traceback (most recent call last): File "C:\Users\xxx\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bitex\utils.py", line 40, in wrapper r.raise_for_status() File "C:\Users\xxx\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 935, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://api.bitfinex.com/v1/order/new {'message': 'Invalid X-BFX-SIGNATURE.'}

Regards

deepbrook commented 6 years ago

Hey @Razorbob, Thanks for contributing! What version are you using ? I'll look into this as soon as I can.

Cheers, Nils

Razorbob commented 6 years ago

Hello @nlsdfnbch , I installed with pip3.6.3 and got bitex version 1.2.1

I wrote a short script for authenticated Rest and WSS calls in python for apiv2 to assure that the keys are correct - so no issue there, but strangely I got the same error when I tried with v1. Maybe a bitfinex problem?

Liebe Grüße, Vincent

deepbrook commented 6 years ago

@Razorbob , ok, to recap - it works on the 'v2' API but not v1 ? Or it doesnt work with either? Could you send me the code snippet you use ? (sans the keys, of course).

As long as the return code isn't a 5XX status code, it appears to be an issue with my code, unfortunately.

Razorbob commented 6 years ago

@nlsdfnbch, I just wrote the API Call for WSS and REST in a quick and dirty Script in my own - Not with bitex.

I can send you the codesnipped for v2 from my own Script - but it is nothing special. I will post it after I return.

Liebe Grüße

Razorbob commented 6 years ago

Oh and i will try bitex v2, when i have Time again.

deepbrook commented 6 years ago

Hey @Razorbob,

Running this (Bitex 1.2.1):

from bitex import Bitfinex

c = Bitfinex(key,  secret)

print(c.balance())

works without issue for me.

Razorbob commented 6 years ago

Hey @nlsdfnbch,

Can you try doing an ask or Bid?

deepbrook commented 6 years ago

Ah, I just noticed the error You're APIkey does not have the required permissions. Make sure you have read AND write access, if you want to place new order or cancel existing ones.

Razorbob commented 6 years ago

Hello @nlsdfnbch I am sorry, but I am srsly getting this on the code you proposed:

ERROR:bitex.utils:return_api_response: HTTPError for url https://api.bitfinex.com/v1/balances Traceback (most recent call last): File "C:\Users\xxx\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bitex\utils.py", line 40, in wrapp er r.raise_for_status() File "C:\Users\xxx\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 935, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.bitfinex.com/v1/balances <Response [400]>

Instead with a quick and dirty script

async def bid(pair, price, ammount):
    address = "wss://api.bitfinex.com/ws/2"

    apiKey = 'xxxx'
    apiSecret = 'xxxx' 
    authNonce = str(int(time.time() * 10000000))
    authPayload = 'AUTH' + authNonce
    authSig = hmac.new(str(apiSecret).encode('utf-8'), authPayload.encode('utf-8'), hashlib.sha384).hexdigest()

    payload = json.dumps({
                'event': 'auth',
                'apiKey': apiKey, 
                'authSig': authSig, 
                'authNonce': authNonce,
                'authPayload': authPayload  
            })

    order = json.dumps([
                  '0',
                  'on',
                  'null',
                  {
                    'gid': '1',
                    'cid': '12345',
                    'type': "LIMIT",
                    'symbol': pair,
                    'amount': ammount,
                    'price': price,
                    'hidden': '0'
                  }
                ])

    async with websockets.connect(address) as ws:
        await ws.send(payload)
        result = await ws.recv()
        result = json.loads("".join(list(format(result))))
        print (result)
        result = await ws.recv()
        result = json.loads("".join(list(format(result))))
        print (result)
        print("BID ORDER")
        await ws.send(order)
        result = await ws.recv()
        result = json.loads("".join(list(format(result))))
        print (result)
        ws.close()

I am getting fine results - I gave the key full access to everything. So I srsly don't know, sorry

Regards

Razorbob commented 6 years ago

Imports

import requests  
import json
import base64
import hashlib
import hmac
import websockets
import asyncio
import os
import time

execute the methode with:

loop = asyncio.get_event_loop()
loop.run_until_complete(bid("tBTCUSD", "500", "1.0"))
deepbrook commented 6 years ago

Hey @Razorbob , That second log had a different error code. Could you test it again now ? If you haven't changed anything in your API key and codebase, that error code should always be identical. If that is the case, like you say, then it points towards an issue with bitfinex.

Also, just to clarify - the client you're using accesses the REST API (not the websocket, like you are in your code), just to make sure we're on the same page.

Thanks!

Razorbob commented 6 years ago

Hey @nlsdfnbch, The first error i was getting with loading a keyfile:

c = Bitfinex(key_file=keyfile)

which was simply structured like this (I think this was your Documentation of Bitex):

apikey
secretkey

The second error is constantly showing, if i call it like this: c = Bitfinex(key, secret)

As for the example code I posted, it was just some quick test if the keys work and since v2 REST API has no place bid or ask functionality, even for authenticated requests, I had to code up a websocket call.

Razorbob commented 6 years ago

And I missclicked, sorry didn't want to close the issue.

deepbrook commented 6 years ago

@Razorbob, v2 REST isn't supported by bitex 1.2.x anyway.

Alright, since somethings' amiss, try running this:

from bitex import Bitfinex
import logging

logging.basicConfig(filename="main.log", filemode="w+", level=logging.DEBUG)
log = logging.getLogger(__name__)

c = Bitfinex(key="BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5",
             secret="X7bP4NZHgf7JU6UPfzrHqujkgh4TdgBVD17dBEyUz86")

print(c.balance().json())

Keep the key and secret and upload the contents of main.log, please. It should look something like this:

C:\Users\nls\Anaconda3\python.exe F:/git/bitex/main.py
DEBUG:bitex.api.REST.api:Initialized API Client for URI: https://api.bitfinex.com; Will request on API version: v1
DEBUG:bitex.api.REST.api:Making request to: https://api.bitfinex.com/v1/balances, kwargs: {'headers': {'X-BFX-SIGNATURE': 'c5b8dcfc426e46bfc99928b7257546b13abf9e31eef1f488c0ae80cbe173b71512fd2ca09e4db0a52c088d18c8f77d6d', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9iYWxhbmNlcyIsICJub25jZSI6ICIxNTEwNDc4Mjg2OTk2In0=', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5'}}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.bitfinex.com
DEBUG:urllib3.connectionpool:https://api.bitfinex.com:443 "POST /v1/balances HTTP/1.1" 200 None
[]
DEBUG:bitex.api.REST.api:Made POST request made to https://api.bitfinex.com/v1/balances, with headers {'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9iYWxhbmNlcyIsICJub25jZSI6ICIxNTEwNDc4Mjg2OTk2In0=', 'User-Agent': 'python-requests/2.18.4', 'Content-Length': '0', 'Connection': 'keep-alive', 'X-BFX-SIGNATURE': 'c5b8dcfc426e46bfc99928b7257546b13abf9e31eef1f488c0ae80cbe173b71512fd2ca09e4db0a52c088d18c8f77d6d', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*'} and body None. Status code 200
Razorbob commented 6 years ago

@nlsdfnbch

Here is the Log:

DEBUG:bitex.api.REST.api:Initialized API Client for URI: https://api.bitfinex.com; Will request on API version: v1
DEBUG:bitex.api.REST.api:Making request to: https://api.bitfinex.com/v1/balances, kwargs: {'headers': {'X-BFX-APIKEY': '
BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5', 'X-BFX-SIGNATURE': '73ca7fc9e92fa013c172ce73c062998c3f037df0ebc0b1725612e2
ef92edddc227e66a0b2cfab787c782ddee8effd7b8', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9iYWxhbmNlcyIsICJub25jZSI6ICIxNTEw
NDk2MDY0MzkxIn0='}}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.bitfinex.com
DEBUG:urllib3.connectionpool:https://api.bitfinex.com:443 "POST /v1/balances HTTP/1.1" 200 None
DEBUG:bitex.api.REST.api:Made POST request made to https://api.bitfinex.com/v1/balances, with headers {'User-Agent': 'py
thon-requests/2.18.4', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'X-BFX-APIKEY':
'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5', 'X-BFX-SIGNATURE': '73ca7fc9e92fa013c172ce73c062998c3f037df0ebc0b1725612e
2ef92edddc227e66a0b2cfab787c782ddee8effd7b8', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9iYWxhbmNlcyIsICJub25jZSI6ICIxNTE
wNDk2MDY0MzkxIn0=', 'Content-Length': '0'} and body None. Status code 200
[]

I tried it out with my api keys as well, also yields a 200

Regards

deepbrook commented 6 years ago

Hm. Then this issue is resolved, no? Did you try the other methods as well?

Razorbob commented 6 years ago

@nlsdfnbch Not really - getting Orders have been possible before. I tried with my key, because your keys dont have write permissions on orders it seems.

I tried this :

from bitex import Bitfinex
import logging

logging.basicConfig(filename="main.log", filemode="w+", level=logging.DEBUG)
log = logging.getLogger(__name__)

c = Bitfinex(key="xxxx", #'' BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5
             secret="xxx") #  X7bP4NZHgf7JU6UPfzrHqujkgh4TdgBVD17dBEyUz86

print(c.ask("BTCUSD", 300, 2).json())

with that error :

ERROR:bitex.utils:return_api_response: HTTPError for url https://api.bitfinex.com/v1/order/new
Traceback (most recent call last):
  File "C:\Users\xxx\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bitex\utils.py", line 40, in wrapp
er
    r.raise_for_status()
  File "C:\Users\xxx\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 935, in
raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.bitfinex.com/v1/order/new
{'message': 'Nonce is too small.'}
deepbrook commented 6 years ago

That smells familiar. I will look into this first thing tomorrow morning. Thanks for your patience!

deepbrook commented 6 years ago

Ok, so I've had a similar issue in btfxwss, which was due to too many successive calls to authenticated endpoints within one second. Since this does not appear to be the case here, I doubt this may be the issue. However, I do not have high hopes for it.

Since I took the bitfinex doc nonce as a reference, I doubt this is the cause for this error.

In the meantime, can you confirm that this happens everytime you try to call it ? or just sporadically?

pchandra-uchicago commented 6 years ago

@nlsdfnbch - I still have have the same issue after upgrading to latest update from production. Below is the code I am executing and have attached the logs

from bitex.api.REST import BitfinexREST

k = BitfinexREST()
k.load_key('bitfinex.txt')  # loads key and secret from given file;
status = k.query('POST', 'orders', authenticate=True)# query an authenticated end point;
print(status.text)

test.log

deepbrook commented 6 years ago

Hm. I cannot replicate this error.

C:\Users\nls\Anaconda3\python.exe F:/git/bitex/main.py
The API clients available in this package are deprecated and will be no longer available in their current form starting with version 2.0!
DEBUG:bitex.api.REST.api:Initialized API Client for URI: https://api.bitfinex.com; Will request on API version: v1
DEBUG:bitex.api.REST.api:Making request to: https://api.bitfinex.com/v1/orders, kwargs: {'headers': {'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNTg2ODE5In0=', 'X-BFX-SIGNATURE': '71d3d60532738d9ce1197ea45d632efc5bc256fc713ffab6a6ef2761e569c62e3b0ca8ccb840a5d2ec38b33798f531b7', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5'}}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.bitfinex.com
DEBUG:urllib3.connectionpool:https://api.bitfinex.com:443 "POST /v1/orders HTTP/1.1" 200 None
[]
DEBUG:bitex.api.REST.api:Made POST request made to https://api.bitfinex.com/v1/orders, with headers {'Content-Length': '0', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNTg2ODE5In0=', 'User-Agent': 'python-requests/2.18.4', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Accept': '*/*', 'X-BFX-SIGNATURE': '71d3d60532738d9ce1197ea45d632efc5bc256fc713ffab6a6ef2761e569c62e3b0ca8ccb840a5d2ec38b33798f531b7'} and body None. Status code 200
DEBUG:bitex.api.REST.api:Making request to: https://api.bitfinex.com/v1/orders, kwargs: {'headers': {'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNjMwMTUyIn0=', 'X-BFX-SIGNATURE': 'e178e1b149867a517d2d9b2e217a13524dfbf18920d05207c8d9bbf8cbd913d10f72e38c5811daa4275827943b82c7cd', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5'}}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.bitfinex.com
DEBUG:urllib3.connectionpool:https://api.bitfinex.com:443 "POST /v1/orders HTTP/1.1" 200 None
[]
DEBUG:bitex.api.REST.api:Made POST request made to https://api.bitfinex.com/v1/orders, with headers {'Content-Length': '0', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNjMwMTUyIn0=', 'User-Agent': 'python-requests/2.18.4', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Accept': '*/*', 'X-BFX-SIGNATURE': 'e178e1b149867a517d2d9b2e217a13524dfbf18920d05207c8d9bbf8cbd913d10f72e38c5811daa4275827943b82c7cd'} and body None. Status code 200
DEBUG:bitex.api.REST.api:Making request to: https://api.bitfinex.com/v1/orders, kwargs: {'headers': {'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNjU4NDAwIn0=', 'X-BFX-SIGNATURE': 'cc56659ae9806dd63a9964e2f6092e8be1dfe7be21b1b2daf8b9d738fe116b197a8bae6b0593fdda45c533ee2cf2707b', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5'}}
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.bitfinex.com
DEBUG:urllib3.connectionpool:https://api.bitfinex.com:443 "POST /v1/orders HTTP/1.1" 200 None
DEBUG:bitex.api.REST.api:Made POST request made to https://api.bitfinex.com/v1/orders, with headers {'Content-Length': '0', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNjU4NDAwIn0=', 'User-Agent': 'python-requests/2.18.4', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Accept': '*/*', 'X-BFX-SIGNATURE': 'cc56659ae9806dd63a9964e2f6092e8be1dfe7be21b1b2daf8b9d738fe116b197a8bae6b0593fdda45c533ee2cf2707b'} and body None. Status code 200
DEBUG:bitex.api.REST.api:Making request to: https://api.bitfinex.com/v1/orders, kwargs: {'headers': {'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNjk3MTAwIn0=', 'X-BFX-SIGNATURE': '4c0627e12a50a21d0d06faade2d9718c1b1d50535a2825cdc96680ddb916c916ee07403b0e7f39448ea92a8348399d27', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5'}}
[]
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.bitfinex.com
DEBUG:urllib3.connectionpool:https://api.bitfinex.com:443 "POST /v1/orders HTTP/1.1" 200 None
[]
DEBUG:bitex.api.REST.api:Made POST request made to https://api.bitfinex.com/v1/orders, with headers {'Content-Length': '0', 'X-BFX-PAYLOAD': b'eyJyZXF1ZXN0IjogIi92MS9vcmRlcnMiLCAibm9uY2UiOiAiMTUxMDY4NjMyNjk3MTAwIn0=', 'User-Agent': 'python-requests/2.18.4', 'X-BFX-APIKEY': 'BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Accept': '*/*', 'X-BFX-SIGNATURE': '4c0627e12a50a21d0d06faade2d9718c1b1d50535a2825cdc96680ddb916c916ee07403b0e7f39448ea92a8348399d27'} and body None. Status code 200

calling Bitfinex.orders() works fine for me. Which indicates that the general authentication process is solid in principle; unfortunately, that doesn't solve your issue. However, without being able to replicate this error, I cannot solve this.

pchandra-uchicago commented 6 years ago

How are you able to call Bitfinex.orders() ? Do you see anything wrong with the code I posted above.

DEBUG:urllib3.connectionpool:https://api.bitfinex.com:443 "POST /v1/orders HTTP/1.1" 200 None is what you get when you send a request. I have 400 instead of 200. Is it something to do with that ?

deepbrook commented 6 years ago

Code 200 is the HTTP Request Statuscode - 200 indicates that the request was successful and no errors occurred. A Code 4xx indicates that there was a problem with the request. This particular difference in our logs is what makes this very difficult to reproduce - since we're using the same code base, the only other difference must therefore be our input. Which in the case of orders() is exactly None (therefore also identical).

To use the interface object, do this:

from bitex import Bitfinex
c = Bitfinex(key="BAEtHJu3ze6hBN26R8ArWSA5Gawb39IGtOcB4WHRWJ5",
             secret="X7bP4NZHgf7JU6UPfzrHqujkgh4TdgBVD17dBEyUz86")

print(c.orders().json())  # returns []

You can call any other supported method (see the source code for more on this).

Your code isn't wrong - it just uses the low-level API objects, instead of the high-level and more user-friendly interface objects.

pchandra-uchicago commented 6 years ago

@nlsdfnbch - When I use your key as displayed above, it works. Probably there is an issue with my account key. I will try again with new set of key and secret.

Thanks

pchandra-uchicago commented 6 years ago

@nlsdfnbch - I still have the same error {Nonce is too small'}. Not sure what's going wrong.

I have the following nonce() function. Should the multiplier be 1000000 instead of 100000 str(round(100000 * time.time()))

deepbrook commented 6 years ago

@pchandra-uchicago , I need reproducible code. As you have already mentioned, my key and secret work for you, which indicates that this isn't a problem with btfxwss. Please contact support at Bitfinex and see if they can help with this.

abbasc52 commented 6 years ago

@nlsdfnbch - I tried your lib for bitfinex to post order. I was always getting 400 with message {Nonce is too small'}. I looked up a bit and found the currect nonce needs to be multiplied by a factor(20 worked for me). I extended your classes to make them work for me

class CustomBitfinex(Bitfinex):
    def nonce(self):
        return str(math.floor(datetime.datetime.now().timestamp()*2 * 1000000))

class CustomBitfinexREST(BitfinexREST):
    def nonce(self):
        return str(math.floor(datetime.datetime.now().timestamp()*2 * 1000000))

Seems this issue is there with official bitfinex node api as well(but they allow us to pass custom nonce generator)

deepbrook commented 6 years ago

@abb152, where did you find this information?

Their API documentation uses a unix timestamp with millisecond resolution (which is what the library currently employs).

Unfortunately Bitfinex hasn't answered any of my tickets regarding this issue, which makes it quite frustrating to fix.

I'll add multiplication by factor 2. @pchandra-uchicago, @Razorbob , let me know if this solves the issue.

It certainly wouldn't be the ideal solution, but I guess I'll just have to roll with it.

abbasc52 commented 6 years ago

@nlsdfnbch https://github.com/askmike/gekko/issues/595

Here a guy mentioned this:

This is on ubuntu 16.04 and:

Nonce must be greater than 1905332886555001. You provided 149315522139600.

The nonce i generated was around 15XXXXXXXXXXX so i thought of multiplying with a factor and it worked

Cloniko commented 6 years ago

I do not know if it will be related to this but I have seen an error in interfaces\bitfinex.py.

You have to delete a hyphen in "type" so that the orders are correctly executed.

The correct is 'type': 'exchange limit'} without a hyphen

deepbrook commented 6 years ago

@Cloniko , thanks for the pointer! I fixed this on dev and it should no longer be an issue.

mark-atk commented 6 years ago

Not sure if this is the best place to put this, but I was getting a similar issue. It turned out to be a function in the bitfinex.py interfaces module.

basically I had to change: ` @return_api_response(fmt.order)

def bid(self, pair, price, size, replace=False, **kwargs):

    return self._place_order(pair, size, price, 'buy', replace=replace, **kwargs)`

` @return_api_response(fmt.order)

def bid(self, pair, price, size, replace=False, **kwargs):

    return self._place_order(pair, str(size), str(price), 'buy', replace=replace, **kwargs)`

The size and price parameters needed to be cast to strings in the place_order function. This was already done in ask, just missing in bid.

Could be a separate issue?

deepbrook commented 6 years ago

It's not an issue with the library per se. On dev, we no longer convert to str, since per definition of the Bitfinex API the parameters need to be strings anyway.

However, adding this conversion would require less reading of API documentation for lib users - this can be both a good and bad thing. So I'm currently undecided how to handle this.

But thank you for pointing this out!

mark-atk commented 6 years ago

Agreed, maybe just make sure the bid and ask methods are aligned then, as one converts to string and the other doesnt

ZZQR commented 6 years ago

@Razorbob Hi Razorbob, I use ubuntu 16.04 and have encountered a 400 issue as well. After spending hours, I found that there is a missing "/" in endpoint_path while creating signature (in bitex/api/REST/bitfinex.py):

req['request'] = endpoint_path req['nonce'] = self.nonce() js = json.dumps(req) data = base64.standard_b64encode(js.encode('utf8'))

The value of req['request'] is "0/action" in this case, but should be "/0/action" to get a correct "data". This works for me, but I don't know whether it works in your case. Thanks