Last active
January 30, 2020 16:36
-
-
Save jjttjj/e63ba5a366961c314b40118edc548aed to your computer and use it in GitHub Desktop.
A draft of a time series query language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;The goal of this is to specify a query format which clients can use to request | |
;;time series data from a server. The two primary operations are `:seek`s, which | |
;;are database lookups, and `:calc`s which tell the server to calculate | |
;;something using a previous seek as an argument. The result of either a seek or | |
;;a calc can be either a vector of data points or a map of columns (column name | |
;;-> vector). | |
;;Queries are either maps of names to subqueries, or just a vector of | |
;;subqueries. In either case, the response mirrors the shape of the query, with | |
;;subqueries replaced with either a vector of data points, or a map of column | |
;;names to data points. | |
;;There are two types of "subqueries", which are indicated by metadata tags: | |
;;^:seek and ^:calc. Stored data is retrived with ^:seek and and calculations | |
;;can be made with ^:calc. Caculations are simliar to functions and can be | |
;;dependent on both retrieved data and/or other calculations. | |
;;A ^:seek vector has both a lookup map of arbitrary clojure data identifying a | |
;;series (presumably in a db somewhere), and a range map with a start/end time, | |
;;defining the time bounds of the data we want. ^:seek values are replaced with | |
;;their results (a vector of data or a map of columns). | |
;;A ^:calc vector as a keyword identifying a calculation, followed by any number | |
;;of arguemnts to that calculation. an argument can be anything serialzable by | |
;;transit, or a ^:ref vector, which denotes a path in the query. refs can "reach | |
;;into" results which are column maps to get a specific column | |
;;To limit results returned, :select [<paths to keep>] metadata can be placed on | |
;;the whole query, or ^:keep metadata can be placed on one or more | |
;;subqueries. Otherwise, all results are returned in a map or vector mirroring | |
;;the query. | |
(def range1 {:tick/beginning (t/- (t/zoned-date-time) #time/period "P100D") | |
:tick/end (t/zoned-date-time)}) | |
(def q1 | |
^{:select [:aapl :rel-ema]} | |
{:msft ^:seek [{:symbol "MSFT" :resolution "1 day"} range1] | |
:aapl ^:seek [{:symbol "AAPL" :resolution "1 day"} range1] | |
:relative ^:calc [:divide ^:ref [:msft :close] ^:ref [:aapl :close]] | |
:rel-ema ^:calc [:ema 20 ^:ref [:relative]]}) | |
(def q2 | |
[^:seek ^:keep [{:symbol "MSFT" :resolution "1 day"} range1] | |
^:seek [{:symbol "AAPL" :resolution "1 day"} range1] | |
^:calc [:divide ^:ref [0 :close] ^:ref [1 :close]] | |
^:calc ^:keep [:ema 20 ^:ref [2]]]) | |
(comment | |
(query db q1) | |
;;=> | |
{:aapl {:open [5,,,,] :high [7,,,,] :low [4,,,,] :close [6,,,,]} | |
:rel-ema [4 3 2,,,]} | |
(query db q2) | |
;;=> | |
[{:open [5,,,,] :high [7,,,,] :low [4,,,,] :close [6,,,,]} | |
[4 3 2,,,]]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment