Market Data Storage Server
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.
 

114 lines
3.0 KiB

{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedStrings #-}
module ATrade.MDS.Protocol (
QHPRequest(..),
HAPRequest(..),
Period(..),
periodSeconds
) where
-- import ATrade.Types
import Control.Monad
import Data.Aeson
import Data.Aeson.Types as Aeson
import Data.Attoparsec.Text as Attoparsec
import qualified Data.Text as T
import Data.Time.Calendar
import Data.Time.Clock
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"
periodSeconds :: Period -> Int
periodSeconds Period1Min = 60
periodSeconds Period5Min = 60 * 5
periodSeconds Period15Min = 60 * 15
periodSeconds Period30Min = 60 * 30
periodSeconds PeriodHour = 3600
periodSeconds PeriodDay = 86400
periodSeconds PeriodWeek = 86400 * 7
periodSeconds PeriodMonth = 86400 * 7 * 4
data QHPRequest =
QHPRequest {
rqTicker :: T.Text,
rqStartTime :: UTCTime,
rqEndTime :: UTCTime,
rqPeriod :: Period
} deriving (Show, Eq)
instance FromJSON QHPRequest where
parseJSON = withObject "Request" $ \v -> QHPRequest <$>
v .: "ticker" <*>
(v .: "from" >>= parseTime) <*>
(v .: "to" >>= parseTime) <*>
(v .: "timeframe" >>= parseTf)
where
parseTf :: T.Text -> Aeson.Parser Period
parseTf t = if
| t == "M1" -> return Period1Min
| t == "M5" -> return Period5Min
| t == "M15" -> return Period15Min
| t == "M30" -> return Period30Min
| t == "H1" -> return PeriodHour
| t == "D" -> return PeriodDay
| t == "W" -> return PeriodWeek
| t == "MN" -> return PeriodMonth
| otherwise -> fail "Invalid period specified"
data HAPRequest =
HAPRequest {
hapTicker :: T.Text,
hapStartTime :: UTCTime,
hapEndTime :: UTCTime,
hapTimeframeSec :: Int
} deriving (Show, Eq)
instance FromJSON HAPRequest where
parseJSON = withObject "Request" $ \v -> HAPRequest <$>
v .: "ticker" <*>
(v .: "start_time" >>= parseTime) <*>
(v .: "end_time" >>= parseTime) <*>
v .: "timeframe_sec"
parseTime :: T.Text -> Aeson.Parser UTCTime
parseTime text = case Attoparsec.parse timeParse text of
Done _ r -> return r
_ -> fail $ "Can't parse time: " ++ T.unpack text
timeParse :: Attoparsec.Parser UTCTime
timeParse = do
year <- decimal
void $ char '-'
month <- decimal
void $ char '-'
day <- decimal
void $ char 'T'
hour <- decimal
void $ char '-'
minute <- decimal
void $ char '-'
sec <- decimal
case fromGregorianValid year month day of
Just gregorianDay -> return $ UTCTime gregorianDay (secondsToDiffTime $ hour * 3600 + minute * 60 + sec)
_ -> fail "Can't parse date: invalid values"