I don't know scala too well, but being from java, I would say integer math on operations would be the best. Also how are you storing balances? Again I would say that should be in integer math. Their are any performance hits you take when doing integer math. It just means you should have a class for displaying it in a pretty string format (eg: 7.0533 BTC).
Balances are stored as numerics in PostgreSQL. They are read by the frontend with JDBC into Java BigDecimal objects, which we wrap into Scala BigDecimals. There is not much math done on BigDecimal objects as the majority of calculations happen in the database.
This will fail under heavy loads or volume. I would suggest having a trade matching aglo, hold every trade in redis, then dump that redis database into pgSQL once you have completed a trade. This would be the best way to handle that. Remember Mt. Gox was using php and mysql, which no better than yours, and that failed under heavy volumes.
There is a trade matching algorithm, I wrote it in PL/pgSQL. How would using Redis make this faster? Writing the data into Postgres after completing a trade would result in a disk access the same as using Postgres by itself. Postgres can cache indexes of tables in memory so lookups should be fast, especially with the use of sorted partial indexes. Additionally I have concerns with using something like Redis as it is not a transactional database and is not ACID compliant. With Postgres, I can be certain that orders will be matched based on the time inserted at a particular price and that a user can only place an order if there is sufficient funds on the account. The language you use does not mean as much as the algorithms you implement. I could write an exchange entirely in C++ but that does not mean my code will be efficient.
Very nice, I would say give details (like how do you hash the password (Bcrypt, SHA 512)?)
Passwords are salted 8 iteration blowfish-based hashes and even the salted hashes are never visible to any of our servers except for the database where they are stored. It's easy to change the hashing algorithm if you would like. We wrote our own database functions to do 2FA as well. Unlike most exchanges that implement 2FA on their frontend, for example in PHP or Java, we implement it in SQL. This means that in order to place a withdrawal, your 2FA token must be passed to the withdraw function on the database. Withdrawals are processed by a separate server so in the unlikely event that the frontend web server is compromised, an attacker cannot issue withdrawals without your PIN. The frontend can only execute the stored procedures needed to do its job so it cannot execute arbitrary SQL queries or dump the database.