|
|
|
|
@ -1,4 +1,5 @@
@@ -1,4 +1,5 @@
|
|
|
|
|
{-# LANGUAGE MultiWayIf #-} |
|
|
|
|
{-# LANGUAGE OverloadedStrings #-} |
|
|
|
|
|
|
|
|
|
module ATrade.MDS.Protocol ( |
|
|
|
|
QHPRequest(..), |
|
|
|
|
@ -9,10 +10,13 @@ module ATrade.MDS.Protocol (
@@ -9,10 +10,13 @@ module ATrade.MDS.Protocol (
|
|
|
|
|
|
|
|
|
|
-- import ATrade.Types |
|
|
|
|
|
|
|
|
|
import Control.Monad |
|
|
|
|
import Data.Aeson |
|
|
|
|
import Data.Aeson.Types |
|
|
|
|
import Data.Time.Clock |
|
|
|
|
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 | |
|
|
|
|
@ -56,11 +60,11 @@ data QHPRequest =
@@ -56,11 +60,11 @@ data QHPRequest =
|
|
|
|
|
instance FromJSON QHPRequest where |
|
|
|
|
parseJSON = withObject "Request" $ \v -> QHPRequest <$> |
|
|
|
|
v .: "ticker" <*> |
|
|
|
|
v .: "from" <*> |
|
|
|
|
v .: "to" <*> |
|
|
|
|
(v .: "from" >>= parseTime) <*> |
|
|
|
|
(v .: "to" >>= parseTime) <*> |
|
|
|
|
(v .: "timeframe" >>= parseTf) |
|
|
|
|
where |
|
|
|
|
parseTf :: T.Text -> Parser Period |
|
|
|
|
parseTf :: T.Text -> Aeson.Parser Period |
|
|
|
|
parseTf t = if |
|
|
|
|
| t == "M1" -> return Period1Min |
|
|
|
|
| t == "M5" -> return Period5Min |
|
|
|
|
@ -72,6 +76,7 @@ instance FromJSON QHPRequest where
@@ -72,6 +76,7 @@ instance FromJSON QHPRequest where
|
|
|
|
|
| t == "MN" -> return PeriodMonth |
|
|
|
|
| otherwise -> fail "Invalid period specified" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data HAPRequest = |
|
|
|
|
HAPRequest { |
|
|
|
|
hapTicker :: T.Text, |
|
|
|
|
@ -83,6 +88,27 @@ data HAPRequest =
@@ -83,6 +88,27 @@ data HAPRequest =
|
|
|
|
|
instance FromJSON HAPRequest where |
|
|
|
|
parseJSON = withObject "Request" $ \v -> HAPRequest <$> |
|
|
|
|
v .: "ticker" <*> |
|
|
|
|
v .: "start_time" <*> |
|
|
|
|
v .: "end_time" <*> |
|
|
|
|
(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" |
|
|
|
|
|