Browse Source

BrokerServer

master
Denis Tereshkin 3 years ago
parent
commit
00f9863de0
  1. 1
      src/TXML.hs
  2. 63
      src/TXMLConnector.hs
  3. 15
      src/Transaq.hs

1
src/TXML.hs

@ -81,7 +81,6 @@ uninitialize = c_UnInitialize >>= rawStringToResult
sendCommand :: T.Text -> IO (Either T.Text ()) sendCommand :: T.Text -> IO (Either T.Text ())
sendCommand cmdData = do sendCommand cmdData = do
putStrLn $ T.unpack cmdData
BS.useAsCString (encodeUtf8 cmdData) $ \fpcstr -> BS.useAsCString (encodeUtf8 cmdData) $ \fpcstr ->
c_SendCommand fpcstr >>= rawStringToResult c_SendCommand fpcstr >>= rawStringToResult

63
src/TXMLConnector.hs

@ -47,6 +47,7 @@ import Text.XML.Light.Types (Content (Elem),
QName (qName)) QName (qName))
import Transaq (AllTradesTrade (..), import Transaq (AllTradesTrade (..),
Candle (..), ClientData (..), Candle (..), ClientData (..),
CommandChangePass (..),
CommandConnect (..), CommandConnect (..),
CommandDisconnect (CommandDisconnect), CommandDisconnect (CommandDisconnect),
CommandGetHistoryData (CommandGetHistoryData), CommandGetHistoryData (CommandGetHistoryData),
@ -94,8 +95,10 @@ import ATrade.Types (Bar (..),
fromDouble, toDouble) fromDouble, toDouble)
import qualified ATrade.Types as AT import qualified ATrade.Types as AT
import Colog.Monad (WithLog) import Colog.Monad (WithLog)
import Control.Applicative ((<|>))
import Control.Concurrent.BoundedChan (BoundedChan, writeChan) import Control.Concurrent.BoundedChan (BoundedChan, writeChan)
import Control.Concurrent.STM.TMVar (TMVar) import Control.Concurrent.STM.TMVar (TMVar)
import Control.Error (headMay)
import Control.Monad (forM_) import Control.Monad (forM_)
import Control.Monad.IO.Class (MonadIO (liftIO)) import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad.Reader (ReaderT (runReaderT)) import Control.Monad.Reader (ReaderT (runReaderT))
@ -311,6 +314,9 @@ workThread = do
"quotations" -> TransaqResponseQuotations <$> fromXml el "quotations" -> TransaqResponseQuotations <$> fromXml el
"alltrades" -> TransaqResponseAllTrades <$> fromXml el "alltrades" -> TransaqResponseAllTrades <$> fromXml el
"quotes" -> TransaqResponseQuotes <$> fromXml el "quotes" -> TransaqResponseQuotes <$> fromXml el
"orders" -> TransaqResponseOrders <$> fromXml el
"trades" -> TransaqResponseTrades <$> fromXml el
"result" -> TransaqResponseResult <$> fromXml el
_ -> Nothing _ -> Nothing
writeToQueue queue resp = atomically $ writeTBQueue queue resp writeToQueue queue resp = atomically $ writeTBQueue queue resp
handleConnected :: App () handleConnected :: App ()
@ -354,15 +360,6 @@ workThread = do
_ -> log Warning "TXMLConnector.WorkThread" "Incoming candles without response var" _ -> log Warning "TXMLConnector.WorkThread" "Incoming candles without response var"
TransaqResponseOrders (ResponseOrders orders) -> forM_ orders handleOrder TransaqResponseOrders (ResponseOrders orders) -> forM_ orders handleOrder
TransaqResponseTrades (ResponseTrades trades) -> forM_ trades handleTrade TransaqResponseTrades (ResponseTrades trades) -> forM_ trades handleTrade
TransaqResponseResult (ResponseSuccess (Just transactionId)) -> do
brState <- asks brokerState
liftIO $ atomically $ do
deque <- readTVar (bsPendingOrders brState)
case D.uncons deque of
Just (order, deque') -> do
writeTVar (bsPendingOrders brState) deque'
modifyTVar' (bsOrderTransactionIdMap brState) (BM.insert (orderId order) (TransactionId transactionId))
Nothing -> pure ()
_ -> pure () _ -> pure ()
MainQueueRequest (RequestHistory request) -> do MainQueueRequest (RequestHistory request) -> do
cur <- asks currentCandles cur <- asks currentCandles
@ -386,12 +383,21 @@ workThread = do
Just cmd -> do Just cmd -> do
v <- liftIO . sendCommand . toXml $ cmd v <- liftIO . sendCommand . toXml $ cmd
case v of case v of
Left err -> log Warning "TXMLConnector.WorkThread" $ "Unable to send request: [" <> err <> "]" Left result -> do
case headMay (parseXML result) >>= parseContent of
Just (TransaqResponseResult (ResponseSuccess (Just transactionId))) -> do
brState <- asks brokerState
respVar <- asks responseVar
liftIO $ atomically $ do
modifyTVar' (bsOrderMap brState) (M.insert (orderId order) order)
modifyTVar' (bsOrderTransactionIdMap brState) (BM.insert (orderId order) (TransactionId transactionId))
resp <- readTMVar respVar
putTMVar resp ResponseOrderSubmitted
log Debug "TXMLConnector.WorkThread" $ "Inserting orderid: " <>
(T.pack . show) (orderId order) <> " <-> " <> (T.pack . show) transactionId
_ -> log Warning "TXMLConnector.WorkThread" "Unable to parse result"
Right _ -> do Right _ -> do
brState <- asks brokerState log Warning "TXMLConnector.WorkThread" "Expected result, got nothing"
liftIO $ atomically $ do
modifyTVar' (bsPendingOrders brState) (order `D.snoc`)
modifyTVar' (bsOrderMap brState) (M.insert (orderId order) order)
_ -> pure () _ -> pure ()
_ -> pure () _ -> pure ()
@ -407,10 +413,13 @@ workThread = do
case maybeCb of case maybeCb of
Just cb -> case BM.lookupR (ExchangeOrderId (tOrderNo transaqTrade)) trIdMap of Just cb -> case BM.lookupR (ExchangeOrderId (tOrderNo transaqTrade)) trIdMap of
Just oid -> case M.lookup oid orderMap of Just oid -> case M.lookup oid orderMap of
Just order -> liftIO $ cb (BackendTradeNotification (fromTransaqTrade transaqTrade order)) Just order -> do
_ -> pure () let notif = BackendTradeNotification (fromTransaqTrade transaqTrade order)
_ -> pure () log Debug "TXMLConnector.WorkThread" $ "Sending trade notification: " <> (T.pack . show) notif
Nothing -> pure () liftIO $ cb notif
_ -> log Warning "TXMLConnector.WorkThread" $ "Unable to find order for trade: " <> (T.pack . show) transaqTrade
_ -> log Warning "TXMLConnector.WorkThread" $ "Unable to find order in ordermap: " <> (T.pack . show) transaqTrade
Nothing -> log Warning "TXMLConnector.WorkThread" $ "No callback for trade notification!"
fromTransaqTrade transaqTrade order = fromTransaqTrade transaqTrade order =
Trade Trade
@ -436,10 +445,18 @@ workThread = do
trIdMap <- liftIO $ readTVarIO (bsOrderTransactionIdMap brState) trIdMap <- liftIO $ readTVarIO (bsOrderTransactionIdMap brState)
maybeCb <- liftIO $ readTVarIO (bsNotificationCallback brState) maybeCb <- liftIO $ readTVarIO (bsNotificationCallback brState)
case maybeCb of case maybeCb of
Just cb -> case BM.lookupR (TransactionId (fromIntegral $ oTransactionId orderUpdate)) trIdMap of Just cb -> case BM.lookupR (ExchangeOrderId (oOrderNo orderUpdate)) trIdMap <|>
Just oid -> liftIO $ cb (BackendOrderNotification oid (orderStateFromTransaq orderUpdate)) BM.lookupR (TransactionId (fromIntegral $ oTransactionId orderUpdate)) trIdMap of
_ -> pure () Just oid -> do
Nothing -> pure () let notif = BackendOrderNotification oid (orderStateFromTransaq orderUpdate)
log Debug "TXMLConnector.WorkThread" $ "Sending order notification: " <> (T.pack . show) notif
liftIO $ atomically $ do
m <- readTVar (bsOrderTransactionIdMap brState)
when (BM.notMemberR (ExchangeOrderId (oOrderNo orderUpdate)) m) $ do
modifyTVar' (bsOrderTransactionIdMap brState) (BM.insert oid (ExchangeOrderId $ oOrderNo orderUpdate))
liftIO $ cb notif
_ -> log Warning "TXMLConnector.WorkThread" "Unable to find order for order notification"
Nothing -> log Warning "TXMLConnector.WorkThread" "No callback for order notification"
orderStateFromTransaq orderUpdate = orderStateFromTransaq orderUpdate =
case oStatus orderUpdate of case oStatus orderUpdate of
@ -484,6 +501,8 @@ workThread = do
liftIO . atomically $ writeTVar conn StageConnection liftIO . atomically $ writeTVar conn StageConnection
Transaq.Connected -> do Transaq.Connected -> do
log Info "TXMLConnector.WorkThread" "Server connected" log Info "TXMLConnector.WorkThread" "Server connected"
void $ liftIO . sendCommand $ toXml $
CommandChangePass (transaqPassword cfg) "goobaka12"
liftIO . atomically $ writeTVar conn StageConnected liftIO . atomically $ writeTVar conn StageConnected
v <- makeSubscriptions cfg v <- makeSubscriptions cfg
case v of case v of

15
src/Transaq.hs

@ -15,6 +15,7 @@ module Transaq
CommandCancelOrder(..), CommandCancelOrder(..),
CommandGetSecuritiesInfo(..), CommandGetSecuritiesInfo(..),
CommandGetHistoryData(..), CommandGetHistoryData(..),
CommandChangePass(..),
ResponseResult(..), ResponseResult(..),
ResponseCandles(..), ResponseCandles(..),
ResponseServerStatus(..), ResponseServerStatus(..),
@ -310,6 +311,20 @@ instance TransaqCommand CommandGetSecuritiesInfo where
T.pack . showElement $ unode "command" ([strAttr "id" "get_securities_info"], T.pack . showElement $ unode "command" ([strAttr "id" "get_securities_info"],
fmap (unode "security") securities) fmap (unode "security") securities)
data CommandChangePass =
CommandChangePass
{
cOldPass :: T.Text
, cNewPass :: T.Text
} deriving (Show, Eq)
instance TransaqCommand CommandChangePass where
toXml CommandChangePass{..} =
T.pack . showElement $ unode "command"
[strAttr "id" "change_pass",
strAttr "oldpass" $ T.unpack cOldPass,
strAttr "newpass" $ T.unpack cNewPass]
data ResponseResult = data ResponseResult =
ResponseSuccess (Maybe Int64) ResponseSuccess (Maybe Int64)
| ResponseFailure T.Text | ResponseFailure T.Text

Loading…
Cancel
Save