Updated Bitstamp REST API (complete coverage)

This commit is contained in:
Adrian Gallagher
2015-10-20 12:57:59 +11:00
parent c1910bf6b6
commit a7e90cb703
2 changed files with 254 additions and 77 deletions

View File

@@ -13,13 +13,16 @@ const (
BITSTAMP_API_URL = "https://www.bitstamp.net/api/"
BITSTAMP_API_VERSION = "0"
BITSTAMP_API_TICKER = "ticker/"
BITSTAMP_API_TICKER_HOURLY = "ticker_hour/"
BITSTAMP_API_ORDERBOOK = "order_book/"
BITSTAMP_API_TRANSACTIONS = "transactions/"
BITSTAMP_API_EURUSD = "eur_usd/"
BITSTAMP_API_BALANCE = "balance/"
BITSTAMP_API_USER_TRANSACTIONS = "user_transactions/"
BITSTAMP_API_OPEN_ORDERS = "open_orders/"
BITSTAMP_API_ORDER_STATUS = "order_status"
BITSTAMP_API_CANCEL_ORDER = "cancel_order/"
BITSTAMP_API_CANCEL_ALL_ORDERS = "cancel_all_orders/"
BITSTAMP_API_BUY = "buy/"
BITSTAMP_API_SELL = "sell/"
BITSTAMP_API_WITHDRAWAL_REQUESTS = "withdrawal_requests/"
@@ -38,10 +41,6 @@ type Bitstamp struct {
RESTPollingDelay time.Duration
AuthenticatedAPISupport bool
ClientID, APIKey, APISecret string
Ticker BitstampTicker
Orderbook Orderbook
ConversionRate ConversionRate
Transactions []Transactions
Balance BitstampAccountBalance
TakerFee, MakerFee float64
BaseCurrencies []string
@@ -69,20 +68,73 @@ type BitstampAccountBalance struct {
USDAvailable float64 `json:"usd_available,string"`
}
type Orderbook struct {
Timestamp string
Bids [][]string
Asks [][]string
type BitstampOrderbookBase struct {
Price float64
Amount float64
}
type Transactions struct {
Date, Price, Amount string
Tid int64
type BitstampOrderbook struct {
Timestamp int64 `json:"timestamp,string"`
Bids []BitstampOrderbookBase
Asks []BitstampOrderbookBase
}
type ConversionRate struct {
Buy string
Sell string
type BitstampTransactions struct {
Date int64 `json:"date,string"`
TradeID int64 `json:"tid"`
Price float64 `json:"price,string"`
Type int `json:"type"`
Amount float64 `json:"amount,string"`
}
type BitstampEURUSDConversionRate struct {
Buy float64 `json:"buy,string"`
Sell float64 `json:"sell,string"`
}
type BitstampUserTransactions struct {
Date string `json:"datetime"`
TransID int64 `json:"id"`
Type int `json:"type"`
USD float64 `json:"usd,string"`
BTC float64 `json:"btc,string"`
BTCUSD float64 `json:"btc_usd,string"`
Fee float64 `json:"fee,string"`
OrderID interface{} `json:"order_id"`
}
type BitstampOrder struct {
ID int64 `json:"id"`
Date string `json:"date"`
Type int `json:"type"`
Price float64 `json:"price"`
Amount float64 `json:"amount"`
}
type BitstampOrderStatus struct {
Status string
Transactions []struct {
TradeID int64 `json:"tid"`
USD float64 `json:"usd,string"`
Price float64 `json:"price,string"`
Fee float64 `json:"fee,string"`
BTC float64 `json:"btc,string"`
}
}
type BitstampWithdrawalRequests struct {
OrderID int64 `json:"id"`
Date string `json:"datetime"`
Type int `json:"type"`
Amount float64 `json:"amount,string"`
Status int `json:"status"`
Data interface{}
}
type BitstampUnconfirmedBTCTransactions struct {
Amount float64 `json:"amount,string"`
Address string `json:"address"`
Confirmations int `json:"confirmations"`
}
func (b *Bitstamp) SetDefaults() {
@@ -130,7 +182,11 @@ func (b *Bitstamp) Run() {
for _, x := range b.EnabledPairs {
currency := x
go func() {
ticker := b.GetTicker()
ticker, err := b.GetTicker(true)
if err != nil {
log.Println(err)
return
}
log.Printf("Bitstamp %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume)
AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume)
}()
@@ -139,141 +195,243 @@ func (b *Bitstamp) Run() {
}
}
func (b *Bitstamp) GetTicker() BitstampTicker {
err := SendHTTPGetRequest(BITSTAMP_API_URL+BITSTAMP_API_TICKER, true, &b.Ticker)
func (b *Bitstamp) GetTicker(hourly bool) (BitstampTicker, error) {
path := BITSTAMP_API_URL
ticker := BitstampTicker{}
if err != nil {
log.Println(err)
return BitstampTicker{}
if hourly {
path += BITSTAMP_API_TICKER_HOURLY
} else {
path += BITSTAMP_API_TICKER
}
return b.Ticker
}
func (b *Bitstamp) GetOrderbook() {
err := SendHTTPGetRequest(BITSTAMP_API_URL+BITSTAMP_API_ORDERBOOK, true, &b.Orderbook)
err := SendHTTPGetRequest(path, true, &ticker)
if err != nil {
log.Println(err)
return
return ticker, err
}
return ticker, nil
}
func (b *Bitstamp) GetTransactions() {
err := SendHTTPGetRequest(BITSTAMP_API_URL+BITSTAMP_API_TRANSACTIONS, true, &b.Transactions)
func (b *Bitstamp) GetOrderbook() (BitstampOrderbook, error) {
type response struct {
Timestamp int64 `json:"timestamp,string"`
Bids [][]string
Asks [][]string
}
resp := response{}
err := SendHTTPGetRequest(BITSTAMP_API_URL+BITSTAMP_API_ORDERBOOK, true, &resp)
if err != nil {
return BitstampOrderbook{}, err
}
orderbook := BitstampOrderbook{}
orderbook.Timestamp = resp.Timestamp
for _, x := range resp.Bids {
price, err := strconv.ParseFloat(x[0], 64)
if err != nil {
log.Println(err)
continue
}
amount, err := strconv.ParseFloat(x[1], 64)
if err != nil {
log.Println(err)
continue
}
orderbook.Bids = append(orderbook.Bids, BitstampOrderbookBase{price, amount})
}
for _, x := range resp.Asks {
price, err := strconv.ParseFloat(x[0], 64)
if err != nil {
log.Println(err)
continue
}
amount, err := strconv.ParseFloat(x[1], 64)
if err != nil {
log.Println(err)
continue
}
orderbook.Asks = append(orderbook.Asks, BitstampOrderbookBase{price, amount})
}
return orderbook, nil
}
func (b *Bitstamp) GetTransactions(values url.Values) ([]BitstampTransactions, error) {
transactions := []BitstampTransactions{}
path := BITSTAMP_API_URL + BITSTAMP_API_TRANSACTIONS
if len(values) > 0 {
path += "?" + values.Encode()
}
log.Println(path)
err := SendHTTPGetRequest(path, true, &transactions)
if err != nil {
log.Println(err)
return
return nil, err
}
return transactions, nil
}
func (b *Bitstamp) GetEURUSDConversionRate() {
err := SendHTTPGetRequest(BITSTAMP_API_URL+BITSTAMP_API_EURUSD, true, &b.ConversionRate)
func (b *Bitstamp) GetEURUSDConversionRate() (BitstampEURUSDConversionRate, error) {
rate := BitstampEURUSDConversionRate{}
err := SendHTTPGetRequest(BITSTAMP_API_URL+BITSTAMP_API_EURUSD, true, &rate)
if err != nil {
log.Println(err)
return
return rate, err
}
return rate, nil
}
func (b *Bitstamp) GetBalance() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BALANCE, url.Values{}, &b.Balance)
func (b *Bitstamp) GetBalance() (BitstampAccountBalance, error) {
balance := BitstampAccountBalance{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BALANCE, url.Values{}, &balance)
if err != nil {
log.Println(err)
return balance, err
}
return balance, nil
}
func (b *Bitstamp) GetUserTransactions(offset, limit, sort int64) {
var req = url.Values{}
req.Add("offset", strconv.FormatInt(offset, 10))
req.Add("limit", strconv.FormatInt(limit, 10))
req.Add("sort", strconv.FormatInt(sort, 10))
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_USER_TRANSACTIONS, req, nil)
func (b *Bitstamp) GetUserTransactions(values url.Values) ([]BitstampUserTransactions, error) {
response := []BitstampUserTransactions{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_USER_TRANSACTIONS, values, &response)
if err != nil {
log.Println(err)
return nil, err
}
return response, nil
}
func (b *Bitstamp) CancelOrder(OrderID int64) {
func (b *Bitstamp) GetOpenOrders() ([]BitstampOrder, error) {
resp := []BitstampOrder{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_OPEN_ORDERS, nil, &resp)
if err != nil {
return nil, err
}
return resp, nil
}
func (b *Bitstamp) GetOrderStatus(OrderID int64) (BitstampOrderStatus, error) {
var req = url.Values{}
req.Add("id", strconv.FormatInt(OrderID, 10))
resp := BitstampOrderStatus{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_CANCEL_ORDER, req, nil)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_CANCEL_ORDER, req, &resp)
if err != nil {
log.Println(err)
return resp, err
}
return resp, nil
}
func (b *Bitstamp) GetOpenOrders() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_OPEN_ORDERS, url.Values{}, nil)
func (b *Bitstamp) CancelOrder(OrderID int64) (bool, error) {
var req = url.Values{}
result := false
req.Add("id", strconv.FormatInt(OrderID, 10))
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_CANCEL_ORDER, req, &result)
if err != nil {
log.Println(err)
return result, err
}
return result, nil
}
func (b *Bitstamp) PlaceOrder(price float64, amount float64, Type int) {
func (b *Bitstamp) CancelAllOrders() (bool, error) {
result := false
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_CANCEL_ALL_ORDERS, nil, &result)
if err != nil {
return result, err
}
return result, nil
}
func (b *Bitstamp) PlaceOrder(price float64, amount float64, buy bool) (BitstampOrder, error) {
var req = url.Values{}
req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64))
req.Add("price", strconv.FormatFloat(price, 'f', -1, 64))
response := BitstampOrder{}
orderType := BITSTAMP_API_BUY
if Type == 1 {
if !buy {
orderType = BITSTAMP_API_SELL
}
log.Printf("Placing %s order at price %f for %f amount.\n", orderType, price, amount)
err := b.SendAuthenticatedHTTPRequest(orderType, req, nil)
err := b.SendAuthenticatedHTTPRequest(orderType, req, &response)
if err != nil {
log.Println(err)
return response, err
}
return response, nil
}
func (b *Bitstamp) GetWithdrawalRequests() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_WITHDRAWAL_REQUESTS, url.Values{}, nil)
func (b *Bitstamp) GetWithdrawalRequests() ([]BitstampWithdrawalRequests, error) {
resp := []BitstampWithdrawalRequests{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_WITHDRAWAL_REQUESTS, url.Values{}, &resp)
if err != nil {
log.Println(err)
return nil, err
}
return resp, nil
}
func (b *Bitstamp) BitcoinWithdrawal(amount float64, address string) {
func (b *Bitstamp) BitcoinWithdrawal(amount float64, address string) (string, error) {
var req = url.Values{}
req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64))
req.Add("address", address)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_WITHDRAWAL, req, nil)
type response struct {
ID string `json:"id"`
}
resp := response{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_WITHDRAWAL, req, &resp)
if err != nil {
log.Println(err)
return "", err
}
return resp.ID, nil
}
func (b *Bitstamp) BitcoinDepositAddress() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_DEPOSIT, url.Values{}, nil)
func (b *Bitstamp) GetBitcoinDepositAddress() (string, error) {
address := ""
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_DEPOSIT, url.Values{}, &address)
if err != nil {
log.Println(err)
return address, err
}
return address, nil
}
func (b *Bitstamp) UnconfirmedBitcoin() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_UNCONFIRMED_BITCOIN, url.Values{}, nil)
func (b *Bitstamp) GetUnconfirmedBitcoinDeposits() ([]BitstampUnconfirmedBTCTransactions, error) {
response := []BitstampUnconfirmedBTCTransactions{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_UNCONFIRMED_BITCOIN, nil, &response)
if err != nil {
log.Println(err)
return nil, err
}
return response, nil
}
func (b *Bitstamp) RippleWithdrawal(amount float64, address, currency string) {
func (b *Bitstamp) RippleWithdrawal(amount float64, address, currency string) (bool, error) {
var req = url.Values{}
req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64))
req.Add("address", address)
@@ -282,20 +440,34 @@ func (b *Bitstamp) RippleWithdrawal(amount float64, address, currency string) {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_WITHDRAWAL, req, nil)
if err != nil {
log.Println(err)
return false, err
}
return true, nil
}
func (b *Bitstamp) RippleDepositAddress() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_DESPOIT, url.Values{}, nil)
func (b *Bitstamp) GetRippleDepositAddress() (string, error) {
type response struct {
Address string
}
resp := response{}
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_DESPOIT, nil, &resp)
if err != nil {
log.Println(err)
return "", err
}
return resp.Address, nil
}
func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, values url.Values, result interface{}) (err error) {
nonce := strconv.FormatInt(time.Now().UnixNano(), 10)
if values == nil {
values = url.Values{}
}
values.Set("key", b.APIKey)
values.Set("nonce", nonce)
hmac := GetHMAC(HASH_SHA256, []byte(nonce+b.ClientID+b.APIKey), []byte(b.APISecret))

View File

@@ -123,7 +123,12 @@ func (e *Event) CheckCondition() bool {
lastPrice = result.Last
}
} else if bot.exchange.bitstamp.GetName() == e.Exchange {
lastPrice = bot.exchange.bitstamp.GetTicker().Last
result, err := bot.exchange.bitstamp.GetTicker(false)
if err != nil {
lastPrice = 0
} else {
lastPrice = result.Last
}
} else if bot.exchange.coinbase.GetName() == e.Exchange {
lastPrice = bot.exchange.coinbase.GetTicker("BTC-USD").Price
} else if bot.exchange.cryptsy.GetName() == e.Exchange {