|
|
|
|
@ -8,8 +8,10 @@ module ATrade.ESim.Core (
@@ -8,8 +8,10 @@ module ATrade.ESim.Core (
|
|
|
|
|
executeMatchingActions |
|
|
|
|
) where |
|
|
|
|
|
|
|
|
|
import ATrade.Price (decompose) |
|
|
|
|
import ATrade.Types |
|
|
|
|
(Operation (Buy, Sell), Order (orderId, orderOperation, orderPrice, orderQuantity), OrderId, Price, TickerId) |
|
|
|
|
(Operation (Buy, Sell), Order (orderId, orderOperation, orderPrice, orderQuantity), OrderId, |
|
|
|
|
OrderPrice (Limit, Market), Price, TickerId) |
|
|
|
|
import Data.Map.Strict qualified as M |
|
|
|
|
import Data.Maybe (fromMaybe) |
|
|
|
|
import Data.Sequence (Seq, empty, (|>)) |
|
|
|
|
@ -42,7 +44,35 @@ newtype Exchange
@@ -42,7 +44,35 @@ newtype Exchange
|
|
|
|
|
= Exchange { eLobs :: M.Map TickerId LimitOrderBook } |
|
|
|
|
|
|
|
|
|
addToLob :: Order -> LimitOrderBook -> [MatchingAction] |
|
|
|
|
addToLob order lob = [] |
|
|
|
|
addToLob order lob = fromMaybe [Reject order] (addToLob' order lob) |
|
|
|
|
where |
|
|
|
|
truncatePrice p = let (i, _) = decompose p in i |
|
|
|
|
maybePriceTick price = if (price / lobTickSize lob) * lobTickSize lob == price |
|
|
|
|
then Just (PriceTick . fromIntegral . truncatePrice $ price / lobTickSize lob) |
|
|
|
|
else Nothing |
|
|
|
|
addToLob' order lob = case (orderPrice order, maybeStartPrice) of |
|
|
|
|
(Market, Just startPrice) -> addToLobMarket (orderQuantity order) lob startPrice |
|
|
|
|
(Market, Nothing) -> Nothing |
|
|
|
|
(Limit price, Just startPrice) -> maybePriceTick price >>= addToLobLimit (orderQuantity order) lob startPrice |
|
|
|
|
(Limit price, Nothing) -> maybePriceTick price >>= (\priceTick -> |
|
|
|
|
Just [Enqueue (orderId order) priceTick (Volume . fromIntegral $ orderQuantity order) (orderOperation order)]) |
|
|
|
|
_ -> error "Not implemented" |
|
|
|
|
|
|
|
|
|
maybeStartPrice = fst <$> case orderOperation order of |
|
|
|
|
Buy -> M.lookupMin lobPart |
|
|
|
|
Sell -> M.lookupMax lobPart |
|
|
|
|
|
|
|
|
|
(lobPart, lookupFun) = if orderOperation order == Buy |
|
|
|
|
then (lobOffers lob, M.lookupLE) |
|
|
|
|
else (lobBids lob, M.lookupGE) |
|
|
|
|
|
|
|
|
|
addToLobMarket left lob currentPrice = if left == 0 |
|
|
|
|
then Just [] |
|
|
|
|
else case lookupFun currentPrice lobPart of |
|
|
|
|
Just sq -> undefined |
|
|
|
|
Nothing -> undefined |
|
|
|
|
|
|
|
|
|
addToLobLimit left lob currentPrice priceTick = undefined |
|
|
|
|
|
|
|
|
|
emptyLob :: TickerId -> Price -> LimitOrderBook |
|
|
|
|
emptyLob tid tickSize = LimitOrderBook tickSize M.empty M.empty tid M.empty |
|
|
|
|
|