From 968c4aeeebe42a574a622b955d0c981ea6b5dc36 Mon Sep 17 00:00:00 2001 From: niten Date: Tue, 21 Jun 2022 17:59:33 -0700 Subject: [PATCH] Allow non-USD markets, but default to USD. --- flake.nix | 1 + src/coinbase_pro/client.clj | 66 +++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/flake.nix b/flake.nix index 945444c..55ae5c8 100644 --- a/flake.nix +++ b/flake.nix @@ -25,6 +25,7 @@ name = "org.fudo/coinbase-pro.client"; main-ns = "coinbase-pro.client.core"; jdkRunner = pkgs.jdk17_headless; + version = "0.1"; }; }; diff --git a/src/coinbase_pro/client.clj b/src/coinbase_pro/client.clj index ac48af8..46eddab 100644 --- a/src/coinbase_pro/client.clj +++ b/src/coinbase_pro/client.clj @@ -77,17 +77,19 @@ (def lower-case-keyword (comp keyword str/lower-case)) -(defn- currency-product [currency] +(defn- currency-product [base currency] (str (-> currency name str/upper-case) - "-USD")) + "-" + base)) -(defn- product-currency [product] - (if-let [currency (some-> (re-matches #"^([A-Z]{2,5})-USD$" product) - (get 1) - (lower-case-keyword))] - currency - (throw (ex-info (str "not a valid product_id: " product) - {:product product})))) +(defn- product-currency [base product] + (let [product-rx (re-pattern (format "^([A-Z]{2,5})-%s$" base))] + (if-let [currency (some-> (re-matches product-rx product) + (get 1) + (lower-case-keyword))] + currency + (throw (ex-info (str "not a valid product_id: " product) + {:product product}))))) (defn- accounts-request [] (-> (req/base-request) @@ -112,12 +114,12 @@ (req/with-path (build-path :orders order-id)))) (defn- currency-orders-request - ([currency] (currency-orders-request currency {})) - ([currency query] (-> (req/base-request) - (req/as-get); - (req/with-path (build-path :orders)) - (req/with-query-params - (merge query { :product_id (currency-product currency) }))))) + ([base currency] (currency-orders-request currency {})) + ([base currency query] (-> (req/base-request) + (req/as-get); + (req/with-path (build-path :orders)) + (req/with-query-params + (merge query { :product_id (currency-product base currency) }))))) (defn- create-order-request [order] (-> (req/base-request) @@ -128,11 +130,11 @@ :args (s/cat :params ::order-req/order) :ret ::req/request) -(defn- ticker-request [currency] +(defn- ticker-request [base currency] (-> (req/base-request) (req/as-get) (req/with-path (build-path :products - (currency-product currency) + (currency-product base currency) :ticker)))) (defn- ensure-keys [ks m] @@ -186,11 +188,12 @@ (defn- reify-exchange-client [{client ::http/client hostname ::hostname - logger ::log/logger}] + logger ::log/logger + base ::base-currency}] (let [request! (fn [req] (http/execute-request! client (req/with-host req hostname)))] (reify client/ExchangeClient (get-ticker! [_ currency] - (map-success (request! (ticker-request currency)) + (map-success (request! (ticker-request base currency)) (partial reify-ticker currency))) (get-market-price! [self currency] (map-success (client/get-ticker! self currency) @@ -199,10 +202,12 @@ (defn- reify-exchange-account-client [opts] (let [{client ::http/client hostname ::hostname - logger ::log/logger} opts + logger ::log/logger + base ::base-currency} opts public-client (reify-exchange-client opts) request! (fn [req] (http/execute-request! client (req/with-host req hostname))) before (fn [a b] (.isBefore a b)) + reify-order (partial reify-order base) reify-orders (comp (partial sort-by order/created before) (partial map reify-order)) accounts-map (fn [accts] (into {} (map (juxt acct/currency identity) accts)))] @@ -231,15 +236,17 @@ reify-order)) (get-orders! [_ currency] - (map-success (request! (currency-orders-request currency)) + (map-success (request! (currency-orders-request base currency)) reify-orders)) (get-incomplete-orders! [_ currency] - (map-success (request! (currency-orders-request currency { ::order/status [:open :pending] })) + (map-success (request! (currency-orders-request base currency + { ::order/status [:open :pending] })) reify-orders)) (get-completed-orders! [_ currency] - (map-success (request! (currency-orders-request currency { ::order/status [:done] })) + (map-success (request! (currency-orders-request base currency + { ::order/status [:done] })) reify-orders)) (get-completed-limit-orders! [self currency] @@ -259,21 +266,21 @@ to-uuid)) (create-stop-loss-order! [_ currency stop-price sell-price size] - (map-success (request! (create-order-request (-> (order-req/base-order (currency-product currency)) + (map-success (request! (create-order-request (-> (order-req/base-order (currency-product base currency)) (order-req/as-stop-loss (bigdec stop-price)) (order-req/with-price (bigdec sell-price)) (order-req/with-size (bigdec size))))) (comp to-uuid :id))) (create-stop-gain-order! [_ currency stop-price buy-price size] - (map-success (request! (create-order-request (-> (order-req/base-order (currency-product currency)) + (map-success (request! (create-order-request (-> (order-req/base-order (currency-product base currency)) (order-req/as-stop-gain (bigdec stop-price)) (order-req/with-price (bigdec buy-price)) (order-req/with-size (bigdec size))))) (comp to-uuid :id))) (create-limit-sell-order! [_ currency sell-price size] - (map-success (request! (create-order-request (-> (order-req/base-order (currency-product currency)) + (map-success (request! (create-order-request (-> (order-req/base-order (currency-product base currency)) (order-req/as-limit) (order-req/as-sell) (order-req/with-price (bigdec sell-price)) @@ -281,15 +288,16 @@ (comp to-uuid :id))) (create-limit-buy-order! [_ currency buy-price size] - (map-success (request! (create-order-request (-> (order-req/base-order (currency-product currency)) + (map-success (request! (create-order-request (-> (order-req/base-order (currency-product base currency)) (order-req/as-limit) (order-req/as-buy) (order-req/with-price (bigdec buy-price)) (order-req/with-size (bigdec size))))) (comp to-uuid :id)))))) -(defn connect [& {:keys [hostname logger credentials] - :or { logger (log/print-logger :error :notify) }}] +(defn connect [& {:keys [hostname logger credentials base-currency] + :or { logger (log/print-logger :error :notify) + base-currency "USD"}}] (if credentials (let [authenticator (make-request-authenticator credentials)] (reify-exchange-account-client {::http/client (http/json-client :authenticator authenticator