going somewhere
This commit is contained in:
1 parent
9f36d28ce2
commit
519ac9ce07
7 files changed
+114
-46
No files matched your search
@@ -12,3 +12,4 @@ pom.xml.asc
|
|||||||
.idea/
|
.idea/
|
||||||
book.iml
|
book.iml
|
||||||
skirmish.iml
|
skirmish.iml
|
||||||
|
full-stack
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
# book
|
# 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.
|
||||||
@@ -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 |
@@ -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
@@ -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,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...
|
||||||
|
|||||||
@@ -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)));;;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in new issue
Block a user