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.
58 lines
1.8 KiB
58 lines
1.8 KiB
{-# LANGUAGE FlexibleContexts #-} |
|
{-# LANGUAGE OverloadedStrings #-} |
|
|
|
module ATrade.Quotes.QTIS |
|
( |
|
TickerInfo(..), |
|
qtisGetTickersInfo |
|
) where |
|
|
|
import ATrade.Exceptions |
|
import ATrade.Logging (Message, logInfo) |
|
import ATrade.Types |
|
import Colog (WithLog) |
|
import Control.Exception.Safe |
|
import Control.Monad.IO.Class (MonadIO (liftIO)) |
|
import Data.Aeson |
|
import qualified Data.ByteString.Char8 as BC8 |
|
import qualified Data.ByteString.Lazy as BL |
|
import qualified Data.Text as T |
|
import System.ZMQ4 |
|
|
|
data TickerInfo = TickerInfo { |
|
tiTicker :: T.Text, |
|
tiLotSize :: Integer, |
|
tiTickSize :: Price |
|
} deriving (Show, Eq) |
|
|
|
instance FromJSON TickerInfo where |
|
parseJSON = withObject "object" (\obj -> |
|
TickerInfo <$> |
|
obj .: "ticker" <*> |
|
obj .: "lot_size" <*> |
|
obj .: "tick_size") |
|
|
|
instance ToJSON TickerInfo where |
|
toJSON ti = object [ "ticker" .= tiTicker ti, |
|
"lot_size" .= tiLotSize ti, |
|
"tick_size" .= tiTickSize ti ] |
|
|
|
qtisGetTickersInfo :: (WithLog env Message m, MonadIO m) => Context -> T.Text -> TickerId -> m TickerInfo |
|
qtisGetTickersInfo ctx endpoint tickerId = do |
|
logInfo "QTIS" $ "Requesting ticker: " <> tickerId <> " from " <> endpoint |
|
liftIO $ withSocket ctx Req $ \sock -> do |
|
connect sock $ T.unpack endpoint |
|
send sock [] $ BL.toStrict tickerRequest |
|
response <- receiveMulti sock |
|
let r = parseResponse response |
|
case r of |
|
Just resp -> return resp |
|
Nothing -> throw $ QTISFailure "Can't parse response" |
|
where |
|
tickerRequest = encode $ object ["ticker" .= tickerId] |
|
parseResponse :: [BC8.ByteString] -> Maybe TickerInfo |
|
parseResponse (header:payload:_) = if header == "OK" |
|
then decode $ BL.fromStrict payload |
|
else Nothing |
|
parseResponse _ = Nothing |
|
|
|
|