Execution layer for algorithmic trading
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.

93 lines
2.5 KiB

7 years ago
{-# LANGUAGE OverloadedStrings #-}
module ATrade.Quotes.QHP (
getQuotes,
Period(..),
RequestParams(..)
) where
import ATrade.Types
import Data.Aeson
import qualified Data.Text as T
import qualified Data.ByteString.Lazy as BL
import Data.Binary.Get
import Data.Binary.IEEE754
import Data.Time.Calendar
import Data.Time.Clock.POSIX
import System.ZMQ4
import System.Log.Logger
data Period =
Period1Min |
Period5Min |
Period15Min |
Period30Min |
PeriodHour |
PeriodDay |
PeriodWeek |
PeriodMonth
deriving (Eq)
instance Show Period where
show Period1Min = "M1"
show Period5Min = "M5"
show Period15Min = "M15"
show Period30Min = "M30"
show PeriodHour = "H1"
show PeriodDay = "D"
show PeriodWeek = "W"
show PeriodMonth = "MN"
data RequestParams =
RequestParams
{
endpoint :: T.Text,
ticker :: T.Text,
startDate :: Day,
endDate :: Day,
period :: Period
} deriving (Show, Eq)
instance ToJSON RequestParams where
toJSON p = object [ "ticker" .= ticker p,
"from" .= showGregorian (startDate p),
"to" .= showGregorian (endDate p),
"timeframe" .= show (period p) ]
getQuotes :: Context -> RequestParams -> IO [Bar]
getQuotes ctx params =
withSocket ctx Req $ \sock -> do
debugM "QHP" $ "Connecting to ep: " ++ show (endpoint params)
connect sock $ (T.unpack . endpoint) params
send sock [] (BL.toStrict $ encode params)
response <- receiveMulti sock
case response of
[header, rest] -> if header == "OK"
then return $ reverse $ parseBars (ticker params) $ BL.fromStrict rest
else return []
_ -> return []
parseBars :: TickerId -> BL.ByteString -> [Bar]
parseBars tickerId input =
case runGetOrFail parseBar input of
Left _ -> []
Right (rest, _, bar) -> bar : parseBars tickerId rest
where
parseBar = do
rawTimestamp <- realToFrac <$> getWord64le
baropen <- getDoublele
barhigh <- getDoublele
barlow <- getDoublele
barclose <- getDoublele
barvolume <- getWord64le
return Bar
{
barSecurity = tickerId,
barTimestamp = posixSecondsToUTCTime rawTimestamp,
barOpen = fromDouble baropen,
barHigh = fromDouble barhigh,
barLow = fromDouble barlow,
barClose = fromDouble barclose,
barVolume = toInteger barvolume
}