packages feed

bitx-bitcoin 0.6.0.0 → 0.7.0.0

raw patch · 9 files changed

+78/−53 lines, 9 filesdep +QuickCheckPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck

API changes (from Hackage documentation)

+ Network.Bitcoin.BitX: aesToRec :: BitXAesRecordConvert recd => Aes recd -> recd
+ Network.Bitcoin.BitX: class FromJSON (Aes recd) => BitXAesRecordConvert recd where type family Aes recd
+ Network.Bitcoin.BitX.Types: IDR :: Asset
+ Network.Bitcoin.BitX.Types: IDRXBT :: CcyPair
+ Network.Bitcoin.BitX.Types: XBTIDR :: CcyPair
+ Network.Bitcoin.BitX.Types: [tradeIsBuy] :: Trade -> Bool
+ Network.Bitcoin.BitX.Types: class HasIsBuy s a | s -> a
+ Network.Bitcoin.BitX.Types: instance GHC.Generics.Constructor Network.Bitcoin.BitX.Types.C1_10CcyPair
+ Network.Bitcoin.BitX.Types: instance GHC.Generics.Constructor Network.Bitcoin.BitX.Types.C1_11CcyPair
+ Network.Bitcoin.BitX.Types: instance GHC.Generics.Constructor Network.Bitcoin.BitX.Types.C1_6Asset
+ Network.Bitcoin.BitX.Types: instance Network.Bitcoin.BitX.Types.HasIsBuy Network.Bitcoin.BitX.Types.Trade GHC.Types.Bool
+ Network.Bitcoin.BitX.Types: isBuy :: HasIsBuy s a => Lens' s a
- Network.Bitcoin.BitX.Public: getTrades :: CcyPair -> IO (BitXAPIResponse [Trade])
+ Network.Bitcoin.BitX.Public: getTrades :: Maybe UTCTime -> CcyPair -> IO (BitXAPIResponse [Trade])
- Network.Bitcoin.BitX.Types: Trade :: UTCTime -> Scientific -> Int -> Trade
+ Network.Bitcoin.BitX.Types: Trade :: UTCTime -> Scientific -> Int -> Bool -> Trade

Files

CHANGES view
@@ -1,3 +1,8 @@+v0.7.0.0+* Added new "since" option to public trades' endpoint. BREAKING CHANGE.+* Added is_buy field for trade record.+* Added Indonesian Rupiah.+ v0.6.0.0 * Added the new endpoint for creating market (spot) orders. * Replaced http-conduit with http-client and http-client-tls.@@ -5,8 +10,6 @@  v0.5.0.1 * A few more major bugfixes w.r.t. to BitX number formatting.--v0.5.0.1 * Fixed issue due to BitX's handling of ints as decimal.  v0.5.0.0
bitx-bitcoin.cabal view
@@ -1,5 +1,5 @@ name:                bitx-bitcoin-version:             0.6.0.0+version:             0.7.0.0 synopsis:            A Haskell library for working with the BitX bitcoin exchange.  description:@@ -67,6 +67,7 @@                        time,                        bytestring,                        network,+                       QuickCheck >= 2.8,                        split >= 0.2.0.0,                        scientific,                        http-client >= 0.4.6.1,
src/Network/Bitcoin/BitX/Public.hs view
@@ -47,7 +47,9 @@  import Network.Bitcoin.BitX.Internal import Network.Bitcoin.BitX.Types+import Network.Bitcoin.BitX.Types.Internal import Network.Bitcoin.BitX.Response+import Data.Time.Clock (UTCTime)  {- | Returns the latest ticker indicators. -} @@ -69,5 +71,6 @@  {- | Returns a list of the most recent trades -} -getTrades :: CcyPair -> IO (BitXAPIResponse [Trade])-getTrades cyp = simpleBitXGet_ $ "trades?pair=" ++ show cyp+getTrades :: Maybe UTCTime -> CcyPair -> IO (BitXAPIResponse [Trade])+getTrades   Nothing    cyp = simpleBitXGet_ $ "trades?pair=" ++ show cyp+getTrades (Just since) cyp = simpleBitXGet_ $ "trades?pair=" ++ show cyp ++ "since=" ++ show (timeToTimestamp since)
src/Network/Bitcoin/BitX/Types.hs view
@@ -123,7 +123,8 @@     HasExpiresAt(..),     HasDiscarded(..),     HasExercised(..),-    HasName(..)+    HasName(..),+    HasIsBuy(..)   ) where  import Data.Aeson (FromJSON(..))@@ -176,6 +177,8 @@     | MYRXBT -- ^ Malaysian Ringgit vs. Bitcoin     | XBTNGN -- ^ Bitcoin vs. Nigerian Naira     | NGNXBT -- ^ Nigerian Naira vs. Bitcoin+    | XBTIDR -- ^ Bitcoin vs. Indonesian Rupiah+    | IDRXBT -- ^ Indonesian Rupiah vs. Bitcoin   deriving (Show, Generic, Eq)  -- | The state of a single market, identified by the currency pair.@@ -200,6 +203,7 @@     | KES -- ^ Kenyan Shilling     | MYR -- ^ Malaysian Ringgit     | NGN -- ^ Nigerian Naira+    | IDR -- ^ Indonesian Rupiah   deriving (Show, Generic, Eq)  -- | The type of a withdrawal request.@@ -242,7 +246,8 @@ data Trade = Trade {     tradeTimestamp :: UTCTime,     tradeVolume :: Scientific,-    tradePrice :: Int+    tradePrice :: Int,+    tradeIsBuy :: Bool     } deriving (Eq, Show)  makeFields ''Trade
src/Network/Bitcoin/BitX/Types/Internal.hs view
@@ -1,12 +1,13 @@ {-# LANGUAGE QuasiQuotes, OverloadedStrings, TemplateHaskell, TypeFamilies, FlexibleContexts,-    FlexibleInstances, DataKinds, CPP, RecordWildCards #-}+    FlexibleInstances, DataKinds, CPP, RecordWildCards, GeneralizedNewtypeDeriving #-}  module Network.Bitcoin.BitX.Types.Internal     (     BitXAesRecordConvert(..),     POSTEncodeable(..),     Transaction_(..),-    pendingTransactionsToTransactions+    pendingTransactionsToTransactions,+    timeToTimestamp     ) where @@ -18,7 +19,7 @@ import qualified Data.Text.Encoding as Txt import Data.Text (Text) import Data.Time.Clock (UTCTime)-import Data.Time.Clock.POSIX (posixSecondsToUTCTime)+import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds) import Lens.Micro ((^.)) #if __GLASGOW_HASKELL__ >= 710 -- base 4.8+ (GHC 7.10+) re-exports Monoid and its functions/constants@@ -32,18 +33,33 @@ #if __GLASGOW_HASKELL__ >= 708 import Data.Coerce #endif+import Test.QuickCheck  {-# ANN module ("HLint: ignore Use camelCase" :: String) #-} +newtype UnixStampMS = UnixStampMS {unUnixStampMS_ :: Integer} deriving (Eq, Ord, Show, Num, Integral, Real, Enum)++instance Arbitrary UnixStampMS where+    arbitrary = do+        k <- choose (1225497600000, 32782406400000) -- 1 Nov 2008 00:00:00 to 1 Nov 3008 00:00:00+        return $ UnixStampMS k+ timestampParse_ :: Integer -> UTCTime timestampParse_ = posixSecondsToUTCTime     . realToFrac     . ( / 1000)     . (fromIntegral :: Integer -> Scientific) ---class (FromJSON aes) => BitXAesRecordConvert recd aes | recd -> aes where---    aesToRec :: aes -> recd+timeToTimestamp :: UTCTime -> Integer+timeToTimestamp = truncate . (* 1000). utcTimeToPOSIXSeconds +-- $setup+-- >>> import Test.QuickCheck++-- |+-- prop> \ n -> (timeToTimestamp $ timestampParse_ $ unUnixStampMS_ n) == unUnixStampMS_ n+--+ class FromJSON (Aes recd) => BitXAesRecordConvert recd where     type Aes recd     aesToRec :: Aes recd -> recd@@ -55,9 +71,6 @@ showableToBytestring_ :: Show a => a -> ByteString showableToBytestring_ = Txt.encodeUtf8 . Txt.pack . show ---realToDecimalByteString_ :: Real a => a -> ByteString---realToDecimalByteString_ k = pack . reverse . dropWhile (== '0') . reverse $ (showFFloat (Just 6) . (fromRational :: Rational -> Double) . toRational $ k) ""- -- | Wrappers around Scientific and Int, and FromJSON instance, to facilitate automatic JSON instances  newtype QuotedScientific = QuotedScientific Scientific deriving (Read, Show)@@ -149,7 +162,7 @@  instance BitXAesRecordConvert Types.Ticker where     type Aes Types.Ticker = Ticker_-    aesToRec (Ticker_ {..}) =+    aesToRec Ticker_ {..} =         Types.Ticker {tickerTimestamp = tsmsToUTCTime ticker'timestamp,                   tickerBid = qiToInt ticker'bid,                   tickerAsk = qiToInt ticker'ask,@@ -168,7 +181,7 @@  instance BitXAesRecordConvert [Types.Ticker] where     type Aes [Types.Ticker] = Tickers_-    aesToRec (Tickers_ {..}) =+    aesToRec Tickers_ {..} =         map aesToRec tickers'tickers  -------------------------------------------- BitXError type ----------------------------------------@@ -182,7 +195,7 @@  instance BitXAesRecordConvert Types.BitXError where     type Aes Types.BitXError = BitXError_-    aesToRec (BitXError_ {..}) =+    aesToRec BitXError_ {..} =         Types.BitXError { bitXErrorError = bitXError'error, bitXErrorErrorCode = bitXError'error_code}  -------------------------------------------- Order type --------------------------------------------@@ -196,7 +209,7 @@  instance BitXAesRecordConvert Types.Order where     type Aes Types.Order = Order_-    aesToRec (Order_ {..}) =+    aesToRec Order_ {..} =         Types.Order {orderVolume = qsToScientific order'volume,               orderPrice = qiToInt order'price} @@ -216,7 +229,7 @@  instance BitXAesRecordConvert Types.Orderbook where     type Aes Types.Orderbook = Orderbook_-    aesToRec (Orderbook_ {..}) =+    aesToRec Orderbook_ {..} =         Types.Orderbook {orderbookTimestamp = tsmsToUTCTime orderbook'timestamp,                   orderbookBids = map aesToRec orderbook'bids,                   orderbookAsks = map aesToRec orderbook'asks}@@ -227,6 +240,7 @@     { trade'volume :: QuotedScientific     , trade'timestamp :: TimestampMS     , trade'price :: QuotedInt+    , trade'is_buy :: Bool     }  $(AesTH.deriveFromJSON AesTH.defaultOptions{AesTH.fieldLabelModifier = last . splitOn "'"}@@ -234,10 +248,11 @@  instance BitXAesRecordConvert Types.Trade where     type Aes Types.Trade = Trade_-    aesToRec (Trade_ {..}) =+    aesToRec Trade_ {..} =         Types.Trade { tradeTimestamp = tsmsToUTCTime trade'timestamp,             tradeVolume = qsToScientific trade'volume,-            tradePrice = qiToInt trade'price }+            tradePrice = qiToInt trade'price,+            tradeIsBuy = trade'is_buy}  ----------------------------------------- PublicTrades type ---------------------------------------- @@ -250,7 +265,7 @@  instance BitXAesRecordConvert [Types.Trade] where     type Aes [Types.Trade] = PublicTrades_-    aesToRec (PublicTrades_ {..}) =+    aesToRec PublicTrades_ {..} =         map aesToRec publicTrades'trades  ------------------------------------------ PrivateOrder type ---------------------------------------@@ -275,7 +290,7 @@  instance BitXAesRecordConvert Types.PrivateOrder where     type Aes Types.PrivateOrder = PrivateOrder_-    aesToRec (PrivateOrder_ {..}) =+    aesToRec PrivateOrder_ {..} =         Types.PrivateOrder {privateOrderBase = qsToScientific privateOrder'base,                   privateOrderCounter = qsToScientific privateOrder'counter,                   privateOrderCreationTimestamp = tsmsToUTCTime privateOrder'creation_timestamp,@@ -300,7 +315,7 @@  instance BitXAesRecordConvert [Types.PrivateOrder] where     type Aes [Types.PrivateOrder] = PrivateOrders_-    aesToRec (PrivateOrders_ {..}) =+    aesToRec PrivateOrders_ {..} =         map aesToRec privateOrders'orders  ------------------------------------------ OrderRequest type ---------------------------------------@@ -323,7 +338,7 @@  instance BitXAesRecordConvert Types.OrderID where     type Aes Types.OrderID = OrderIDRec_-    aesToRec (OrderIDRec_ {..}) =+    aesToRec OrderIDRec_ {..} =         orderIDResponse'order_id  instance POSTEncodeable Types.OrderID where@@ -341,7 +356,7 @@  instance BitXAesRecordConvert Types.RequestSuccess where     type Aes Types.RequestSuccess = RequestSuccess_-    aesToRec (RequestSuccess_ {..}) =+    aesToRec RequestSuccess_ {..} =         requestSuccess'success  ------------------------------------- PrivateOrderWithTrades type ----------------------------------@@ -367,7 +382,7 @@  instance BitXAesRecordConvert Types.PrivateOrderWithTrades where     type Aes Types.PrivateOrderWithTrades = PrivateOrderWithTrades_-    aesToRec (PrivateOrderWithTrades_ {..}) =+    aesToRec PrivateOrderWithTrades_ {..} =         Types.PrivateOrderWithTrades {privateOrderWithTradesBase = qsToScientific privateOrderWithTrades'base,                   privateOrderWithTradesCounter = qsToScientific privateOrderWithTrades'counter,                   privateOrderWithTradesCreationTimestamp = tsmsToUTCTime privateOrderWithTrades'creation_timestamp,@@ -397,7 +412,7 @@  instance BitXAesRecordConvert Types.Balance where     type Aes Types.Balance = Balance_-    aesToRec (Balance_ {..}) =+    aesToRec Balance_ {..} =         Types.Balance {balanceId = balance'account_id,                   balanceAsset = balance'asset,                   balanceBalance = qsToScientific balance'balance,@@ -415,7 +430,7 @@  instance BitXAesRecordConvert [Types.Balance] where     type Aes [Types.Balance] = Balances_-    aesToRec (Balances_ {..}) =+    aesToRec Balances_ {..} =         map aesToRec balances'balance  ----------------------------------------- FundingAddress type --------------------------------------@@ -432,7 +447,7 @@  instance BitXAesRecordConvert Types.FundingAddress where     type Aes Types.FundingAddress = FundingAddress_-    aesToRec (FundingAddress_ {..}) =+    aesToRec FundingAddress_ {..} =         Types.FundingAddress {fundingAddressAsset = fundingAdress'asset,                   fundingAddressAddress = fundingAdress'address,                   fundingAddressTotalReceived = qsToScientific fundingAdress'total_received,@@ -456,7 +471,7 @@  instance BitXAesRecordConvert Types.WithdrawalRequest where     type Aes Types.WithdrawalRequest = WithdrawalRequest_-    aesToRec (WithdrawalRequest_ {..}) =+    aesToRec WithdrawalRequest_ {..} =         Types.WithdrawalRequest {withdrawalRequestStatus = requestStatusParse withdrawalRequest'status,                   withdrawalRequestId = withdrawalRequest'id} @@ -471,7 +486,7 @@  instance BitXAesRecordConvert [Types.WithdrawalRequest] where     type Aes [Types.WithdrawalRequest] = WithdrawalRequests_-    aesToRec (WithdrawalRequests_ {..}) =+    aesToRec WithdrawalRequests_ {..} =         map aesToRec withdrawalRequests'withdrawals  ----------------------------------------- NewWithdrawal type ---------------------------------------@@ -521,7 +536,7 @@  instance BitXAesRecordConvert Types.OrderQuote where     type Aes Types.OrderQuote = OrderQuote_-    aesToRec (OrderQuote_ {..}) =+    aesToRec OrderQuote_ {..} =         Types.OrderQuote {orderQuoteId = orderQuote'id,                   orderQuoteQuoteType = orderQuote'type,                   orderQuotePair = orderQuote'pair,@@ -544,7 +559,7 @@  instance BitXAesRecordConvert Types.BitXAuth where     type Aes Types.BitXAuth = BitXAuth_-    aesToRec (BitXAuth_ {..}) =+    aesToRec BitXAuth_ {..} =         Types.BitXAuth {bitXAuthId = bitXAuth'api_key_id,                   bitXAuthSecret = bitXAuth'api_key_secret} @@ -566,7 +581,7 @@  instance BitXAesRecordConvert Types.Transaction where     type Aes Types.Transaction = Transaction_-    aesToRec (Transaction_ {..}) =+    aesToRec Transaction_ {..} =         Types.Transaction {transactionRowIndex = transaction'row_index,                   transactionTimestamp = tsmsToUTCTime transaction'timestamp,                   transactionBalance = qsToScientific transaction'balance,@@ -587,7 +602,7 @@  instance BitXAesRecordConvert [Types.Transaction] where     type Aes [Types.Transaction] = Transactions_-    aesToRec (Transactions_ {..}) =+    aesToRec Transactions_ {..} =         map aesToRec transactions'transactions  @@ -600,7 +615,7 @@  instance BitXAesRecordConvert PendingTransactions__ where     type Aes PendingTransactions__ = PendingTransactions_-    aesToRec (PendingTransactions_ {..}) =+    aesToRec PendingTransactions_ {..} =         PendingTransactions__ {pendingTransactions__transactions = map aesToRec transactions'pending}  data PendingTransactions__ = PendingTransactions__@@ -622,7 +637,7 @@  instance BitXAesRecordConvert Types.Account where     type Aes Types.Account = Account_-    aesToRec (Account_ {..}) =+    aesToRec Account_ {..} =         Types.Account {accountId = account'id,                   accountName = account'name,                   accountCurrency = account'currency}
test/Doctests.hs view
@@ -1,3 +1,3 @@ import Test.DocTest -main = doctest ["-isrc", "src/Network/Bitcoin/BitX/Types/Internal/Decimal.hs"]+main = doctest ["-isrc", "src/Network/Bitcoin/BitX/Types/Internal/Decimal.hs","src/Network/Bitcoin/BitX/Types/Internal.hs"]
test/Network/Bitcoin/BitX/Spec/Specs/AesonRecordSpec.hs view
@@ -64,16 +64,12 @@              orderbookAsks = [orderInner]}     it "Trade is parsed properly" $       recordAesCheck-        "{\"timestamp\":1431811395699,\"volume\":\"6754.09\",\"price\":\"5327.00\"}"+        "{\"timestamp\":1431811395699,\"volume\":\"6754.09\",\"price\":\"5327.00\", \"is_buy\": true}"         Trade             {tradeTimestamp = posixSecondsToUTCTime 1431811395.699,              tradeVolume = 6754.09,-             tradePrice = 5327}-    it "PublicTrades is parsed properly" $-      recordAesCheck-        "{\"trades\":[{\"timestamp\":1431811395699,\"volume\":\"6754.09\",\-            \ \"price\":\"5327.00\"}],\"currency\":\"ZAR\"}"-        [tradeInner]+             tradePrice = 5327,+             tradeIsBuy = True}     it "PrivateOrder is parsed properly" $       recordAesCheck         "{\"base\":\"568.7\", \"counter\":3764.2,\"creation_timestamp\":478873467, \@@ -106,7 +102,7 @@         ("57983" :: OrderID)     it "PublicTrades is parsed properly" $       recordAesCheck-        "{\"trades\":[{\"timestamp\":1431811395699,\"volume\":\"6754.09\",\"price\":\"5327.00\"}], \+        "{\"trades\":[{\"timestamp\":1431811395699,\"volume\":\"6754.09\",\"price\":\"5327.00\",\"is_buy\":false}], \             \ \"currency\":\"ZAR\"}"          [tradeInner]     it "RequestSuccess is parsed properly" $@@ -119,7 +115,7 @@             \ \"expiration_timestamp\":8768834222, \"fee_base\":\"3687.3\", \"fee_counter\":12.9,\             \ \"limit_price\":765.00,\"limit_volume\":55.2,\"order_id\":\"83YG\",\"pair\":\"NADXBT\",\             \ \"state\":\"COMPLETE\",\"type\":\"BID\", \"trades\":[{\"timestamp\":1431811395699, \-            \ \"volume\":\"6754.09\",\"price\":\"5327.00\"}]}"+            \ \"volume\":\"6754.09\",\"price\":\"5327.00\",\"is_buy\":false}]}"         PrivateOrderWithTrades             {privateOrderWithTradesBase = 568.7,              privateOrderWithTradesCounter = 3764.2,@@ -188,7 +184,8 @@     Trade {          tradeTimestamp = posixSecondsToUTCTime 1431811395.699,          tradeVolume = 6754.09,-         tradePrice = 5327}+         tradePrice = 5327,+         tradeIsBuy = False}  privateOrderInner :: PrivateOrder privateOrderInner =
test/Network/Bitcoin/BitX/Spec/Specs/LensSpec.hs view
@@ -56,10 +56,11 @@  _trade :: Maybe Int _trade = do-    let x = BitX.Trade (posixSecondsToUTCTime 0) 0 0+    let x = BitX.Trade (posixSecondsToUTCTime 0) 0 0 False     let _ = x ^. BitX.timestamp     let _ = x ^. BitX.volume     let _ = x ^. BitX.price+    let _ = x ^. BitX.isBuy     Nothing  _bitXAuth :: Maybe Int@@ -88,7 +89,7 @@  _privateOrderWithTrades :: Maybe Int _privateOrderWithTrades = do-    let x = BitX.PrivateOrderWithTrades 0 0 (posixSecondsToUTCTime 0) (posixSecondsToUTCTime 0) 0 0 0 0 "" XBTZAR PENDING ASK [BitX.Trade (posixSecondsToUTCTime 0) 0 0]+    let x = BitX.PrivateOrderWithTrades 0 0 (posixSecondsToUTCTime 0) (posixSecondsToUTCTime 0) 0 0 0 0 "" XBTZAR PENDING ASK [BitX.Trade (posixSecondsToUTCTime 0) 0 0 False]     let _ = x ^. BitX.base     let _ = x ^. BitX.counter     let _ = x ^. BitX.creationTimestamp
test/Network/Bitcoin/BitX/Spec/Specs/NetSpec.hs view
@@ -22,7 +22,7 @@     it "getOrderBook connects to BitX and works" $       connectsAndParsesOkay $ getOrderBook XBTZAR     it "getTrades connects to BitX and works" $-      connectsAndParsesOkay $ getTrades XBTKES+      connectsAndParsesOkay $ getTrades Nothing XBTKES  connectsAndParsesOkay :: IO (BitXAPIResponse recd) -> Bool connectsAndParsesOkay = isValidResponse . unsafePerformIO