{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
module BfHaskell.StreamingAPI.Types
(
crlf
, StreamCache(..)
, scSubscriptionId, scClk, scInitialClk, scPt, scHeartbeatMs, scConflateMs
, scStatus, scStore, scSegments
, StreamMessageParser(..)
, StreamingState(..)
, ssStreamBuffer, ssConnectionId, ssAuthMsgId
, SMConnectionState(..)
, BetId, MarketId, Handicap, SelectionId
, StreamingMessage(..)
, MarketDetails (..), MarketRunnerTable
, mdMarketDefinition, mdTv, mdMarketRunners
, MarketRunner (..), MarketRunnerKey
, mrBackPrices, mrLayPrices, mrDispBackPrices, mrDispLayPrices, mrTv, mrLtp
, OrderRunner(..), OrderRunnerTable
, orMatchedBacks, orMatchedLays, orOrders
, StreamingHandler (..)
, getNextStreamMessage, tryGetNextStreamMessage
, subscribeToMarkets, getMarketCache
, subscribeToOrders, getOrderCache
, StreamingConnectionInfo(..)
, sciHostName, sciPort
) where
import BfHaskell.StreamingAPI.Model
import BfHaskell.StreamingAPI.Prices (LadderPrices (..),
PricePoints (..))
import Control.Lens (makeLenses)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Default
import qualified Data.Map as M
import qualified Data.Sequence as Seq
import Data.Text (Text)
import Polysemy
crlf :: ByteString
crlf = B.pack [13, 10]
data StreamCache c k v = StreamCache
{ _scSubscriptionId :: Int
, _scClk :: Maybe Text
, _scInitialClk :: Maybe Text
, _scPt :: Maybe Integer
, _scHeartbeatMs :: Maybe Integer
, _scConflateMs :: Maybe Integer
, _scStatus :: Maybe Int
, _scStore :: M.Map k v
, _scSegments :: Seq.Seq [c]
} deriving (Show)
instance Default (StreamCache c k v) where
def = StreamCache def def def def def def def def def
makeLenses ''StreamCache
class StreamMessageParser msg c | msg -> c where
getMessageId :: msg -> Maybe Int
getCt :: msg -> Maybe E'Ct
getInitialClk :: msg -> Maybe Text
getClk :: msg -> Maybe Text
getHeartbeatMs :: msg -> Maybe Integer
getPt :: msg -> Maybe Integer
getConflateMs :: msg -> Maybe Integer
getSegmentType :: msg -> Maybe E'SegmentType
getStatus :: msg -> Maybe Int
getChanges :: msg -> Maybe [c]
instance StreamMessageParser MarketChangeMessage MarketChange where
getMessageId = marketChangeMessageId
getCt = marketChangeMessageCt
getInitialClk = marketChangeMessageInitialClk
getClk = marketChangeMessageClk
getHeartbeatMs = marketChangeMessageHeartbeatMs
getPt = marketChangeMessagePt
getConflateMs = marketChangeMessageConflateMs
getSegmentType = marketChangeMessageSegmentType
getStatus = marketChangeMessageStatus
getChanges = marketChangeMessageMc
instance StreamMessageParser OrderChangeMessage OrderMarketChange where
getMessageId = orderChangeMessageId
getCt = orderChangeMessageCt
getInitialClk = orderChangeMessageInitialClk
getClk = orderChangeMessageClk
getHeartbeatMs = orderChangeMessageHeartbeatMs
getPt = orderChangeMessagePt
getConflateMs = orderChangeMessageConflateMs
getSegmentType = orderChangeMessageSegmentType
getStatus = orderChangeMessageStatus
getChanges = orderChangeMessageOc
data StreamingState = StreamingState
{ _ssStreamBuffer :: !ByteString
, _ssConnectionId :: Maybe Text
, _ssAuthMsgId :: Maybe Int
}
instance Default StreamingState where
def = StreamingState mempty Nothing Nothing
makeLenses ''StreamingState
type BetId = Text
type MarketId = Text
type Handicap = Maybe Double
type SelectionId = Integer
data SMConnectionState = SMCSConnected | SMCSDisconnected
deriving (Eq, Show)
data StreamingMessage = SMConnectionStateChanged SMConnectionState
| SMMarketUpdate [MarketId]
| SMOrderUpdate [MarketId]
deriving (Show)
type MarketRunnerKey = (SelectionId, Handicap)
data MarketRunner = MarketRunner
{ _mrBackPrices :: LadderPrices
, _mrLayPrices :: LadderPrices
, _mrDispBackPrices :: LadderPrices
, _mrDispLayPrices :: LadderPrices
, _mrTv :: Maybe Double
, _mrLtp :: Maybe Double
} deriving (Show)
makeLenses ''MarketRunner
instance Default MarketRunner where
def = MarketRunner def def def def def def
type MarketRunnerTable = M.Map MarketRunnerKey MarketRunner
data MarketDetails = MarketDetails
{ _mdMarketDefinition :: Maybe MarketDefinition
, _mdTv :: Maybe Double
, _mdMarketRunners :: MarketRunnerTable
}
makeLenses ''MarketDetails
instance Default MarketDetails where
def = MarketDetails def def def
data OrderRunner = OrderRunner
{ _orMatchedBacks :: PricePoints
, _orMatchedLays :: PricePoints
, _orOrders :: M.Map BetId Order
} deriving (Show)
makeLenses ''OrderRunner
instance Default OrderRunner where
def = OrderRunner def def def
type OrderRunnerTable = M.Map MarketRunnerKey OrderRunner
data StreamingConnectionInfo = StreamingConnectionInfo
{ _sciHostName :: Text
, _sciPort :: Int
}
deriving (Show)
makeLenses ''StreamingConnectionInfo
data StreamingHandler m a where
GetNextStreamMessage :: StreamingHandler m StreamingMessage
TryGetNextStreamMessage :: StreamingHandler m (Maybe StreamingMessage)
SubscribeToMarkets :: MarketFilter
-> StreamingHandler m ()
GetMarketCache :: StreamingHandler m (M.Map MarketId MarketDetails)
SubscribeToOrders :: StreamingHandler m ()
GetOrderCache :: StreamingHandler m (M.Map MarketId OrderRunnerTable)
makeSem_ ''StreamingHandler
getNextStreamMessage :: Member StreamingHandler r => Sem r StreamingMessage
tryGetNextStreamMessage :: Member StreamingHandler r => Sem r (Maybe StreamingMessage)
subscribeToMarkets :: Member StreamingHandler r => MarketFilter -> Sem r ()
getMarketCache :: Member StreamingHandler r => Sem r (M.Map MarketId MarketDetails)
subscribeToOrders :: Member StreamingHandler r => Sem r ()
getOrderCache :: Member StreamingHandler r => Sem r (M.Map MarketId OrderRunnerTable)