started to refactor code.
This commit is contained in:
1 parent
c5d4e83d44
commit
ed7f4ef668
5 files changed
+300
-111
No files matched your search
@@ -7,6 +7,7 @@
|
||||
[compojure.route :refer [not-found]]
|
||||
[skirmish.exchange-gateway.exchange-gateway :refer [create-routes-for-exchange]]
|
||||
[skirmish.rest.util :refer [build-response get-body cors-middleware]]
|
||||
[skirmish.ledger.data-layer :as data-layer]
|
||||
[skirmish.ledger.accounts]
|
||||
[datomic.api :as d]
|
||||
[taoensso.timbre :as timbre]
|
||||
@@ -17,86 +18,6 @@
|
||||
|
||||
;; the ledger is the central
|
||||
|
||||
|
||||
|
||||
(defn compute-simple-face-value [amount daily-interest-rate deposit-date value-date]
|
||||
(let [min-in-milliseconds (infix 60 * 1000)
|
||||
minute-interest-rate (infix daily-interest-rate / (24 * 60. * 10000.))
|
||||
ite (quot (- (. value-date getTime) (. deposit-date getTime)) min-in-milliseconds)
|
||||
base (infix 1 + minute-interest-rate)]
|
||||
(infix amount * base ** ite)))
|
||||
|
||||
(defn- in-interval? [[_ start end] x]
|
||||
(let [x-time (. x getTime)]
|
||||
(and (<= (. start getTime) x-time)
|
||||
(< x-time (. end getTime)))))
|
||||
|
||||
(defn- larger-then-interval? [[ _ start end] x]
|
||||
(and (<= (. x getTime) (. end getTime))
|
||||
(<= (. x getTime) (. start getTime))))
|
||||
|
||||
|
||||
(defn- split-interest-rate-intervals [interest-rates-intervals deposit-date value-date]
|
||||
(let [xf (comp (drop-while #((comp not in-interval?) % deposit-date))
|
||||
(take-while #((comp not larger-then-interval?) % value-date)))
|
||||
ret (into [] xf interest-rates-intervals)
|
||||
ret (assoc-in ret [0 1] deposit-date)
|
||||
ret (assoc-in ret [(-> ret count dec) 2] value-date)]
|
||||
ret))
|
||||
|
||||
(defn- find-interest-rate-for [interest-rates-intervals d]
|
||||
(if (in-interval? (first interest-rates-intervals) d)
|
||||
(ffirst interest-rates-intervals)
|
||||
(recur (rest interest-rates-intervals) d)))
|
||||
|
||||
|
||||
(defn split-interest-rates [interest-rates deposit-date value-date]
|
||||
(let [interest-rates (into [[0 (new java.util.Date 0)]] interest-rates)
|
||||
interest-rates (conj interest-rates [0 (new java.util.Date Long/MAX_VALUE)])
|
||||
interest-rates-intervals (partition 2 1 interest-rates)
|
||||
interest-rates-intervals (map (juxt ffirst (comp second first) (comp second second)) interest-rates-intervals)]
|
||||
(if (= deposit-date value-date)
|
||||
[[(find-interest-rate-for interest-rates-intervals deposit-date) deposit-date value-date]]
|
||||
(split-interest-rate-intervals interest-rates-intervals deposit-date value-date))))
|
||||
|
||||
(defn compute-face-value [amount interest-rates deposit-date value-date]
|
||||
(loop [interest-rates (split-interest-rates interest-rates deposit-date value-date)
|
||||
amount amount]
|
||||
(let [[interest-rate start end] (first interest-rates)
|
||||
amount (compute-simple-face-value amount interest-rate start end)]
|
||||
(if (empty? (rest interest-rates))
|
||||
(long amount)
|
||||
(recur (rest interest-rates) amount)))))
|
||||
|
||||
(defn get-interest-rate-history [db sec-id]
|
||||
(let [history (d/history db)
|
||||
interest-rates (d/q '[:find ?interest-rate ?v
|
||||
:in $ ?eid
|
||||
:where [?e :skirmish.security/interest-rate ?interest-rate ?tx]
|
||||
[?e :skirmish.security/sec-id ?sec-id]
|
||||
[?tx :db/txInstant ?v]]
|
||||
history sec-id)]
|
||||
(sort-by second interest-rates)))
|
||||
|
||||
(defn compute-face-value-from-db [db amount sec-id date]
|
||||
(compute-face-value amount
|
||||
(get-interest-rate-history db sec-id)
|
||||
date
|
||||
(new java.util.Date)))
|
||||
|
||||
(defn get-amount-in-account [db account-id]
|
||||
(let [[amount sec-id pk date] (d/q '[:find [?amount ?sec-id ?pk ?v]
|
||||
:in $ ?account-id
|
||||
:where [?e :skirmish.ledger/owner-public-key ?account-id]
|
||||
[?e :skirmish.ledger/amount ?amount ?tx]
|
||||
[?e :skirmish.ledger/sec ?sec]
|
||||
[?sec :skirmish.security/sec-id ?sec-id]
|
||||
[?e :skirmish.ledger/owner-public-key ?pk]
|
||||
[?tx :db/txInstant ?v]] db account-id)]
|
||||
{:amount (when (some? sec-id) (compute-face-value-from-db db amount sec-id date))
|
||||
:sec-id sec-id
|
||||
:account-public-key pk}))
|
||||
|
||||
;; an :account-id is the public key of a
|
||||
;; an :account-secret is an :account-id private key
|
||||
|
||||
@@ -114,7 +35,7 @@
|
||||
"Returns the value of an account."
|
||||
(fn [{{account-id :account-id} :route-params :as request}]
|
||||
(let [db (d/db conn)
|
||||
account-info (get-amount-in-account db account-id)]
|
||||
account-info (data-layer/get-amount-in-account db account-id)]
|
||||
(get-account-body request account-info))))
|
||||
|
||||
(s/def ::transaction (s/cat :type #{:transfer-immediately}
|
||||
@@ -152,7 +73,7 @@
|
||||
name :skirmish.security/name
|
||||
number-of-decimal :skirmish.security/number-of-decimal
|
||||
type_ :skirmish.security/type} e
|
||||
interest-rate-history (get-interest-rate-history db id)
|
||||
interest-rate-history (data-layer/get-interest-rate-history db id)
|
||||
volumes (d/q '[:find ?amount ?date
|
||||
:in $ ?id
|
||||
:where [?e :skirmish.ledger/sec ?id]
|
||||
@@ -160,7 +81,7 @@
|
||||
[?tx :db/txInstant ?date]]
|
||||
db id)
|
||||
now (new java.util.Date)
|
||||
volume (reduce + 0 (map #(compute-face-value (first %) interest-rate-history (second %) now) volumes))]
|
||||
volume (reduce + 0 (map #(data-layer/compute-face-value (first %) interest-rate-history (second %) now) volumes))]
|
||||
{:sec-id sec-id
|
||||
:interest-rate interest-rate
|
||||
:volume (or volume 0)
|
||||
@@ -184,7 +105,7 @@
|
||||
(fn [{body :body :as request}]
|
||||
(try+
|
||||
(let [[sec-id interest-rate] (-> body get-body get-new-security)
|
||||
new-sec @(d/transact conn [[:skirmish.ledger/create-security sec-id interest-rate]])]
|
||||
new-sec @(data-layer/create-security conn sec-id interest-rate)]
|
||||
(build-response request {:body {:success true}
|
||||
:headers {"location" (str "/api/1" "/ledger/securities/" (name sec-id))}}))
|
||||
(catch [:error-type :4XX] e (build-response request e))
|
||||
@@ -219,7 +140,8 @@
|
||||
|
||||
(defn get-available-securities [conn]
|
||||
(fn [request]
|
||||
(let [securities (d/q '[:find ?s :where [?e :skirmish.security/sec-id ?s]] (d/db conn))]
|
||||
(let [db (d/db conn)
|
||||
securities (data-layer/get-all-securities-id db)]
|
||||
(build-response request (get-available-securities-body securities)))))
|
||||
|
||||
|
||||
@@ -259,8 +181,8 @@
|
||||
|
||||
(defn get-available-accounts [conn]
|
||||
(fn [request]
|
||||
(let [securities (d/q '[:find ?pk :where [?e :skirmish.ledger/owner-public-key ?pk]] (d/db conn))]
|
||||
(build-response request (get-available-accounts-body securities)))))
|
||||
(let [db (d/db conn)]
|
||||
(build-response request (get-available-accounts-body (data-layer/get-all-account-public-key db))))))
|
||||
|
||||
|
||||
(defn get-api-description [request]
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
(ns skirmish.ledger.data-layer
|
||||
(:require [datomic.api :as d]
|
||||
[infix.macros :refer [infix]]))
|
||||
|
||||
(defn get-all-account-public-key [db]
|
||||
(d/q '[:find ?pk :where [?e :skirmish.ledger/owner-public-key ?pk]] db))
|
||||
|
||||
(defn compute-simple-face-value [amount daily-interest-rate deposit-date value-date]
|
||||
(let [min-in-milliseconds (infix 60 * 1000)
|
||||
minute-interest-rate (infix daily-interest-rate / (24 * 60. * 10000.))
|
||||
ite (quot (- (. value-date getTime) (. deposit-date getTime)) min-in-milliseconds)
|
||||
base (infix 1 + minute-interest-rate)]
|
||||
(infix amount * base ** ite)))
|
||||
|
||||
(defn- in-interval? [[_ start end] x]
|
||||
(let [x-time (. x getTime)]
|
||||
(and (<= (. start getTime) x-time)
|
||||
(< x-time (. end getTime)))))
|
||||
|
||||
(defn- larger-then-interval? [[ _ start end] x]
|
||||
(and (<= (. x getTime) (. end getTime))
|
||||
(<= (. x getTime) (. start getTime))))
|
||||
|
||||
(defn- split-interest-rate-intervals [interest-rates-intervals deposit-date value-date]
|
||||
(let [xf (comp (drop-while #((comp not in-interval?) % deposit-date))
|
||||
(take-while #((comp not larger-then-interval?) % value-date)))
|
||||
ret (into [] xf interest-rates-intervals)
|
||||
ret (assoc-in ret [0 1] deposit-date)
|
||||
ret (assoc-in ret [(-> ret count dec) 2] value-date)]
|
||||
ret))
|
||||
|
||||
(defn- find-interest-rate-for [interest-rates-intervals d]
|
||||
(if (in-interval? (first interest-rates-intervals) d)
|
||||
(ffirst interest-rates-intervals)
|
||||
(recur (rest interest-rates-intervals) d)))
|
||||
|
||||
(defn split-interest-rates [interest-rates deposit-date value-date]
|
||||
(let [interest-rates (into [[0 (new java.util.Date 0)]] interest-rates)
|
||||
interest-rates (conj interest-rates [0 (new java.util.Date Long/MAX_VALUE)])
|
||||
interest-rates-intervals (partition 2 1 interest-rates)
|
||||
interest-rates-intervals (map (juxt ffirst (comp second first) (comp second second)) interest-rates-intervals)]
|
||||
(if (= deposit-date value-date)
|
||||
[[(find-interest-rate-for interest-rates-intervals deposit-date) deposit-date value-date]]
|
||||
(split-interest-rate-intervals interest-rates-intervals deposit-date value-date))))
|
||||
|
||||
(defn compute-face-value [amount interest-rates deposit-date value-date]
|
||||
(loop [interest-rates (split-interest-rates interest-rates deposit-date value-date)
|
||||
amount amount]
|
||||
(let [[interest-rate start end] (first interest-rates)
|
||||
amount (compute-simple-face-value amount interest-rate start end)]
|
||||
(if (empty? (rest interest-rates))
|
||||
(long amount)
|
||||
(recur (rest interest-rates) amount)))))
|
||||
|
||||
(defn get-interest-rate-history [db sec-id]
|
||||
(let [history (d/history db)
|
||||
interest-rates (d/q '[:find ?interest-rate ?v
|
||||
:in $ ?eid
|
||||
:where [?e :skirmish.security/interest-rate ?interest-rate ?tx]
|
||||
[?e :skirmish.security/sec-id ?sec-id]
|
||||
[?tx :db/txInstant ?v]]
|
||||
history sec-id)]
|
||||
(sort-by second interest-rates)))
|
||||
|
||||
(defn compute-face-value-from-db [db amount sec-id date]
|
||||
(compute-face-value amount
|
||||
(get-interest-rate-history db sec-id)
|
||||
date
|
||||
(new java.util.Date)))
|
||||
|
||||
(defn get-amount-in-account [db account-id]
|
||||
(let [[amount sec-id pk date] (d/q '[:find [?amount ?sec-id ?pk ?v]
|
||||
:in $ ?account-id
|
||||
:where [?e :skirmish.ledger/owner-public-key ?account-id]
|
||||
[?e :skirmish.ledger/amount ?amount ?tx]
|
||||
[?e :skirmish.ledger/sec ?sec]
|
||||
[?sec :skirmish.security/sec-id ?sec-id]
|
||||
[?e :skirmish.ledger/owner-public-key ?pk]
|
||||
[?tx :db/txInstant ?v]] db account-id)]
|
||||
{:amount (when (some? sec-id) (compute-face-value-from-db db amount sec-id date))
|
||||
:sec-id sec-id
|
||||
:account-public-key pk}))
|
||||
|
||||
(defn get-all-securities-id [db]
|
||||
(d/q '[:find ?s :where [?e :skirmish.security/sec-id ?s]] db))
|
||||
|
||||
(defn create-security [conn sec-id interest-rate]
|
||||
(d/transact conn [[:skirmish.ledger/create-security sec-id interest-rate]]))
|
||||
@@ -0,0 +1,183 @@
|
||||
(ns skirmish.ledger.routes
|
||||
(:require [skirmish.rest.util :refer [build-response get-body cors-middleware]]
|
||||
[skirmish.ledger.data-layer :as data-layer]
|
||||
[skirmish.routes.core :as routes]
|
||||
[compojure.core :as compojure]
|
||||
[compojure.route :refer [not-found]]
|
||||
[clojure.spec.alpha :as s]
|
||||
[datomic.api :as d]
|
||||
[slingshot.slingshot :refer [try+ throw+]]))
|
||||
|
||||
|
||||
|
||||
(defn get-api-description [request]
|
||||
(let [body [{:url "ledger/accounts" :name "accounts"}
|
||||
{:url "ledger/securities" :name "securities"}]]
|
||||
(build-response request body)))
|
||||
|
||||
(defn get-available-accounts-body [accounts]
|
||||
(let [sec-id->url #(routes/get-path-for :ledger/account {:account-id (name %)})
|
||||
to-security-description #(hash-map :account-public-key % :url (sec-id->url %))
|
||||
xf (comp cat (map to-security-description))
|
||||
securities-info (sequence xf accounts)]
|
||||
{:accounts securities-info}))
|
||||
|
||||
|
||||
(defn get-available-accounts [conn]
|
||||
(fn [request]
|
||||
(let [db (d/db conn)
|
||||
resp (get-available-accounts-body (data-layer/get-all-account-public-key db))]
|
||||
(build-response request resp))))
|
||||
|
||||
(defn get-account-body [request {sec-id :sec-id amount :amount account-public-key :account-public-key}]
|
||||
(if (nil? sec-id)
|
||||
(build-response request {:status 404})
|
||||
(let [sec-url (str "/api/1/ledger/securities/" (name sec-id))
|
||||
beautify-account { :amount amount
|
||||
:sec-id sec-id
|
||||
:account-public-key account-public-key}
|
||||
ret {:account beautify-account :sec-url sec-url}]
|
||||
(build-response request ret))))
|
||||
|
||||
(defn get-account [conn]
|
||||
"Returns the value of an account."
|
||||
(fn [{{account-id :account-id} :route-params :as request}]
|
||||
(let [db (d/db conn)
|
||||
account-info (data-layer/get-amount-in-account db account-id)]
|
||||
(get-account-body request account-info))))
|
||||
|
||||
(defn get-account [conn]
|
||||
"Returns the value of an account."
|
||||
(fn [{{account-id :account-id} :route-params :as request}]
|
||||
(let [db (d/db conn)
|
||||
account-info (data-layer/get-amount-in-account db account-id)]
|
||||
(get-account-body request account-info))))
|
||||
|
||||
(defn get-transactions [conn]
|
||||
(fn [request]
|
||||
(let [all-pending-transactions []]
|
||||
(build-response request all-pending-transactions))))
|
||||
|
||||
(defn create-transactions [conn]
|
||||
(fn [{body :body :as request}]
|
||||
(try+
|
||||
(build-response request {:message "merci beaucoup"})
|
||||
(catch [:error-type :4XX] e (build-response request e))
|
||||
(catch [:error-type :5XX] e (build-response request e)))))
|
||||
|
||||
(defn get-available-securities-body [securities]
|
||||
(let [sec-id->url #(routes/get-path-for :ledger/security {:sec-id (name %)})
|
||||
to-security-description #(hash-map :sec-id % :url (sec-id->url %))
|
||||
xf (comp cat (map to-security-description))
|
||||
securities-info (sequence xf securities)];;
|
||||
{:securities securities-info}))
|
||||
|
||||
|
||||
(defn get-available-securities [conn]
|
||||
(fn [request]
|
||||
(let [db (d/db conn)
|
||||
securities (data-layer/get-all-securities-id db)]
|
||||
(build-response request (get-available-securities-body securities)))))
|
||||
|
||||
(defn get-new-security [raw-securities]
|
||||
(if (s/valid? :skirmish.ledger.core/security raw-securities)
|
||||
raw-securities
|
||||
(throw+ {:error-type :4XX :status 400 :body {:error "Invalid security format."}})))
|
||||
|
||||
(defn create-security [conn]
|
||||
"Create a fresh new security."
|
||||
(fn [{body :body :as request}]
|
||||
(try+
|
||||
(let [[sec-id interest-rate] (-> body get-body get-new-security)
|
||||
new-sec @(data-layer/create-security conn sec-id interest-rate)]
|
||||
(build-response request {:body {:success true}
|
||||
:headers {"location" (str "/api/1" "/ledger/securities/" (name sec-id))}}))
|
||||
(catch [:error-type :4XX] e (build-response request e))
|
||||
(catch [:error-type :5XX] e (build-response request e)))))
|
||||
|
||||
|
||||
(defn prettify-security [e db]
|
||||
(let [{interest-rate :skirmish.security/interest-rate
|
||||
description :skirmish.security/description
|
||||
id :db/id
|
||||
sec-id :skirmish.security/sec-id
|
||||
symbol :skirmish.security/symbol
|
||||
name :skirmish.security/name
|
||||
number-of-decimal :skirmish.security/number-of-decimal
|
||||
type_ :skirmish.security/type} e
|
||||
interest-rate-history (data-layer/get-interest-rate-history db id)
|
||||
volumes (d/q '[:find ?amount ?date
|
||||
:in $ ?id
|
||||
:where [?e :skirmish.ledger/sec ?id]
|
||||
[?e :skirmish.ledger/amount ?amount ?tx]
|
||||
[?tx :db/txInstant ?date]]
|
||||
db id)
|
||||
now (new java.util.Date)
|
||||
volume (reduce + 0 (map #(data-layer/compute-face-value (first %) interest-rate-history (second %) now) volumes))]
|
||||
{:sec-id sec-id
|
||||
:interest-rate interest-rate
|
||||
:volume (or volume 0)
|
||||
:name name
|
||||
:interest-rate-history interest-rate-history
|
||||
:symbol symbol
|
||||
:number-of-decimal number-of-decimal
|
||||
:type type_
|
||||
:description description}))
|
||||
|
||||
(defn get-security-from-db [conn sec-id]
|
||||
(let [db (d/db conn)
|
||||
e (d/pull db '[*] [:skirmish.security/sec-id sec-id])]
|
||||
(if (-> e :db/id nil?)
|
||||
(throw+ {:error-type :4XX :status 404 :body {:error "Security not found."}})
|
||||
(prettify-security e db))))
|
||||
|
||||
(defn get-security [conn]
|
||||
"Returns the security."
|
||||
(fn [{{sec-id-str :sec-id} :route-params :as request}]
|
||||
(try+
|
||||
(let [sec-id (keyword sec-id-str)]
|
||||
(build-response request (get-security-from-db conn sec-id)))
|
||||
(catch [:error-type :4XX] e (build-response request e))
|
||||
(catch [:error-type :5XX] e (build-response request e)))))
|
||||
|
||||
(defn update-security [conn]
|
||||
"Update a security with new features."
|
||||
(fn [request]
|
||||
(try+
|
||||
(catch [:error-type :4XX] e (build-response request e))
|
||||
(catch [:error-type :5XX] e (build-response request e)))))
|
||||
|
||||
(defn get-emit-securities-request [[amount account] sec-id]
|
||||
(if (s/valid? :skirmish.ledger.core/emit-securities [sec-id amount account])
|
||||
[:skirmish.ledger/emit-securities sec-id amount account]
|
||||
(throw+ {:error-type :4XX :status 400 :body {:error "Invalid emit request."}})))
|
||||
|
||||
|
||||
(defn emit-securities [conn]
|
||||
"Emit securities in the specified wallet. This is the only way to
|
||||
create securities.
|
||||
|
||||
payload
|
||||
[:amount :account]"
|
||||
(fn [{{sec-id-str :sec-id} :route-params body :body :as request}]
|
||||
(try+
|
||||
(let [emit-request (-> body get-body (get-emit-securities-request (keyword sec-id-str)))]
|
||||
@(d/transact conn [emit-request])
|
||||
(build-response request {}))
|
||||
(catch [:error-type :4XX] e (build-response request e))
|
||||
(catch [:error-type :5XX] e (build-response request e)))))
|
||||
|
||||
(defn create-routes-for-ledger [conn]
|
||||
(compojure/routes
|
||||
(routes/context :ledger []
|
||||
(routes/GET :ledger/home [] get-api-description)
|
||||
(routes/GET :ledger/accounts [] (get-available-accounts conn))
|
||||
(routes/GET :ledger/account [] (get-account conn))
|
||||
(routes/GET :ledger/transactions [] (get-transactions conn))
|
||||
(routes/POST :ledger/transactions [] (create-transactions conn))
|
||||
(routes/GET :ledger/securities [] (get-available-securities conn))
|
||||
(routes/POST :ledger/securities [] (create-security conn))
|
||||
(routes/GET :ledger/security [] (get-security conn))
|
||||
(routes/PUT :ledger/security [] (update-security conn))) ;; not done
|
||||
;(routes/POST :ledger/security [] (emit-securities conn))) ;; done
|
||||
(not-found "not found")))
|
||||
@@ -1,6 +0,0 @@
|
||||
(ns skirmish.ledger.core-test
|
||||
(:require [clojure.test :refer :all])
|
||||
(:require [skirmish.ledger.core :refer [get-amount-in-account]]))
|
||||
|
||||
(deftest get-amount-in-account-test)
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
(ns skirmish.ledger.test-core
|
||||
(:require [midje.sweet :refer :all]
|
||||
[datomic.api :as d]
|
||||
[clojure.edn]
|
||||
[skirmish.ledger.data-layer :as data-layer]
|
||||
[skirmish.ledger.accounts :refer [create-connection schema]]
|
||||
[skirmish.rest.util :refer [build-response]]
|
||||
[skirmish.ledger.core :refer :all]
|
||||
[skirmish.rest.util :refer [edn->stream]]
|
||||
[datomic.api :as d]
|
||||
[clojure.edn]
|
||||
[clojure.spec.alpha :as s]
|
||||
[infix.macros :refer [infix]]
|
||||
[skirmish.ledger.accounts :refer [create-connection schema]]))
|
||||
[infix.macros :refer [infix]]))
|
||||
|
||||
|
||||
(defn spec-check [spec]
|
||||
#(s/valid? spec %))
|
||||
@@ -208,11 +210,11 @@
|
||||
start #inst"2020-09-05T00:00:00.000-00:00"
|
||||
start+1d #inst"2020-09-06T00:00:00.000-00:00"
|
||||
start+2d #inst"2020-09-07T00:00:00.000-00:00"]
|
||||
(compute-simple-face-value amount interest-rate start start) => (roughly amount)
|
||||
(compute-simple-face-value amount interest-rate start start+1d) => (roughly 1105.1670808)
|
||||
(compute-simple-face-value amount interest-rate start start+2d) => (roughly 1221.3942766)
|
||||
(compute-simple-face-value amount negative-interest-rate start start+2d) => (roughly 818.7250672)
|
||||
(compute-simple-face-value amount 0 start start+2d) => (roughly amount)))
|
||||
(data-layer/compute-simple-face-value amount interest-rate start start) => (roughly amount)
|
||||
(data-layer/compute-simple-face-value amount interest-rate start start+1d) => (roughly 1105.1670808)
|
||||
(data-layer/compute-simple-face-value amount interest-rate start start+2d) => (roughly 1221.3942766)
|
||||
(data-layer/compute-simple-face-value amount negative-interest-rate start start+2d) => (roughly 818.7250672)
|
||||
(data-layer/compute-simple-face-value amount 0 start start+2d) => (roughly amount)))
|
||||
(fact "split-interest-rates"
|
||||
(let [d-1d #inst"2020-09-04T00:00:00.000-00:00"
|
||||
d-½d #inst"2020-09-04T12:00:00.000-00:00"
|
||||
@@ -225,11 +227,11 @@
|
||||
d+3d #inst"2020-09-08T00:00:00.000-00:00"
|
||||
d+3½d #inst"2020-09-08T12:00:00.000-00:00";;
|
||||
interest-rates [[10 d] [15 d+1d] [20 d+2d]]]
|
||||
(split-interest-rates interest-rates d+½d d+3d) => [[10 d+½d d+1d] [15 d+1d d+2d] [20 d+2d d+3d]]
|
||||
(split-interest-rates interest-rates d+3d d+3½d) => [[20 d+3d d+3½d]]
|
||||
(split-interest-rates interest-rates d-1d d-½d) => [[0 d-1d d-½d]]
|
||||
(split-interest-rates interest-rates d d+½d) => [[10 d d+½d]]
|
||||
(split-interest-rates interest-rates d+2½d d+2½d) => [[20 d+2½d d+2½d]]))
|
||||
(data-layer/split-interest-rates interest-rates d+½d d+3d) => [[10 d+½d d+1d] [15 d+1d d+2d] [20 d+2d d+3d]]
|
||||
(data-layer/split-interest-rates interest-rates d+3d d+3½d) => [[20 d+3d d+3½d]]
|
||||
(data-layer/split-interest-rates interest-rates d-1d d-½d) => [[0 d-1d d-½d]]
|
||||
(data-layer/split-interest-rates interest-rates d d+½d) => [[10 d d+½d]]
|
||||
(data-layer/split-interest-rates interest-rates d+2½d d+2½d) => [[20 d+2½d d+2½d]]))
|
||||
(fact "compute-face-value"
|
||||
(let [d-1d #inst"2020-09-04T00:00:00.000-00:00"
|
||||
d-½d #inst"2020-09-04T12:00:00.000-00:00"
|
||||
@@ -243,15 +245,15 @@
|
||||
d+3½d #inst"2020-09-08T12:00:00.000-00:00"
|
||||
amount 10000000
|
||||
interest-rates [[10 d] [15 d+1d] [20 d+2d]]]
|
||||
(compute-face-value amount interest-rates d+½d d+½d) => amount
|
||||
(compute-face-value amount interest-rates d-1d d-½d) => amount
|
||||
(compute-face-value amount interest-rates d-1d d+3d) => 10045101))
|
||||
(data-layer/compute-face-value amount interest-rates d+½d d+½d) => amount
|
||||
(data-layer/compute-face-value amount interest-rates d-1d d-½d) => amount
|
||||
(data-layer/compute-face-value amount interest-rates d-1d d+3d) => 10045101))
|
||||
(fact "we had bugs... we need to fix them"
|
||||
(let [deposit-date #inst"2020-09-09T18:49:47.205-00:00"
|
||||
value-date #inst"2020-09-09T18:52:56.760-00:00"
|
||||
amount 105402100
|
||||
interest-rates (list [1000 #inst "2020-09-09T18:47:34.152-00:00"])]
|
||||
(compute-face-value amount interest-rates deposit-date value-date) => 105424060)))
|
||||
(data-layer/compute-face-value amount interest-rates deposit-date value-date) => 105424060)))
|
||||
|
||||
|
||||
;; 4. transfer sec from one account to the other.
|
||||
|
||||
Reference in new issue
Block a user