Live data from Hacker News

Fintech engineering mistakes (2022)

startupwin.kelsus.com

31–40 of 112 posts

Re: Fintech engineering mistakes (2022)

#31
post #13
post #2

You can absolutely use doubles for money. Excel does it and so do many other financial tools. There are pros and cons but as long as you do rounding and comparisons correctly it works perfectly fine.

For example 16.10 is not exactly 16.10 in IEEE floating point. When you do enough operations, and depending on the order of operations, you can wind up several cents off. That sounds small, but can be enough to give your auditors heart-burn. COBOL does BCD arithmetic, (not really but at least conceptually), and it's penny accurate to 31 digits (as per the standard - implementations may have greater accuracy). Frankly…

It would be neat to have a fundamental "money" primitive alongside int, float, string, etc.

It might not be simple to implement, though. Off the top of my head,

* Can you confidently say that $100>¥10 in an offline environment?

* You'd need to support different bases for splitting units to deal with eldritch values such as farthings.

* Where is the line drawn? Is a Bitcoin a valid currency? A gold Krugerrand? A bundle of stock shares? A bushel of apples?

All of that said, I would love to see a world where I could write code like:

    money balance = money.lumber.grade.kilograms(8);

Re: Fintech engineering mistakes (2022)

#32
post #22

One more: Timezones Various platforms use: UTC, the user’s timezone as set in their dashboard, the user’s detected timezone, the timezone of the server that is generating the reports. Aggregating or reconciling data from different platforms can be a pain if the timezones aren’t clearly indicated. I’ve had bank statements that didn’t agree to CSV exports of the same data because the servers generating the two reports…

Haha yeah for the past tax year I I looked at my transaction history and it was missing some that I expected to be there. Turns out, the exchange (Gemini, for crypto) uses UTC, but the IRS docs always tell you that a cutoff is relative to your own time zone. The transactions were in the late evening on New Year's Eve, central US time, but that was already the next year by UTC, so any readout of "transactions for 2022…

That’d be a great subplot for a movie. The antagonist sets up an elaborate money laundering operation that leverages conflicting definitions of the taxable year and moves off shore profits that are “lost” between the systems. Could call it “Black Ink to the Future.

Re: Fintech engineering mistakes (2022)

#34
> Over the last decade, fintechs using RDBMS databases to record transactions have built features onto their databases like a journal of all changes to all data and clever ways of making sure the data hasn’t been modified by storing checksums of data as transactions are added. (under “Updating transactions”)

It is worth noting that many of these methods don't prevent tampering, they only make it visible when you look for it at which point the fact you are explicitly looking for it (rather than having been alerted to a potential issue) might imply it is too late.

Re: Fintech engineering mistakes (2022)

#35
The recommendation that "developers should use integers to represent money" (with an implicit 2 decimal places, that will work for many but not all currencies) is not a great one.

If your language has a dedicated type for monetary amounts, use that. (1)

If it does not, but you can make a value object to represent, e.g. amount and currency code, then do that.

If however, your language does not have a dedicated type for monetary amounts, or one cannot be trivially built or retrieved as a package (2), then you should ask yourself if it is really a suitable language for financial tasks.

1) https://learn.microsoft.com/en-us/dotnet/api/system.decimal

2) https://github.com/shopspring/decimal https://www.npmjs.com/package/ts-money

Re: Fintech engineering mistakes (2022)

#36
post #21

I’d also add: — If you’re using JSON to pass around monetary quantities (eg. from the frontend to the backend), put them in strings as opposed to the native number type. You never know what the serializers and deserializers across languages will do to your numbers (round them, truncate them etc.). — Start recording the currency of the transactions as early as possible. It can be a separate column in your table. — Use…

> — Use TIMESTAMPTZ. Always.

When you’re using JSON to pass around datetime data, Use ISO8601 date and time with offset info, always.

e.g. "transactionDate": "2023‐06‐28T15:55:22.511Z"

Re: Fintech engineering mistakes (2022)

#37

One more: Timezones Various platforms use: UTC, the user’s timezone as set in their dashboard, the user’s detected timezone, the timezone of the server that is generating the reports. Aggregating or reconciling data from different platforms can be a pain if the timezones aren’t clearly indicated. I’ve had bank statements that didn’t agree to CSV exports of the same data because the servers generating the two reports…

That's why Datetime data should be handled in a type that includes this data (e.g. DateTimeOffset (1) ) and exchanged as ISO 8601 with offset. e.g. "2023‐06‐28T15:55:22+01:00"

1) https://learn.microsoft.com/en-us/dotnet/api/system.datetime...

Re: Fintech engineering mistakes (2022)

#38
post #33

I wish strictly INSERT-only tables were a standard SQL feature. It would be so very useful.

What’s the advantage of INSERT-only table over having a normal table and all normal users only have INSERT privilege on that table?

As admin I can still recreate the whole insert table with modified data, etc.

Re: Fintech engineering mistakes (2022)

#39
post #13

Earlier quoted context omitted.

For example 16.10 is not exactly 16.10 in IEEE floating point. When you do enough operations, and depending on the order of operations, you can wind up several cents off. That sounds small, but can be enough to give your auditors heart-burn. COBOL does BCD arithmetic, (not really but at least conceptually), and it's penny accurate to 31 digits (as per the standard - implementations may have greater accuracy). Frankly…

It would be neat to have a fundamental "money" primitive alongside int, float, string, etc. It might not be simple to implement, though. Off the top of my head, * Can you confidently say that $100>¥10 in an offline environment? * You'd need to support different bases for splitting units to deal with eldritch values such as farthings. * Where is the line drawn? Is a Bitcoin a valid currency? A gold Krugerrand? A bundl…

"Can you confidently say that $100>¥10 in an offline environment?"

A major problem money has is that it isn't a unit in the sense we usually take the term to mean. We expect, for instance, that translating one unit to another with a suitable level of precision should be translatable without loss back to the original unit, but that's not true for money, even ignoring transaction costs. If "US dollar" is a unit, it is a unit that technically stands alone in its own universe, not truly convertible to anything else, not even other currencies. All conversions are transient events with no repeatability. But that is very inconvenient to deal with, and with sufficient value stability of all the relevant values, often it's a sufficient approximation to just pretend it's a unit. But if you zoom in enough, the approximation breaks down.

For that and similar reasons, while you could theoretically write that line of code, it would be implicitly depending on a huge pile of what would in most languages be global state. It would be a dubious line of code.

Re: Fintech engineering mistakes (2022)

#40
post #2

You can absolutely use doubles for money. Excel does it and so do many other financial tools. There are pros and cons but as long as you do rounding and comparisons correctly it works perfectly fine.

The question is why? What does the double give you over a 64-bit integer? Sure when you divide and it leaves a fractional part you loose it and need to think about what happens there explicitly but you need to do the same for doubles to avoid pennies going missing and snowballing into larger errors.

Using integer representations for currencies becomes very messy when dealing with more than one currency at a time.

The United States dollar is famously subdivided into cents, but is also subdivided into 'mills' (one thousand to the dollar).[0]

The Mauritanian ouguiya is divided into five khoums.

The Madagascan ariary is divided into five iraimbilanja.

The Maltese scudo is divided into twelve tarì, which are divided into twenty grani, which are divided into six piccioli.

Historically, such currencies were ubiquitous. For example, prior to 15 February 1971, the pound sterling was divided into twenty shillings, each of which was divided into twelve pence, a system that originated with Roman currency and was used throughout the British Empire.

Exchange rates are typically quoted in terms of the largest unit, whereas integer representations of currency would need to be done in terms of the smallest unit, so extensive information about currency structures would need to be used to correctly represent exchange rates. Floating point or binary-coded decimal representations are consequently much better.

[0]: https://en.wikipedia.org/wiki/Mill_(currency)

Post reply on HN