ccxt: [cex.io] prices rounded incorrectly

The cex.io BTC/GBP market allows 1 decimal place on the price. The metadata in the cex call for that market has a zero for price precision:

"BTC/GBP": {
      "limits": {
        "amount": {
          "min": 0.002
        },
        "price": {
          "min": 1300,
          "max": 30000
        },
        "cost": {
          "min": 20
        }
      },
      "precision": {
        "price": 0, <-- this looks wrong
        "amount": 3
      },

I think the error comes from this:

  'precision': {
    'price': this.precisionFromString (this.safeString (market, 'minPrice')), <-- this looks wrong
    'amount': this.precisionFromString (this.safeString (market, 'minLotSize')),
  },

The source data (https://cex.io/api/currency_limits) has:

{
"symbol1": "BTC",
"symbol2": "GBP",
"minLotSize": 0.002,
"minLotSizeS2": 20,
"maxLotSize": null,
"minPrice": "1300", <-- these don't show the precision
"maxPrice": "30000"
}

Which doesn’t show the precision as a field, and the minPrice and maxPrice fields aren’t shown with the max precision.

@kroitor do you have a suggestion for a fix? I’m happy to implement.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 31 (31 by maintainers)

Commits related to this issue

Most upvoted comments

@kroitor A precision of 2 DECIMAL_PLACES is the same as a TICK_SIZE of 0.01, so I think it is probably easier to calculate 1 / 1000 and use this as the TICK_SIZE then counting the zeros and use it as DECIMAL_PLACES. Also TICK_SIZE would be able to handle a precision of /2000, where DECIMAL_PLACES isnt able to do that (I dont know if they would return something like this in the future) @npomfret mentioned minLotSize which makes me think the exchange uses TICK_SIZE, but I never traded on this exchange, so I dont know it.

@kroitor I got this further clarification about the price precision from cex support:

If you want to place the bid order (this means your order will match with ask order) for Pair ETH/EUR priced at 123.8877665544332211, you need to check https://cex.io/api/currency_profile and you will see that parameter “priceScale” has the following setup: “/10000.” This means that a price must be stated up to 4th digit after the decimal point and parameter pricePrecision":2 means that after 4th digit 2 digits will be filled with 0. In your example, it will be 123.887700.

… so it looks like the correct way to round is to use the ‘priceScale’ field. For ETH/EUR for example, the priceScale is ‘/10000’, which I guess translates to: 1 / 10000 = 0.0001 --> pricePrecision: 4

@kroitor did you make any progress? I can take a look if you don’t have time.

I don’t no. But I will ask.

At a glance though, there seems to be a pattern. Everywhere that scale is non-zero, the minimumCurrencyAmount has trailing zeros:

{"code":"ETH","precision":8,"scale":2,"minimumCurrencyAmount":"0.00000100"...
{"code":"DOGE",,"precision":2,"scale":2,"minimumCurrencyAmount":"1.00"... 
{"code":"DGB","precision":2,"scale":2,"minimumCurrencyAmount":"1.00"...
{"code":"USDE","precision":2,"scale":2,"minimumCurrencyAmount":"1.00"...

etc.

So perhaps they represent currencies at a higher precision than can be specified by the user (in say a transfer request).

I’ve also requested that they add this to the API. However, I’ve been asking them for stuff for years, including really simply things like documenting the fields in the API. Nothing has ever changed.

Ok, I opened another ticket and got an answer. Sadly it is to scrape from here: https://blog.cex.io/news/engine-updates-16956

I’ve raised a request, but their support is pretty terrible.

I found this in my browser’s debugger: https://cex.io/scripts/currencyProfile/1564741298124-v901400

Looks like is has the data we need, only it’s embedded in a javascript variable. What do you think?

Or maybe you can shed some light in why you think precision = 1 is correct in this case, and whether you think it will work in other cases…

I just noticed the difference between the ccxt rounded price and the prices in the order book for this market.

I will contact the exchange to see if there’s another api call, or something similar we can use.

I think we should consider removing the current values though as they are incorrect.