{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} module Network.GDAX.Types.Private where import Data.Aeson import Data.HashMap.Strict (HashMap) import Data.Int import Data.Monoid import Data.Text (Text) import qualified Data.Text as T import Data.Time import Data.Typeable import Data.Vector (Vector) import GHC.Generics import Network.GDAX.Parsers import Network.GDAX.Types.Shared import Text.Read (readMaybe) import Text.Regex.TDFA import Text.Regex.TDFA.Text () data Account = Account { _accountId :: AccountId , _accountProfileId :: ProfileId , _accountCurrency :: CurrencyId , _accountBalance :: Double , _accountAvailable :: Double , _accountHold :: Double , _accountMargin :: Maybe MarginAccount } deriving (Show, Typeable, Generic) data MarginAccount = MarginAccount { _maccountFundedAmount :: Double , _maccountDefaultAmount :: Double } deriving (Show, Typeable, Generic) instance FromJSON Account where parseJSON = withObject "Account" $ \o -> do Account <$> o .: "id" <*> o .: "profile_id" <*> o .: "currency" <*> (o .: "balance" >>= textRead) <*> (o .: "available" >>= textRead) <*> (o .: "hold" >>= textRead) <*> do enabled <- o .:? "margin_enabled" if enabled == (Just True) then (\a b -> Just $ MarginAccount a b) <$> (o .: "funded_amount" >>= textRead) <*> (o .: "default_amount" >>= textRead) else return Nothing data Entry = Entry { _entryId :: EntryId , _entryType :: EntryType , _entryCreatedAt :: UTCTime , _entryAmount :: Double , _entryBalance :: Double , _entryDetails :: EntryDetails } deriving (Show, Typeable, Generic) instance FromJSON Entry where parseJSON = withObject "Entry" $ \o -> Entry <$> o .: "id" <*> o .: "type" <*> o .: "created_at" <*> (o .: "amount" >>= textRead) <*> (o .: "balance" >>= textRead) <*> o .: "details" data EntryDetails = EntryDetails { _edetailsOrderId :: Maybe OrderId , _edetailsTradeId :: Maybe TradeId , _edetailsProductId :: Maybe ProductId } deriving (Show, Typeable, Generic) instance FromJSON EntryDetails where parseJSON = withObject "EntryDetails" $ \o -> EntryDetails <$> o .:? "order_id" <*> o .:? "trade_id" <*> o .:? "product_id" data Hold = Hold { _holdId :: HoldId , _holdAccountId :: AccountId , _holdCreatedAt :: UTCTime , _holdUpdatedAt :: UTCTime , _holdAmount :: Double , _holdReference :: HoldReference } deriving (Show, Typeable, Generic) data HoldReference = HoldOrder OrderId | HoldTransfer TransferId deriving (Show, Typeable, Generic) instance FromJSON Hold where parseJSON = withObject "Hold" $ \o -> Hold <$> o .: "id" <*> o .: "account_id" <*> o .: "created_at" <*> o .: "updated_at" <*> o .: "amount" <*> parseRef o where parseRef o = do t <- o .: "type" case t of "order" -> HoldOrder <$> o .: "ref" "transfer" -> HoldTransfer <$> o .: "ref" _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid type for hold orders." data NewOrder = NewOrderLimit NewLimitOrder | NewOrderMarket NewMarketOrder | NewOrderStop NewStopOrder deriving (Show, Typeable, Generic) instance ToJSON NewOrder where toJSON (NewOrderLimit o) = toJSON o toJSON (NewOrderMarket o) = toJSON o toJSON (NewOrderStop o) = toJSON o data NewLimitOrder = NewLimitOrder { _nloClientOrderId :: Maybe ClientOrderId , _nloSide :: Side , _nloProductId :: ProductId , _nloSelfTradePrevention :: SelfTradePolicy , _nloPrice :: Double , _nloSize :: Double , _nloTimeInForce :: Maybe TimeInForce , _nloCancelAfter :: Maybe CancelAfterPolicy , _nloPostOnly :: Maybe Bool } deriving (Show, Typeable, Generic) instance ToJSON NewLimitOrder where toJSON NewLimitOrder{..} = object [ "client_oid" .= _nloClientOrderId , "type" .= ("limit"::Text) , "side" .= _nloSide , "product_id" .= _nloProductId , "stp" .= _nloSelfTradePrevention , "price" .= _nloPrice , "size" .= _nloSize , "time_in_force" .= _nloTimeInForce , "cancel_after" .= _nloCancelAfter , "post_only" .= _nloPostOnly ] data NewMarketOrder = NewMarketOrder { _nmoClientOrderId :: Maybe ClientOrderId , _nmoSide :: Side , _nmoProductId :: ProductId , _nmoSelfTradePrevention :: SelfTradePolicy , _nmoMarketDesire :: MarketDesire } deriving (Show, Typeable, Generic) instance ToJSON NewMarketOrder where toJSON NewMarketOrder{..} = object $ [ "client_oid" .= _nmoClientOrderId , "type" .= ("market"::Text) , "side" .= _nmoSide , "product_id" .= _nmoProductId , "stp" .= _nmoSelfTradePrevention ] <> case _nmoMarketDesire of (DesireSize s) -> [ "size" .= s ] (DesireFunds f) -> [ "funds" .= f ] data NewStopOrder = NewStopOrder { _nsoClientOrderId :: Maybe ClientOrderId , _nsoSide :: Side , _nsoProductId :: ProductId , _nsoSelfTradePrevention :: SelfTradePolicy , _nsoPrice :: Double , _nsoMarketDesire :: MarketDesire } deriving (Show, Typeable, Generic) instance ToJSON NewStopOrder where toJSON NewStopOrder{..} = object $ [ "client_oid" .= _nsoClientOrderId , "type" .= ("stop"::Text) , "side" .= _nsoSide , "product_id" .= _nsoProductId , "stp" .= _nsoSelfTradePrevention , "price" .= _nsoPrice ] <> case _nsoMarketDesire of (DesireSize s) -> [ "size" .= s ] (DesireFunds f) -> [ "funds" .= f ] data MarketDesire = DesireSize Double -- ^ Desired amount in commodity (e.g. BTC) | DesireFunds Double -- ^ Desired amount in quote currency (e.g. USD) deriving (Show, Typeable, Generic) data TimeInForce = GoodTillCanceled | GoodTillTime | ImmediateOrCancel | FillOrKill deriving (Eq, Ord, Typeable, Generic) instance Show TimeInForce where show GoodTillCanceled = "GTC" show GoodTillTime = "GTT" show ImmediateOrCancel = "IOC" show FillOrKill = "FOK" instance ToJSON TimeInForce where toJSON = String . T.pack . show instance FromJSON TimeInForce where parseJSON = withText "TimeInForce" $ \t -> case t of "GTC" -> pure GoodTillCanceled "GTT" -> pure GoodTillTime "IOC" -> pure ImmediateOrCancel "FOK" -> pure FillOrKill _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid time in force." data SelfTradePolicy = DecreaseOrCancel | CancelOldest | CancelNewest | CancelBoth deriving (Eq, Ord, Typeable, Generic) instance Show SelfTradePolicy where show DecreaseOrCancel = "dc" show CancelOldest = "co" show CancelNewest = "cn" show CancelBoth = "cb" instance ToJSON SelfTradePolicy where toJSON = String . T.pack . show instance FromJSON SelfTradePolicy where parseJSON = withText "SelfTradePolicy" $ \t -> case t of "dc" -> pure DecreaseOrCancel "co" -> pure CancelOldest "cn" -> pure CancelNewest "cb" -> pure CancelBoth _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid self trade policy." data CancelAfterPolicy = CancelAfterMinutes Word | CancelAfterHours Word | CancelAfterDays Word deriving (Typeable, Generic) instance Show CancelAfterPolicy where show (CancelAfterMinutes w) = show w <> " mintes" show (CancelAfterHours w) = show w <> " hours" show (CancelAfterDays w) = show w <> " days" instance ToJSON CancelAfterPolicy where toJSON = String . T.pack . show instance FromJSON CancelAfterPolicy where parseJSON = withText "CancelAfterPolicy" $ \t -> case t =~ ("([0-9]+) (days|minutes|hours)"::Text) of ((_, _, _, [mv, mtag]) :: (Text, Text, Text, [Text])) -> case readMaybe $ T.unpack mv of Just v -> case mtag of "minutes" -> pure $ CancelAfterMinutes v "hours" -> pure $ CancelAfterHours v "days" -> pure $ CancelAfterDays v _ -> fail $ T.unpack $ "'" <> mtag <> "' was not 'minutes', 'hours', or 'days'." Nothing -> fail $ T.unpack $ "'" <> mv <> "' could not be parsed as a word." _ -> fail $ T.unpack $ "'" <> t <> "' did not match regex validation." -- data NewMarginOrder -- Implement with the rest of margin accounts. -- = NewMarginOrder -- { -- } -- deriving (Show, Typeable, Generic) data NewOrderConfirmation = NewOrderConfirmation { _nocOrderId :: OrderId } deriving (Show, Typeable, Generic) instance FromJSON NewOrderConfirmation where parseJSON = withObject "NewOrderConfirmation" $ \o -> NewOrderConfirmation <$> o .: "id" data Order = Order { _orderId :: OrderId , _orderPrice :: Double , _orderSize :: Double , _orderProductId :: ProductId , _orderSide :: Side , _orderSelfTradePrevention :: SelfTradePolicy , _orderType :: OrderType , _orderTimeInForce :: TimeInForce , _orderPostOnly :: Bool , _orderCreatedAt :: UTCTime , _orderFillFees :: Double , _orderFilledSize :: Double , _orderExecutedValue :: Double , _orderStatus :: OrderStatus , _orderSettled :: Bool } deriving (Show, Typeable, Generic) instance FromJSON Order where parseJSON = withObject "Order" $ \o -> Order <$> o .: "id" <*> o .: "price" <*> o .: "size" <*> o .: "product_id" <*> o .: "side" <*> o .: "stp" <*> o .: "type" <*> o .: "time_in_force" <*> o .: "post_only" <*> o .: "created_at" <*> o .: "fill_fees" <*> o .: "filled_size" <*> o .: "executed_value" <*> o .: "status" <*> o .: "settled" data Fill = Fill { _fillTradeId :: TradeId , _fillProductId :: ProductId , _fillPrice :: Double , _fillSize :: Double , _fillOrderId :: OrderId , _fillCreatedAt :: UTCTime , _fillLiquidity :: Liquidity , _fillFee :: Double , _fillSettled :: Bool , _fillSide :: Side } deriving (Show, Typeable, Generic) instance FromJSON Fill where parseJSON = withObject "Fill" $ \o -> Fill <$> o .: "trade_id" <*> o .: "product_id" <*> o .: "price" <*> o .: "size" <*> o .: "order_id" <*> o .: "created_at" <*> o .: "liquidity" <*> o .: "fee" <*> o .: "settled" <*> o .: "side" data Funding = Funding { _fundingId :: FundingId , _fundingOrderId :: OrderId , _fundingProfileId :: ProfileId , _fundingAmount :: Double , _fundingStatus :: FundingStatus , _fundingCreatedAt :: UTCTime , _fundingCurrency :: CurrencyId , _fundingRepaidAmount :: Double , _fundingDefaultAmount :: Double , _fundingRepaidDefault :: Bool } deriving (Show, Typeable, Generic) instance FromJSON Funding where parseJSON = withObject "Funding" $ \o -> Funding <$> o .: "id" <*> o .: "order_id" <*> o .: "profile_id" <*> o .: "amount" <*> o .: "status" <*> o .: "created_at" <*> o .: "currency" <*> o .: "repaid_amount" <*> o .: "default_amount" <*> o .: "repaid_default" data NewMarginTransfer = NewMarginTransfer { _nmtMarginProfileId :: ProfileId , _nmtType :: MarginType , _nmtCurrency :: CurrencyId , _nmtAmount :: Double } deriving (Show, Typeable, Generic) instance ToJSON NewMarginTransfer where toJSON NewMarginTransfer{..} = object [ "margin_profile_id" .= _nmtMarginProfileId , "type" .= _nmtType , "currency" .= _nmtCurrency , "amount" .= _nmtAmount ] data MarginTransfer = MarginTransfer { _mtCreatedAt :: UTCTime , _mtId :: MarginTransferId , _mtUserId :: UserId , _mtProfileId :: ProfileId , _mtMarginProfileId :: ProfileId , _mtType :: MarginType , _mtAmount :: Double , _mtCurrency :: CurrencyId , _mtAccountId :: AccountId , _mtMarginAccountId :: AccountId , _mtMarginProductId :: ProductId , _mtStatus :: MarginStatus , _mtNonce :: Int64 } deriving (Show, Typeable, Generic) instance FromJSON MarginTransfer where parseJSON = withObject "MarginTransfer" $ \o -> MarginTransfer <$> o .: "created_at" <*> o .: "id" <*> o .: "user_id" <*> o .: "profile_id" <*> o .: "margin_profile_id" <*> o .: "type" <*> o .: "amount" <*> o .: "currency" <*> o .: "accountId" <*> o .: "margin_account_id" <*> o .: "margin_product_id" <*> o .: "status" <*> o .: "nonce" data Position = Position { _posStatus :: PositionStatus , _posFunding :: PositionFunding , _posAccounts :: HashMap Text PositionAccount -- ^ Text should be CurrencyId, but it will have to be fixed later. , _posMarginCall :: MarginCall , _posUserId :: UserId , _posProfileId :: ProfileId , _posPositionInfo :: PositionInfo , _posProductId :: ProductId } deriving (Show, Typeable, Generic) instance FromJSON Position where parseJSON = withObject "Position" $ \o -> Position <$> o .: "status" <*> o .: "funding" <*> o .: "accounts" <*> o .: "margin_call" <*> o .: "user_id" <*> o .: "profile_id" <*> o .: "position" <*> o .: "product_id" data PositionFunding = PositionFunding { _posfunMaxFundingValue :: Double , _posfunFundingValue :: Double , _posfunOldestOutstanding :: OutstandingFunding } deriving (Show, Typeable, Generic) instance FromJSON PositionFunding where parseJSON = withObject "PositionFunding" $ \o -> PositionFunding <$> o .: "max_funding_value" <*> o .: "funding_value" <*> o .: "oldest_outstanding" data OutstandingFunding = OutstandingFunding { _ofunId :: FundingId , _ofunOrderId :: OrderId , _ofunCreatedAt :: UTCTime , _ofunCurrency :: CurrencyId , _ofunAccountId :: AccountId , _ofunAmount :: Double } deriving (Show, Typeable, Generic) instance FromJSON OutstandingFunding where parseJSON = withObject "OutstandingFunding" $ \o -> OutstandingFunding <$> o .: "id" <*> o .: "order_id" <*> o .: "created_at" <*> o .: "currency" <*> o .: "account_id" <*> o .: "amount" data PositionAccount = PositionAccount { _paccountId :: AccountId , _paccountBalance :: Double , _paccountHold :: Double , _paccountFundedAmount :: Double , _paccountDefaultAmount :: Double } deriving (Show, Typeable, Generic) instance FromJSON PositionAccount where parseJSON = withObject "PositionAccount" $ \o -> PositionAccount <$> o .: "id" <*> o .: "balance" <*> o .: "hold" <*> o .: "funded_amount" <*> o .: "default_amount" data MarginCall = MarginCall { _mcallActive :: Bool , _mcallPrice :: Double , _mcallSide :: Side , _mcallSize :: Double , _mcallFunds :: Double } deriving (Show, Typeable, Generic) instance FromJSON MarginCall where parseJSON = withObject "MarginCall" $ \o -> MarginCall <$> o .: "active" <*> o .: "price" <*> o .: "side" <*> o .: "size" <*> o .: "funds" data PositionInfo = PositionInfo { _pinfoType :: PositionType , _pinfoSize :: Double , _pinfoComplement :: Double , _pinfoMaxSize :: Double } deriving (Show, Typeable, Generic) instance FromJSON PositionInfo where parseJSON = withObject "PositionInfo" $ \o -> PositionInfo <$> o .: "type" <*> o .: "size" <*> o .: "complement" <*> o .: "max_size" data Deposit = Deposit { _depositAmount :: Double , _depositCurrency :: CurrencyId , _depositPaymentMethod :: PaymentMethodId } deriving (Show, Typeable, Generic) instance ToJSON Deposit where toJSON Deposit{..} = object [ "amount" .= _depositAmount , "currency" .= _depositCurrency , "payment_method_id" .= _depositPaymentMethod ] data DepositReceipt = DepositReceipt { _dreceiptId :: DepositId , _dreceiptAmount :: Double , _dreceiptCurrency :: CurrencyId , _dreceiptPayoutAt :: UTCTime } deriving (Show, Typeable, Generic) instance FromJSON DepositReceipt where parseJSON = withObject "DepositReceipt" $ \o -> DepositReceipt <$> o .: "id" <*> (o .: "amount" >>= textRead) <*> o .: "currency" <*> o .: "payput_at" data CoinbaseDeposit = CoinbaseDeposit { _cdepositAmount :: Double , _cdepositCurrency :: CurrencyId , _cdepositCoinbaseAccount :: AccountId } deriving (Show, Typeable, Generic) instance ToJSON CoinbaseDeposit where toJSON CoinbaseDeposit{..} = object [ "amount" .= _cdepositAmount , "currency" .= _cdepositCurrency , "coinbase_account_id" .= _cdepositCoinbaseAccount ] data CoinbaseDepositReceipt = CoinbaseDepositReceipt { _cdreceiptId :: DepositId , _cdreceiptAmount :: Double , _cdreceiptCurrency :: CurrencyId } deriving (Show, Typeable, Generic) instance FromJSON CoinbaseDepositReceipt where parseJSON = withObject "CoinbaseDepositReceipt" $ \o -> CoinbaseDepositReceipt <$> o .: "id" <*> (o .: "amount" >>= textRead) <*> o .: "currency" data Withdraw = Withdraw { _withdrawAmount :: Double , _withdrawCurrency :: CurrencyId , _withdrawPaymentMethod :: PaymentMethodId } deriving (Show, Typeable, Generic) instance ToJSON Withdraw where toJSON Withdraw{..} = object [ "amount" .= _withdrawAmount , "currency" .= _withdrawCurrency , "payment_method_id" .= _withdrawPaymentMethod ] data WithdrawReceipt = WithdrawReceipt { _wreceiptId :: WithdrawId , _wreceiptAmount :: Double , _wreceiptCurrency :: CurrencyId , _wreceiptPayoutAt :: UTCTime } deriving (Show, Typeable, Generic) instance FromJSON WithdrawReceipt where parseJSON = withObject "WithdrawReceipt" $ \o -> WithdrawReceipt <$> o .: "id" <*> (o .: "amount" >>= textRead) <*> o .: "currency" <*> o .: "payout_at" data CoinbaseWithdraw = CoinbaseWithdraw { _cwithdrawAmount :: Double , _cwithdrawCurrency :: CurrencyId , _cwithdrawCoinbaseAccount :: AccountId } deriving (Show, Typeable, Generic) instance ToJSON CoinbaseWithdraw where toJSON CoinbaseWithdraw{..} = object [ "amount" .= _cwithdrawAmount , "currency" .= _cwithdrawCurrency , "coinbase_account_id" .= _cwithdrawCoinbaseAccount ] data CoinbaseWithdrawReceipt = CoinbaseWithdrawReceipt { _cwreceiptId :: WithdrawId , _cwreceiptAmount :: Double , _cwreceiptCurrency :: CurrencyId } deriving (Show, Typeable, Generic) instance FromJSON CoinbaseWithdrawReceipt where parseJSON = withObject "CoinbaseWithdrawReceipt" $ \o -> CoinbaseWithdrawReceipt <$> o .: "id" <*> (o .: "amount" >>= textRead) <*> o .: "currency" data CryptoWithdraw = CryptoWithdraw { _crwithdrawAmount :: Double , _crwithdrawCurrency :: CurrencyId , _crwithdrawCoinbaseAccount :: AccountId } deriving (Show, Typeable, Generic) instance ToJSON CryptoWithdraw where toJSON CryptoWithdraw{..} = object [ "amount" .= _crwithdrawAmount , "currency" .= _crwithdrawCurrency , "payment_method_id" .= _crwithdrawCoinbaseAccount ] data CryptoWithdrawReceipt = CryptoWithdrawReceipt { _crwreceiptId :: WithdrawId , _crwreceiptAmount :: Double , _crwreceiptCurrency :: CurrencyId } deriving (Show, Typeable, Generic) instance FromJSON CryptoWithdrawReceipt where parseJSON = withObject "CryptoWithdrawReceipt" $ \o -> CryptoWithdrawReceipt <$> o .: "id" <*> (o .: "amount" >>= textRead) <*> o .: "currency" data PaymentMethod = PaymentMethod { _pmethId :: PaymentMethodId , _pmethType :: PaymentMethodType , _pmethName :: Text , _pmethCurrency :: CurrencyId , _pmethPrimaryBuy :: Bool , _pmethPrimarySell :: Bool , _pmethAllowBuy :: Bool , _pmethAllowSell :: Bool , _pmethAllowDeposit :: Bool , _pmethAllowWithdraw :: Bool , _pmethLimits :: Limits } deriving (Show, Typeable, Generic) instance FromJSON PaymentMethod where parseJSON = withObject "PaymentMethod" $ \o -> PaymentMethod <$> o .: "id" <*> o .: "type" <*> o .: "name" <*> o .: "currency" <*> o .: "primary_buy" <*> o .: "primary_sell" <*> o .: "allow_buy" <*> o .: "allow_sell" <*> o .: "allow_deposit" <*> o .: "allow_withdraw" <*> o .: "limits" data Limits = Limits { _limitsBuy :: Vector Limit , _limitsInstantBuy :: Vector Limit , _limitsSell :: Vector Limit , _limitsDeposit :: Vector Limit } deriving (Show, Typeable, Generic) instance FromJSON Limits where parseJSON = withObject "Limits" $ \o -> Limits <$> (nothingToEmptyVector <$> o .:? "buy") <*> (nothingToEmptyVector <$> o .:? "instant_buy") <*> (nothingToEmptyVector <$> o .:? "sell") <*> (nothingToEmptyVector <$> o .:? "deposit") data Limit = Limit { _limitPeriodInDays :: Word , _limitTotal :: LimitValue , _limitRemaining :: LimitValue } deriving (Show, Typeable, Generic) instance FromJSON Limit where parseJSON = withObject "Limit" $ \o -> Limit <$> o .: "period_in_days" <*> o .: "total" <*> o .: "remaining" data LimitValue = LimitValue { _lvalAmount :: Double , _lvalCurrency :: CurrencyId } deriving (Show, Typeable, Generic) instance FromJSON LimitValue where parseJSON = withObject "LimitValue" $ \o -> LimitValue <$> (o .: "amount" >>= textRead) <*> o .: "currency" data CoinbaseAccount = CoinbaseAccount { _cbaccountId :: AccountId , _cbaccountName :: Text , _cbaccountBalance :: Double , _cbaccountCurrency :: CurrencyId , _cbaccountType :: CoinbaseAccountType , _cbaccountPrimary :: Bool , _cbaccountActive :: Bool , _cbaccountWireDepositInfo :: Maybe WireDepositInfo , _cbaccountSepaDepositInfo :: Maybe SepaDepositInfo } deriving (Show, Typeable, Generic) instance FromJSON CoinbaseAccount where parseJSON = withObject "CoinbaseAccount" $ \o -> CoinbaseAccount <$> o .: "id" <*> o .: "name" <*> (o .: "balance" >>= textRead) <*> o .: "currency" <*> o .: "type" <*> o .: "primary" <*> o .: "active" <*> o .:? "wire_deposit_information" <*> o .:? "sepa_deposit_information" data WireDepositInfo = WireDepositInfo { _wdiAccountNumber :: Integer , _wdiRoutingNumber :: Integer , _wdiBankName :: Text , _wdiBankAddress :: Text , _wdiBankCountry :: Country , _wdiAccountName :: Text , _wdiAccountAddress :: Text , _wdiReference :: Text } deriving (Show, Typeable, Generic) instance FromJSON WireDepositInfo where parseJSON = withObject "WireDepositInfo" $ \o -> WireDepositInfo <$> (o .: "account_number" >>= textRead) <*> (o .: "routing_number" >>= textRead) <*> o .: "bank_name" <*> o .: "bank_address" <*> o .: "bank_country" <*> o .: "account_name" <*> o .: "account_address" <*> o .: "reference" data Country = Country { _countryCode :: Text , _countryName :: Text } deriving (Show, Typeable, Generic) instance FromJSON Country where parseJSON = withObject "Country" $ \o -> Country <$> o .: "code" <*> o .: "name" data SepaDepositInfo = SepaDepositInfo { _sepaIban :: Text , _sepaSwift :: Text , _sepaBankName :: Text , _sepaBankAddress :: Text , _sepaBankCountryName :: Text , _sepaAccountName :: Text , _sepaAccountAddress :: Text , _sepaReference :: Text } deriving (Show, Typeable, Generic) instance FromJSON SepaDepositInfo where parseJSON = withObject "SepaDepositInfo" $ \o -> SepaDepositInfo <$> o .: "iban" <*> o .: "swift" <*> o .: "bank_name" <*> o .: "bank_address" <*> o .: "bank_country_name" <*> o .: "account_name" <*> o .: "account_address" <*> o .: "reference" data NewReport = NewReport { _nreportType :: ReportType , _nreportStartDate :: UTCTime , _nreportEndDate :: UTCTime } deriving (Show, Typeable, Generic) instance ToJSON NewReport where toJSON NewReport{..} = object [ "type" .= _nreportType , "start_date" .= _nreportStartDate , "end_date" .= _nreportEndDate ] data Report = Report { _reportId :: ReportId , _reportType :: ReportType , _reportStatus :: ReportStatus , _reportCreatedAt :: UTCTime , _reportCompletedAt :: Maybe UTCTime , _reportExpiresAt :: UTCTime , _reportFileUrl :: Maybe Text , _reportParams :: ReportParams } deriving (Show, Typeable, Generic) instance FromJSON Report where parseJSON = withObject "Report" $ \o -> Report <$> o .: "id" <*> o .: "type" <*> o .: "status" <*> o .: "created_at" <*> o .: "completed_at" <*> o .: "expires_at" <*> o .: "file_url" <*> o .: "params" data ReportParams = ReportParams { _rparamStartDate :: UTCTime , _rparamEndDate :: UTCTime } deriving (Show, Typeable, Generic) instance FromJSON ReportParams where parseJSON = withObject "ReportParmas" $ \o -> ReportParams <$> o .: "start_date" <*> o .: "end_date" data TrailingVolume = TrailingVolume { _tvProductId :: ProductId , _tvExchangeVolume :: Double , _tvVolume :: Double , _tvRecorededAt :: UTCTime } deriving (Show, Typeable, Generic) instance FromJSON TrailingVolume where parseJSON = withObject "TrailingVolume" $ \o -> TrailingVolume <$> o .: "product_id" <*> o .: "exchange_volume" <*> o .: "volume" <*> o .: "recorded_at"