module Coinbase.Exchange.MarketData
( getProducts
, getTopOfBook
, getTop50OfBook
, getOrderBook
, getProductTicker
, getTrades
, getHistory
, getStats
, getCurrencies
, getExchangeTime
, module Coinbase.Exchange.Types.MarketData
) where
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.Trans.Resource
import Data.List
import qualified Data.Text as T
import Data.Time
import Data.UUID.Aeson ()
#if MIN_VERSION_time(1,5,0)
import Data.Time.Format (defaultTimeLocale)
#else
import System.Locale (defaultTimeLocale)
#endif
import Coinbase.Exchange.Rest
import Coinbase.Exchange.Types
import Coinbase.Exchange.Types.Core
import Coinbase.Exchange.Types.MarketData
getProducts :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> m [Product]
getProducts = coinbaseGet False "/products" voidBody
getTopOfBook :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> ProductId -> m (Book Aggregate)
getTopOfBook (ProductId p) = coinbaseGet False ("/products/" ++ T.unpack p ++ "/book?level=1") voidBody
getTop50OfBook :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> ProductId -> m (Book Aggregate)
getTop50OfBook (ProductId p) = coinbaseGet False ("/products/" ++ T.unpack p ++ "/book?level=2") voidBody
getOrderBook :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> ProductId -> m (Book OrderId)
getOrderBook (ProductId p) = coinbaseGet False ("/products/" ++ T.unpack p ++ "/book?level=3") voidBody
getProductTicker :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> ProductId -> m Tick
getProductTicker (ProductId p) = coinbaseGet False ("/products/" ++ T.unpack p ++ "/ticker") voidBody
getTrades :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> ProductId -> m [Trade]
getTrades (ProductId p) = coinbaseGet False ("/products/" ++ T.unpack p ++ "/trades") voidBody
type StartTime = UTCTime
type EndTime = UTCTime
type Scale = Int
getHistory :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> ProductId -> Maybe StartTime -> Maybe EndTime -> Maybe Scale -> m [Candle]
getHistory (ProductId p) start end scale = coinbaseGet False path voidBody
where path = "/products/" ++ T.unpack p ++ "/candles?" ++ params
params = intercalate "&" $ map (\(k, v) -> k ++ "=" ++ v) $ start' ++ end' ++ scale'
start' = case start of Nothing -> []
Just t -> [( "start", fmt t)]
end' = case end of Nothing -> []
Just t -> [( "end", fmt t)]
scale' = case scale of Nothing -> []
Just s -> [("granularity", show s)]
fmt t = let t' = formatTime defaultTimeLocale "%FT%T." t
in t' ++ take 6 (formatTime defaultTimeLocale "%q" t) ++ "Z"
getStats :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> ProductId -> m Stats
getStats (ProductId p) = coinbaseGet False ("/products/" ++ T.unpack p ++ "/stats") voidBody
getCurrencies :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> m [Currency]
getCurrencies = coinbaseGet False "/currencies" voidBody
getExchangeTime :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)
=> m ExchangeTime
getExchangeTime = coinbaseGet False "/time" voidBody