5

I realize that we should use BigDecimal for all monetary values, but what about stock prices in dollars?

I noticed that data feed API from major vendors uses the type double for stock quotes. Does anyone know why?

Does that mean my application can use the type double to store stock quotes that come from these vendors?

Tom Tucker
  • 11,676
  • 22
  • 89
  • 130

5 Answers5

11

The reason for not using binary floating-point for money is that money uses decimal fractions and people (and accounting regulations) expect specific decimal behaviour from arithmetic operations performed on it - which binary floating-point does not provide.

However, stock quote feeds aren't generally used for accounting. They're displayed, compared, used as input for various chart analysis indicators or trading algorithms - all much closer to scientific applications than accounting, and not requiring decimal behaviour or precision. Instead, because of the large amount of data, storage efficiency and performance are relevant, and BigDecimal really sucks at those.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
7

I work in the field. BigDecimal is obviously ideal from a precision perspective, but it sucks from a performance perspective. doubles are an option in some circumstances (particularly when dealing with normal equity prices, doubles are easily - with appropriate precautions - able to represent the entirety of the price range of all the equity exchanges I regularly deal with).

Another option is, if you know the range of DP used by the exchanges in question, to use fixed-point and a normal int or long. To take an example I know well, Xetra (the German electronic exchange) currently has at most 3 decimal places. Using 3dp, you can represent prices up to 2,147,483.647 with a normal int. Fine for an individual price, no good for representing the total of a day's trading.

It's all a question of what data you're receiving, what the precision of that data is and how you're processing it.

Jon Bright
  • 13,388
  • 3
  • 31
  • 46
5

I reject the use of BigDecimal for monetary values (in general*). Use a data-type designed for use with currency (which has a minimum precision such as mils for USD) and knows how to handle other rules. This can also be used to prevent "accidental" conversion of USD to Yen, etc. Joda Money or timeandmoney are two such examples.

While a BigDecimal is far better than a double for addressing a fixed precision, it is still not a correct monetary representation IMOHO. (BigDecimal may be the back-end [or it could be entirely replaced with another impl.], as a front-end it doesn't adequately represent the domain.)

Happy coding.

*As others have said, it depends upon the use.

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
3

Personally I would stick to BigDecimal. It's somewhat disturbing that the vendors are using doubles, but there's no reason why you should propagate their mistake. You'll start with "slightly bad" data, but at least you won't introduce further unexpected behaviour in whatever you do with the values.

You might want to talk to the vendors and find out why they're using doubles though...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    As long as you're not doing anything with the values other than relaying them/displaying them (fairly common with stock prices), there's no harm in keeping doubles. Though I hesitate to disagree with the person who gave such a great talk at Dev Days London (including a section on floating point, if I remember right)... – Jon Bright Mar 12 '11 at 21:27
  • 1
    There is no way of representing `BigDecimal` in Web Services/REST Api's. What would be the best way to represent money with such format if not for double? – Buhake Sindi Mar 12 '11 at 21:49
  • 1
    @The Elite Gentleman: I would probably offer an API which uses a decimal string using the invariant culture (i.e. a way which can be parsed in practically any language). – Jon Skeet Mar 12 '11 at 22:05
  • It does indeed depend on what you're doing with it. If you're not going to be performing *any* operations on it other than displaying it, you're clearly not going to lose any information. – Jon Skeet Mar 12 '11 at 22:05
0

A guess on this:

I noticed that data feed API from major vendors uses the type double for stock quotes. Does anyone know why?

When such a API uses a text-based format (like XML or JSON), the data transmitted are actually not double, but decimal numbers - and decimal numbers is what is meant here. And often double is the only datatype which supports decimal numbers (with digits after the point) in some of these APIs.

When you receive a stock price as double and want to calculate "in a money way" about it, make sure you know how much decimal digits (after the point) it has (should have - not from the double, but from the type of stock price), and convert it with this scale to a BigDecimal (or whatever you are using for money calculations).

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210