Skip to content

Instantly share code, notes, and snippets.

@mtnygard
Created March 2, 2017 17:29
Show Gist options
  • Select an option

  • Save mtnygard/8ccc0b091f4ad6a4b98d445abca21bb4 to your computer and use it in GitHub Desktop.

Select an option

Save mtnygard/8ccc0b091f4ad6a4b98d445abca21bb4 to your computer and use it in GitHub Desktop.
Simulating foreign exchange rates as Brownian motion processes
;; Caution: do not attempt to print this out. It contains many
;; lazy infinite sequences.
(def rate-table
(atom
(into {}
(map (fn [[ccypair rate]]
[ccypair (rand/brownian rate 0.0005)]))
rates/rate-table)))
(defn exchange-rate
[ccypair]
(let [process (or (get @rate-table ccypair) (rand/brownian 100.0 0.01))]
(swap! rate-table assoc ccypair (rest process))
(first process)))
(ns simulator.rand
(:import java.util.Random))
(defonce random (Random.))
(defn normal
[mean stddev]
(+ mean (* stddev (.nextGaussian random))))
(defn brownian
"Return a 1-dimensional infinite lazy sequence starting with 'start'
and taking steps whose deltas (i.e., as a fraction of the current
value) that are normally distributed about 'mean' with 'stddev'."
[start volatility]
(lazy-seq
(cons start
(brownian
(+ start (* start (normal 0 volatility)))
volatility))))
(ns simulator.rates)
;; Rates snagged from dailyfx.com on 3/2/2017 around 10 am Eastern time.
(def raw-rate-table
[[:currency/eur :currency/usd 1.05137 1.05143]
[:currency/usd :currency/jpy 114.450 114.457]
[:currency/aud :currency/usd 0.75766 0.75772]
[:currency/gbp :currency/usd 1.22657 1.22666]
[:currency/usd :currency/cad 1.33844 1.33861]
[:currency/nzd :currency/usd 0.70674 0.70694]
[:currency/aud :currency/cad 1.01395 1.01435]
[:currency/aud :currency/chf 0.76671 0.76696]
[:currency/aud :currency/jpy 86.705 86.735]
[:currency/aud :currency/nzd 1.07180 1.07210]
[:currency/cad :currency/chf 0.75599 0.75624]
[:currency/cad :currency/jpy 85.487 85.527]
[:currency/chf :currency/jpy 113.081 113.101]
[:currency/eur :currency/aud 1.38758 1.38776]
[:currency/eur :currency/cad 1.40714 1.40744]
[:currency/eur :currency/chf 1.06399 1.06419]
[:currency/eur :currency/gbp 0.85712 0.85721]
[:currency/eur :currency/jpy 120.328 120.343]
[:currency/eur :currency/nok 8.90510 8.90760]
[:currency/eur :currency/nzd 1.48734 1.48764]
[:currency/eur :currency/sek 9.53250 9.53550]
[:currency/eur :currency/try 3.90470 3.90826]
[:currency/gbp :currency/aud 1.61862 1.61912]
[:currency/gbp :currency/cad 1.64167 1.64202]
[:currency/gbp :currency/chf 1.24127 1.24157]
[:currency/gbp :currency/jpy 140.380 140.405]
[:currency/gbp :currency/nzd 1.73491 1.73571]
[:currency/nzd :currency/cad 0.94597 0.94632]
[:currency/nzd :currency/chf 0.71519 0.71559]
[:currency/nzd :currency/jpy 80.889 80.914]
[:currency/try :currency/jpy 30.763 30.843]
[:currency/usd :currency/chf 1.01199 1.01214]
[:currency/usd :currency/cnh 6.88285 6.88385]
[:currency/usd :currency/mxn 19.92267 19.93017]
[:currency/usd :currency/nok 8.46979 8.47229]
[:currency/usd :currency/sek 9.06684 9.06934]
[:currency/usd :currency/try 3.71139 3.71423]
[:currency/usd :currency/zar 13.10190 13.11090]])
(defn midpoint
[bid ask]
(/ (+ bid ask) 2))
(def spot-mid
(map (fn [[from to bid ask]]
[from to (midpoint bid ask)])))
(def pair-currencies
(map (fn [[from to & more]]
(apply vector [from to] more))))
(def rate-table
(into {}
(comp spot-mid pair-currencies)
raw-rate-table))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment