diff --git a/exchanges/btse/btse.go b/exchanges/btse/btse.go index 32be20ba..d6417151 100644 --- a/exchanges/btse/btse.go +++ b/exchanges/btse/btse.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net/http" + "net/url" "strconv" "strings" "time" @@ -23,14 +24,16 @@ type BTSE struct { const ( btseAPIURL = "https://api.btse.com/v1/restapi" + btseAPIURLv2 = "https://api.btse.com/spot/v2" btseAPIVersion = "1" // Public endpoints - btseMarkets = "markets" - btseTrades = "trades" - btseTicker = "ticker" - btseStats = "stats" - btseTime = "time" + btseMarkets = "markets" + btseTrades = "trades" + btseTicker = "ticker" + btseOrderbook = "orderbook" + btseStats = "stats" + btseTime = "time" // Authenticated endpoints btseAccount = "account" @@ -66,6 +69,34 @@ func (b *BTSE) GetTicker(symbol string) (*Ticker, error) { return &t, nil } +// GetOrderbook returns the orderbook for a specified symbol +func (b *BTSE) GetOrderbook(symbol string, group, limitAsks, limitBids int64) (*Orderbook, error) { + var t Orderbook + vals := url.Values{} + if group != 0 { + vals.Set("group", strconv.FormatInt(group, 10)) + } + + if limitAsks != 0 { + vals.Set("limit_asks", strconv.FormatInt(limitAsks, 10)) + } + + if limitBids != 0 { + vals.Set("limit_bids", strconv.FormatInt(limitBids, 10)) + } + + if symbol == "" { + return nil, errors.New("symbol not set") + } + + endpoint := fmt.Sprintf("%s/%s", btseOrderbook, symbol) + err := b.SendHTTPRequestv2(http.MethodGet, endpoint, vals, &t) + if err != nil { + return nil, err + } + return &t, nil +} + // GetMarketStatistics gets market statistics for a specificed market func (b *BTSE) GetMarketStatistics(symbol string) (*MarketStatistics, error) { var m MarketStatistics @@ -188,6 +219,22 @@ func (b *BTSE) SendHTTPRequest(method, endpoint string, result interface{}) erro b.HTTPRecording) } +// SendHTTPRequestv2 sends an HTTP request to the desired endpoint +func (b *BTSE) SendHTTPRequestv2(method, endpoint string, values url.Values, result interface{}) error { + path := fmt.Sprintf("%s/%s", btseAPIURLv2, endpoint) + path = common.EncodeURLValues(path, values) + return b.SendPayload(method, + path, + nil, + nil, + &result, + false, + false, + b.Verbose, + b.HTTPDebugging, + b.HTTPRecording) +} + // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to the desired endpoint func (b *BTSE) SendAuthenticatedHTTPRequest(method, endpoint string, req map[string]interface{}, result interface{}) error { if !b.AllowAuthenticatedRequest() { diff --git a/exchanges/btse/btse_test.go b/exchanges/btse/btse_test.go index 47b46f6f..d4093681 100644 --- a/exchanges/btse/btse_test.go +++ b/exchanges/btse/btse_test.go @@ -61,6 +61,14 @@ func TestGetTicker(t *testing.T) { } } +func TestGetOrderbook(t *testing.T) { + b.SetDefaults() + _, err := b.GetOrderbook("BTC-USD", 0, 0, 0) + if err != nil { + t.Fatalf("Test failed. Err: %s", err) + } +} + func TestGetMarketStatistics(t *testing.T) { b.SetDefaults() _, err := b.GetMarketStatistics("BTC-USD") diff --git a/exchanges/btse/btse_types.go b/exchanges/btse/btse_types.go index 6ac5781c..2f4031a6 100644 --- a/exchanges/btse/btse_types.go +++ b/exchanges/btse/btse_types.go @@ -41,6 +41,18 @@ type Ticker struct { Time string `json:"time"` } +// OrderbookItem stores the price and size orderbook data +type OrderbookItem struct { + Price float64 `json:"price,string"` + Size float64 `json:"size,string"` +} + +// Orderbook stores the orderbook bids and asks +type Orderbook struct { + Bids []OrderbookItem `json:"buyQuote"` + Asks []OrderbookItem `json:"sellQuote"` +} + // MarketStatistics stores market statistics for a particular product type MarketStatistics struct { Open float64 `json:"open,string"` diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index 674a89ae..67f99822 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -247,7 +247,41 @@ func (b *BTSE) FetchOrderbook(p currency.Pair, assetType asset.Item) (orderbook. // UpdateOrderbook updates and returns the orderbook for a currency pair func (b *BTSE) UpdateOrderbook(p currency.Pair, assetType asset.Item) (orderbook.Base, error) { - return orderbook.Base{}, common.ErrFunctionNotSupported + var orderBook orderbook.Base + obNew, err := b.GetOrderbook( + b.FormatExchangeCurrency(p, assetType).String(), 0, 0, 0) + if err != nil { + return orderBook, err + } + + for x := range obNew.Bids { + orderBook.Bids = append(orderBook.Bids, + orderbook.Item{ + Amount: obNew.Bids[x].Size, + Price: obNew.Bids[x].Price, + }, + ) + } + + for x := range obNew.Asks { + orderBook.Asks = append(orderBook.Asks, + orderbook.Item{ + Amount: obNew.Asks[x].Size, + Price: obNew.Asks[x].Price, + }, + ) + } + + orderBook.Pair = p + orderBook.ExchangeName = b.Name + orderBook.AssetType = assetType + + err = orderBook.Process() + if err != nil { + return orderBook, err + } + + return orderbook.Get(b.Name, p, assetType) } // GetAccountInfo retrieves balances for all enabled currencies for the