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