Phil Cooper / May 10 2023
Remix of XTDB Portfolio by Phil Cooper
Datascript Portfolio
This is to demonstrate a super small portfolio as seen in the XTDB Portfolio workbook page in Datascript
Before we get started, we'll start with a deps.edn that includes xtdb
{:deps
{org.clojure/clojure {:mvn/version "1.10.3"}
org.clojure/tools.deps.alpha
{:git/url "https://github.com/clojure/tools.deps.alpha.git"
:sha "e4fb92eef724fa39e29b39cc2b1a850567d490dd"}
compliment/compliment {:mvn/version "0.3.11"}
datascript/datascript {:mvn/version "1.4.2"}}}
Extensible Data Notation
(require [datascript.core :as d])
0.0s
Schema
need more info on schema usage. Unlike XTDB, in Datascript, we quire some sechema setup. This identifies attributes like :issuer
as references to other entities. In RDF terms that means another subject, in OO terms it means another object.
(def schema {:issuer {:db/valueType :db.type/ref :db/cardinality :db.cardinality/one}
:asset {:db/valueType :db.type/ref :db/cardinality :db.cardinality/one}
:holdings {:db/valueType :db.type/ref :db/cardinality :db.cardinality/many}})
(def conn (d/create-conn schema))
0.0s
This creates a utility to view portfolios at 4 asof valuation dates
Load up initial portfolio
(d/transact! conn
[ ;; add 3 companies
{:db/id ":company/t1", :name "IBM"}
{:db/id ":company/t2", :name "JP Morgan"}
{:db/id -100, :name "Ford"}
;; add 3 assets based on those companies
{:db/id ":security/t1",
:issuer ":company/t1" :ticker "IBM",
:type :Equity}
{:db/id ":security/t2",
:issuer ":company/t2" :ticker "JPM",
:type :Equity}
{:db/id ":security/t3",
:issuer -100 :ticker "F",
:type :Equity}
;; add 2 positions (portfolio unspecified)
{:db/id ":pm/p1", :asset ":security/t1", :quantity 100}
{:db/id ":pm/p2", :asset ":security/t2", :quantity 200}
;; add portfolio (with those 2 positions)
{:db/id ":p/p1",
:holdings [":pm/p1" ":pm/p2"],
:name "My Trading Portfolio"}])
0.6s
;; use pull syntax to get security info and issuer name
(d/q [:find (pull ?security ["*" {:issuer [:name]}])
:where [?security :ticker "F"]]
conn)
0.0s
(d/q [:find (pull ?h [:quantity {:asset [:ticker {:issuer [:name]}]}])
:where [?port :name "My Trading Portfolio"]
[?port :holdings ?h]]
conn)
0.1s
;; same info flattened
(d/q [:find ?t ?q ?n
:where [?port :name "My Trading Portfolio"]
[?port :holdings ?h]
[?h :quantity ?q]
[?h :asset ?a]
[?a :ticker ?t]
[?a :issuer ?c]
[?c :name ?n]]
conn)
0.1s
(->> (d/q [:find ?t ?q ?n
:where [?port :name "My Trading Portfolio"]
[?port :holdings ?h]
[?h :quantity ?q]
[?h :asset ?a]
[?a :ticker ?t]
[?a :issuer ?c]
[?c :name ?n]]
conn)
(apply map vector)
(map vector [:ticker :quantity :name])
(into {}))
0.0s