ATrade core infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.4 KiB

module MockBroker (
MockBrokerState(..),
mockSubmitOrder,
mockCancelOrder,
mockStopBroker,
mkMockBroker,
emitNotification,
mockBrokerLastOrderId
) where
import ATrade.Broker.Backend
4 years ago
import ATrade.Broker.Protocol
import ATrade.Broker.Server
import ATrade.Types
import ATrade.Util
import Data.IORef
import qualified Data.List as L
data MockBrokerState = MockBrokerState {
4 years ago
orders :: [Order],
cancelledOrders :: [Order],
notificationCallback :: Maybe (BrokerBackendNotification -> IO ()),
lastOrderId :: OrderId
}
mockSubmitOrder :: IORef MockBrokerState -> Order -> IO ()
mockSubmitOrder state order = do
atomicModifyIORef' state (\s -> (s { orders = submittedOrder : orders s,
lastOrderId = orderId submittedOrder }, ()))
maybeCb <- notificationCallback <$> readIORef state
case maybeCb of
Just cb -> cb $ BackendOrderNotification (orderId order) Submitted
Nothing -> return ()
where
submittedOrder = order { orderState = Submitted }
mockCancelOrder :: IORef MockBrokerState -> OrderId -> IO ()
mockCancelOrder state oid = do
ors <- orders <$> readIORef state
case L.find (\o -> orderId o == oid) ors of
Just order -> do
atomicModifyIORef' state (\s -> (s { cancelledOrders = order : cancelledOrders s}, ()))
maybeCb <- notificationCallback <$> readIORef state
case maybeCb of
Just cb -> cb $ BackendOrderNotification (orderId order) Cancelled
Nothing -> return ()
Nothing -> return ()
mockStopBroker :: IORef MockBrokerState -> IO ()
mockStopBroker state = return ()
emitNotification :: IORef MockBrokerState -> BrokerBackendNotification -> IO ()
emitNotification state notification = do
bro <- readIORef state
case notificationCallback bro of
Just cb -> cb notification
Nothing -> return ()
mkMockBroker accs = do
state <- newIORef MockBrokerState {
orders = [],
cancelledOrders = [],
notificationCallback = Nothing,
lastOrderId = 0
}
return (BrokerBackend {
accounts = accs,
setNotificationCallback = \cb -> atomicMapIORef state (\s -> s { notificationCallback = cb }),
submitOrder = mockSubmitOrder state,
cancelOrder = mockCancelOrder state,
stop = mockStopBroker state
}, state)
mockBrokerLastOrderId :: IORef MockBrokerState -> IO OrderId
mockBrokerLastOrderId state = lastOrderId <$> readIORef state