packages feed

coinbase-exchange 0.3.0.0 → 0.4.0.0

raw patch · 14 files changed

+1023/−175 lines, 14 filesdep ~aesondep ~mtldep ~timePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: aeson, mtl, time

API changes (from Hackage documentation)

- Coinbase.Exchange.Types: instance GHC.Generics.Constructor Coinbase.Exchange.Types.C1_0ExchangeFailure
- Coinbase.Exchange.Types: instance GHC.Generics.Constructor Coinbase.Exchange.Types.C1_1ExchangeFailure
- Coinbase.Exchange.Types: instance GHC.Generics.Constructor Coinbase.Exchange.Types.C1_2ExchangeFailure
- Coinbase.Exchange.Types: instance GHC.Generics.Constructor Coinbase.Exchange.Types.C1_3ExchangeFailure
- Coinbase.Exchange.Types: instance GHC.Generics.Datatype Coinbase.Exchange.Types.D1ExchangeFailure
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.Aggregate
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.ClientOrderId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.CoinScientific
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.Cost
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.CurrencyId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.OrderId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.OrderStatus
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.OrderType
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.Price
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.ProductId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.Reason
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.Sequence
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.Side
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.Size
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Core.TradeId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.Aggregate
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.ClientOrderId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.CoinScientific
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.Cost
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.CurrencyId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.OrderId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.OrderStatus
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.OrderType
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.Price
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.ProductId
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.Reason
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.Sequence
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.Side
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.Size
- Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Core.TradeId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0Aggregate
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0ClientOrderId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0Cost
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0CurrencyId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0OrderId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0OrderStatus
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0OrderType
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0Price
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0ProductId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0Reason
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0Sequence
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0Side
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0Size
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_0TradeId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_1OrderStatus
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_1OrderType
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_1Reason
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_1Side
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_2OrderStatus
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Core.C1_3OrderStatus
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1Aggregate
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1ClientOrderId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1Cost
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1CurrencyId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1OrderId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1OrderStatus
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1OrderType
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1Price
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1ProductId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1Reason
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1Sequence
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1Side
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1Size
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Core.D1TradeId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0Aggregate
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0ClientOrderId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0Cost
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0CurrencyId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0OrderId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0Price
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0ProductId
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0Sequence
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0Size
- Coinbase.Exchange.Types.Core: instance GHC.Generics.Selector Coinbase.Exchange.Types.Core.S1_0_0TradeId
- Coinbase.Exchange.Types.MarketData: Ask :: Price -> Size -> a -> Ask a
- Coinbase.Exchange.Types.MarketData: Bid :: Price -> Size -> a -> Bid a
- Coinbase.Exchange.Types.MarketData: data Ask a
- Coinbase.Exchange.Types.MarketData: data Bid a
- Coinbase.Exchange.Types.MarketData: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Candle
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Close
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Currency
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.ExchangeTime
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.High
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Low
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Open
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Product
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Stats
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Tick
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Trade
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.MarketData.Volume
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON a => Data.Aeson.Types.Class.FromJSON (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON a => Data.Aeson.Types.Class.FromJSON (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.FromJSON a => Data.Aeson.Types.Class.FromJSON (Coinbase.Exchange.Types.MarketData.Book a)
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Close
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Currency
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.ExchangeTime
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.High
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Low
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Open
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Product
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Stats
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Tick
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Trade
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.MarketData.Volume
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON a => Data.Aeson.Types.Class.ToJSON (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON a => Data.Aeson.Types.Class.ToJSON (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.Class.ToJSON a => Data.Aeson.Types.Class.ToJSON (Coinbase.Exchange.Types.MarketData.Book a)
- Coinbase.Exchange.Types.MarketData: instance Data.Data.Data a => Data.Data.Data (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance Data.Data.Data a => Data.Data.Data (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Classes.Eq a => GHC.Classes.Eq (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Classes.Eq a => GHC.Classes.Eq (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Classes.Ord a => GHC.Classes.Ord (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Classes.Ord a => GHC.Classes.Ord (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Ask
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Bid
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Book
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Candle
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Close
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Currency
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0ExchangeTime
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0High
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Low
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Open
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Stats
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Tick
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Trade
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Constructor Coinbase.Exchange.Types.MarketData.C1_0Volume
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Ask
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Bid
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Book
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Candle
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Close
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Currency
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1ExchangeTime
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1High
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Low
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Open
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Stats
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Tick
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Trade
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Datatype Coinbase.Exchange.Types.MarketData.D1Volume
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Generic (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Generic (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Book
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Close
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Currency
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0ExchangeTime
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0High
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Low
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Open
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Stats
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Tick
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Trade
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_0Volume
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_1Book
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_1Currency
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_1ExchangeTime
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_1Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_1Stats
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_1Tick
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_1Trade
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_2Book
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_2Currency
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_2Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_2Stats
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_2Tick
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_2Trade
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_3Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_3Stats
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_3Tick
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_3Trade
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_4Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_4Trade
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_5Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Selector Coinbase.Exchange.Types.MarketData.S1_0_6Product
- Coinbase.Exchange.Types.MarketData: instance GHC.Read.Read a => GHC.Read.Read (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Read.Read a => GHC.Read.Read (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Show.Show a => GHC.Show.Show (Coinbase.Exchange.Types.MarketData.Ask a)
- Coinbase.Exchange.Types.MarketData: instance GHC.Show.Show a => GHC.Show.Show (Coinbase.Exchange.Types.MarketData.Bid a)
- Coinbase.Exchange.Types.Private: [transAmount] :: Transfer -> Size
- Coinbase.Exchange.Types.Private: [transCoinbaseAccount] :: Transfer -> CoinbaseAccountId
- Coinbase.Exchange.Types.Private: data Transfer
- Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.Transfer
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.Account
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.AccountId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.CoinbaseAccountId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.Entry
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.EntryDetails
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.EntryId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.EntryType
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.Fill
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.Hold
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.HoldId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.Liquidity
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.Order
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.OrderConfirmation
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.OrderContigency
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.SelfTrade
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.Transfer
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Private.TransferId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.Account
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.AccountId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.CoinbaseAccountId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.Entry
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.EntryDetails
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.EntryId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.EntryType
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.Fill
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.Hold
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.HoldId
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.Liquidity
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.NewOrder
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.Order
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.OrderConfirmation
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.OrderContigency
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.SelfTrade
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.Transfer
- Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Private.TransferId
- Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0Account
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0AccountId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0CoinbaseAccountId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0EntryDetails
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0EntryId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0EntryType
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0HoldId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0Liquidity
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0OrderConfirmation
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0OrderContigency
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0SelfTrade
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_0TransferId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1EntryType
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1Liquidity
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1OrderContigency
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1SelfTrade
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_1Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_2EntryType
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_2OrderContigency
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_2SelfTrade
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Private.C1_3SelfTrade
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1Account
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1AccountId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1CoinbaseAccountId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1EntryDetails
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1EntryId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1EntryType
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1HoldId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1Liquidity
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1OrderConfirmation
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1OrderContigency
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1SelfTrade
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Private.D1TransferId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0Account
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0AccountId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0CoinbaseAccountId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0EntryDetails
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0EntryId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0HoldId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0OrderConfirmation
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_0TransferId
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_10Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_11Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_12Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_13Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_14Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1Account
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1EntryDetails
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_1Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_2Account
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_2Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_2EntryDetails
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_2Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_2Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_2NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_2Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_3Account
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_3Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_3Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_3Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_3NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_3Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_4Account
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_4Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_4Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_4Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_4NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_4Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_5Entry
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_5Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_5Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_5NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_5Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_6Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_6NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_6Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_7Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_7NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_7Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_8Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_8Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_9Fill
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_0_9Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_0Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_0NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_0Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_0Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_10Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_11Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_1Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_1NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_1Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_1Transfer
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_2Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_2NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_2Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_3Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_3NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_3Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_4Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_4NewOrder
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_4Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_5Hold
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_5Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_6Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_7Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_8Order
- Coinbase.Exchange.Types.Private: instance GHC.Generics.Selector Coinbase.Exchange.Types.Private.S1_1_9Order
- Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.Transfer
- Coinbase.Exchange.Types.Socket: DoneLimit :: UTCTime -> ProductId -> Sequence -> OrderId -> Side -> Size -> Price -> Reason -> OrderType -> ExchangeMessage
- Coinbase.Exchange.Types.Socket: DoneMarket :: UTCTime -> ProductId -> Sequence -> OrderId -> Side -> Reason -> OrderType -> ExchangeMessage
- Coinbase.Exchange.Types.Socket: [msgOrderType] :: ExchangeMessage -> OrderType
- Coinbase.Exchange.Types.Socket: instance Data.Aeson.Types.Class.FromJSON Coinbase.Exchange.Types.Socket.ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance Data.Aeson.Types.Class.ToJSON Coinbase.Exchange.Types.Socket.ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_7ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_8ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Constructor Coinbase.Exchange.Types.Socket.C1_9ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Datatype Coinbase.Exchange.Types.Socket.D1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_0_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_1_7ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_2_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_2_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_2_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_2_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_2_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_2_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_2_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_3_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_3_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_3_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_3_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_3_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_3_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_3_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_7ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_4_8ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_7ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_5_8ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_6_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_6_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_6_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_6_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_6_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_6_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_6_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_7_7ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_0ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_1ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_2ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_3ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_4ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_5ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_6ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_8_7ExchangeMessage
- Coinbase.Exchange.Types.Socket: instance GHC.Generics.Selector Coinbase.Exchange.Types.Socket.S1_9_0ExchangeMessage
+ Coinbase.Exchange.Private: cancelAllOrders :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m) => Maybe ProductId -> m [OrderId]
+ Coinbase.Exchange.Private: createCryptoWithdrawal :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m) => CryptoWithdrawal -> m CryptoWithdrawalResp
+ Coinbase.Exchange.Private: createReport :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m) => ReportRequest -> m ReportInfo
+ Coinbase.Exchange.Private: getReportStatus :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m) => ReportId -> m ReportInfo
+ Coinbase.Exchange.Types: data ExchangeT m a
+ Coinbase.Exchange.Types: liveRealCoinbaseRest :: Endpoint
+ Coinbase.Exchange.Types: sandboxRealCoinbaseRest :: Endpoint
+ Coinbase.Exchange.Types.Core: Active :: OrderStatus
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.Aggregate
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.ClientOrderId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.CoinScientific
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.Cost
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.CurrencyId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.OrderId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.OrderStatus
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.OrderType
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.Price
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.ProductId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.Reason
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.Sequence
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.Side
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.Size
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Core.TradeId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.Aggregate
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.ClientOrderId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.CoinScientific
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.Cost
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.CurrencyId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.OrderId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.OrderStatus
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.OrderType
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.Price
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.ProductId
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.Reason
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.Sequence
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.Side
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.Size
+ Coinbase.Exchange.Types.Core: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Core.TradeId
+ Coinbase.Exchange.Types.Core: instance GHC.Enum.Enum Coinbase.Exchange.Types.Core.Sequence
+ Coinbase.Exchange.Types.MarketData: BookItem :: Price -> Size -> a -> BookItem a
+ Coinbase.Exchange.Types.MarketData: data BookItem a
+ Coinbase.Exchange.Types.MarketData: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Candle
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Close
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Currency
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.ExchangeTime
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.High
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Low
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Open
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Product
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Stats
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Tick
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Trade
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.MarketData.Volume
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Coinbase.Exchange.Types.MarketData.Book a)
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Close
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Currency
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.ExchangeTime
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.High
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Low
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Open
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Product
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Stats
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Tick
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Trade
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.MarketData.Volume
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Coinbase.Exchange.Types.MarketData.Book a)
+ Coinbase.Exchange.Types.MarketData: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance Data.Data.Data a => Data.Data.Data (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance GHC.Classes.Eq a => GHC.Classes.Eq (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance GHC.Classes.Ord a => GHC.Classes.Ord (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance GHC.Generics.Generic (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance GHC.Read.Read a => GHC.Read.Read (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.MarketData: instance GHC.Show.Show a => GHC.Show.Show (Coinbase.Exchange.Types.MarketData.BookItem a)
+ Coinbase.Exchange.Types.Private: AccountReport :: ReportType
+ Coinbase.Exchange.Types.Private: BTCTransferId :: UUID -> BTCTransferId
+ Coinbase.Exchange.Types.Private: BTCTransferResponse :: BTCTransferId -> BTCTransferResponse
+ Coinbase.Exchange.Types.Private: BTCWallet :: BitcoinWallet -> CryptoWallet
+ Coinbase.Exchange.Types.Private: CSV :: ReportFormat
+ Coinbase.Exchange.Types.Private: CoinbaseAccount :: CoinbaseAccountId -> String -> Bool -> String -> Size -> CoinbaseAccount
+ Coinbase.Exchange.Types.Private: Day :: OrderCancelAfter
+ Coinbase.Exchange.Types.Private: FillsReport :: ReportType
+ Coinbase.Exchange.Types.Private: FromBTCAddress :: String -> BitcoinWallet
+ Coinbase.Exchange.Types.Private: GoodTillTime :: OrderContigency
+ Coinbase.Exchange.Types.Private: Hour :: OrderCancelAfter
+ Coinbase.Exchange.Types.Private: Min :: OrderCancelAfter
+ Coinbase.Exchange.Types.Private: NewStopOrder :: ProductId -> Side -> SelfTrade -> Maybe ClientOrderId -> Price -> Either Size (Maybe Size, Cost) -> NewOrder
+ Coinbase.Exchange.Types.Private: PDF :: ReportFormat
+ Coinbase.Exchange.Types.Private: ReportCreating :: ReportStatus
+ Coinbase.Exchange.Types.Private: ReportId :: UUID -> ReportId
+ Coinbase.Exchange.Types.Private: ReportInfo :: ReportId -> ReportType -> ReportStatus -> Maybe UTCTime -> Maybe UTCTime -> Maybe UTCTime -> Maybe String -> Maybe ReportParams -> ReportInfo
+ Coinbase.Exchange.Types.Private: ReportParams :: UTCTime -> UTCTime -> ReportParams
+ Coinbase.Exchange.Types.Private: ReportPending :: ReportStatus
+ Coinbase.Exchange.Types.Private: ReportReady :: ReportStatus
+ Coinbase.Exchange.Types.Private: ReportRequest :: ReportType -> UTCTime -> UTCTime -> ProductId -> AccountId -> ReportFormat -> Maybe String -> ReportRequest
+ Coinbase.Exchange.Types.Private: SendBitcoin :: Size -> BitcoinWallet -> BTCTransferReq
+ Coinbase.Exchange.Types.Private: StopOrder :: OrderId -> ProductId -> OrderStatus -> SelfTrade -> Bool -> Side -> UTCTime -> Maybe Size -> Maybe Price -> Maybe UTCTime -> Maybe Reason -> Price -> Either Size (Maybe Size, Cost) -> Order
+ Coinbase.Exchange.Types.Private: TransferResponse :: TransferId -> TransferToCoinbaseResponse
+ Coinbase.Exchange.Types.Private: Withdrawal :: Size -> CurrencyId -> CryptoWallet -> CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: WithdrawalResp :: TransferId -> Size -> CurrencyId -> CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: [bitcoinWallet] :: BTCTransferReq -> BitcoinWallet
+ Coinbase.Exchange.Types.Private: [btcAddress] :: BitcoinWallet -> String
+ Coinbase.Exchange.Types.Private: [btcBalance] :: CoinbaseAccount -> Size
+ Coinbase.Exchange.Types.Private: [cbAccID] :: CoinbaseAccount -> CoinbaseAccountId
+ Coinbase.Exchange.Types.Private: [getBtcTransferId] :: BTCTransferId -> UUID
+ Coinbase.Exchange.Types.Private: [name] :: CoinbaseAccount -> String
+ Coinbase.Exchange.Types.Private: [noCancelAfter] :: NewOrder -> Maybe OrderCancelAfter
+ Coinbase.Exchange.Types.Private: [orderCancelAfter] :: Order -> Maybe OrderCancelAfter
+ Coinbase.Exchange.Types.Private: [primary] :: CoinbaseAccount -> Bool
+ Coinbase.Exchange.Types.Private: [reportCompleted] :: ReportInfo -> Maybe UTCTime
+ Coinbase.Exchange.Types.Private: [reportCreated] :: ReportInfo -> Maybe UTCTime
+ Coinbase.Exchange.Types.Private: [reportEndDate] :: ReportParams -> UTCTime
+ Coinbase.Exchange.Types.Private: [reportExpires] :: ReportInfo -> Maybe UTCTime
+ Coinbase.Exchange.Types.Private: [reportId] :: ReportInfo -> ReportId
+ Coinbase.Exchange.Types.Private: [reportParams] :: ReportInfo -> Maybe ReportParams
+ Coinbase.Exchange.Types.Private: [reportStartDate] :: ReportParams -> UTCTime
+ Coinbase.Exchange.Types.Private: [reportStatus] :: ReportInfo -> ReportStatus
+ Coinbase.Exchange.Types.Private: [reportType] :: ReportInfo -> ReportType
+ Coinbase.Exchange.Types.Private: [reportUrl] :: ReportInfo -> Maybe String
+ Coinbase.Exchange.Types.Private: [resourcePath] :: CoinbaseAccount -> String
+ Coinbase.Exchange.Types.Private: [rrqAccountId] :: ReportRequest -> AccountId
+ Coinbase.Exchange.Types.Private: [rrqEmail] :: ReportRequest -> Maybe String
+ Coinbase.Exchange.Types.Private: [rrqEndDate] :: ReportRequest -> UTCTime
+ Coinbase.Exchange.Types.Private: [rrqFormat] :: ReportRequest -> ReportFormat
+ Coinbase.Exchange.Types.Private: [rrqProductId] :: ReportRequest -> ProductId
+ Coinbase.Exchange.Types.Private: [rrqStartDate] :: ReportRequest -> UTCTime
+ Coinbase.Exchange.Types.Private: [rrqType] :: ReportRequest -> ReportType
+ Coinbase.Exchange.Types.Private: [sendAmount] :: BTCTransferReq -> Size
+ Coinbase.Exchange.Types.Private: [sendId] :: BTCTransferResponse -> BTCTransferId
+ Coinbase.Exchange.Types.Private: [trAmount] :: TransferToCoinbase -> Size
+ Coinbase.Exchange.Types.Private: [trCoinbaseAccountId] :: TransferToCoinbase -> CoinbaseAccountId
+ Coinbase.Exchange.Types.Private: [trId] :: TransferToCoinbaseResponse -> TransferId
+ Coinbase.Exchange.Types.Private: [unReportId] :: ReportId -> UUID
+ Coinbase.Exchange.Types.Private: [wdAmount] :: CryptoWithdrawal -> Size
+ Coinbase.Exchange.Types.Private: [wdCryptoAddress] :: CryptoWithdrawal -> CryptoWallet
+ Coinbase.Exchange.Types.Private: [wdCurrency] :: CryptoWithdrawal -> CurrencyId
+ Coinbase.Exchange.Types.Private: [wdrAmount] :: CryptoWithdrawalResp -> Size
+ Coinbase.Exchange.Types.Private: [wdrCurrency] :: CryptoWithdrawalResp -> CurrencyId
+ Coinbase.Exchange.Types.Private: [wdrId] :: CryptoWithdrawalResp -> TransferId
+ Coinbase.Exchange.Types.Private: data BTCTransferReq
+ Coinbase.Exchange.Types.Private: data BTCTransferResponse
+ Coinbase.Exchange.Types.Private: data CoinbaseAccount
+ Coinbase.Exchange.Types.Private: data CryptoWallet
+ Coinbase.Exchange.Types.Private: data CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: data CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: data OrderCancelAfter
+ Coinbase.Exchange.Types.Private: data ReportFormat
+ Coinbase.Exchange.Types.Private: data ReportInfo
+ Coinbase.Exchange.Types.Private: data ReportParams
+ Coinbase.Exchange.Types.Private: data ReportRequest
+ Coinbase.Exchange.Types.Private: data ReportStatus
+ Coinbase.Exchange.Types.Private: data ReportType
+ Coinbase.Exchange.Types.Private: data TransferToCoinbase
+ Coinbase.Exchange.Types.Private: data TransferToCoinbaseResponse
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.BTCTransferReq
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.BTCTransferResponse
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.BitcoinWallet
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.CryptoWallet
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.ReportInfo
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.ReportParams
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.ReportRequest
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.TransferToCoinbase
+ Coinbase.Exchange.Types.Private: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Private.TransferToCoinbaseResponse
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.Account
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.AccountId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.BTCTransferResponse
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.BitcoinWallet
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.CoinbaseAccount
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.CoinbaseAccountId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.CryptoWallet
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.Entry
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.EntryDetails
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.EntryId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.EntryType
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.Fill
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.Hold
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.HoldId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.Liquidity
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.Order
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.OrderConfirmation
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.OrderContigency
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.ReportInfo
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.ReportParams
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.ReportRequest
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.SelfTrade
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.TransferId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Private.TransferToCoinbaseResponse
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.Account
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.AccountId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.BTCTransferReq
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.BitcoinWallet
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.CoinbaseAccountId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.CryptoWallet
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.Entry
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.EntryDetails
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.EntryId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.EntryType
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.Fill
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.Hold
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.HoldId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.Liquidity
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.NewOrder
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.Order
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.OrderConfirmation
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.OrderContigency
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.ReportInfo
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.ReportParams
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.ReportRequest
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.SelfTrade
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.TransferId
+ Coinbase.Exchange.Types.Private: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Private.TransferToCoinbase
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.BTCTransferReq
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.BTCTransferResponse
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.BitcoinWallet
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.CoinbaseAccount
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.CryptoWallet
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.ReportInfo
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.ReportParams
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.ReportRequest
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance Data.Data.Data Coinbase.Exchange.Types.Private.TransferToCoinbase
+ Coinbase.Exchange.Types.Private: instance Data.Hashable.Class.Hashable Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance Data.Hashable.Class.Hashable Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance Data.Hashable.Class.Hashable Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance Data.Hashable.Class.Hashable Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.BTCTransferResponse
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Eq Coinbase.Exchange.Types.Private.TransferToCoinbaseResponse
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Ord Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Ord Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Ord Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Ord Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Ord Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance GHC.Classes.Ord Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.BTCTransferReq
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.BTCTransferResponse
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.BitcoinWallet
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.CoinbaseAccount
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.CryptoWallet
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.ReportInfo
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.ReportParams
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.ReportRequest
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.TransferToCoinbase
+ Coinbase.Exchange.Types.Private: instance GHC.Generics.Generic Coinbase.Exchange.Types.Private.TransferToCoinbaseResponse
+ Coinbase.Exchange.Types.Private: instance GHC.Read.Read Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance GHC.Read.Read Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance GHC.Read.Read Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance GHC.Read.Read Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance GHC.Read.Read Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance GHC.Read.Read Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.BTCTransferId
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.BTCTransferReq
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.BTCTransferResponse
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.BitcoinWallet
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.CoinbaseAccount
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.CryptoWallet
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.CryptoWithdrawal
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.CryptoWithdrawalResp
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.OrderCancelAfter
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.ReportFormat
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.ReportId
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.ReportInfo
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.ReportParams
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.ReportRequest
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.ReportStatus
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.ReportType
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.TransferToCoinbase
+ Coinbase.Exchange.Types.Private: instance GHC.Show.Show Coinbase.Exchange.Types.Private.TransferToCoinbaseResponse
+ Coinbase.Exchange.Types.Private: newtype BTCTransferId
+ Coinbase.Exchange.Types.Private: newtype BitcoinWallet
+ Coinbase.Exchange.Types.Private: newtype ReportId
+ Coinbase.Exchange.Types.Socket: Done :: UTCTime -> ProductId -> Sequence -> OrderId -> Side -> Reason -> Maybe Price -> Maybe Size -> ExchangeMessage
+ Coinbase.Exchange.Types.Socket: Heartbeat :: UTCTime -> ProductId -> Sequence -> TradeId -> ExchangeMessage
+ Coinbase.Exchange.Types.Socket: SetHeartbeat :: Bool -> SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: [msgLastTradeId] :: ExchangeMessage -> TradeId
+ Coinbase.Exchange.Types.Socket: [msgMaybePrice] :: ExchangeMessage -> Maybe Price
+ Coinbase.Exchange.Types.Socket: [msgMaybeRemSize] :: ExchangeMessage -> Maybe Size
+ Coinbase.Exchange.Types.Socket: data SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance Control.DeepSeq.NFData Coinbase.Exchange.Types.Socket.SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance Data.Aeson.Types.FromJSON.FromJSON Coinbase.Exchange.Types.Socket.ExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Socket.ExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance Data.Aeson.Types.ToJSON.ToJSON Coinbase.Exchange.Types.Socket.SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance Data.Data.Data Coinbase.Exchange.Types.Socket.SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance GHC.Classes.Eq Coinbase.Exchange.Types.Socket.SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance GHC.Generics.Generic Coinbase.Exchange.Types.Socket.SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance GHC.Read.Read Coinbase.Exchange.Types.Socket.SendExchangeMessage
+ Coinbase.Exchange.Types.Socket: instance GHC.Show.Show Coinbase.Exchange.Types.Socket.SendExchangeMessage
- Coinbase.Exchange.Private: createTransfer :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m) => Transfer -> m ()
+ Coinbase.Exchange.Private: createTransfer :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m) => TransferToCoinbase -> m TransferToCoinbaseResponse
- Coinbase.Exchange.Socket: subscribe :: ApiType -> ProductId -> ClientApp a -> IO a
+ Coinbase.Exchange.Socket: subscribe :: ApiType -> [ProductId] -> ClientApp a -> IO a
- Coinbase.Exchange.Types.MarketData: Book :: Sequence -> [Bid a] -> [Ask a] -> Book a
+ Coinbase.Exchange.Types.MarketData: Book :: Sequence -> [BookItem a] -> [BookItem a] -> Book a
- Coinbase.Exchange.Types.MarketData: [bookAsks] :: Book a -> [Ask a]
+ Coinbase.Exchange.Types.MarketData: [bookAsks] :: Book a -> [BookItem a]
- Coinbase.Exchange.Types.MarketData: [bookBids] :: Book a -> [Bid a]
+ Coinbase.Exchange.Types.MarketData: [bookBids] :: Book a -> [BookItem a]
- Coinbase.Exchange.Types.Private: Deposit :: Size -> CoinbaseAccountId -> Transfer
+ Coinbase.Exchange.Types.Private: Deposit :: Size -> CoinbaseAccountId -> TransferToCoinbase
- Coinbase.Exchange.Types.Private: LimitOrder :: OrderId -> ProductId -> OrderStatus -> SelfTrade -> Bool -> Side -> UTCTime -> Maybe Size -> Maybe Price -> Maybe UTCTime -> Maybe Reason -> Price -> Size -> OrderContigency -> Bool -> Order
+ Coinbase.Exchange.Types.Private: LimitOrder :: OrderId -> ProductId -> OrderStatus -> SelfTrade -> Bool -> Side -> UTCTime -> Maybe Size -> Maybe Price -> Maybe UTCTime -> Maybe Reason -> Price -> Size -> OrderContigency -> Maybe OrderCancelAfter -> Bool -> Order
- Coinbase.Exchange.Types.Private: NewLimitOrder :: ProductId -> Side -> SelfTrade -> Maybe ClientOrderId -> Price -> Size -> OrderContigency -> Bool -> NewOrder
+ Coinbase.Exchange.Types.Private: NewLimitOrder :: ProductId -> Side -> SelfTrade -> Maybe ClientOrderId -> Price -> Size -> OrderContigency -> Maybe OrderCancelAfter -> Bool -> NewOrder
- Coinbase.Exchange.Types.Private: Withdraw :: Size -> CoinbaseAccountId -> Transfer
+ Coinbase.Exchange.Types.Private: Withdraw :: Size -> CoinbaseAccountId -> TransferToCoinbase
- Coinbase.Exchange.Types.Socket: ChangeLimit :: UTCTime -> ProductId -> Sequence -> OrderId -> Side -> Price -> Size -> Size -> ExchangeMessage
+ Coinbase.Exchange.Types.Socket: ChangeLimit :: UTCTime -> ProductId -> Sequence -> OrderId -> Side -> Maybe Price -> Size -> Size -> ExchangeMessage
- Coinbase.Exchange.Types.Socket: ChangeMarket :: UTCTime -> ProductId -> Sequence -> OrderId -> Side -> Price -> Cost -> Cost -> ExchangeMessage
+ Coinbase.Exchange.Types.Socket: ChangeMarket :: UTCTime -> ProductId -> Sequence -> OrderId -> Side -> Cost -> Cost -> ExchangeMessage
- Coinbase.Exchange.Types.Socket: Subscribe :: ProductId -> ExchangeMessage
+ Coinbase.Exchange.Types.Socket: Subscribe :: [ProductId] -> SendExchangeMessage

Files

coinbase-exchange.cabal view
@@ -1,5 +1,5 @@ name:                coinbase-exchange-version:             0.3.0.0+version:             0.4.0.0 synopsis:            Connector library for the coinbase exchange. description:         Access library for the coinbase exchange. Allows the use                      of both the public market data API as well as the private@@ -28,20 +28,20 @@      other-modules:      Coinbase.Exchange.Rest -    build-depends:      base                ==4.*-                    ,   mtl                 >=2.2+    build-depends:      base    >= 4 && < 5+                    ,   mtl                     ,   resourcet                     ,   transformers-base                     ,   conduit                     ,   conduit-extra                     ,   http-conduit-                    ,   aeson               >=0.10.0+                    ,   aeson                     ,   aeson-casing                     ,   http-types                     ,   text                     ,   bytestring                     ,   base64-bytestring-                    ,   time                >=1.5+                    ,   time                     ,   scientific                     ,   uuid                     ,   uuid-aeson@@ -63,13 +63,13 @@     hs-source-dirs:     sbox     default-language:   Haskell2010 -    build-depends:      base                ==4.*+    build-depends:      base    >= 4 && < 5                     ,   http-client                     ,   http-client-tls                      ,   uuid                     ,   text-                    ,   aeson               >=0.10.0+                    ,   aeson                     ,   bytestring                     ,   time                     ,   old-locale@@ -93,7 +93,11 @@     ghc-options:        -threaded     default-language:   Haskell2010 -    build-depends:      base                ==4.*+    other-modules:      Coinbase.Exchange.MarketData.Test+                        Coinbase.Exchange.Private.Test+                        Coinbase.Exchange.Socket.Test++    build-depends:      base    >= 4 && < 5                     ,   tasty                     ,   tasty-th                     ,   tasty-quickcheck@@ -110,7 +114,7 @@                     ,   scientific                     ,   async                     ,   websockets-                    ,   aeson               >=0.10.0+                    ,   aeson                     ,   unordered-containers                      ,   coinbase-exchange
sbox/Main.hs view
@@ -38,19 +38,25 @@ withCoinbase :: Exchange a -> IO a withCoinbase act = do         mgr     <- newManager tlsManagerSettings-        tKey    <- liftM CBS.pack $ getEnv "COINBASE_KEY"-        tSecret <- liftM CBS.pack $ getEnv "COINBASE_SECRET"-        tPass   <- liftM CBS.pack $ getEnv "COINBASE_PASSPHRASE"+        tKey    <- liftM CBS.pack $ getEnv "GDAX_KEY"+        tSecret <- liftM CBS.pack $ getEnv "GDAX_SECRET"+        tPass   <- liftM CBS.pack $ getEnv "GDAX_PASSPHRASE" +        sbox    <- getEnv "GDAX_SANDBOX"+        let apiType  = case sbox of+                        "FALSE" -> Live+                        "TRUE"  -> Sandbox+                        _       -> error "Coinbase sandbox option must be either: TRUE or FALSE (all caps)"+         case mkToken tKey tSecret tPass of-            Right tok -> do res <- runExchange (ExchangeConf mgr (Just tok) Live) act+            Right tok -> do res <- runExchange (ExchangeConf mgr (Just tok) apiType) act                             case res of                                 Right s -> return s                                 Left  f -> error $ show f             Left   er -> error $ show er  printSocket :: IO ()-printSocket = subscribe Live btc $ \conn -> do+printSocket = subscribe Live [btc] $ \conn -> do         putStrLn "Connected."         _ <- forkIO $ forever $ do             ds <- WS.receiveData conn
src/Coinbase/Exchange/Private.hs view
@@ -10,13 +10,18 @@      , createOrder     , cancelOrder+    , cancelAllOrders     , getOrderList     , getOrder      , getFills      , createTransfer+    , createCryptoWithdrawal +    , createReport+    , getReportStatus+     , module Coinbase.Exchange.Types.Private     ) where @@ -59,12 +64,18 @@  cancelOrder :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)             => OrderId -> m ()-cancelOrder (OrderId o) = coinbaseDelete True ("/orders/" ++ toString o) voidBody+cancelOrder (OrderId o) = coinbaseDeleteDiscardBody True ("/orders/" ++ toString o) voidBody +cancelAllOrders :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)+                => Maybe ProductId -> m [OrderId]+cancelAllOrders prodId = coinbaseDelete True ("/orders" ++ opt prodId) voidBody+    where opt Nothing   = ""+          opt (Just id) = "?product_id=" ++ T.unpack (unProductId id)+ getOrderList :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)              => [OrderStatus] -> m [Order] getOrderList os = coinbaseGet True ("/orders?" ++ query os) voidBody-    where query [] = "status=all"+    where query [] = "status=open&status=pending&status=active"           query xs = intercalate "&" $ map (\x -> "status=" ++ map toLower (show x)) xs  getOrder :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)@@ -84,5 +95,21 @@ -- Transfers  createTransfer :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)-               => Transfer -> m ()+               => TransferToCoinbase -> m TransferToCoinbaseResponse createTransfer = coinbasePost True "/transfers" . Just++createCryptoWithdrawal+    :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)+    => CryptoWithdrawal+    -> m CryptoWithdrawalResp+createCryptoWithdrawal = coinbasePost True "/withdrawals/crypto" . Just++-- Reports++createReport :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)+             => ReportRequest -> m ReportInfo+createReport = coinbasePost True "/reports" . Just++getReportStatus :: (MonadResource m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)+             => ReportId -> m ReportInfo+getReportStatus (ReportId r) = coinbaseGet True ("/reports/" ++ toString r) voidBody
src/Coinbase/Exchange/Rest.hs view
@@ -6,6 +6,7 @@     ( coinbaseGet     , coinbasePost     , coinbaseDelete+    , coinbaseDeleteDiscardBody     , voidBody     ) where @@ -32,9 +33,10 @@  import           Coinbase.Exchange.Types --- import Debug.Trace+import           Debug.Trace  type Signed = Bool+type IsForExchange = Bool  voidBody :: Maybe () voidBody = Nothing@@ -45,7 +47,7 @@                , MonadReader ExchangeConf m                , MonadError ExchangeFailure m )             => Signed -> Path -> Maybe a -> m b-coinbaseGet sgn p ma = coinbaseRequest "GET" sgn p ma >>= processResponse+coinbaseGet sgn p ma = coinbaseRequest "GET" sgn p ma >>= processResponse True  coinbasePost :: ( ToJSON a                 , FromJSON b@@ -53,15 +55,23 @@                 , MonadReader ExchangeConf m                 , MonadError ExchangeFailure m )              => Signed -> Path -> Maybe a -> m b-coinbasePost sgn p ma = coinbaseRequest "POST" sgn p ma >>= processResponse+coinbasePost sgn p ma = coinbaseRequest "POST" sgn p ma >>= processResponse True  coinbaseDelete :: ( ToJSON a+                  , FromJSON b                   , MonadResource m                   , MonadReader ExchangeConf m                   , MonadError ExchangeFailure m )-               => Signed -> Path -> Maybe a -> m ()-coinbaseDelete sgn p ma = coinbaseRequest "DELETE" sgn p ma >>= processEmpty+               => Signed -> Path -> Maybe a -> m b+coinbaseDelete sgn p ma = coinbaseRequest "DELETE" sgn p ma >>= processResponse True +coinbaseDeleteDiscardBody :: ( ToJSON a+                             , MonadResource m+                             , MonadReader ExchangeConf m+                             , MonadError ExchangeFailure m )+                             => Signed -> Path -> Maybe a -> m ()+coinbaseDeleteDiscardBody sgn p ma = coinbaseRequest "DELETE" sgn p ma >>= processEmpty+ coinbaseRequest :: ( ToJSON a                    , MonadResource m                    , MonadReader ExchangeConf m@@ -70,17 +80,37 @@ coinbaseRequest meth sgn p ma = do         conf <- ask         req  <- case apiType conf of-                    Sandbox -> parseUrl $ sandboxRest ++ p-                    Live    -> parseUrl $ liveRest ++ p+                    Sandbox -> parseUrlThrow $ sandboxRest ++ p+                    Live    -> parseUrlThrow $ liveRest ++ p         let req' = req { method         = meth                        , requestHeaders = [ ("user-agent", "haskell")                                           , ("accept", "application/json")                                           ]                        } -        flip http (manager conf) =<< signMessage sgn meth p+        flip http (manager conf) =<< signMessage True sgn meth p                                  =<< encodeBody ma req' +realCoinbaseRequest :: ( ToJSON a+                           , MonadResource m+                           , MonadReader ExchangeConf m+                           , MonadError ExchangeFailure m )+                        => Method -> Signed -> Path -> Maybe a -> m (Response (ResumableSource m BS.ByteString))+realCoinbaseRequest meth sgn p ma = do+        conf <- ask+        req  <- case apiType conf of+                    Sandbox -> parseUrlThrow $ sandboxRealCoinbaseRest ++ p+                    Live    -> parseUrlThrow $ liveRealCoinbaseRest ++ p+        let req' = req { method         = meth+                       , requestHeaders = [ ("user-agent", "haskell")+                                          , ("accept", "application/json")+                                          , ("content-type", "application/json")+                                          ]+                       }++        flip http (manager conf) =<< signMessage False sgn meth p+                                 =<< encodeBody ma req'+ encodeBody :: (ToJSON a, Monad m)            => Maybe a -> Request -> m Request encodeBody (Just a) req = return req@@ -91,29 +121,33 @@ encodeBody Nothing  req = return req  signMessage :: (MonadIO m, MonadReader ExchangeConf m, MonadError ExchangeFailure m)-            => Signed -> Method -> Path -> Request -> m Request-signMessage True meth p req = do+            => IsForExchange -> Signed -> Method -> Path -> Request -> m Request+signMessage isForExchange True meth p req = do         conf <- ask         case authToken conf of             Just tok -> do time <- liftM (realToFrac . utcTimeToPOSIXSeconds) (liftIO getCurrentTime)                                     >>= \t -> return . CBS.pack $ printf "%.0f" (t::Double)                            rBody <- pullBody $ requestBody req                            let presign = CBS.concat [time, meth, CBS.pack p, rBody]-                               sign    = toBytes (hmac (secret tok) presign :: HMAC SHA256)+                               sign    = if isForExchange+                                            then Base64.encode         $ toBytes       (hmac (secret tok)                 presign :: HMAC SHA256)+                                            else digestToHexByteString $ hmacGetDigest (hmac (Base64.encode $ secret tok) presign :: HMAC SHA256)+                            return req                                 { requestBody    = RequestBodyBS rBody                                 , requestHeaders = requestHeaders req ++                                        [ ("cb-access-key", key tok)-                                       , ("cb-access-sign", Base64.encode sign)+                                       , ("cb-access-sign", sign )                                        , ("cb-access-timestamp", time)-                                       , ("cb-access-passphrase", passphrase tok)-                                       ]+                                       ] ++ if isForExchange+                                                then [("cb-access-passphrase", passphrase tok)]+                                                else [("cb-version", "2016-05-11")]                                 }             Nothing  -> throwError $ AuthenticationRequiredFailure $ T.pack p     where pullBody (RequestBodyBS  b) = return b           pullBody (RequestBodyLBS b) = return $ LBS.toStrict b           pullBody _                  = throwError AuthenticationRequiresByteStrings-signMessage False _ _ req = return req+signMessage _ False _ _ req = return req  -- @@ -121,15 +155,17 @@                    , MonadResource m                    , MonadReader ExchangeConf m                    , MonadError ExchangeFailure m )-                => Response (ResumableSource m BS.ByteString) -> m b-processResponse res =+                => IsForExchange -> Response (ResumableSource m BS.ByteString) -> m b+processResponse isForExchange res =     case responseStatus res of-        s | s == status200 -> do body <- responseBody res $$+- sinkParser (fmap {-(\x -> trace (show x) fromJSON x)-} fromJSON json)-                                 case body of-                                     Success b -> return b-                                     Error  er -> throwError $ ParseFailure $ T.pack er-          | otherwise      -> do body <- responseBody res $$+- CB.sinkLbs-                                 throwError $ ApiFailure $ T.decodeUtf8 $ LBS.toStrict body+        s | s == status200 || (s == created201 && not isForExchange) ->+            do body <- responseBody res $$+- sinkParser (fmap (\x -> {-trace (show x)-} fromJSON x) json)+               case body of+                   Success b -> return b+                   Error  er -> throwError $ ParseFailure $ T.pack er++          | otherwise -> do body <- responseBody res $$+- CB.sinkLbs+                            throwError $ ApiFailure $ T.decodeUtf8 $ LBS.toStrict body  processEmpty :: ( MonadResource m                 , MonadReader ExchangeConf m
src/Coinbase/Exchange/Socket.hs view
@@ -5,19 +5,29 @@     , module Coinbase.Exchange.Types.Socket     ) where +------------------------------------------------------------------------------- import           Data.Aeson import           Network.Socket import qualified Network.WebSockets             as WS import           Wuss-+------------------------------------------------------------------------------- import           Coinbase.Exchange.Types import           Coinbase.Exchange.Types.Core import           Coinbase.Exchange.Types.Socket+------------------------------------------------------------------------------- -subscribe :: ApiType -> ProductId -> WS.ClientApp a -> IO a-subscribe atype pid app = withSocketsDo $++-------------------------------------------------------------------------------+subscribe :: ApiType -> [ProductId] -> WS.ClientApp a -> IO a+subscribe atype pids app = withSocketsDo $         runSecureClient location 443 "/" $ \conn -> do-            WS.sendBinaryData conn $ encode (Subscribe pid)+            WS.sendTextData conn $ encode (Subscribe pids)             app conn     where location = case atype of Sandbox -> sandboxSocket                                    Live    -> liveSocket+++-------------------------------------------------------------------------------+-- | Enable/disable heartbeat anytime you want in your 'ClientApp'+setHeartbeat :: Bool -> WS.ClientApp ()+setHeartbeat b conn = WS.sendTextData conn (encode $ SetHeartbeat b)
src/Coinbase/Exchange/Types.hs view
@@ -17,6 +17,8 @@     , sandboxSocket     , liveRest     , liveSocket+    , liveRealCoinbaseRest+    , sandboxRealCoinbaseRest      , Key     , Secret@@ -32,6 +34,7 @@     , ExchangeFailure (..)      , Exchange+    , ExchangeT     , ExceptT     , runExchange     , runExchangeT@@ -65,19 +68,27 @@ type Path     = String  website :: Endpoint-website = "https://public.sandbox.exchange.coinbase.com"+website = "https://public.sandbox.gdax.com"  sandboxRest :: Endpoint-sandboxRest = "https://api-public.sandbox.exchange.coinbase.com"+sandboxRest = "https://api-public.sandbox.gdax.com"  sandboxSocket :: Endpoint-sandboxSocket = "ws-feed-public.sandbox.exchange.coinbase.com"+sandboxSocket = "ws-feed-public.sandbox.gdax.com"  liveRest :: Endpoint-liveRest = "https://api.exchange.coinbase.com"+liveRest = "https://api.gdax.com"  liveSocket :: Endpoint-liveSocket = "ws-feed.exchange.coinbase.com"+liveSocket = "ws-feed.gdax.com"++-- Coinbase needs to provide real BTC transfers through the exchange API soon,+-- making 2 API calls with 2 sets of authentication credentials is ridiculous.+liveRealCoinbaseRest :: Endpoint+liveRealCoinbaseRest = "https://api.coinbase.com"++sandboxRealCoinbaseRest :: Endpoint+sandboxRealCoinbaseRest = "https://api.sandbox.coinbase.com"  -- Monad Stack 
src/Coinbase/Exchange/Types/Core.hs view
@@ -30,13 +30,25 @@     deriving (Eq, Ord, Show, Read, Data, Typeable, Generic, IsString, NFData, Hashable, FromJSON, ToJSON)  newtype Price = Price { unPrice :: CoinScientific }-    deriving (Eq, Ord, Num, Fractional, Real, RealFrac, Show, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON, ToJSON)+    deriving (Eq, Ord, Num, Fractional, Real, RealFrac, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON)+instance ToJSON Price where+    toJSON (Price (CoinScientific v)) = String . T.pack . formatScientific Fixed Nothing $ v+instance Show Price where+    show (Price (CoinScientific v)) = formatScientific Fixed Nothing v  newtype Size = Size { unSize :: CoinScientific }-    deriving (Eq, Ord, Num, Fractional, Real, RealFrac, Show, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON, ToJSON)+    deriving (Eq, Ord, Num, Fractional, Real, RealFrac, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON)+instance ToJSON Size where+    toJSON (Size (CoinScientific v)) = String . T.pack . formatScientific Fixed Nothing $ v+instance Show Size where+    show (Size (CoinScientific v)) = formatScientific Fixed Nothing v  newtype Cost = Cost { unCost :: CoinScientific }-    deriving (Eq, Ord, Num, Fractional, Real, RealFrac, Show, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON, ToJSON)+    deriving (Eq, Ord, Num, Fractional, Real, RealFrac, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON)+instance ToJSON Cost where+    toJSON (Cost (CoinScientific v)) = String . T.pack . formatScientific Fixed Nothing $ v+instance Show Cost where+    show (Cost (CoinScientific v)) = formatScientific Fixed Nothing v  newtype OrderId = OrderId { unOrderId :: UUID }     deriving (Eq, Ord, Show, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON, ToJSON)@@ -45,7 +57,7 @@     deriving (Eq, Ord, Show, Read, Num, Data, Typeable, Generic, NFData, Hashable, FromJSON, ToJSON)  newtype Sequence = Sequence { unSequence :: Word64 }-    deriving (Eq, Ord, Num, Show, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON, ToJSON)+    deriving (Eq, Ord, Num, Enum, Show, Read, Data, Typeable, Generic, NFData, Hashable, FromJSON, ToJSON)  -- @@ -80,7 +92,7 @@ instance FromJSON TradeId where     parseJSON (String t) = pure $ TradeId $ read $ T.unpack t     parseJSON (Number n) = pure $ TradeId $ floor n-    parseJSON _ = mzero+    parseJSON _          = mzero  -- @@ -94,6 +106,7 @@     | Settled     | Open     | Pending+    | Active     deriving (Eq, Show, Read, Data, Typeable, Generic)  instance NFData OrderStatus@@ -125,8 +138,9 @@ newtype CoinScientific = CoinScientific { unCoinScientific :: Scientific }     deriving (Eq, Ord, Num, Fractional, Real, RealFrac, Show, Read, Data, Typeable, NFData, Hashable) +-- Shows 8 decimal places (needs to be adapted for prices and costs in USD) instance ToJSON CoinScientific where-    toJSON (CoinScientific v) = String . T.pack . show $ v+    toJSON (CoinScientific v) = String . T.pack . formatScientific Fixed (Just 8) $ v instance FromJSON CoinScientific where     parseJSON = withText "CoinScientific" $ \t ->         case readMaybe (T.unpack t) of
src/Coinbase/Exchange/Types/MarketData.hs view
@@ -52,8 +52,8 @@ data Book a     = Book         { bookSequence :: Sequence-        , bookBids     :: [Bid a]-        , bookAsks     :: [Ask a]+        , bookBids     :: [BookItem a]+        , bookAsks     :: [BookItem a]         }     deriving (Show, Data, Typeable, Generic) @@ -63,22 +63,13 @@ instance (FromJSON a) => FromJSON (Book a) where     parseJSON = genericParseJSON coinbaseAesonOptions -data Ask a = Ask Price Size a-    deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)--instance (NFData a) => NFData (Ask a)-instance (ToJSON a) => ToJSON (Ask a) where-    toJSON = genericToJSON defaultOptions-instance (FromJSON a) => FromJSON (Ask a) where-    parseJSON = genericParseJSON defaultOptions--data Bid a = Bid Price Size a+data BookItem a = BookItem Price Size a     deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -instance (NFData a) => NFData (Bid a)-instance (ToJSON a) => ToJSON (Bid a) where+instance (NFData a) => NFData (BookItem a)+instance (ToJSON a) => ToJSON (BookItem a) where     toJSON = genericToJSON defaultOptions-instance (FromJSON a) => FromJSON (Bid a) where+instance (FromJSON a) => FromJSON (BookItem a) where     parseJSON = genericParseJSON defaultOptions  -- Product Ticker
src/Coinbase/Exchange/Types/Private.hs view
@@ -140,6 +140,7 @@ -- Orders data OrderContigency     = GoodTillCanceled+    | GoodTillTime     | ImmediateOrCancel     | FillOrKill     deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)@@ -149,14 +150,35 @@  instance ToJSON OrderContigency where     toJSON GoodTillCanceled  = String "GTC"+    toJSON GoodTillTime      = String "GTT"     toJSON ImmediateOrCancel = String "IOC"     toJSON FillOrKill        = String "FOK" instance FromJSON OrderContigency where     parseJSON (String "GTC") = return GoodTillCanceled+    parseJSON (String "GTT") = return GoodTillTime     parseJSON (String "IOC") = return ImmediateOrCancel     parseJSON (String "FOK") = return FillOrKill     parseJSON _ = mzero +data OrderCancelAfter+    = Min+    | Hour+    | Day+    deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance NFData   OrderCancelAfter+instance Hashable OrderCancelAfter++instance ToJSON OrderCancelAfter where+    toJSON Min                  = String "min"+    toJSON Hour                 = String "hour"+    toJSON Day                  = String "day"+instance FromJSON OrderCancelAfter where+    parseJSON (String "min")    = return Min+    parseJSON (String "hour")   = return Hour+    parseJSON (String "day")    = return Day+    parseJSON _ = mzero+ data SelfTrade     = DecrementAndCancel     | CancelOldest@@ -188,6 +210,7 @@         , noPrice     :: Price         , noSize      :: Size         ,noTimeInForce:: OrderContigency+        ,noCancelAfter:: Maybe OrderCancelAfter         , noPostOnly  :: Bool         }     | NewMarketOrder@@ -198,6 +221,15 @@         ---         , noSizeAndOrFunds  :: Either Size (Maybe Size, Cost)         }+    | NewStopOrder+        { noProductId :: ProductId+        , noSide      :: Side+        , noSelfTrade :: SelfTrade+        , noClientOid :: Maybe ClientOrderId+        ---+        , noPrice     :: Price+        , noSizeAndOrFunds  :: Either Size (Maybe Size, Cost)+        }     deriving (Show, Data, Typeable, Generic)  instance NFData NewOrder@@ -211,11 +243,14 @@             , "size"          .= noSize             , "time_in_force" .= noTimeInForce             , "post_only"     .= noPostOnly-            ] ++ clientID )+            ] ++ clientID ++ cancelAfter )             where                 clientID = case noClientOid of                                 Just cid -> [ "client_oid" .= cid ]                                 Nothing  -> []+                cancelAfter = case noCancelAfter of+                                   Just time -> [ "cancel_after" .= time ]+                                   Nothing   -> []          toJSON NewMarketOrder{..} = object            ([ "type" .= ("market" :: Text)@@ -233,7 +268,24 @@                                             Nothing -> ( []            , ["funds" .= f] )                                             Just s' -> ( ["size" .= s'], ["funds" .= f] ) +        toJSON NewStopOrder{..} = object+           ([ "type" .= ("stop" :: Text)+            , "product_id"    .= noProductId+            , "side"          .= noSide+            , "stp"           .= noSelfTrade+            , "price"         .= noPrice+            ] ++ clientID ++ size ++ funds )+            where+                clientID = case noClientOid of+                                Just cid -> [ "client_oid" .= cid ]+                                Nothing  -> []+                (size,funds) = case noSizeAndOrFunds of+                                Left  s -> (["size" .= s],[])+                                Right (ms,f) -> case ms of+                                            Nothing -> ( []            , ["funds" .= f] )+                                            Just s' -> ( ["size" .= s'], ["funds" .= f] ) + data OrderConfirmation     = OrderConfirmation         { ocId :: OrderId@@ -263,6 +315,7 @@         , orderPrice      :: Price         , orderSize       :: Size         , orderTimeInForce:: OrderContigency+        , orderCancelAfter:: Maybe OrderCancelAfter         , orderPostOnly   :: Bool         }     | MarketOrder@@ -280,6 +333,22 @@          , orderSizeAndOrFunds  :: Either Size (Maybe Size, Cost)         }+    | StopOrder+        { orderId         :: OrderId+        , orderProductId  :: ProductId+        , orderStatus     :: OrderStatus+        , orderSelfTrade  :: SelfTrade+        , orderSettled    :: Bool+        , orderSide       :: Side+        , orderCreatedAt  :: UTCTime+        , orderFilledSize :: Maybe Size+        , orderFilledFees :: Maybe Price+        , orderDoneAt     :: Maybe UTCTime+        , orderDoneReason :: Maybe Reason++        , orderPrice      :: Price+        , orderSizeAndOrFunds  :: Either Size (Maybe Size, Cost)+        }     deriving (Show, Data, Typeable, Generic)  instance NFData Order@@ -301,6 +370,7 @@         , "price"         .= orderPrice         , "size"          .= orderSize         , "time_in_force" .= orderTimeInForce+        , "cancel_after"  .= orderCancelAfter         , "post_only"     .= orderPostOnly         ]     toJSON MarketOrder{..} = object@@ -322,8 +392,29 @@                         Right (ms,f) -> case ms of                                     Nothing -> ( []            , ["funds" .= f] )                                     Just s' -> ( ["size" .= s'], ["funds" .= f] )+    toJSON StopOrder{..} = object+       ([ "type" .= ("market" :: Text)+        , "id"            .= orderId+        , "product_id"    .= orderProductId+        , "status"        .= orderStatus+        , "stp"           .= orderSelfTrade+        , "settled"       .= orderSettled+        , "side"          .= orderSide+        , "created_at"    .= orderCreatedAt+        , "filled_size"   .= orderFilledSize+        , "filled_fees"   .= orderFilledFees+        , "done_at"       .= orderDoneAt+        , "done_reason"   .= orderDoneReason +        , "price"         .= orderPrice+        ] ++ size ++ funds )+            where (size,funds) = case orderSizeAndOrFunds of+                        Left  s -> (["size" .= s],[])+                        Right (ms,f) -> case ms of+                                    Nothing -> ( []            , ["funds" .= f] )+                                    Just s' -> ( ["size" .= s'], ["funds" .= f] ) + instance FromJSON Order where     parseJSON (Object m) = do         ordertype <- m .: "type"@@ -343,6 +434,7 @@                 <*> m .: "price"                 <*> m .: "size"                 <*> m .:? "time_in_force" .!= GoodTillCanceled -- older orders don't seem to have this field+                <*> m .:? "cancel_after"                 <*> m .: "post_only"              "market" -> MarketOrder@@ -366,6 +458,29 @@                             (Nothing, Just f ) -> return $ Right (Nothing, f)                             (Just s , Just f ) -> return $ Right (Just s , f)                             )++            "stop" -> StopOrder+                <$> m .: "id"+                <*> m .: "product_id"+                <*> m .: "status"+                <*> m .: "stp"+                <*> m .: "settled"+                <*> m .: "side"+                <*> m .: "created_at"+                <*> m .:? "filled_size"+                <*> m .:? "filled_fees"+                <*> m .:? "done_at"+                <*> m .:? "done_reason"+                <*> m .: "price"+                <*> (do+                        ms <- m .:? "size"+                        mf <- m .:? "funds"+                        case (ms,mf) of+                            (Nothing, Nothing) -> mzero+                            (Just s , Nothing) -> return $ Left  s+                            (Nothing, Just f ) -> return $ Right (Nothing, f)+                            (Just s , Just f ) -> return $ Right (Just s , f)+                            )             _ -> mzero      parseJSON _ = mzero@@ -438,19 +553,269 @@ newtype CoinbaseAccountId = CoinbaseAccountId { unCoinbaseAccountId :: UUID }     deriving (Eq, Ord, Show, Read, Data, Typeable, Generic, NFData, FromJSON, ToJSON) -data Transfer+data TransferToCoinbase     = Deposit-        { transAmount          :: Size-        , transCoinbaseAccount :: CoinbaseAccountId+        { trAmount            :: Size+        , trCoinbaseAccountId :: CoinbaseAccountId         }     | Withdraw-        { transAmount          :: Size-        , transCoinbaseAccount :: CoinbaseAccountId+        { trAmount            :: Size+        , trCoinbaseAccountId :: CoinbaseAccountId         }     deriving (Show, Data, Typeable, Generic) -instance NFData Transfer-instance ToJSON Transfer where+instance NFData TransferToCoinbase+instance ToJSON TransferToCoinbase where     toJSON = genericToJSON coinbaseAesonOptions-instance FromJSON Transfer where++data CryptoWithdrawal+    = Withdrawal+        { wdAmount        :: Size+        , wdCurrency      :: CurrencyId+        , wdCryptoAddress :: CryptoWallet+        }+    deriving (Show, Data, Typeable, Generic)++instance NFData CryptoWithdrawal+instance ToJSON CryptoWithdrawal where+    toJSON = genericToJSON coinbaseAesonOptions+instance FromJSON CryptoWithdrawal where     parseJSON = genericParseJSON coinbaseAesonOptions++---------------------------+data TransferToCoinbaseResponse+    = TransferResponse+        { trId :: TransferId+        -- FIX ME! and other stuff I'm going to ignore.+        } deriving (Eq, Show, Generic, Typeable)++instance NFData   TransferToCoinbaseResponse+instance FromJSON TransferToCoinbaseResponse where+    parseJSON (Object m) = TransferResponse+        <$> m .: "id"+    parseJSON _ = mzero++data CryptoWithdrawalResp+    = WithdrawalResp+        { wdrId       :: TransferId+        , wdrAmount   :: Size+        , wdrCurrency :: CurrencyId+        } deriving (Eq, Show, Generic, Typeable)++instance NFData CryptoWithdrawalResp+instance ToJSON CryptoWithdrawalResp where+    toJSON = genericToJSON coinbaseAesonOptions+instance FromJSON CryptoWithdrawalResp where+    parseJSON = genericParseJSON coinbaseAesonOptions++---------------------------+data CryptoWallet+    = BTCWallet BitcoinWallet deriving (Show, Data, Typeable, Generic)+--  | To Do: add other...+--  | ... possibilities here later++instance NFData CryptoWallet+instance ToJSON CryptoWallet where+    toJSON = genericToJSON coinbaseAesonOptions+instance FromJSON CryptoWallet where+    parseJSON = genericParseJSON coinbaseAesonOptions+++newtype BitcoinWallet = FromBTCAddress { btcAddress :: String }+      deriving (Show, Data, Typeable, Generic, ToJSON, FromJSON)+instance NFData BitcoinWallet++data BTCTransferReq+    = SendBitcoin+        { sendAmount    :: Size+        , bitcoinWallet :: BitcoinWallet+        }+    deriving (Show, Data, Typeable, Generic)++instance NFData BTCTransferReq+instance ToJSON BTCTransferReq where+    toJSON SendBitcoin {..} = object+        [ "type"     .= ("send" :: Text)+        , "currency" .= ("BTC"  :: Text)+        , "to"       .= btcAddress bitcoinWallet+        , "amount"   .= sendAmount+        ]++---------------------------+newtype BTCTransferId = BTCTransferId { getBtcTransferId :: UUID }+    deriving (Eq, Ord, Show, Read, Data, Typeable, Generic, NFData, FromJSON, ToJSON)++data BTCTransferResponse = BTCTransferResponse+        { sendId :: BTCTransferId+        -- FIX ME! and other stuff I'm going to ignore.+        } deriving (Eq, Data, Show, Generic, Typeable)++instance NFData BTCTransferResponse+instance FromJSON BTCTransferResponse where+    parseJSON (Object m) = do+        transferData <- m .:? "data" -- FIX ME! I should factor this out of all responses from Coinbase+        case transferData of+            Nothing -> mzero+            Just da -> BTCTransferResponse <$> da .: "id"+    parseJSON _ = mzero++---------------------------+data CoinbaseAccount =+    CoinbaseAccount+        { cbAccID      :: CoinbaseAccountId+        , resourcePath :: String+        , primary      :: Bool+        , name         :: String+        , btcBalance   :: Size+        }+    deriving (Show, Data, Typeable, Generic)++instance FromJSON CoinbaseAccount where+    parseJSON (Object m) = do+        transferData <- m .:? "data" -- FIX ME! I should factor this out of all responses from Coinbase+        case transferData of+            Nothing -> mzero+            Just da -> CoinbaseAccount+                <$> da .: "id"+                <*> da .: "resource_path"+                <*> da .: "primary"+                <*> da .: "name"+                <*> (do+                        btcBalance <- da .: "balance"+                        case btcBalance of+                            Object b -> b .: "amount"+                            _        -> mzero+                    )++    parseJSON _ = mzero++ -- Reports++newtype ReportId = ReportId { unReportId :: UUID }+    deriving (Eq, Ord, Show, Read, Data, Typeable, Generic, NFData, FromJSON, ToJSON)++data ReportType+    = FillsReport+    | AccountReport+    deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance NFData   ReportType+instance Hashable ReportType++instance ToJSON ReportType where+    toJSON FillsReport                = String "fills"+    toJSON AccountReport              = String "account"+instance FromJSON ReportType where+    parseJSON (String "fills")   = return FillsReport+    parseJSON (String "account") = return AccountReport+    parseJSON _ = mzero++data ReportFormat+    = PDF+    | CSV+    deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance NFData   ReportFormat+instance Hashable ReportFormat++instance ToJSON ReportFormat where+    toJSON PDF                  = String "pdf"+    toJSON CSV                  = String "csv"+instance FromJSON ReportFormat where+    parseJSON (String "pdf")    = return PDF+    parseJSON (String "csv")    = return CSV+    parseJSON _ = mzero++data ReportRequest -- analgous to Transfer or NewOrder+    = ReportRequest+        { rrqType            :: ReportType+        , rrqStartDate       :: UTCTime+        , rrqEndDate         :: UTCTime+        , rrqProductId       :: ProductId+        , rrqAccountId       :: AccountId+        , rrqFormat          :: ReportFormat+        , rrqEmail           :: Maybe String+        }+    deriving (Show, Data, Typeable, Generic)++instance NFData ReportRequest+instance ToJSON ReportRequest where+    toJSON = genericToJSON coinbaseAesonOptions+instance FromJSON ReportRequest where+    parseJSON = genericParseJSON coinbaseAesonOptions++data ReportParams+    = ReportParams+        { reportStartDate       :: UTCTime+        , reportEndDate         :: UTCTime+        }+    deriving (Show, Data, Typeable, Generic)++instance NFData ReportParams+instance ToJSON ReportParams where+    toJSON ReportParams{..} = object+       ([ "start_date"        .= reportStartDate+        , "end_date"          .= reportEndDate+        ])+instance FromJSON ReportParams where+    parseJSON (Object m) = ReportParams+            <$> m .:  "start_date"+            <*> m .:  "end_date"+    parseJSON _ = mzero++data ReportStatus+    = ReportPending+    | ReportCreating+    | ReportReady+    deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance NFData   ReportStatus+instance Hashable ReportStatus++instance ToJSON ReportStatus where+    toJSON ReportPending        = String "pending"+    toJSON ReportCreating       = String "creating"+    toJSON ReportReady          = String "ready"+instance FromJSON ReportStatus where+    parseJSON (String "pending")    = return ReportPending+    parseJSON (String "creating")   = return ReportCreating+    parseJSON (String "ready")      = return ReportReady+    parseJSON _ = mzero++data ReportInfo+    = ReportInfo+        { reportId          :: ReportId+        , reportType        :: ReportType+        , reportStatus      :: ReportStatus+        , reportCreated     :: Maybe UTCTime+        , reportCompleted   :: Maybe UTCTime+        , reportExpires     :: Maybe UTCTime+        , reportUrl         :: Maybe String+        , reportParams      :: Maybe ReportParams+        }+    deriving (Show, Data, Typeable, Generic)++instance NFData ReportInfo+instance ToJSON ReportInfo where+    toJSON ReportInfo{..} = object+       ([ "id"            .= reportId+        , "type"          .= reportType+        , "status"        .= reportStatus+        , "created_at"    .= reportCreated+        , "completed_at"  .= reportCompleted+        , "expires_at"    .= reportExpires+        , "file_url"      .= reportUrl+        , "params"        .= reportParams+        ])++instance FromJSON ReportInfo where+    parseJSON (Object m) = ReportInfo+            <$> m .:  "id"+            <*> m .:  "type"+            <*> m .:  "status"+            <*> m .:? "created_at"+            <*> m .:? "completed_at"+            <*> m .:? "expires_at"+            <*> m .:? "file_url"+            <*> m .:? "params"+    parseJSON _ = mzero
src/Coinbase/Exchange/Types/Socket.hs view
@@ -7,22 +7,43 @@  module Coinbase.Exchange.Types.Socket where +-------------------------------------------------------------------------------+import           Control.Applicative import           Control.DeepSeq import           Control.Monad-import           Data.Aeson.Types      hiding (Error)+import           Data.Aeson.Types             hiding (Error) import           Data.Data import           Data.Hashable+import qualified Data.HashMap.Strict          as H import           Data.Text                    (Text) import           Data.Time import           Data.Word import           GHC.Generics-import qualified Data.HashMap.Strict as H+-------------------------------------------------------------------------------+import           Coinbase.Exchange.Types.Core hiding (OrderStatus (..))+------------------------------------------------------------------------------- -import           Coinbase.Exchange.Types.Core  hiding (OrderStatus(..)) ++-------------------------------------------------------------------------------+-- | Messages we can send to the exchange+data SendExchangeMessage+    = Subscribe [ProductId]+    | SetHeartbeat Bool+    deriving (Eq, Show, Read, Data, Typeable, Generic)++instance NFData SendExchangeMessage++++-------------------------------------------------------------------------------+-- | Messages they send back to us data ExchangeMessage-    = Subscribe-        { msgProductId :: ProductId+    = Heartbeat+        { msgTime        :: UTCTime+        , msgProductId   :: ProductId+        , msgSequence    :: Sequence+        , msgLastTradeId :: TradeId         }     | ReceivedLimit         { msgTime      :: UTCTime@@ -36,12 +57,12 @@         , msgSize      :: Size         }     | ReceivedMarket-        { msgTime      :: UTCTime-        , msgProductId :: ProductId-        , msgSequence  :: Sequence-        , msgOrderId   :: OrderId-        , msgSide      :: Side-        , msgClientOid :: Maybe ClientOrderId+        { msgTime         :: UTCTime+        , msgProductId    :: ProductId+        , msgSequence     :: Sequence+        , msgOrderId      :: OrderId+        , msgSide         :: Side+        , msgClientOid    :: Maybe ClientOrderId         -- market orders have no price and are bounded by either size, funds or both         , msgMarketBounds :: (Either Size (Maybe Size, Cost))         }@@ -65,35 +86,33 @@         , msgSize         :: Size         , msgPrice        :: Price         }-    | DoneLimit-        { msgTime      :: UTCTime-        , msgProductId :: ProductId-        , msgSequence  :: Sequence-        , msgOrderId   :: OrderId-        , msgSide      :: Side-        , msgRemainingSize :: Size-        , msgPrice     :: Price-        , msgReason    :: Reason-        , msgOrderType :: OrderType-        }-    | DoneMarket-        { msgTime      :: UTCTime-        , msgProductId :: ProductId-        , msgSequence  :: Sequence-        , msgOrderId   :: OrderId-        , msgSide      :: Side-        , msgReason    :: Reason-        , msgOrderType :: OrderType+    | Done+        { msgTime         :: UTCTime+        , msgProductId    :: ProductId+        , msgSequence     :: Sequence+        , msgOrderId      :: OrderId+        , msgSide         :: Side+        , msgReason       :: Reason+        -- It is possible for these next two fields to be Nothing separately+        -- Filled market orders limited by funds will not have a price but may have remaining_size+        -- Filled limit orders may have a price but not a remaining_size (assumed zero)+        -- CURRENTLY ** `remaining_size` reported in Done messages is sometimes incorrect **+        -- This appears to be bug at GDAX. I've told them about it.+        , msgMaybePrice   :: Maybe Price+        , msgMaybeRemSize :: Maybe Size         }     | ChangeLimit-        { msgTime      :: UTCTime-        , msgProductId :: ProductId-        , msgSequence  :: Sequence-        , msgOrderId   :: OrderId-        , msgSide      :: Side-        , msgPrice     :: Price-        , msgNewSize   :: Size-        , msgOldSize   :: Size+        { msgTime       :: UTCTime+        , msgProductId  :: ProductId+        , msgSequence   :: Sequence+        , msgOrderId    :: OrderId+        , msgSide       :: Side+        -- Observation has revealed Price is not always present in+        -- change messages with old_size and new_size. This may be+        -- self trade prevention or something of the sort.+        , msgMaybePrice :: Maybe Price+        , msgNewSize    :: Size+        , msgOldSize    :: Size         }     | ChangeMarket         { msgTime      :: UTCTime@@ -101,7 +120,6 @@         , msgSequence  :: Sequence         , msgOrderId   :: OrderId         , msgSide      :: Side-        , msgPrice     :: Price         , msgNewFunds  :: Cost         , msgOldFunds  :: Cost         }@@ -116,7 +134,14 @@ instance FromJSON ExchangeMessage where     parseJSON (Object m) = do         msgtype <- m .: "type"+        -- TO DO: `HeartbeatReq` and `Subscribe` message types are missing as those are+        -- never received by the client.         case (msgtype :: String) of+            "hearbeat"-> Heartbeat+                <$> m .: "time"+                <*> m .: "product_id"+                <*> m .: "sequence"+                <*> m .: "last_trade_id"             "open" -> Open                 <$> m .: "time"                 <*> m .: "product_id"@@ -125,27 +150,15 @@                 <*> m .: "side"                 <*> m .: "remaining_size"                 <*> m .: "price"-            "done" -> do-                typ  <- m .: "order_type"-                case typ of-                    Limit -> DoneLimit-                        <$> m .: "time"-                        <*> m .: "product_id"-                        <*> m .: "sequence"-                        <*> m .: "order_id"-                        <*> m .: "side"-                        <*> m .: "remaining_size"-                        <*> m .: "price"-                        <*> m .: "reason"-                        <*> m .: "order_type"-                    Market -> DoneMarket-                        <$> m .: "time"-                        <*> m .: "product_id"-                        <*> m .: "sequence"-                        <*> m .: "order_id"-                        <*> m .: "side"-                        <*> m .: "reason"-                        <*> m .: "order_type"+            "done" -> Done+                <$> m .: "time"+                <*> m .: "product_id"+                <*> m .: "sequence"+                <*> m .: "order_id"+                <*> m .: "side"+                <*> m .: "reason"+                <*> m .:? "price"+                <*> m .:? "remaining_size"             "match" -> Match                 <$> m .: "time"                 <*> m .: "product_id"@@ -157,18 +170,16 @@                 <*> m .: "size"                 <*> m .: "price"             "change" -> do-                ms <- m .:? "new_size"-                case (ms :: Maybe Size) of-                    Nothing -> ChangeMarket+                ms <- m .:? "price"+                let market = ChangeMarket                                 <$> m .: "time"                                 <*> m .: "product_id"                                 <*> m .: "sequence"                                 <*> m .: "order_id"                                 <*> m .: "side"-                                <*> m .: "price"                                 <*> m .: "new_funds"                                 <*> m .: "old_funds"-                    Just _ -> ChangeLimit+                    limit = ChangeLimit                                 <$> m .: "time"                                 <*> m .: "product_id"                                 <*> m .: "sequence"@@ -177,9 +188,12 @@                                 <*> m .: "price"                                 <*> m .: "new_size"                                 <*> m .: "old_size"+                case (ms :: Maybe Price) of+                    Nothing -> market <|> limit+                    Just _ -> limit <|> market             "received" -> do                 typ  <- m .:  "order_type"-                mcid <- m .:? "client_id"+                mcid <- m .:? "client_oid"                 case typ of                     Limit -> ReceivedLimit                                 <$> m .: "time"@@ -208,6 +222,7 @@                                             (Nothing, Just f ) -> return $ Right (Nothing, f)                                             (Just s , Just f ) -> return $ Right (Just s , f)                                             )+            "error" -> error (show m)      parseJSON _ = mzero @@ -221,13 +236,21 @@                    then pure Nothing                    else obj .:? key ---------------------------- -instance ToJSON ExchangeMessage where-    toJSON Subscribe{..} = object+-------------------------------------------------------------------------------+instance ToJSON SendExchangeMessage where+    toJSON (Subscribe pids) = object         [ "type"       .= ("subscribe" :: Text)-        , "product_id" .= msgProductId+        , "product_ids" .= pids         ]+    toJSON (SetHeartbeat b) = object+        [ "type"       .= ("heartbeat" :: Text)+        , "on"         .= b]+++-------------------------------------------------------------------------------+-- | Convenience/storage instance; never sent to exchange+instance ToJSON ExchangeMessage where     toJSON Open{..} = object         [ "type"       .= ("open" :: Text)         , "time"       .= msgTime@@ -238,28 +261,22 @@         , "remaining_size" .= msgRemainingSize         , "price"      .= msgPrice         ]-    toJSON DoneLimit{..} = object-        [ "type"       .= ("done" :: Text)+    toJSON Done{..} = object+        ([ "type"      .= ("done" :: Text)         , "time"       .= msgTime         , "product_id" .= msgProductId         , "sequence"   .= msgSequence         , "order_id"   .= msgOrderId         , "side"       .= msgSide-        , "remaining_size" .= msgRemainingSize-        , "price"      .= msgPrice         , "reason"     .= msgReason-        , "order_type" .= Limit         ]-    toJSON DoneMarket{..} = object-        [ "type"       .= ("done" :: Text)-        , "time"       .= msgTime-        , "product_id" .= msgProductId-        , "sequence"   .= msgSequence-        , "order_id"   .= msgOrderId-        , "side"       .= msgSide-        , "reason"     .= msgReason-        , "order_type" .= Market-        ]+        ++ case msgMaybePrice of+                Nothing -> []+                Just  p -> ["price" .= p]+        ++ case msgMaybeRemSize of+                Nothing -> []+                Just  s -> ["remaining_size" .= s]+        )     toJSON Match{..} = object         [ "type"       .= ("match" :: Text)         , "time"       .= msgTime@@ -276,7 +293,7 @@         [ "type" .= ("error" :: Text)         , "message" .= msgMessage         ]-    toJSON ChangeLimit{..} = object+    toJSON ChangeLimit{..} = object $         [ "type"       .= ("change" :: Text)         , "time"       .= msgTime         , "product_id" .= msgProductId@@ -285,8 +302,7 @@         , "side"       .= msgSide         , "new_size"   .= msgNewSize         , "old_size"   .= msgOldSize-        , "price"      .= msgPrice-        ]+        ] ++ maybe [] (return . ("price" .= )) msgMaybePrice     toJSON ChangeMarket{..} = object         [ "type"       .= ("change" :: Text)         , "time"       .= msgTime@@ -294,7 +310,6 @@         , "sequence"   .= msgSequence         , "order_id"   .= msgOrderId         , "side"       .= msgSide-        , "price"      .= msgPrice         , "new_funds"  .= msgNewFunds         , "old_funds"  .= msgOldFunds         ]@@ -313,7 +328,7 @@             where                 clientID = case msgClientOid of                     Nothing -> []-                    Just ci -> ["client_id" .= msgClientOid ]+                    Just ci -> ["client_oid" .= msgClientOid ]      toJSON ReceivedMarket{..} = object (         ["type"       .= ("received" :: Text)@@ -327,7 +342,7 @@             where                 clientID = case msgClientOid of                     Nothing -> []-                    Just ci -> ["client_id" .= msgClientOid ]+                    Just ci -> ["client_oid" .= msgClientOid ]                 (size,funds) = case msgMarketBounds of                     Left  s -> (["size" .= s],[])                     Right (ms,f) -> case ms of
+ test/Coinbase/Exchange/MarketData/Test.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE OverloadedStrings #-}++module Coinbase.Exchange.MarketData.Test+    ( tests+    ) where++import           Control.Monad.IO.Class+import           Data.Time+import           Test.Tasty+import           Test.Tasty.HUnit++import           Coinbase.Exchange.MarketData+import           Coinbase.Exchange.Types+import           Coinbase.Exchange.Types.Core++--------------------------------+-- NOTE: ["case_parse" test cases]+--+-- The 'case_parse' function does NOT test that the API responses are parsed correctly+-- For example, the price can be $240 be parsed as $420 and the test will succeed.+-- The function only tests that the parser did not fail and returned *a value*+-- Whether the value returned is the correct one, that's a different matter, and+-- 'case-parse' is NOT testing that.+--+--------------------------------++tests :: ExchangeConf -> TestTree+tests conf = testGroup "MarketData Parse"+        [ case_parse conf "getProducts"      $ getProducts+        , case_parse conf "getTopOfBook"     $ getTopOfBook     defProduct+        , case_parse conf "getTop50OfBook"   $ getTop50OfBook   defProduct+        , case_parse conf "getOrderBook"     $ getOrderBook     defProduct+        , case_parse conf "getProductTicker" $ getProductTicker defProduct+        , case_parse conf "getTrades"        $ getTrades        defProduct+        , case_parse conf "getHistory"       $ getHistory       defProduct defStart defEnd (Just 3600)+        , case_parse conf "getCurrencies"    $ getCurrencies+        , case_parse conf "getExchangeTime"  $ getExchangeTime+        ]++defProduct :: ProductId+defProduct = ProductId "BTC-USD"++-- The date range below works well to provide data for the getHistory call in the sandboxed environment+-- The previous range yielded an empty list with no data when connected to the sandbox.+defStart :: Maybe UTCTime+defStart = Just $ parseTimeOrError True defaultTimeLocale "%FT%X%z" "2015-10-01T20:22:37+0000"++defEnd :: Maybe UTCTime+defEnd = Just $ parseTimeOrError True defaultTimeLocale "%FT%X%z" "2015-10-07T21:22:37+0000"++-- See NOTE: ["case_parse" test cases]+case_parse :: Show a => ExchangeConf -> String -> Exchange a -> TestTree+case_parse conf l fn = testCase l $ do+        v <- liftIO $ runExchange conf fn+        assertBool ("Failed to parse: " ++ show v)+            (case v of+                Left  _ -> False+                Right _ -> True)
+ test/Coinbase/Exchange/Private/Test.hs view
@@ -0,0 +1,205 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-}++module Coinbase.Exchange.Private.Test+    ( tests+    , giveAwayOrder+    , run_placeOrder+    ) where++import           Control.Monad+import           Control.Monad.IO.Class+import           Control.Concurrent++import           Data.IORef+import           Data.Maybe+import           Data.List+import           Data.Time+import           Data.Scientific+import           Data.UUID++import           System.Random++import           Test.Tasty+import           Test.Tasty.HUnit++import           Coinbase.Exchange.Private+import           Coinbase.Exchange.Types+import           Coinbase.Exchange.Types.Core+import           Coinbase.Exchange.Types.Private++import           Network.HTTP.Client.TLS+import           Network.HTTP.Conduit+import           System.Environment+import qualified Data.ByteString.Char8             as CBS++deriving instance Eq Order+++tests :: ExchangeConf -> TestTree+tests conf = testGroup "Private"+        [ testCase "getAccountList"     (do as <- run_getAccountList conf+                                            case as of+                                                [] -> error "Received empty list of accounts"+                                                _  -> return ()+                                        )++        , testCase "getUSDAccount"      (do as <- run_getAccountList conf+                                            let usdAccount = findUSDAccount as+                                            ac <- run_getAccount conf (accId usdAccount)+                                            assertEqual "accounts match" usdAccount ac+                                        )++        ,testCase "getUSDAccountLedger" (do as <- run_getAccountList conf+                                            let usdAccount = findUSDAccount as+                                            es <- run_getAccountLedger conf (accId usdAccount)+                                            case es of+                                                [] -> assertFailure "Received empty list of ledger entries" -- must not be empty to test parser+                                                _  -> return ()+                                        )++        , testCase "placeOrder"         (do o   <- creatNewLimitOrder+                                            oid <- run_placeOrder conf o             -- limit order+                                            oid'<- run_placeOrder conf giveAwayOrder -- market order+                                            return ()+                                        )++        , testCase "getOrderList"       (do run_getOrderList conf [Open, Pending] -- making sure this request is well formed+                                            os <- run_getOrderList conf []+                                            case os of+                                                [] -> assertFailure "Received empty order list"+                                                _  -> return ()+                                        )++        , testCase "getOrder"           (do no  <- creatNewLimitOrder+                                            oid <- run_placeOrder conf no+                                            threadDelay 1000000 -- 1 second delay+                                            o   <- run_getOrder conf oid+                                            assertEqual "order price"    (noPrice no) (orderPrice o)+                                            assertEqual "order size"     (noSize  no) (orderSize  o)+                                            assertEqual "order side"     (noSide  no) (orderSide  o)+                                            assertEqual "order product"  (noProductId no) (orderProductId o)+                                        )+        , testCase "cancelOrder"        (do no  <- creatNewLimitOrder+                                            threadDelay 4000000 -- 4 second delay, to run after other tests+                                            oid <- run_placeOrder  conf no+                                            threadDelay 1000000 -- 1 second delay+                                            os  <- run_getOrderList conf [Open, Pending]+                                            threadDelay 1000000 -- 1 second delay+                                            run_cancelOrder conf oid+                                            threadDelay 1000000 -- 1 second delay+                                            os' <- run_getOrderList conf [Open, Pending]+                                            case os \\ os' of+                                                            [o] -> do+                                                                    assertEqual "order price"    (noPrice no) (orderPrice o)+                                                                    assertEqual "order size"     (noSize  no) (orderSize  o)+                                                                    assertEqual "order side"     (noSide  no) (orderSide  o)+                                                                    assertEqual "order product"  (noProductId no) (orderProductId o)++                                                            [] -> assertFailure "order not canceled"+                                                            _  -> assertFailure "more than one order canceled"+                                        )++        , testCase "getFills" (do oid <- run_placeOrder conf giveAwayOrder+                                  threadDelay 1000000 -- 1 second delay+                                  fs <- run_getFills conf (Just oid) Nothing+                                  case fs of+                                    [] -> assertFailure "No fills found for an order that should execute immediately"+                                    _  -> return ()+                              )+++        -------------------------- BTC TRANSFER TESTS --------------------------+        -- CAREFULL ON LIVE ENVIRONMENT!!! TRANSFERS ARE IRREVERSIBLE!!!++        -- This test cause a "403 Forbiden" error when run in the Sanbox. I'm not sure that can be fixed on my end.+        , testCase "Withdraw BTCs" $+            assertFailure "BTC withdrawal test Suspended for Safety"+            -- (do+            -- res <- run_withdrawBTC conf sampleTransfer+            -- print res+            -- return ()+            -- )++        --------------------------------------------------------------------------------+        ]++-----------------------------------------------+-- DO NOT USE!! CAREFUL!! THIS WILL TRY TO SEND YOUR BITCOINS TO THE SPECIFIED WALLET BELOW!+-- THIS MAY BE IRREVERSIBLE.+sampleTransfer :: CryptoWithdrawal+sampleTransfer = Withdrawal+        { wdAmount        = 0.02+        , wdCurrency      = CurrencyId "BTC"+        , wdCryptoAddress = BTCWallet (FromBTCAddress "INVALID-WALLET-INVALID-WALLET-INVA")+        }++giveAwayOrder :: NewOrder+giveAwayOrder = NewMarketOrder+    -- CAREFUL CHANGING THESE VALUES IF YOU PERFORM TESTING IN THE LIVE ENVIRONMENT. YOU MAY LOSE MONEY.+    { noProductId = "BTC-USD"+    , noSide      = Sell+    , noSelfTrade = DecrementAndCancel+    , noClientOid = Just $ ClientOrderId $ fromJust $ fromString "c2cc10e1-57d6-4b6f-9899-deadbeef2d8c"+    , noSizeAndOrFunds = Right (Just 0.01, 5) -- at most 1 BTC cent or 5 dollars per test+    }++creatNewLimitOrder :: IO NewOrder+creatNewLimitOrder = do+    -- can't be deterministic because exchange is stateful+    -- running a test twice with same random input may produce different results+    sz <- randomRIO (0,9999)+    -- CAREFUL CHANGING THESE VALUES IF YOU PERFORM TESTING IN THE LIVE ENVIRONMENT. YOU MAY LOOSE MONEY.+    return NewLimitOrder+        { noSize      = 0.01 + Size (CoinScientific $ fromInteger sz / 1000000 )+        , noPrice     = 10.36+        , noProductId = "BTC-USD"+        , noSide      = Buy+        , noSelfTrade = DecrementAndCancel+        , noClientOid = Just $ ClientOrderId $ fromJust $ fromString "c2cc10e1-57d6-4b6f-9899-111122223d8c"+        , noPostOnly  = False+        , noTimeInForce = GoodTillCanceled+        , noCancelAfter = Nothing+        }+++findUSDAccount :: [Account] -> Account+findUSDAccount as = case filter (\a -> accCurrency a == CurrencyId "USD") as of+                        [a] -> a+                        []  -> error "no USD denominated account found"+                        _   -> error "more than one account denominated in USD found"++-----------------------------------------------+onSuccess :: ExchangeConf -> Exchange a -> String -> IO a+onSuccess conf apicall errorstring = do+        r <- liftIO $ runExchange conf apicall+        case r of+            Left  e -> print e >> error errorstring+            Right a -> return a++run_getAccountList :: ExchangeConf -> IO [Account]+run_getAccountList conf = onSuccess conf getAccountList "Failed to get account list"++run_getAccount :: ExchangeConf -> AccountId -> IO Account+run_getAccount conf acID = onSuccess conf (getAccount acID) "Failed to get account info"++run_getAccountLedger :: ExchangeConf -> AccountId -> IO [Entry]+run_getAccountLedger conf acID = onSuccess conf (getAccountLedger acID) "Failed to get account ledger"++run_placeOrder :: ExchangeConf -> NewOrder -> IO OrderId+run_placeOrder conf o = onSuccess conf (createOrder o) "Failed to create order"++run_getOrder :: ExchangeConf -> OrderId -> IO Order+run_getOrder conf oid = onSuccess conf (getOrder oid) "Failed to get order info"++run_getOrderList :: ExchangeConf -> [OrderStatus] -> IO [Order]+run_getOrderList conf ss = onSuccess conf (getOrderList ss) "Failed to get order list"++run_cancelOrder :: ExchangeConf -> OrderId -> IO ()+run_cancelOrder conf oid = onSuccess conf (cancelOrder oid) "Failed to cancel order"++run_getFills :: ExchangeConf -> Maybe OrderId -> Maybe ProductId -> IO [Fill]+run_getFills conf moid mpid = onSuccess conf (getFills moid mpid) "Failed to get fills"++run_withdrawBTC :: ExchangeConf -> CryptoWithdrawal -> IO CryptoWithdrawalResp+run_withdrawBTC conf w = onSuccess conf (createCryptoWithdrawal w) "Failed to create withdrawal"
+ test/Coinbase/Exchange/Socket/Test.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE OverloadedStrings #-}++module Coinbase.Exchange.Socket.Test (tests) where++import           Control.Concurrent+import           Control.Concurrent.Async+import           Control.Monad+import           Data.Aeson++import           Test.Tasty+import           Test.Tasty.HUnit++import qualified Network.WebSockets             as WS++import           Coinbase.Exchange.Private+import           Coinbase.Exchange.Socket+import           Coinbase.Exchange.Types+import           Coinbase.Exchange.Types.Core++import qualified Coinbase.Exchange.Private.Test as P++import           Debug.Trace++-------------------------------------+-- NOTE: [Connectivity Precondition]+--+-- The parsing tests are time-based and assume we are receiving messages during the+-- time we are connected. However, those tests are NOT FAILSAFE.+--+-- ** If no data is received, parsing succeeds and, therefore, the parsing tests succeed **+--+-- To ensure this unsafe behavior does not go unnoticed (we thinking we are+-- parsing correctly when, in fact, we are not parsing anything at all),+-- We first verify we can receive at least 20 messages (i.e. a fixed minimum number)+-- from the socket, before running the parsing tests.+-------------------------------------++tests :: ExchangeConf -> ProductId -> TestTree+tests conf market= testGroup "Socket"+        -- See NOTE: [Connectivity Precondition]+        [ testCase "Do I receive messages?"  (receiveSocket  conf [market])+        , testCase "Parse Websocket Stream"  (parseSocket    conf [market] (threadDelay $ 1000000 * 20))+        , testCase "Decode Re-Encode Decode" (reencodeSocket conf [market])+        ]++receiveSocket :: ExchangeConf -> [ProductId] -> IO ()+receiveSocket conf market = subscribe (apiType conf) market $ \conn -> do+    sequence_ $ replicate 20 (receiveAndDecode conn)++-- Success: no parse errors   found while running+-- Failure: a parse error is  found while running+parseSocket :: ExchangeConf -> [ProductId] -> IO a -> IO ()+parseSocket conf market challenge = subscribe (apiType conf) market $ \conn -> do+    waitCancelThreads challenge (forever $ receiveAndDecode conn)+    return ()++-- FIX ME! there's no guarantee we are hitting all order types.+-- a more thorough test would be better.+reencodeSocket :: ExchangeConf -> [ProductId] -> IO ()+reencodeSocket conf market = subscribe (apiType conf) market $ \conn -> do+    sequence_ $ replicate 1000 (decodeEncode conn)++decodeEncode :: WS.Connection -> IO ()+decodeEncode conn = do+    ds <- WS.receiveData conn+    let res = eitherDecode ds+    case res :: Either String ExchangeMessage of+        Left er -> assertFailure "Failure parsing data from exchange" >> print er+        Right received -> do+            let enc = encode received+                dec = eitherDecode enc+            if dec == res+                then return ()+                else do+                    putStrLn $ "### original: " ++ show res+                    putStrLn $ "### obtained: " ++ show dec+                    assertFailure "decoded object is different from original"++++receiveAndDecode :: WS.Connection -> IO ()+receiveAndDecode conn = do+    ds <- WS.receiveData conn+    let res = eitherDecode {- $ trace (show ds) -} ds+    case res :: Either String ExchangeMessage of+        Left er -> print er   >> assertFailure "Parsing failure found"+        Right v -> return ()++waitCancelThreads :: IO a -> IO b -> IO (Either a b)+waitCancelThreads action1 action2 = do+    a <- async action1+    b <- async action2+    c <- waitEither a b+    case c of+        Left  a -> cancel b+        Right b -> cancel a+    return c
test/Main.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE OverloadedStrings #-}+ module Main where  import           Control.Monad@@ -8,6 +10,7 @@ import           Test.Tasty  import           Coinbase.Exchange.Types+import           Coinbase.Exchange.Types.Core  import qualified Coinbase.Exchange.MarketData.Test as MarketData import qualified Coinbase.Exchange.Private.Test    as Private@@ -16,17 +19,23 @@ main :: IO () main = do         mgr     <- newManager tlsManagerSettings-        tKey    <- liftM CBS.pack $ getEnv "COINBASE_KEY"-        tSecret <- liftM CBS.pack $ getEnv "COINBASE_SECRET"-        tPass   <- liftM CBS.pack $ getEnv "COINBASE_PASSPHRASE"+        tKey    <- liftM CBS.pack $ getEnv "GDAX_KEY"+        tSecret <- liftM CBS.pack $ getEnv "GDAX_SECRET"+        tPass   <- liftM CBS.pack $ getEnv "GDAX_PASSPHRASE" +        sbox    <- getEnv "GDAX_SANDBOX"+        let apiType  = case sbox of+                        "FALSE" -> Live+                        "TRUE"  -> Sandbox+                        _       -> error "Coinbase sandbox option must be either: TRUE or FALSE (all caps)"+         case mkToken tKey tSecret tPass of-            Right tok -> defaultMain (tests $ ExchangeConf mgr (Just tok) Live)+            Right tok -> defaultMain (tests $ ExchangeConf mgr (Just tok) apiType)             Left   er -> error $ show er  tests :: ExchangeConf -> TestTree tests conf = testGroup "Tests"         [ MarketData.tests conf         , Private.tests    conf-        , Socket.tests     conf+        , Socket.tests conf (ProductId "ETH-BTC")          ]