diff --git a/src/ATrade/ESim/Core.hs b/src/ATrade/ESim/Core.hs index 01d31bb..e3f79f8 100644 --- a/src/ATrade/ESim/Core.hs +++ b/src/ATrade/ESim/Core.hs @@ -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 = 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