module BfHaskell.StreamingAPI.StreamingOrders
(
extractOrderChanges
, OrderCache
) where
import BfHaskell.StreamingAPI.Model
import BfHaskell.StreamingAPI.Prices (updatePricePoints)
import BfHaskell.StreamingAPI.Types (BetId, MarketId, OrderRunner,
OrderRunnerTable,
StreamCache (..),
orMatchedBacks, orMatchedLays,
orOrders, scStore)
import Control.Lens (over, (%~), (&))
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Maybe
import Data.Default
import qualified Data.Map as M
import Data.Maybe (fromMaybe)
import Polysemy
import Polysemy.State
type OrderCache = StreamCache OrderMarketChange MarketId OrderRunnerTable
extractOrderChanges :: Member (State OrderCache) r
=> OrderMarketChange
-> Sem r (Maybe MarketId)
extractOrderChanges oc =
runMaybeT $ do
marketId <- MaybeT . pure $ orderMarketChangeId oc
lift . modify . over scStore $ \store ->
if isClosed then M.delete marketId store
else
case orderMarketChangeOrc oc of
Nothing -> store
Just rcs ->
let currentRunnerTable = fromMaybe M.empty $ M.lookup marketId store
updatedRunnerTable = foldl updateMarket currentRunnerTable rcs
in M.insert marketId updatedRunnerTable store
return marketId
where
isClosed = orderMarketChangeClosed oc == Just True
updateMarket :: OrderRunnerTable -> OrderRunnerChange -> OrderRunnerTable
updateMarket t rc =
case runnerKey of
Nothing -> t
Just key ->
let currentRunner = if isImage then Nothing else M.lookup key t
updatedRunner = updateRunner rc $ fromMaybe def currentRunner
in M.insert key updatedRunner t
where
runnerKey = do
selectionId <- orderRunnerChangeId rc
let handicap = orderRunnerChangeHc rc
return (selectionId, handicap)
isImage = orderRunnerChangeFullImage rc == Just True
updateRunner :: OrderRunnerChange -> OrderRunner -> OrderRunner
updateRunner rc orderRunner =
orderRunner & orMatchedBacks %~ updatePricePoints (orderRunnerChangeMb rc)
& orMatchedLays %~ updatePricePoints (orderRunnerChangeMl rc)
& orOrders %~ updateOrders (orderRunnerChangeUo rc)
updateOrders :: Maybe [Order] -> M.Map BetId Order -> M.Map BetId Order
updateOrders Nothing orderTable = orderTable
updateOrders (Just orders) orderTable = foldl addOrder orderTable orders
addOrder :: M.Map BetId Order -> Order -> M.Map BetId Order
addOrder m order = fromMaybe m add
where
add = do
oid <- orderId order
return $ M.insert oid order m