going somewhere

This commit is contained in:
didier amyot committed 2018-07-08 12:46:15 -04:00
1 parent 9f36d28ce2
commit 519ac9ce07
7 files changed
+114 -46

No files matched your search

+1
View File
@@ -12,3 +12,4 @@ pom.xml.asc
.idea/ .idea/
book.iml book.iml
skirmish.iml skirmish.iml
full-stack
+8 -18
View File
@@ -1,10 +1,14 @@
# book # Skrimish
![logo](doc/logo.svg "Skrimish")
A stock exchange simulator. The scope of this project is not yet defined but it should
allow end user(s?) to exchange securities via the common exchange rules.
FIXME: description
## Installation ## Installation
Okay, this should be easy but it is hard...
Download from http://example.com/FIXME.
## Usage ## Usage
@@ -12,25 +16,11 @@ FIXME: explanation
$ java -jar book-0.1.0-standalone.jar [args] $ java -jar book-0.1.0-standalone.jar [args]
## Options
FIXME: listing of options this app accepts.
## Examples
...
### Bugs
...
### Any Other Sections
### That You Think
### Might be Useful
## License ## License
Copyright © 2018 FIXME Copyright © 2018 didier amyot
Distributed under the Eclipse Public License either version 1.0 or (at Distributed under the Eclipse Public License either version 1.0 or (at
your option) any later version. your option) any later version.
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
<g><g transform="translate(0.000000,417.000000) scale(0.100000,-0.100000)"><path d="M5949.3,3095c-341.4-77.2-617.3-287.4-758.1-574.9c-94.5-196.8-104.2-385.8-27-609.6c21.2-57.9,34.7-108,30.9-110c-3.8-3.9-36.7,17.4-73.3,48.2c-129.3,106.1-416.7,287.5-609.6,385.8c-372.3,185.2-551.7,237.3-1018.6,293.2c-601.9,71.4-1531.8,69.5-1674.5-3.9c-23.2-11.6-65.6-44.4-94.5-69.5l-50.2-48.2l-117.7,40.5c-148.6,52.1-299,52.1-451.4,0c-501.6-167.8-708-584.5-412.9-837.3c44.4-38.6,125.4-83,187.1-100.3c123.5-36.7,385.8-40.5,540.2-7.7c115.8,23.2,158.2,25.1,704.2,23.2c376.2,0,806.4-38.6,1001.3-88.7c173.6-46.3,397.4-148.6,466.9-214.1c54-50.2,65.6-75.2,65.6-140.8c0-200.6-150.5-353-819.9-825.7c-397.4-279.7-661.7-547.9-779.4-787.1c-125.4-254.7-179.4-511.2-225.7-1057.2c-28.9-356.9-32.8-374.3-90.7-474.6c-133.1-225.7-609.6-655.9-1130.5-1020.5C181.1-3385.1,102-3487.4,100-3753.6c-3.9-353,291.3-816,619.3-970.4c96.5-44.4,135-52.1,285.5-52.1c208.3,1.9,339.5,34.7,414.8,106.1c119.6,111.9,102.2,227.6-69.5,455.3c-67.5,92.6-117.7,175.5-110,181.3c7.7,7.7,75.2,54,146.6,102.2l133.1,86.8l108-50.2c84.9-38.6,146.6-50.1,291.3-57.9c565.3-25.1,941.5,293.2,673.3,569.1c-32.8,34.7-57.9,65.6-52.1,69.4c3.9,3.9,86.8,30.9,181.3,59.8c735,223.8,1356.2,547.9,1664.9,866.2c339.5,351.1,376.2,729.3,119.6,1238.5c-42.4,84.9-77.2,160.1-77.2,165.9c0,7.7,63.7,52.1,140.8,100.3c75.2,48.2,260.4,175.6,409,283.6c148.5,110,277.8,200.6,289.4,204.5c9.6,3.9,63.6-52.1,119.6-123.5c148.6-191,412.9-468.8,551.7-578.8c158.2-125.4,250.8-169.8,410.9-198.7c177.5-30.9,742.7-11.6,1117,38.6c160.1,23.2,300.9,40.5,314.4,40.5c15.4,0,23.2-44.4,23.2-154.3c0-140.8,5.8-160.1,48.2-202.6c55.9-57.9,156.3-63.7,324.1-19.3c324.1,84.9,569.1,320.3,671.4,644.4l32.8,108l449.5,3.9c291.3,3.9,466.8,13.5,493.9,27c63.7,34.7,92.6,119.6,63.7,191c-13.5,32.8-34.7,65.6-46.3,73.3c-11.6,7.7-233.4,17.4-491.9,23.2l-468.8,9.6l-44.3,119.6c-56,156.3-148.6,297.1-258.5,395.5c-235.3,210.3-679.1,308.7-754.3,169.8c-11.6-19.3-19.3-119.6-19.3-219.9v-185.2h-106.1c-142.8,0-659.8,54-837.3,88.7c-171.7,32.8-208.4,54-320.2,196.8C6439.4,182,6165.4,589,6165.4,610.2c0,9.6,28.9,59.8,65.6,113.8c65.6,96.5,71.4,100.3,196.8,123.5c164,30.9,391.6,144.7,526.7,264.3c135,117.7,272,329.9,331.8,509.3c65.6,198.7,65.6,509.3,1.9,694.5c-123.5,358.8-397.4,630.8-742.7,740.8C6352.5,3118.2,6121,3133.6,5949.3,3095z M6437.4,2757.4c229.6-77.2,397.4-225.7,503.5-437.9c54-110,63.7-152.4,69.4-304.8c11.6-275.9-59.8-459.1-256.6-644.3c-127.3-121.5-274-191-459.2-221.9c-77.2-11.6-152.4-30.9-169.7-40.5c-38.6-25.1-297.1-391.6-314.5-447.6c-19.3-61.7,19.3-138.9,239.2-464.9c248.9-372.3,409-547.9,549.8-600c146.6-54,904.8-156.3,1169.1-156.3c32.8,0,36.7-13.5,36.7-162v-162.1l-61.8-11.6c-150.4-25.1-547.9-71.4-806.4-90.7c-320.2-23.2-532.5-9.6-652.1,40.5c-108,48.2-463,395.5-665.6,652.1C5374.5,18,5389.9,2.5,5314.6,2.5c-55.9,0-115.8-36.7-355-216.1C4801.5-333.1,4566.1-499,4438.8-582c-364.6-237.3-374.3-245-387.8-299c-9.6-38.6,17.4-110,123.5-322.2c146.6-293.2,175.6-387.8,177.5-555.6c1.9-339.6-397.4-675.2-1174.9-989.7c-324.1-133.1-322.2-135-102.3,92.6c135,137,214.1,237.3,245,304.8c94.5,210.3,202.6,839.2,202.6,1176.8c0,154.3-5.8,183.3-42.4,221.9c-55.9,59.8-167.8,61.7-221.9,1.9c-32.8-36.7-40.5-81-52.1-252.7c-21.2-364.6-113.8-893.2-177.5-1020.5c-108-210.3-661.7-655.9-1630.2-1313.8c-229.6-156.3-432.1-300.9-451.4-322.2c-17.4-19.3-38.6-75.2-42.4-123.5c-11.6-100.3,46.3-241.2,154.3-378.1l71.4-86.8l-115.8-5.8c-142.8-7.7-204.5,23.2-347.3,167.8c-194.8,198.7-301,505.4-225.7,652.1c19.3,36.7,119.6,121.5,268.2,223.8c592.3,414.8,1126.6,895.2,1302.2,1171c92.6,144.7,108,219.9,140.8,636.6c38.6,511.2,111.9,816.1,241.1,1012.8c113.8,169.8,387.8,412.8,771.7,684.9c426.4,302.9,663.6,524.7,752.4,704.2c48.2,98.4,55.9,138.9,55.9,270.1c1.9,135-5.8,167.8-55.9,258.5c-67.5,123.5-154.3,192.9-368.5,291.3c-210.3,98.4-320.2,129.3-625.1,175.6c-353,54-1302.2,69.5-1531.8,27c-248.9-48.2-480.4-28.9-507.4,40.5c-30.9,83,110,204.5,324.1,279.7l127.3,44.4l142.8-52.1c81-28.9,183.3-52.1,235.4-52.1c81,0,102.3,9.6,175.6,77.2l84.9,79.1l246.9,21.2c434.1,34.7,1371.7-36.7,1701.5-131.2c426.4-123.5,931.8-432.1,1294.5-794.8c88.8-88.7,183.3-169.8,208.3-179.4c59.8-23.1,123.5,3.9,185.2,79.1c113.8,133.1,98.4,279.7-55.9,588.4c-108,216.1-113.8,237.3-113.8,364.6c1.9,94.5,11.6,158.2,36.6,202.6c48.2,88.7,179.4,229.6,272,287.4C5939.7,2796,6221.4,2828.8,6437.4,2757.4z M8229.7-146c341.5-173.6,443.7-605.8,214.1-908.7c-65.6-88.8-248.9-219.9-304.8-219.9c-19.3,0-25.1,119.6-25.1,588.4c0,324.1,3.8,588.4,9.6,588.4C8129.3-97.8,8177.5-119,8229.7-146z M2202.9-3485.4c46.3-27,90.7-57.9,96.5-67.5c25.1-40.5-275.9-106.1-389.7-86.8l-67.5,13.5l131.2,94.5c71.4,52.1,133.1,94.5,137,94.5C2114.1-3435.3,2154.6-3458.4,2202.9-3485.4z"/></g></g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

+50 -6
View File
@@ -6,7 +6,47 @@
[skirmish.util :refer :all] [skirmish.util :refer :all]
[clojure.core.async :refer [chan go >! <! pub]])) [clojure.core.async :refer [chan go >! <! pub]]))
(def empty-book {:sell (create-sell-book) :buy (create-buy-book)})
(def empty-book {:sell (create-sell-book)
:buy (create-buy-book)
:id 0})
(defn retrieve-new-book-order-from-trade [trade book]
(let [book-id (:book.order/book-id trade)
f #(= book-id (:book.order/id %))
ret-order (first (filter f book))
new-quantity (- (:quantity ret-order 10) (:book.order/quantity trade));; (- (:quantity ret-order) (:book.order/quantity trade))
totally-fulfilled? (= (:book.order/quantity trade) (:quantity ret-order))]
(into ret-order {:status (if totally-fulfilled? :totally-fulfilled :partially-fulfilled)
:status-dual-id (:book.order/order-id trade)
:quantity new-quantity})));;;;
(defn ff [order trade]
(let [new-order-quantity (- (:quantity order) (:book.order/quantity trade))
totally-fulfilled? (= 0 new-order-quantity)
dual-id (:book.order/book-id trade)]
(into order {:status (if totally-fulfilled? :totally-fulfilled :partially-fulfilled)
:status-dual-id dual-id
:quantity new-order-quantity})))
(defn get-processed-orders-in-trades [order book trades]
(let [trades-orders (sequence (map #(retrieve-new-book-order-from-trade % book)) trades)
processed-orders (rest (reductions ff order trades))]
(interleave trades-orders processed-orders)))
(defn get-processed-orders [order leftover-order trades book]
"Computes all the intermediary orders that took place during
a the trade."
(let [ret [(assoc order :status :inserted)]
ret (into ret (get-processed-orders-in-trades order book trades))
ret (if (seq leftover-order)
(conj ret (assoc leftover-order :status :inserted-into-book))
leftover-order)]
ret))
(defn process-abstract [order reference-book same-type-book] (defn process-abstract [order reference-book same-type-book]
@@ -15,30 +55,34 @@
[new-reference-book new-same-type-book leftover-order trades])) [new-reference-book new-same-type-book leftover-order trades]))
(defn process-sell-order [{sell-book :sell buy-book :buy} order] (defn process-sell-order [{sell-book :sell buy-book :buy id :id} order]
(let [[new-buy-book new-sell-book new-order trades] (process-abstract order buy-book sell-book) (let [[new-buy-book new-sell-book new-order trades] (process-abstract order buy-book sell-book)
new-book {:sell new-sell-book :buy new-buy-book}] new-book {:sell new-sell-book :buy new-buy-book :id (inc id)}]
[new-book new-order trades])) [new-book new-order trades]))
(defn process-buy-order [{sell-book :sell buy-book :buy} order]
(defn process-buy-order [{sell-book :sell buy-book :buy id :id} order]
(let [[new-sell-book new-buy-book new-order trades] (process-abstract order sell-book buy-book) (let [[new-sell-book new-buy-book new-order trades] (process-abstract order sell-book buy-book)
new-book {:sell new-sell-book :buy new-buy-book}] new-book {:sell new-sell-book :buy new-buy-book :id (inc id)}]
[new-book new-order trades])) [new-book new-order trades]))
(defn process-order [book order] (defn process-order [book order]
(if (sell? order) (if (sell? order)
(process-sell-order book order) (process-sell-order book order)
(process-buy-order book order))) (process-buy-order book order)))
(defn process-orders [initial-book incoming-order-channel] (defn process-orders [initial-book incoming-order-channel]
(let [trades-channel (chan) (let [trades-channel (chan)
new-book-order-channel (chan)] new-book-order-channel (chan)]
(go (loop [order (<! incoming-order-channel) book initial-book] (go (loop [order (<! incoming-order-channel) book initial-book]
(let [[new-book new-order new-trades] (process-order book order)] (let [[new-book new-order new-trades] (process-order book order)]
(when (not (nil? new-order)) (>! new-book-order-channel new-order)) (when (not (nil? new-order)) (>! new-book-order-channel new-order))
(doseq [trade new-trades] (>! trades-channel trade)) (doseq [trade new-trades] (>! trades-channel trade)) ;; TODO: user clojure.core.async/onto-chan
(recur (<! incoming-order-channel) new-book)))) (recur (<! incoming-order-channel) new-book))))
[(pub trades-channel :book.order/type) (pub new-book-order-channel :type)])) [(pub trades-channel :book.order/type) (pub new-book-order-channel :type)]))
(def create-exchange-for-security process-orders) (def create-exchange-for-security process-orders)
+21 -18
View File
@@ -9,15 +9,15 @@
;; sell-book contains all the sell orders. The second ;; sell-book contains all the sell orders. The second
;; called buy-book contains all the buy orders. ;; called buy-book contains all the buy orders.
(defn create-sell-book [& args] (defn create-sell-book [& orders]
"Creates a sell book with the orders in it."
(let [cmp #(compare (:price %1) (:price %2))] (let [cmp #(compare (:price %1) (:price %2))]
(apply sorted-list-by cmp args))) (apply sorted-list-by cmp orders)))
(defn create-buy-book [& args] (defn create-buy-book [& orders]
"Creates a buy book with the orders in it."
(let [cmp #(compare (:price %2) (:price %1))] (let [cmp #(compare (:price %2) (:price %1))]
(apply sorted-list-by cmp args))) (apply sorted-list-by cmp orders)))
(def book {:sell (create-sell-book) :buy (create-sell-book)})
(defn buy? [order] (defn buy? [order]
(= :buy (:type order))) (= :buy (:type order)))
@@ -25,13 +25,13 @@
(defn sell? [order] (defn sell? [order]
(= (:type order) :sell)) (= (:type order) :sell))
(defn sell-order-fullfillable? [book-order order] (defn- sell-order-fullfillable? [book-order order]
(>= (:price book-order) (:price order))) (>= (:price book-order) (:price order)))
(defn buy-order-fullfillable? [book-order order] (defn- buy-order-fullfillable? [book-order order]
(<= (:price book-order) (:price order))) (<= (:price book-order) (:price order)))
(defn create-sell-trade-factory [order-to-fulfill] (defn- create-sell-trade-factory [order-to-fulfill]
(fn [trade book-order] (fn [trade book-order]
(let [already-fulfilled (:book.order/already-fulfilled trade 0) (let [already-fulfilled (:book.order/already-fulfilled trade 0)
qtn-to-fulfill (min (:quantity book-order) (- (:quantity order-to-fulfill) already-fulfilled)) qtn-to-fulfill (min (:quantity book-order) (- (:quantity order-to-fulfill) already-fulfilled))
@@ -44,7 +44,7 @@
:order-id (:book.order/id order-to-fulfill) :order-id (:book.order/id order-to-fulfill)
:book-id (:book.order/id book-order)})))) :book-id (:book.order/id book-order)}))))
(defn create-buy-trade-factory [order-to-fulfill] (defn- create-buy-trade-factory [order-to-fulfill]
(fn [trade book-order] (fn [trade book-order]
(let [already-fulfilled (:book.order/already-fulfilled trade 0) (let [already-fulfilled (:book.order/already-fulfilled trade 0)
qtn-to-fulfill (min (:quantity book-order) (- (:quantity order-to-fulfill) already-fulfilled)) qtn-to-fulfill (min (:quantity book-order) (- (:quantity order-to-fulfill) already-fulfilled))
@@ -57,21 +57,21 @@
:order-id (:book.order/id order-to-fulfill) :order-id (:book.order/id order-to-fulfill)
:book-id (:book.order/id book-order)})))) :book-id (:book.order/id book-order)}))))
(defn create-trade-factory [order-to-fulfill] (defn- create-trade-factory [order-to-fulfill]
(if (sell? order-to-fulfill) (if (sell? order-to-fulfill)
(create-sell-trade-factory order-to-fulfill) (create-sell-trade-factory order-to-fulfill)
(create-buy-trade-factory order-to-fulfill))) (create-buy-trade-factory order-to-fulfill)))
(defn create-trades [order-to-fulfill sell-book] (defn- create-trades [order-to-fulfill sell-book]
(let [create-trade (create-trade-factory order-to-fulfill) (let [create-trade (create-trade-factory order-to-fulfill)
trades (reductions create-trade {} sell-book) trades (reductions create-trade {} sell-book)
ret (rest (take-while some? trades))] ret (rest (take-while some? trades))]
(map #(dissoc % :book.order/already-fulfilled) ret))) (map #(dissoc % :book.order/already-fulfilled) ret)))
(defn partial-trade? [trade order] (defn- partial-trade? [trade order]
(not= (:quantity order) (:book.order/quantity trade))) (not= (:quantity order) (:book.order/quantity trade)))
(defn compute-partial-order [order trade] (defn- compute-partial-order [order trade]
(assoc order :quantity (- (:quantity order) (:book.order/quantity trade 0)))) (assoc order :quantity (- (:quantity order) (:book.order/quantity trade 0))))
(defn- drop-in-sorted-list [n sorted-list] (defn- drop-in-sorted-list [n sorted-list]
@@ -80,22 +80,25 @@
(<= (count sorted-list) n) (empty sorted-list) (<= (count sorted-list) n) (empty sorted-list)
:else (drop n sorted-list)));; :else (drop n sorted-list)));;
(defn compute-new-book-after-trades [book trades] (defn- compute-new-book-after-trades [book trades]
(let [new-book (drop-in-sorted-list (-> trades count dec) book) (let [new-book (drop-in-sorted-list (-> trades count dec) book)
possible-partial-trade (last trades)] possible-partial-trade (last trades)]
(if (partial-trade? possible-partial-trade (first new-book)) (if (partial-trade? possible-partial-trade (first new-book))
(conj (rest new-book) (compute-partial-order (first new-book) possible-partial-trade)) (conj (rest new-book) (compute-partial-order (first new-book) possible-partial-trade))
(rest new-book)))) (rest new-book))))
(defn leftover-order [order trades] (defn- leftover-order [order trades]
(let [traded-quantity (reduce + (map :book.order/quantity trades)) (let [traded-quantity (reduce + (map :book.order/quantity trades))
leftover-quantity (- (:quantity order) traded-quantity)] leftover-quantity (- (:quantity order) traded-quantity)]
(when (pos? leftover-quantity) (when (pos? leftover-quantity)
(assoc order :quantity leftover-quantity)))) (assoc order :quantity leftover-quantity))))
(defn match-order-in-book [book order] (defn match-order-in-book [book order]
"Matches the order within the book. Returns the applied trades,
the resulting book and left over order if the input order has not
been entirely fulfilled."
(let [trades (create-trades order book) (let [trades (create-trades order book)
new-book (compute-new-book-after-trades book trades) new-book (compute-new-book-after-trades book trades)
new-buy-order (leftover-order order trades)] leftover-order (leftover-order order trades)]
[trades new-book new-buy-order])) [trades new-book leftover-order]))
+11
View File
@@ -11,6 +11,17 @@
(s/def :book.order/price pos-int?) (s/def :book.order/price pos-int?)
(s/def :book.order/quantity pos-int?) (s/def :book.order/quantity pos-int?)
(s/def :book.order/id pos-int?) (s/def :book.order/id pos-int?)
(s/def :book.order/status #{:inserted ;; maybe called acknklowdlge.
:partially-matched
:totally-matched
:inserted-into-book
:partially-fulfilled
:totally-fulfilled
:withdrawn}) ;; for instance the order has been canceled
(s/def :book.order/status-dual-id :book.order/id)
(s/def :book.order/order (s/keys :req-un [:book.order/type :book.order/price :book.order/quantity] :opt [:book.order/id])) (s/def :book.order/order (s/keys :req-un [:book.order/type :book.order/price :book.order/quantity] :opt [:book.order/id]))
;; A trade is defined by the bellow map... ;; A trade is defined by the bellow map...
+16 -4
View File
@@ -3,7 +3,8 @@
(:require [midje.sweet :refer :all] (:require [midje.sweet :refer :all]
[skirmish.exchange :refer :all] [skirmish.exchange :refer :all]
[skirmish.match :refer [create-buy-book [skirmish.match :refer [create-buy-book
create-sell-book]])) create-sell-book
match-order-in-book]]))
(def PersistentSortedList? (comp #(= % skirmish.PersistentSortedList) type)) (def PersistentSortedList? (comp #(= % skirmish.PersistentSortedList) type))
@@ -21,7 +22,7 @@
(fact "process-sell-order should work when there is a buy order that matches" (fact "process-sell-order should work when there is a buy order that matches"
(let [sell-book (create-sell-book) (let [sell-book (create-sell-book)
buy-book (create-buy-book {:type :buy :quantity 10 :price 3 :book.order/id 2}) buy-book (create-buy-book {:type :buy :quantity 10 :price 3 :book.order/id 2})
book {:sell sell-book :buy buy-book} book {:sell sell-book :buy buy-book :id 0}
order {:type :sell :quantity 4 :price 2 :book.order/id 3} order {:type :sell :quantity 4 :price 2 :book.order/id 3}
expt-new-buy-book [{:price 3 :quantity 6 :type :buy :book.order/id 2}] expt-new-buy-book [{:price 3 :quantity 6 :type :buy :book.order/id 2}]
expt-new-trades [#:book.order{:book-id 2 :order-id 3 :price 3 :quantity 4 :type :buy}] expt-new-trades [#:book.order{:book-id 2 :order-id 3 :price 3 :quantity 4 :type :buy}]
@@ -44,7 +45,7 @@
(fact "process-buy-order should work when there is a buy order that matches" (fact "process-buy-order should work when there is a buy order that matches"
(let [sell-book (create-sell-book {:type :sell :quantity 10 :price 3 :book.order/id 2}) (let [sell-book (create-sell-book {:type :sell :quantity 10 :price 3 :book.order/id 2})
buy-book (create-buy-book) buy-book (create-buy-book)
book {:sell sell-book :buy buy-book} book {:sell sell-book :buy buy-book :id 0}
order {:type :buy :quantity 4 :price 4 :book.order/id 3} order {:type :buy :quantity 4 :price 4 :book.order/id 3}
expt-new-sell-book [{:price 3 :quantity 6 :type :sell :book.order/id 2}] expt-new-sell-book [{:price 3 :quantity 6 :type :sell :book.order/id 2}]
expt-new-trades [#:book.order{:book-id 2 :order-id 3 :price 3 :quantity 4 :type :sell}] expt-new-trades [#:book.order{:book-id 2 :order-id 3 :price 3 :quantity 4 :type :sell}]
@@ -60,11 +61,22 @@
order-3 {:type :sell :quantity 17 :price 99 :book.order/id 9} order-3 {:type :sell :quantity 17 :price 99 :book.order/id 9}
order-4 {:type :sell :quantity 1 :price 102 :book.order/id 10} order-4 {:type :sell :quantity 1 :price 102 :book.order/id 10}
expt-book-4 {:buy [{:price 99 :quantity 8 :type :buy :book.order/id 8}] expt-book-4 {:buy [{:price 99 :quantity 8 :type :buy :book.order/id 8}]
:sell [{:price 102 :quantity 1 :type :sell :book.order/id 10}]} :sell [{:price 102 :quantity 1 :type :sell :book.order/id 10}]
:id 4}
[book-1 _ _] (process-order book order-1) [book-1 _ _] (process-order book order-1)
[book-2 _ _] (process-order book-1 order-2) [book-2 _ _] (process-order book-1 order-2)
[book-3 _ _] (process-order book-2 order-3) [book-3 _ _] (process-order book-2 order-3)
[book-4 _ _] (process-order book-3 order-4)] [book-4 _ _] (process-order book-3 order-4)]
book-4 => expt-book-4))) book-4 => expt-book-4)))
(facts "get-processed-orders"
(fact "ss"
(let [sell-book (create-buy-book {:type :buy :quantity 2 :price 14 :book.order/id 116}
{:type :buy :quantity 8 :price 13 :book.order/id 117})
order {:type :sell :quantity 21 :price 13 :book.order/id 118}
[trades new-book leftover-order] (match-order-in-book sell-book order)
processed-order (get-processed-orders order leftover-order trades sell-book)]
processed-order => seq)));;;