Skip to content

Commit

Permalink
working position eval
Browse files Browse the repository at this point in the history
  • Loading branch information
awb99 committed Jul 13, 2024
1 parent 68e1e6a commit 27cf370
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 68 deletions.
13 changes: 1 addition & 12 deletions lib/trade/src/quanta/quote/random.clj
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,14 @@
; shutdown
(println "stop generating quotes for: " asset)
(swap! subscription-a disj asset)
(throw ex)
false))]
(if recur?
(recur (update-price p))
:unsubscribed
))))))


(def get-quote (memoize generate-quotes))

#_(defn get-quote [asset]
(let [quote (or (get @subscription-atom asset)
(start-subscription asset))]
(m/ap (try
(m/amb (m/?> quote))
(catch Cancelled _
(println "view cancelled for: " asset)
(stop-subscription asset))))))

(comment
(initial-price)
(update-price 100.0)
Expand All @@ -73,7 +62,7 @@
(defn print-quotes [& quotes]
(print-table [:asset :last :date] quotes))

(let [assets ["BTC" "ETH" "EURUSD" "QQQ"]
(let [assets ["BTC" "ETH" "EURUSD" "QQQ" "EURUSD"]
quotes (map get-quote assets)]
(m/? (m/reduce (constantly nil)
(apply m/latest print-quotes quotes))))
Expand Down
38 changes: 38 additions & 0 deletions lib/trade/src/quanta/trade/position/exit.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
(ns quanta.trade.position.exit)

(defn get-exit-rule [algo-opts rule-kw]
(let [{:keys [exit]} algo-opts
rule (->> exit
(partition 2)
(filter (fn [[rule rule-opts]]
(= rule rule-kw)))
first)]
(when rule
(into [] rule))))

(comment
(get-exit-rule {:exit [:profit 2.0
:loss 0.3
:time 1]}
:time)
;; => [:time 1]

(get-exit-rule {:exit [:profit 2.0
:loss 0.3]}
:time)
;; => nil

(get-exit-rule {:exit [:profit 2.0
:loss 0.3]}
:profit)
;; => [:profit 2.0]

(get-exit-rule {:exit [:profit 2.0
:loss 0.3]}
:loss)
;; => [:loss 0.3]

;
)


29 changes: 29 additions & 0 deletions lib/trade/src/quanta/trade/position/exit/price.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
(ns quanta.trade.position.exit.price
(:require
[tick.core :as t]
[missionary.core :as m]
[quanta.trade.position.exit :refer [get-exit-rule]]))





(defn get-exit-profit [algo-opts position]
(let [{:keys [calendar]} algo-opts
[exchange-kw interval-kw] calendar
bars (get-time-bars algo-opts)]
(when bars
(let [cal-seq (calendar-seq exchange-kw interval-kw entry-date)
window (take bars cal-seq)]
#_{:start (first window)
:end (last window)}
(last window)))))

(defn profit-trigger [exit-time]
(let [exit-long (-> exit-time t/instant t/long)
now-long (-> t/instant t/long)
diff-ms (* 1000 (- exit-long now-long))
diff-ms (max diff-ms 1)]
(m/sleep diff-ms :time)))


24 changes: 4 additions & 20 deletions lib/trade/src/quanta/trade/position/exit/time.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,9 @@
(:require
[tick.core :as t]
[missionary.core :as m]
[ta.calendar.core :refer [calendar-seq]]))

(defn get-exit-rule [algo-opts]
(let [{:keys [exit]} algo-opts
rule (->> exit
(partition 2)
(filter (fn [[rule rule-opts]]
(= rule :time)))
first)]
(when rule
(into [] rule))))
[ta.calendar.core :refer [calendar-seq]]
[quanta.trade.position.exit :refer [get-exit-rule]]
))

(defn get-time-bars [algo-opts]
(let [[_ bars] (get-exit-rule algo-opts)]
Expand All @@ -38,15 +30,7 @@


(comment
(get-exit-rule {:exit [:profit 2.0
:loss 0.3
:time 1]})
;; => [:time 1]

(get-exit-rule {:exit [:profit 2.0
:loss 0.3]})
;; => nil



(get-exit-time {:calendar [:crypto :m]
:exit [:profit 2.0
Expand Down
79 changes: 78 additions & 1 deletion lib/trade/src/quanta/trade/position/working.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,81 @@
(ns quanta.trade.position.working)
(ns quanta.trade.position.working
(:require
[tick.core :as t]
[missionary.core :as m]
[quanta.quote.random :refer [get-quote]]
[quanta.trade.roundtrip :refer [return-prct return-abs return-log]])
(:import [missionary Cancelled]))

(defn value-position [position
{:keys [date last] :as quote}]
(println "value-position: " position " quote: " quote)
(let [roundtrip (assoc position
:exit-date date
:exit-price last)
abs-ret (return-abs roundtrip)]
(if quote
(assoc roundtrip
:ret-abs abs-ret
:ret-prct (return-prct roundtrip)
:ret-log (return-log roundtrip)
:win? (> abs-ret 0.0))
roundtrip)))

(defn calculate-position [position]
(m/ap
; startup
(println "start calculating position: " position)
(let [asset (:asset position)
quote (get-quote asset)
current-quote (m/?> quote)]
(value-position position current-quote))))

(comment
(require '[tick.core :as t])
(m/? (m/reduce println
(calculate-position {:asset "BTCUSDT"
:qty 500
:entry-price 1000.0
:entry-date (t/instant)})))

(def positions [{:asset "BTCUSDT"
:side :long
:qty 500
:entry-price 1000.0
:entry-date (t/instant)}
{:asset "BTCUSDT"
:side :short
:qty 500
:entry-price 1000.0
:entry-date (t/instant)}
{:asset "ETHUSDT"
:side :long
:qty 500
:entry-price 1000.0
:entry-date (t/instant)}
{:asset "ETHUSDT"
:side :short
:qty 500
:entry-price 1000.0
:entry-date (t/instant)}
])

(require '[clojure.pprint :refer [print-table]])
(defn print-positions [& positions]
(print-table [:asset :side
:exit-price
:ret-prct
:win?] positions))

(let [flows (map calculate-position positions)]
(m/?
(m/reduce (constantly nil)
(apply m/latest print-positions flows))))

;
)





37 changes: 37 additions & 0 deletions lib/trade/src/quanta/trade/roundtrip.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
(ns quanta.trade.roundtrip)


(defn- sign-switch [side v]
(case side
:long v
:short (- 0.0 v)
v))

(defn return-abs [{:keys [exit-price entry-price side] :as _roundtrip}]
(sign-switch side (- exit-price entry-price)))

(defn return-prct [{:keys [entry-price] :as roundtrip}]
(-> 100.0 (* (return-abs roundtrip) (/ entry-price))))

(defn return-log [{:keys [entry-price exit-price side] :as _roundtrip}]
(sign-switch side (- (Math/log10 exit-price) (Math/log10 entry-price))))

(defn set-exit-price-percent [{:keys [entry-price side] :as roundtrip} percent]
(let [m (+ 1.0 (/ (sign-switch side percent) 100.0))]
(assoc roundtrip :exit-price (* m entry-price))))

(comment

(return-abs {:entry-price 100.0 :exit-price 101.0 :side :long})
(return-prct {:entry-price 100.0 :exit-price 101.0 :side :long})
(return-log {:entry-price 100.0 :exit-price 101.0 :side :long})

(return-abs {:entry-price 100.0 :exit-price 101.0 :side :short})
(return-prct {:entry-price 100.0 :exit-price 101.0 :side :short})
(return-log {:entry-price 100.0 :exit-price 101.0 :side :short})

(set-exit-price-percent {:entry-price 100.0 :side :long} 5.0)
(set-exit-price-percent {:entry-price 100.0 :side :short} 5.0)

;
)
12 changes: 7 additions & 5 deletions lib/trade/src/ta/trade/backtest/exit.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(ns ta.trade.backtest.exit
(:require
[ta.trade.roundtrip.roundtrip :as rt]))
[ta.trade.roundtrip.roundtrip :as rt]
[quanta.trade.roundtrip :refer [return-prct set-exit-price-percent]]
))

(defn- create-exit [position rule row]
(assoc position
Expand Down Expand Up @@ -28,8 +30,8 @@
[[type profit-percent] position row]
(let [rt (assoc position :exit-price (extreme-profit-price position row))]
;(println "return-prct: " (rt/return-prct rt) "profit-target-prct: " profit-percent)
(when (>= (rt/return-prct rt) profit-percent)
(-> (rt/set-exit-price-percent position profit-percent)
(when (>= (return-prct rt) profit-percent)
(-> (set-exit-price-percent position profit-percent)
(create-exit type row)))))

(defn- extreme-loss-price [{:keys [_entry-price side] :as _roundtrip} row]
Expand All @@ -40,8 +42,8 @@
(defmethod exit :loss-percent
[[type loss-percent] position row]
(let [rt (assoc position :exit-price (extreme-loss-price position row))]
(when (<= (rt/return-prct rt) (- 0.0 loss-percent))
(-> (rt/set-exit-price-percent position (- 0.0 loss-percent))
(when (<= (return-prct rt) (- 0.0 loss-percent))
(-> (set-exit-price-percent position (- 0.0 loss-percent))
(create-exit type row)))))

; trailing stop loss is stateful.
Expand Down
34 changes: 4 additions & 30 deletions lib/trade/src/ta/trade/roundtrip/roundtrip.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,10 @@
(:require
[tech.v3.datatype :as dtype]
[tech.v3.datatype.functional :as dfn]
[tablecloth.api :as tc]))
[tablecloth.api :as tc]
[quanta.trade.roundtrip :refer [sign-switch]]
))

(defn- sign-switch [side v]
(case side
:long v
:short (- 0.0 v)
v))

(defn return-abs [{:keys [exit-price entry-price side] :as _roundtrip}]
(sign-switch side (- exit-price entry-price)))

(defn return-prct [{:keys [entry-price] :as roundtrip}]
(-> 100.0 (* (return-abs roundtrip) (/ entry-price))))

(defn return-log [{:keys [entry-price exit-price side] :as _roundtrip}]
(sign-switch side (- (Math/log10 exit-price) (Math/log10 entry-price))))

(defn set-exit-price-percent [{:keys [entry-price side] :as roundtrip} percent]
(let [m (+ 1.0 (/ (sign-switch side percent) 100.0))]
(assoc roundtrip :exit-price (* m entry-price))))

(defn- adjust [val-vec side-vec]
(dtype/emap sign-switch :float64 side-vec val-vec))
Expand Down Expand Up @@ -57,17 +41,7 @@
:nav (dfn/+ (Math/log10 100.0) cum-ret-log)})))

(comment
(return-abs {:entry-price 100.0 :exit-price 101.0 :side :long})
(return-prct {:entry-price 100.0 :exit-price 101.0 :side :long})
(return-log {:entry-price 100.0 :exit-price 101.0 :side :long})

(return-abs {:entry-price 100.0 :exit-price 101.0 :side :short})
(return-prct {:entry-price 100.0 :exit-price 101.0 :side :short})
(return-log {:entry-price 100.0 :exit-price 101.0 :side :short})

(set-exit-price-percent {:entry-price 100.0 :side :long} 5.0)
(set-exit-price-percent {:entry-price 100.0 :side :short} 5.0)


(def ds
(tc/dataset {:side [:long :short :long :short]
:entry-idx [1 2 3 4]
Expand Down

0 comments on commit 27cf370

Please sign in to comment.