Live data from Hacker News

Fintech engineering mistakes (2022)

startupwin.kelsus.com

41–50 of 112 posts

Re: Fintech engineering mistakes (2022)

#42
post #26
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…

I'm generally not a fan of overloading fields, but we took the opportunity to add the currency code when we decided to encode monetary quantities in JSON as strings, e.g. "0.02USD". This has worked well, particularly because we use a money handling library that parses it unchanged.

Do you always put the currency behind the number? I know some countries prefer the currency infront (e.g. USD), others behind (EUR).

But since this is not a human visible field, this is probably irrelevant, right?

Re: Fintech engineering mistakes (2022)

#43
post #39

Earlier quoted context omitted.

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…

It looks like math but really it is describing an exchange of goods.

Re: Fintech engineering mistakes (2022)

#44
post #42
post #26

Earlier quoted context omitted.

I'm generally not a fan of overloading fields, but we took the opportunity to add the currency code when we decided to encode monetary quantities in JSON as strings, e.g. "0.02USD". This has worked well, particularly because we use a money handling library that parses it unchanged.

Do you always put the currency behind the number? I know some countries prefer the currency infront (e.g. USD), others behind (EUR). But since this is not a human visible field, this is probably irrelevant, right?

I think I looked at this when I laid it out:

https://ux.stackexchange.com/questions/9105/international-cu...

So we put the ISO code at the end and ignore whitespace. But including a prefix sign as with `€1.234.567,89 EUR` would break it.

Re: Fintech engineering mistakes (2022)

#45
post #5

This is a great little article, and I can't emphasize what a big deal #2 is.

Some folks will laugh at this advice. Others (like me) will cry because we know of multibillion-dollar fintechs that still struggle with this. The one I'm thinking of didn't even have cents for a long time. After a pretty heroic migration effort they added cents. And they did it properly. But within weeks folks were using floats all over the place for money, leading to flaky tests and all kinds of other errors.

I have worked at banks and fintechs for the past 30 years and honestly have never used anything but a doubles for money with no issues (and a simpler code base.)

I understand the sentiment and the potential issues, but it's really kind of domain dependent.

Re: Fintech engineering mistakes (2022)

#46
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…

I don't think it's as big a heft. First, there are standards bodies that list currencies as "default" set, much like we have ISO standard country codes. No one really complains if Narnia isn't a country, that Disneyland isn't a country, or the Austro-Hungarian empire, for ISO Locales.

At a bare minimum, it should be a reasonable fixed point type that correctly handles rounding and intermediate values. So a dollar amount like 123.45 times a rate like 0.3450 doesn't exceed 4 decimal places but intermediate values are extended so we get correct rounding. The destination should probably determine the number of places. That bare minimum wouldn't stop you from comparing yen to dollars, any more than a floating point representing mph stops you from comparing it to a value representing kph.

But there are times where we need to track prices to the nearest tenth or hundredth of a cent. So it should be extensible so that 123.456 dollars * 0.3450 winds up at a correct round/decimal places.

You also don't need always-on, real time currency conversion. You could have a conversion type, operator, or method that does safe conversion based on the value I give it. So if I estimate that Yen are about 130 to the dollar, I can just use that. If I happen to write an application that queries a data provider and can populate that in 'real time,' that's up to me.

If you really wanted, you could find a way to create new types that represent currencies that aren't part of the basic implementation. That might mean you need to specify some things like the representation for different locales, or the default number of digits.

Re: Fintech engineering mistakes (2022)

#47
post #42
post #26

Earlier quoted context omitted.

I'm generally not a fan of overloading fields, but we took the opportunity to add the currency code when we decided to encode monetary quantities in JSON as strings, e.g. "0.02USD". This has worked well, particularly because we use a money handling library that parses it unchanged.

Do you always put the currency behind the number? I know some countries prefer the currency infront (e.g. USD), others behind (EUR). But since this is not a human visible field, this is probably irrelevant, right?

It’s probably fine, but this sort of thing is why transactionAmount and transactionCurrency are better when separated. Consider the case when you’re doing some reporting from your DB based on currency; do you really want to have to deal with one string that contains both or just do a simple WHERE clause?

Re: Fintech engineering mistakes (2022)

#48
post #47
post #42

Earlier quoted context omitted.

Do you always put the currency behind the number? I know some countries prefer the currency infront (e.g. USD), others behind (EUR). But since this is not a human visible field, this is probably irrelevant, right?

It’s probably fine, but this sort of thing is why transactionAmount and transactionCurrency are better when separated. Consider the case when you’re doing some reporting from your DB based on currency; do you really want to have to deal with one string that contains both or just do a simple WHERE clause?

In our case those are indeed separate in the database, so that we can type the value as a numeric, which is very necessary for many operations. Those fields only get combined in the serialization.

Re: Fintech engineering mistakes (2022)

#49
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 is supposed to be a festive hour, not one for trading.

Re: Fintech engineering mistakes (2022)

#50
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.

>as long as you do rounding and comparisons correctly it works perfectly fine.

At least until you need to add things, at which point you need Kahan's algorithm.

Post reply on HN