func (client *Client) getBook() (exchange.Book, []float64) {
	timestamps := make([]float64, 40)
	url := fmt.Sprintf("%s/v1/book/%s%s?limit_bids=%d&limit_asks=%d", client.baseURL, client.symbol, client.currency, 20, 20)
	data, err := client.get(url)
	if err != nil {
		return exchange.Book{Error: fmt.Errorf("%s UpdateBook error: %s", client, err.Error())}, timestamps
	}
	var response struct {
		Bids []struct {
			Price     float64 `json:"price,string"`
			Amount    float64 `json:"amount,string"`
			Timestamp float64 `json:"timestamp,string"`
		} `json:"bids"`
		Asks []struct {
			Price     float64 `json:"price,string"`
			Amount    float64 `json:"amount,string"`
			Timestamp float64 `json:"timestamp,string"`
		} `json:"asks"`
	}
	if err := json.Unmarshal(data, &response); err != nil {
		return exchange.Book{Error: fmt.Errorf("%s UpdateBook error: %s", client, err.Error())}, timestamps
	}
	bids := make(exchange.BidItems, 20)
	asks := make(exchange.AskItems, 20)
	for i := 0; i < 20; i++ {
		bids[i].Price = response.Bids[i].Price
		bids[i].Amount = response.Bids[i].Amount
		asks[i].Price = response.Asks[i].Price
		asks[i].Amount = response.Asks[i].Amount
		timestamps[i] = response.Bids[i].Timestamp
		timestamps[i+20] = response.Asks[i].Timestamp
	}
	sort.Sort(bids)
	sort.Sort(asks)
	return exchange.Book{
		Exg:   client,
		Time:  time.Now(),
		Bids:  bids,
		Asks:  asks,
		Error: nil,
	}, timestamps
}
Get book data with an HTTP request
package bitfinex
import (
	"bitfx/exchange"
	"crypto/hmac"
	"crypto/sha512"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math"
	"net/http"
	"sort"
	"strconv"
	"time"
)
type Client struct {
	key, secret, symbol, currency, name, baseURL  string
	priority                                      int
	position, fee, maxPos, availShort, availFunds float64
	currencyCode                                  byte
	done                                          chan bool
}
func New(key, secret, symbol, currency string, priority int, fee, availShort, availFunds float64) *Client {
	return &Client{
		key:          key,
		secret:       secret,
		symbol:       symbol,
		currency:     currency,
		priority:     priority,
		fee:          fee,
		availShort:   availShort,
		availFunds:   availFunds,
		currencyCode: 0,
		name:         fmt.Sprintf("Bitfinex(%s)", currency),
		baseURL:      "https://api.bitfinex.com",
		done:         make(chan bool, 1),
	}
}
func (client *Client) Done() {
	client.done <- true
}
func (client *Client) String() string {
	return client.name
}
func (client *Client) Priority() int {
	return client.priority
}
func (client *Client) Fee() float64 {
	return client.fee
}
func (client *Client) SetPosition(pos float64) {
	client.position = pos
}
func (client *Client) Position() float64 {
	return client.position
}
func (client *Client) Currency() string {
	return client.currency
}
func (client *Client) CurrencyCode() byte {
	return client.currencyCode
}
func (client *Client) SetMaxPos(maxPos float64) {
	client.maxPos = maxPos
}
func (client *Client) MaxPos() float64 {
	return client.maxPos
}
func (client *Client) AvailFunds() float64 {
	return client.availFunds
}
func (client *Client) AvailShort() float64 {
	return client.availShort
}
func (client *Client) HasCryptoFee() bool {
	return false
}
func (client *Client) CommunicateBook(bookChan chan<- exchange.Book) exchange.Book {
	book, _ := client.getBook()
	go client.runLoop(bookChan)
	return book
}
func (client *Client) runLoop(bookChan chan<- exchange.Book) {
	oldTimestamps := make([]float64, 40)
	for {
		select {
		case <-client.done:
			return
		default:
			book, newTimestamps := client.getBook()
			if bookChanged(oldTimestamps, newTimestamps) {
				bookChan <- book
			}
			oldTimestamps = newTimestamps
		}
	}
}