{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} module Network.GDAX.Types.Shared where import Data.Aeson import Data.Hashable import Data.Int import Data.Monoid import Data.Scientific import Data.String import Data.Text (Text) import qualified Data.Text as T import Data.Typeable import Data.UUID import GHC.Generics import Text.Read (readMaybe) newtype AccountId = AccountId { unAccountId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show AccountId where show = show . unAccountId newtype UserId = UserId { unUserId :: Text } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, IsString, Hashable) instance Show UserId where show = T.unpack . unUserId newtype ProfileId = ProfileId { unProfileId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show ProfileId where show = show . unProfileId newtype OrderId = OrderId { unOrderId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show OrderId where show = show . unOrderId data OrderType = OrderLimit | OrderMarket deriving (Typeable, Generic) instance Hashable OrderType instance Show OrderType where show OrderLimit = "limit" show OrderMarket = "market" instance FromJSON OrderType where parseJSON = withText "OrderType" $ \t -> case t of "limit" -> pure OrderLimit "market" -> pure OrderMarket _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid order type." newtype StopType = StopType { unStopType :: Text } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, IsString, Hashable) instance Show StopType where show = T.unpack . unStopType newtype ProductId = ProductId { unProductId :: Text } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, IsString, Hashable) instance Show ProductId where show = T.unpack . unProductId newtype Sequence = Sequence { unSequence :: Int64 } deriving (Eq, Ord, Enum, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show Sequence where show = show . unSequence newtype TradeId = TradeId { unTradeId :: Int64 } deriving (Eq, Ord, Enum, Typeable, Generic, Hashable) instance Show TradeId where show = show . unTradeId instance FromJSON TradeId where parseJSON (String s) = case readMaybe $ T.unpack s of Nothing -> fail "TradeId string could not be read as integer." Just v -> pure $ TradeId v parseJSON (Number n) = case toBoundedInteger n of Nothing -> fail "TradeId scientific could not be converted into an integer." Just v -> pure $ TradeId v parseJSON _ = fail "TradeId can only accept a number or string." data Side = Buy | Sell deriving (Typeable, Generic) instance Hashable Side instance Show Side where show Buy = "buy" show Sell = "sell" instance ToJSON Side where toJSON = String . T.pack . show instance FromJSON Side where parseJSON = withText "Side" $ \t -> case t of "buy" -> pure Buy "sell" -> pure Sell _ -> fail "Side was not either buy or sell." newtype CurrencyId = CurrencyId { unCurrencyId :: Text } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, IsString, Hashable) instance Show CurrencyId where show = T.unpack . unCurrencyId newtype EntryId = EntryId { unEntryId :: Int64 } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show EntryId where show = show . unEntryId data EntryType = EntryMatch | EntryFee | EntryTransfer deriving (Eq, Typeable, Generic) instance Hashable EntryType instance Show EntryType where show EntryMatch = "match" show EntryFee = "fee" show EntryTransfer = "transfer" instance FromJSON EntryType where parseJSON = withText "EntryType" $ \t -> case t of "match" -> pure EntryMatch "fee" -> pure EntryFee "transfer" -> pure EntryTransfer _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid entry type." newtype TransferId = TransferId { unTransferId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show TransferId where show = show . unTransferId newtype HoldId = HoldId { unHoldId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show HoldId where show = show . unHoldId newtype ClientOrderId = ClientOrderId { unClientOrderId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show ClientOrderId where show = show . unClientOrderId data OrderStatus = OrderOpen | OrderPending | OrderActive | OrderDone | OrderSettled deriving (Typeable, Generic) instance Hashable OrderStatus instance Show OrderStatus where show OrderOpen = "open" show OrderPending = "pending" show OrderActive = "active" show OrderDone = "done" show OrderSettled = "settled" instance ToJSON OrderStatus where toJSON = String . T.pack . show instance FromJSON OrderStatus where parseJSON = withText "OrderStatus" $ \s -> case s of "open" -> pure OrderOpen "pending" -> pure OrderPending "active" -> pure OrderActive "done" -> pure OrderDone "settled" -> pure OrderSettled _ -> fail $ T.unpack $ "'" <> s <> "' is not a valid order status." data Liquidity = LiquidityMaker | LiquidityTaker deriving (Typeable, Generic) instance Hashable Liquidity instance Show Liquidity where show LiquidityMaker = "M" show LiquidityTaker = "T" instance ToJSON Liquidity where toJSON = String . T.pack . show instance FromJSON Liquidity where parseJSON = withText "Liquidity" $ \t -> case t of "M" -> pure LiquidityMaker "T" -> pure LiquidityTaker _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid liquidity." newtype FundingId = FundingId { unFundingId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show FundingId where show = show . unFundingId data FundingStatus = FundingOutstanding | FundingSettled | FundingRejected deriving (Typeable, Generic) instance Hashable FundingStatus instance Show FundingStatus where show FundingOutstanding = "outstanding" show FundingSettled = "settled" show FundingRejected = "rejected" instance ToJSON FundingStatus where toJSON = String . T.pack . show instance FromJSON FundingStatus where parseJSON = withText "FundingStatus" $ \t -> case t of "outstanding" -> pure FundingOutstanding "settled" -> pure FundingSettled "rejected" -> pure FundingRejected _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid funding status." data MarginType = MarginDeposit | MarginWithdraw deriving (Typeable, Generic) instance Hashable MarginType instance Show MarginType where show MarginDeposit = "deposit" show MarginWithdraw = "withdraw" instance ToJSON MarginType where toJSON = String . T.pack . show instance FromJSON MarginType where parseJSON = withText "MarginType" $ \t -> case t of "deposit" -> pure MarginDeposit "withdraw" -> pure MarginWithdraw _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid margin type." newtype MarginTransferId = MarginTransferId { unMarginTransferId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show MarginTransferId where show = show . unMarginTransferId data MarginStatus = MarginCompleted deriving (Typeable, Generic) instance Hashable MarginStatus instance Show MarginStatus where show MarginCompleted = "completed" instance ToJSON MarginStatus where toJSON = String . T.pack . show instance FromJSON MarginStatus where parseJSON = withText "MarginStatus" $ \t -> case t of "completed" -> pure MarginCompleted _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid margin status." data PositionStatus = PositionActive | PositionPending | PositionLocked | PositionDefault deriving (Typeable, Generic) instance Hashable PositionStatus instance Show PositionStatus where show PositionActive = "active" show PositionPending = "pending" show PositionLocked = "locked" show PositionDefault = "default" instance ToJSON PositionStatus where toJSON = String . T.pack . show instance FromJSON PositionStatus where parseJSON = withText "PositionStatus" $ \t -> case t of "active" -> pure PositionActive "pending" -> pure PositionPending "locked" -> pure PositionLocked "default" -> pure PositionDefault _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid margin status." data PositionType = PositionLong | PositionShort deriving (Typeable, Generic) instance Hashable PositionType instance Show PositionType where show PositionLong = "long" show PositionShort = "short" instance ToJSON PositionType where toJSON = String . T.pack . show instance FromJSON PositionType where parseJSON = withText "PositionType" $ \t -> case t of "long" -> pure PositionLong "short" -> pure PositionShort _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid margin status." newtype PaymentMethodId = PaymentMethodId { unPaymentMethodId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show PaymentMethodId where show = show . unPaymentMethodId newtype DepositId = DepositId { unDepositId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show DepositId where show = show . unDepositId newtype WithdrawId = WithdrawId { unWithdrawId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show WithdrawId where show = show . unWithdrawId data PaymentMethodType = MethodFiatAccount | MethodBankWire | MethodACHBankAccount deriving (Eq, Ord, Typeable, Generic) instance Hashable PaymentMethodType instance Show PaymentMethodType where show MethodFiatAccount = "fiat_account" show MethodBankWire = "bank_wire" show MethodACHBankAccount = "ach_bank_account" instance ToJSON PaymentMethodType where toJSON = String . T.pack . show instance FromJSON PaymentMethodType where parseJSON = withText "PaymentMethodType" $ \t -> case t of "fiat_account" -> pure MethodFiatAccount "bank_wire" -> pure MethodBankWire "ach_bank_account" -> pure MethodACHBankAccount _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid payment method type." data CoinbaseAccountType = CBTypeWallet | CBTypeFiat deriving (Typeable, Generic) instance Hashable CoinbaseAccountType instance Show CoinbaseAccountType where show CBTypeWallet = "wallet" show CBTypeFiat = "fiat" instance ToJSON CoinbaseAccountType where toJSON = String . T.pack . show instance FromJSON CoinbaseAccountType where parseJSON = withText "CoinbaseAccountType" $ \t -> case t of "wallet" -> pure CBTypeWallet "fiat" -> pure CBTypeFiat _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid coinbase account type." newtype ReportId = ReportId { unReportId :: UUID } deriving (Eq, Ord, Typeable, Generic, ToJSON, FromJSON, Hashable) instance Show ReportId where show = show . unReportId data ReportType = ReportFills | ReportAccount deriving (Typeable, Generic) instance Hashable ReportType instance Show ReportType where show ReportFills = "fills" show ReportAccount = "account" instance ToJSON ReportType where toJSON = String . T.pack . show instance FromJSON ReportType where parseJSON = withText "ReportType" $ \t -> case t of "fills" -> pure ReportFills "account" -> pure ReportAccount _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid report type." data ReportStatus = ReportPending | ReportCreating | ReportReady deriving (Typeable, Generic) instance Hashable ReportStatus instance Show ReportStatus where show ReportPending = "pending" show ReportCreating = "creating" show ReportReady = "ready" instance ToJSON ReportStatus where toJSON = String . T.pack . show instance FromJSON ReportStatus where parseJSON = withText "ReportStatus" $ \t -> case t of "pending" -> pure ReportPending "creating" -> pure ReportCreating "ready" -> pure ReportReady _ -> fail $ T.unpack $ "'" <> t <> "' is not a valid report status."