Skip to content

Commit

Permalink
studio backtest working
Browse files Browse the repository at this point in the history
  • Loading branch information
awb99 committed Jul 2, 2024
1 parent e72a850 commit 615cd74
Show file tree
Hide file tree
Showing 30 changed files with 326 additions and 270 deletions.
8 changes: 8 additions & 0 deletions README-links.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ https://github.com/cgrand/xforms
;; ftp://ftp.nasdaqtrader.com/symboldirectory
;; ftp://nasdaqtrader.com/SymbolDirectory/nasdaqlisted.txt
;; ftp://nasdaqtrader.com/SymbolDirectory/otherlisted.txt



model
- calendar (add-calendar, set-calendar)
- cells

backtest / live interact with a model!!
4 changes: 2 additions & 2 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"./lib/helper/src"
"./lib/import/src"
"./lib/indicator/src"
"./lib/interact/src"
"./lib/studio/src"
"./lib/live/src"
"./lib/math/src"
"./lib/quote/src"
Expand All @@ -81,7 +81,7 @@
"./lib/helper/src"
"./lib/import/src"
"./lib/indicator/src"
"./lib/interact/src"
"./lib/studio/src"
"./lib/live/src"
"./lib/math/src"
"./lib/quote/src"
Expand Down
2 changes: 1 addition & 1 deletion lib/algo/deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{org.clojure/clojure {:mvn/version "1.11.3"}
ta/db {:local/root "../db" :deps/manifest :deps} ; bar-db
ta/calendar {:local/root "../calendar" :deps/manifest :deps}
ta/engine {:local/root "../engine" :deps/manifest :deps} ; engine (javelin) used by algo-env
ta/model {:local/root "../engine" :deps/manifest :deps} ; engine (javelin) used by algo-env
}
:aliases
{:test {:extra-paths ["test"]
Expand Down
6 changes: 3 additions & 3 deletions lib/algo/resources/quanta/notebook/algo_dummy.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns quanta.notebook.algo-dummy
(:require
[ta.calendar.core :as cal]
[quanta.model.protocol :as eng]
[quanta.model.protocol :as mp]
[ta.algo.env :as algo-env]
[ta.algo.backtest :refer [backtest-algo run-backtest]]))

Expand All @@ -23,11 +23,11 @@ algo

;; 2. test algo calculation

(def engine (algo-env/get-engine e))
(def engine (algo-env/get-model e))

engine

(eng/set-calendar! engine {:calendar [:us :d] :time :evening})
(mp/set-calendar! engine {:calendar [:us :d] :time :evening})

algo
@algo
Expand Down
41 changes: 6 additions & 35 deletions lib/algo/src/ta/algo/backtest.clj
Original file line number Diff line number Diff line change
@@ -1,44 +1,15 @@
(ns ta.algo.backtest
(:require
[tick.core :as t]
[taoensso.timbre :refer [trace debug info warn error]]
[ta.calendar.core :as cal]
[ta.calendar.combined :refer [combined-event-seq]]
[quanta.model.protocol :as eng]
[quanta.model.backtest :refer [fire-backtest-events]]
[ta.algo.env.protocol :as algo-env]
[ta.algo.env :as algo-env-impl]))

(defn- dt->event-seq [calendars dt]
(let [prior-dates (map (fn [[calendar-kw interval-kw]]
(cal/prior-close calendar-kw interval-kw dt))
calendars)
;prior-dates-sorted (sort prior-dates)
]
(map (fn [cal dt]
{:calendar cal :time dt}) calendars prior-dates)))

(defn- fire-calendar-events [engine window-or-dt]
(let [calendars (eng/active-calendars engine)
; 3 modes to create an event-seq
; a map represents a window
; a date represents the last date for all calendars
; no date represents the current time.
event-seq (if (map? window-or-dt)
(combined-event-seq calendars window-or-dt)
(dt->event-seq calendars (or window-or-dt
(-> (t/now)(t/in "UTC")))))
]
(info "backtesting: " window-or-dt " ..")
; fire calendar events
(doall (map #(eng/set-calendar! engine %) event-seq))
(info "backtesting window: " window-or-dt "finished!")))
[ta.algo.env :refer [create-env-javelin]]))

(defn backtest-algo
"runs an algo with data powered by bar-db.
returns the result of the strategy."
[bar-db algo-spec window-or-dt]
(let [env (algo-env-impl/create-env-javelin bar-db)
strategy (algo-env/add-algo env algo-spec)
engine (algo-env/get-engine env)]
(fire-calendar-events engine window-or-dt)
(let [env (create-env-javelin bar-db)
strategy (algo-env/add-algo env algo-spec)
model (algo-env/get-model env)]
(fire-backtest-events model window-or-dt)
strategy))
18 changes: 9 additions & 9 deletions lib/algo/src/ta/algo/env.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
(:require
[taoensso.timbre :refer [trace debug info warn error]]
[de.otto.nom.core :as nom]
[quanta.model.javelin :refer [create-engine-javelin]]
[quanta.model.javelin :refer [create-model-javelin]]
[quanta.model.ops :as ops]
[ta.algo.spec.ops :as spec-ops]
[ta.algo.env.protocol :as algo-env]))

(defrecord env [bar-db engine watcher]
(defrecord env [bar-db model watcher]
algo-env/algo-env
; cell
(get-bar-db [this]
(:bar-db this))
(get-engine [this]
(:engine this))
(get-model [this]
(:model this))
(set-watcher [this w]
(warn "setting watcher!")
(reset! (:watcher this) w))
(add-algo [this spec]
(let [e (algo-env/get-engine this)
(let [model (algo-env/get-model this)
ops (spec-ops/spec->ops this spec)]
(if (nom/anomaly? ops)
ops
Expand All @@ -27,14 +27,14 @@
(w spec)
(warn "no watcher set - cannot trigger it!!"))
(info "adding engine ops: " ops)
(ops/add-ops e ops)))))
(ops/add-ops model ops)))))

(remove-algo [this spec]
nil))

(defn create-env [bar-db engine]
(env. bar-db engine (atom nil)))
(defn create-env [bar-db model]
(env. bar-db model (atom nil)))

(defn create-env-javelin [bar-db]
(create-env bar-db (create-engine-javelin)))
(create-env bar-db (create-model-javelin)))

2 changes: 1 addition & 1 deletion lib/algo/src/ta/algo/env/protocol.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

(defprotocol algo-env
(get-bar-db [this])
(get-engine [this])
(get-model [this])
; algo
(set-watcher [this w])
(add-algo [this spec])
Expand Down
14 changes: 7 additions & 7 deletions lib/db/resources/quanta/notebook/bardb_performance_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
[ta.algo.env :as algo-env-impl]
[ta.algo.env.protocol :as algo-env]
;[ta.algo.backtest :refer [run-backtest]]
[quanta.model.protocol :as eng]
[quanta.model.protocol :as mp]
[ta.calendar.combined :refer [combined-event-seq]]))

(defn- duckdb-start [db-filename]
Expand Down Expand Up @@ -161,11 +161,11 @@
:algo 'notebook.playground.bardb.performance-test/secret})

(defn run-backtest [env window]
(let [engine (algo-env/get-engine env)
cals (eng/active-calendars engine)
(let [engine (algo-env/get-model env)
cals (mp/active-calendars engine)
event-seq (combined-event-seq window cals)]
(info "backtesting window: " window " ..")
(doall (map #(eng/set-calendar! engine %) event-seq))
(doall (map #(mp/set-calendar! engine %) event-seq))
(info "backtesting window: " window "finished!")
:backtest-finished))

Expand All @@ -187,16 +187,16 @@
(let [;bar-db (modular.system/system bar-db-kw)
env (algo-env-impl/create-env-javelin bar-db)
strategy (algo-env/add-algo env algo-spec)
engine (algo-env/get-engine env)
calendars (eng/active-calendars engine)
engine (algo-env/get-model env)
calendars (mp/active-calendars engine)
prior-dates (map (fn [[calendar-kw interval-kw]]
(cal/current-close calendar-kw interval-kw dt))
calendars)
;prior-dates-sorted (sort prior-dates)
event-seq (map (fn [cal dt]
{:calendar cal :time dt}) calendars prior-dates)]
(info "event-seq: " event-seq)
(doall (map #(eng/set-calendar! engine %) event-seq))
(doall (map #(mp/set-calendar! engine %) event-seq))
strategy))

(defn- exists-db? [path]
Expand Down
2 changes: 1 addition & 1 deletion lib/live/deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
org.pinkgorilla/modular {:mvn/version "0.2.56"}
io.github.clojure-quant/fix-engine {:git/sha "d25efeefd2db73dee622e826ae86248f74f38273"}
ta/calendar {:local/root "../calendar" :deps/manifest :deps}
ta/engine {:local/root "../engine" :deps/manifest :deps}
ta/model {:local/root "../engine" :deps/manifest :deps}
ta/db {:local/root "../db" :deps/manifest :deps}}
:aliases
{:test {:extra-paths ["test"]
Expand Down
4 changes: 2 additions & 2 deletions lib/live/src/ta/live/tickerplant.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
(:require
[taoensso.timbre :refer [trace debug info warn error]]
[manifold.stream :as s]
[ta.quote.quote-manager :as qm]
[ta.calendar.generator :as ct]
[ta.quote.quote-manager :as qm]
[quanta.model.protocol :as engine]
[ta.algo.env.protocol :as algo-env]
[ta.live.bar-generator :as bg]
Expand All @@ -13,7 +13,7 @@
(defn start-tickerplant [{:keys [algo-env quote-manager]}]
(assert quote-manager "tickerplant needs :quote-manager")
(assert algo-env "tickerplant needs :algo-env")
(let [eng (algo-env/get-engine algo-env)
(let [eng (algo-env/get-model algo-env)
quote-stream (qm/get-quote-stream quote-manager)
t (ct/create-live-calendar-time-generator)
b (bg/create-bar-generator quote-stream (algo-env/get-bar-db algo-env))
Expand Down
6 changes: 3 additions & 3 deletions lib/model/deps.edn
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{:paths ["src" "resources"]
:deps
{org.clojure/clojure {:mvn/version "1.11.3"}
hoplon/javelin {:mvn/version "3.9.3"}}
:deps {org.clojure/clojure {:mvn/version "1.11.3"}
hoplon/javelin {:mvn/version "3.9.3"}
ta/calendar {:local/root "../calendar" :deps/manifest :deps}}
:aliases
{:test {:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner {:git/url "https://github.com/cognitect-labs/test-runner.git"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
(ns quanta.notebook.engine-calendar
(ns quanta.notebook.model-calendar
(:require
[quanta.model.javelin.calendar :as ecal]
[quanta.model.javelin :as je]))

(def env (je/create-engine-javelin))
(def env (je/create-model-javelin))

env

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
(ns quanta.notebook.engine-direct
(ns quanta.notebook.model-direct
(:require
[quanta.model.javelin :refer [create-engine-javelin]]
[quanta.model.javelin :refer [create-model-javelin]]
[quanta.model.protocol :as p]))

(def e (create-engine-javelin))
(def e (create-model-javelin))

(def c (p/value-cell e 15))
@c
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(ns quanta.notebook.engine-javelin
(ns quanta.notebook.model-javelin
(:require
[de.otto.nom.core :as nom]
[javelin.core-clj :refer [cell cell=]]))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
(ns quanta.notebook.engine-ops
(ns quanta.notebook.model-ops
(:require
[quanta.model.javelin :refer [create-engine-javelin]]
[quanta.model.javelin :refer [create-model-javelin]]
[quanta.model.ops :refer [add-ops]]
[quanta.model.protocol :as p]))

(def e (create-engine-javelin))
(def e (create-model-javelin))

(defn time-as-map [t] {:time t})

Expand Down
33 changes: 33 additions & 0 deletions lib/model/src/quanta/model/backtest.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(ns quanta.model.backtest
(:require
[tick.core :as t]
[taoensso.timbre :refer [trace debug info warn error]]
[ta.calendar.core :as cal]
[ta.calendar.combined :refer [combined-event-seq]]
[quanta.model.protocol :as mp]))


(defn- dt->event-seq [calendars dt]
(let [prior-dates (map (fn [[calendar-kw interval-kw]]
(cal/prior-close calendar-kw interval-kw dt))
calendars)
;prior-dates-sorted (sort prior-dates)
]
(info "date event seq: " prior-dates)
(map (fn [cal dt]
{:calendar cal :time dt}) calendars prior-dates)))

(defn fire-backtest-events [model window-or-dt]
(let [calendars (mp/active-calendars model)
; 3 modes to create an event-seq
; a map represents a window
; a date represents the last date for all calendars
; no date represents the current time.
event-seq (if (map? window-or-dt)
(combined-event-seq calendars window-or-dt)
(dt->event-seq calendars (or window-or-dt
(-> (t/now) (t/in "UTC")))))]
(info "backtesting: " window-or-dt " ..")
; fire calendar events
(doall (map #(mp/set-calendar! model %) event-seq))
(info "backtesting window: " window-or-dt "finished!")))
10 changes: 5 additions & 5 deletions lib/model/src/quanta/model/javelin.clj
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
(ns quanta.model.javelin
(:require
[modular.system]
[quanta.model.protocol :refer [eng]]
[quanta.model.protocol :refer [model]]
[quanta.model.javelin.cell :as j-cell]
[quanta.model.javelin.calendar :as j-cal]))

(defrecord engine-javelin [calendars]
eng
(defrecord model-javelin [calendars]
model
; cell
(calendar-cell [this time-fn calendar]
(j-cell/calendar-cell this time-fn calendar))
Expand All @@ -26,6 +26,6 @@
(active-calendars [this]
(j-cal/active-calendars this)))

(defn create-engine-javelin []
(defn create-model-javelin []
(let [calendars (atom {})]
(engine-javelin. calendars)))
(model-javelin. calendars)))
14 changes: 7 additions & 7 deletions lib/model/src/quanta/model/javelin/calendar.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
[de.otto.nom.core :as nom]
[javelin.core-clj :refer [cell]]))

(defn create-calendar [env calendar]
(defn create-calendar [this calendar]
(assert (vector? calendar) "calendar needs to be [:market :interval]")
(info "creating calendar: " calendar)
(let [c (cell (nom/fail ::calendar {:calendar :not-initialized}))]
(swap! (:calendars env) assoc calendar c)
(swap! (:calendars this) assoc calendar c)
c))

(defn get-calendar [env calendar]
(or (get @(:calendars env) calendar)
(create-calendar env calendar)))
(defn get-calendar [this calendar]
(or (get @(:calendars this) calendar)
(create-calendar this calendar)))

(defn set-calendar! [env {:keys [calendar time]}]
(defn set-calendar! [this {:keys [calendar time]}]
(info "set-calendar! cal: " calendar " time: " time)
(let [c (get-calendar env calendar)]
(let [c (get-calendar this calendar)]
; we need to set time by calendar to env!!!!!
(reset! c time)))

Expand Down
Loading

0 comments on commit 615cd74

Please sign in to comment.