FX Trading Tile with Clojure/ClojureScript

•July 22, 2015 • Leave a Comment

Anyone who subscribes to any of my social network feeds would have seen an increase in Clojure noise over the last time period.  Clojure is interesting not just from a language perspective (Lisp) but from the few financial projects that have made the conferences over the last few years.  Although a niche language in many ways, it has a lot going for it, if like most things, you are prepared to invest a little time and effort.

What follows is my FX trading work in progress hack that will hopefully offer food for thought ;)

The main aim of the code hack was to get a simple FX currency pair tile in a browser built using ClojureScript, backed by a Clojure server.  Starting point for the project as lein-figwheel with Reagent.

Remember the code below (client followed by server code) has been hacked up, so ignore the hard coding et al.  The primary aim is as a learning tool, never to enter production :)

(ns ^:figwheel-always clojurefxtitle.core
    (:require
              [reagent.core :as reagent :refer [atom]]
              [clojurefxtitle.pricecomponent :as t]
    ))

(enable-console-print!)

(defonce app-state (atom {:text "FX Dashboard"
                        :counters {"USDGBP" {:id 1
                                             :name "USDGBP"}
                                   "USDEUR" {:id 2
                                             :name "USDEUR"}
                                   "USDJPY" {:id 3
                                             :name "USDJPY"}
                                  }
                          }))

(defn pricetitle-component []
  [:div
    ])


(defn fxtile [c]
  [:div {:style {:background "green" :width "300" :float "left" :border-style "solid"} }
    [:h1 {:style {:text-align "center" :margin "0" }} (:name c) ]
      [pricetitle-component]
        [:div
          [t/price-component (:name c)  "Buy"]
          [t/price-component (:name c)  "Sell"]
        ]
      ])

(defn dashboard []
  [:div {:style {:width "100%"} }
    (for [counter (vals (:counters @app-state))]
      ^{:key (:name counter)} [fxtile counter]
    )
  ]
)

(reagent/render-component [dashboard]
                          (. js/document (getElementById "app")))

(defn on-js-reload []
)

With the pricing component as per reference above, as follows:

(defn handler [response]
  (println "handler: " (str response))
)

(defn error-handler  [{:keys [status status-text]}]
  (println "error handler: " (str "something bad happened: " status " " status-text))
)

(defn my-click-handler [ccypair side price]
  (println (str "order " ccypair " " side " " price))
  (POST "/order"
          {:params {:price price
                    :side side
                    :ccypair ccypair}
           :handler handler
           :format :json
           :error-handler error-handler})    
  )
  
(defn rand-price [val]
  (rand-nth val))

(defn price-component [ccypair side]
  (let [seconds-elapsed (atom 0)
       whole_number (range 95000 100000)]
    (fn []
      (js/setTimeout #(reset! seconds-elapsed (rand-price whole_number)) 1000)
;;      (js/setTimeout #(swap! seconds-elapsed inc) 1000)
      (let [price (/ @seconds-elapsed 1000)]
        [:button {:style {:background "red" :width "150" :float "left" :text-align "center"}
           :on-click #(my-click-handler ccypair side price)}
         side (gstring/format " %0.3f" price )])))
       )

Clearly the code is using atom’s, as one would expect. I had a few problems with the JSON web service “order” method, but ended up resolving the issue with cljs-ajax. Also using the ring server and handler to handle the routing.  Had a few issues with http-kit deserialisation of the request, but I think that was partly my own silliness.

(ns server
  (:require
   [ring.middleware.resource :refer [wrap-resource]]
   [ring.middleware.json :as middleware]
   [ring.middleware.file-info :refer [wrap-file-info]]
   [ring.util.response :refer [redirect]]
   [compojure.handler :as handler]
   [compojure.core :refer :all]
   [compojure.route :as route]
   ))

(defn handler [request]
  (case (request :uri)
    "/" (redirect "index.html")
  )
)

(defn order-handler [req]
;;  (let [body (-> req :body)]
;;    (println "Request: " req " Body: " body)
;;  )
  (let [price (-> req :params :price)
    ccypair (-> req :params :ccypair)
    side (-> req :params :side)]
      (println (str "Order: " price side ccypair)) 
  )
  
  {:status 200 }
)  
     
(defroutes app-routes
  (GET "/" [] (redirect "index.html"))
  (POST "/order" [] order-handler) 
  (route/not-found "<h1>Custom - Page not found</h1>"))
  
(def app
  (-> (handler/api app-routes)
      (middleware/wrap-json-params)
      (middleware/wrap-json-response)))

Items to work on next:

  • Moving the simply price generator to the Clojure server, and streaming the prices via Websockets – possible using chord or Sente.
  • Look at agents for the server.  Avout and onyx also look interesting.
  • Dependency injection (e.g. clj-di) and MVC would be nice client side.

Summer Finance Tech Coding – Neo4j, Clojure/Om and Spark

•July 15, 2015 • Leave a Comment

I’m playing with a number of different technologies at the moment.  Mostly extensions of ideas I’ve previously blogged about.

  • Timelines and Neo4j
    • Specifically I’m interested in modelling the trade lifecycle in Neo4j (as discussed here) and also Skill Cloud (here) and avoiding the “current” view graphs that most applications/samples use.  Primarily leveraging ES6 code with Seraph as I’m not concerned about performance for this prototype.
    • There are a few interesting references documents that are worth a read:
      • Representing time dependent graphs in Neo4j
      • Time-Based Versioned Graphs – Ian’s solutions is quite clear in that it primarily leverages properties on relationships:

Each relationship has a from property with a long millisecond value representing 1 January 2014, and a to property with a very large long value (End-Of-Time, or EOT, which is a magic number – in this case Long.MAX_VALUE) that effectively means there is no current upper bound to the period associated with the relationship.

  • Spark
  • Clojure
    • Om Next – David Nolen presentation has rekindled my interested in ClojureScript.  Push Technologies offer a simple but FX bias demo of ClojureScript streaming prices – although not overly complex the demo does offer food for though with regards to Clojure in the electronic trading space. “Brandon Bloom – Building CircleCI’s Front end With Om” provide some insight into the challenges of an Om project.  Deployment to production is offered by lein-ring, IDE of choice is Cursive.  Clojure compiling to the JVM should avoid a degree of issues in the corporate space.

ES6 and Visual Studio Code

•July 10, 2015 • Leave a Comment

The July update of Visual Studio Code finally offer some sense in the ES6 world.  Add in a jsconfig.json to the root folder of your project, and at a minimum add the following to the file:

{
     "compilerOptions": {
          "target": "ES6"
     }
}

Post-Trade Blockchain

•July 6, 2015 • Leave a Comment

BNP Paribas Quintessence  provide an interesting view on how Blockchain could affect the post-trade world:

  1. Distributed blockchain system allowing all market participants direct access to the DSD (Decentralised Securities Depositary), to the exchange and to the post trade infrastructure (clearing & settlement)
  2. Standardised post trade integration – custodians or settlement infrastructures might use the blockchain to record the ownership and trades between themselves.

The BNP Paribas comments come at a time when Nasdaq is also trailing blockchain around trade ledger processing.   Its probably also worth watching what comes out of Digital Assets.

Start Writing in ES6

•June 30, 2015 • Leave a Comment

Good advice from “Preparing for the future of AngularJS”, even if you have no interest in Angular 2.0.  My current transpiler of choice is Babel for no reason other than a colleague recommended it.  There are others, so choose and play.

As more of an FYI, Babel also has experimental support for ES7 proposals.

Roslyn, LLILC and WebAssembly?

•June 29, 2015 • Leave a Comment

Given Joe Duffy’s blog is so quite these days, its time to speculate.

The LLILC announcement some months ago is interesting – a continued openness from Microsoft.  The main difference between Roslyn and LLILC, as provided by LLILC github is:

Roslyn provides frontend support, whilst LLILC (via LLVM) provides backend support:

Roslyn exposes the data structures of a frontend – so it’s ideal for building tools such as IDEs, with syntax coloring, warning squiggles, use/definition lookup, refactoring, etc; or translators that convert C# to some other language; or pretty-print formatters; or analyzers that check conformance with coding guidelines (think FxCop).

LLILC, via LLVM, exposes the data structures of a backend – so it’s ideal for building tools that inject extra code (eg: performance profiler, code tracer, debugger, parallelism analyzer, race detector); or super-optimizing code (eg: auto-vectorizer, auto-parallelizer); or test-case reduction.

The key in the above is the reference to LLVM, especially if you read “From ASM.JS to WebAssembly“, and then you read “WebAssembly LLVM Backend Being Discussed”.

Further, Brendan Eich’s recent interview on WebAssembly provides us with this:

Microsoft has their own compiler so they’ll be doing wasm from a different compiler framework, but that’s great.

Given the LLILC work, it would be logically to leverage the LLVM to generate wasm

Interesting times.

Polyglot Lambda Architecture

•June 29, 2015 • Leave a Comment

OTTO has a number of great postings on the work they are doing.  One of the most recent articles is “A tale of two lambdas: The joys of working in a polyglot team.” which speaks volumes to using the right language for the problem you are trying to solve.  Spark has really helped to move the lambda concept forwards in the last time period.  Would also agree with OTT on  Elasticsearch – ELK.  Personally not used Graphite, but it does look interesting.

On MLlib, I’ve previously blogged about success with trading research/idea recommendations.  Its also worth calling out that Logisitic Regression algorithm is very useful in finding relationship from binary response variables – an example in the trading world is the age old classic RFQ reject/accept.

 
Follow

Get every new post delivered to your Inbox.

Join 692 other followers