Reflector maintains a table of conversion rates against Reflector's reserve currency (currently set to USD). There are three mechanisms for setting the values in this table: hard-coded initial values, initialization via a settings file, and updates through the web server:
- Hard-Coded Initial Values - The hard-coded initial values are known to be correct at some point in time, and is taken as the reference to judge whether newer values are sensible.
- Settings File - A new snapshot of all settings is written any time there is a settings change (which includes reference rate changes). The most recent settings file is read at startup. Failure to apply the settings file aborts Reflector.
- Web Server : Reflector's web server allows for the updating of reference rates. Failure to apply exchange rates from a web request is silently ignored.
Internal Mechanism
The Reflector run-time works parses the JSON, and the update function is given a set of currencies to update, along with a numeric value per entry to be updated. The following "fat finger" validation is performed:
- If the update set contains the reserve currency and it rate isn't 1, the update is rejected.
- If any new rate falls outside the range [10^{-6}, 10^6]; update is rejected.
- If any new rate falls outside the range OldRate/2, 2 x OldRate; update is rejected.
- if all new rates fall within a multiple of 1.0001 of old rates, then the update is accepted but not performed (i.e. all or none are accepted).
If the above validation checks all pass, then exchange rates are updated and rate-dependent cached values are recomputed.
External Mechanism
A worker process supports the use of custom market data feeds. This process also interprets, sanity-checks, and filters these feeds for consumption by the Reflector run-time.
The dynamic price worker updates currency reference prices according to the following schedule:
- On every outgoing heartbeat message, the worker checks whether any symbol has changed in price by more than a particular price tolerance p, set by default to 0:1%.
- It then checks whether the prices have been on the Reflector instance in the last t seconds, set by default to 300 (5 minutes).
If either condition holds, the worker pushes a full set of new prices (for all symbols, regardless of the amount by which each has changed) to Reflector, which immediately begins using these new prices.
Both the price tolerance p and the time tolerance t are congurable: while less tolerant parameters (and thus more frequent updates) result in more current pricing, the system incurs slightly heightened latency during price updates. Conversely, more tolerant parameters maintain steady performance at the cost of staler prices. While the default parameters usually results in a mix of updates due to time and due to price, the ultimate balance struck in this trade-off is up to the customer.