Introduce request package and integrate with exchanges

This commit is contained in:
Ryan O'Hara-Reid
2018-03-27 14:05:15 +11:00
committed by Adrian Gallagher
parent 52dfddbb18
commit 7fc9d20fd7
52 changed files with 1990 additions and 1544 deletions

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"log"
"net/http"
"net/url"
"reflect"
"strconv"
@@ -13,6 +14,7 @@ import (
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
@@ -47,12 +49,16 @@ const (
bitstampAPIXrpDeposit = "xrp_address"
bitstampAPIReturnType = "string"
bitstampAPITradingPairsInfo = "trading-pairs-info"
bitstampAuthRate = 0
bitstampUnauthRate = 0
)
// Bitstamp is the overarching type across the bitstamp package
type Bitstamp struct {
exchange.Base
Balance Balances
*request.Handler
}
// SetDefaults sets default for Bitstamp
@@ -68,6 +74,8 @@ func (b *Bitstamp) SetDefaults() {
b.ConfigCurrencyPairFormat.Uppercase = true
b.AssetTypes = []string{ticker.Spot}
b.SupportsAutoPairUpdating = true
b.Handler = new(request.Handler)
b.SetRequestHandler(b.Name, bitstampAuthRate, bitstampUnauthRate, new(http.Client))
}
// Setup sets configuration values to bitstamp
@@ -133,7 +141,7 @@ func (b *Bitstamp) GetTicker(currency string, hourly bool) (Ticker, error) {
tickerEndpoint,
common.StringToLower(currency),
)
return response, common.SendHTTPGetRequest(path, true, b.Verbose, &response)
return response, b.SendHTTPRequest(path, &response)
}
// GetOrderbook Returns a JSON dictionary with "bids" and "asks". Each is a list
@@ -155,7 +163,7 @@ func (b *Bitstamp) GetOrderbook(currency string) (Orderbook, error) {
common.StringToLower(currency),
)
err := common.SendHTTPGetRequest(path, true, b.Verbose, &resp)
err := b.SendHTTPRequest(path, &resp)
if err != nil {
return Orderbook{}, err
}
@@ -218,7 +226,7 @@ func (b *Bitstamp) GetTransactions(currencyPair string, values url.Values) ([]Tr
values,
)
return transactions, common.SendHTTPGetRequest(path, true, b.Verbose, &transactions)
return transactions, b.SendHTTPRequest(path, &transactions)
}
// GetEURUSDConversionRate returns the conversion rate between Euro and USD
@@ -226,15 +234,15 @@ func (b *Bitstamp) GetEURUSDConversionRate() (EURUSDConversionRate, error) {
rate := EURUSDConversionRate{}
path := fmt.Sprintf("%s/%s", bitstampAPIURL, bitstampAPIEURUSD)
return rate, common.SendHTTPGetRequest(path, true, b.Verbose, &rate)
return rate, b.SendHTTPRequest(path, &rate)
}
// GetBalance returns full balance of currency held on the exchange
func (b *Bitstamp) GetBalance() (Balances, error) {
balance := Balances{}
path := fmt.Sprintf("%s/%s", bitstampAPIURL, bitstampAPIBalance)
return balance,
b.SendAuthenticatedHTTPRequest(bitstampAPIBalance, true, url.Values{}, &balance)
return balance, b.SendHTTPRequest(path, &balance)
}
// GetUserTransactions returns an array of transactions
@@ -484,6 +492,11 @@ func (b *Bitstamp) TransferAccountBalance(amount float64, currency, subAccount s
return true, nil
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (b *Bitstamp) SendHTTPRequest(path string, result interface{}) error {
return b.SendPayload("GET", path, nil, nil, result, false, b.Verbose)
}
// SendAuthenticatedHTTPRequest sends an authenticated request
func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url.Values, result interface{}) (err error) {
if !b.AuthenticatedAPISupport {
@@ -518,26 +531,5 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url
headers := make(map[string]string)
headers["Content-Type"] = "application/x-www-form-urlencoded"
resp, err := common.SendHTTPRequest("POST", path, headers, strings.NewReader(values.Encode()))
if err != nil {
return err
}
if b.Verbose {
log.Printf("Received raw: %s\n", resp)
}
/* inconsistent errors, needs to be improved when in production*/
if common.StringContains(resp, "500 error") {
return errors.New("internal server: code 500")
}
capture := CaptureError{}
if err = common.JSONDecode([]byte(resp), &capture); err == nil {
if capture.Code != nil || capture.Error != nil || capture.Reason != nil || capture.Status != nil {
errstring := fmt.Sprint("Status: ", capture.Status, ", Issue: ", capture.Error, ", Reason: ", capture.Reason, ", Code: ", capture.Code)
return errors.New(errstring)
}
}
return common.JSONDecode([]byte(resp), &result)
return b.SendPayload("POST", path, headers, strings.NewReader(values.Encode()), result, true, b.Verbose)
}

View File

@@ -15,9 +15,9 @@ const (
customerID = ""
)
var b Bitstamp
func TestSetDefaults(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.SetDefaults()
if b.Name != "Bitstamp" {
@@ -38,17 +38,12 @@ func TestSetDefaults(t *testing.T) {
}
func TestSetup(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.Name = "Bitstamp"
cfg := config.GetConfig()
cfg.LoadConfig("../../testdata/configtest.json")
bConfig, err := cfg.GetExchangeConfig("Bitstamp")
if err != nil {
t.Error("Test Failed - Bitstamp Setup() init error")
}
b.SetDefaults()
b.Setup(bConfig)
if !b.IsEnabled() || b.AuthenticatedAPISupport || b.RESTPollingDelay != time.Duration(10) ||
@@ -56,33 +51,13 @@ func TestSetup(t *testing.T) {
len(b.AvailablePairs) < 1 || len(b.EnabledPairs) < 1 {
t.Error("Test Failed - Bitstamp Setup values not set correctly")
}
bConfig.Enabled = false
b.Setup(bConfig)
if b.IsEnabled() {
t.Error("Test failed - Bitstamp TestSetup incorrect value")
}
}
func TestGetFee(t *testing.T) {
t.Parallel()
b := Bitstamp{}
if resp := b.GetFee("BTCUSD"); resp != 0 {
t.Error("Test Failed - GetFee() error")
}
if resp := b.GetFee("BTCEUR"); resp != 0 {
t.Error("Test Failed - GetFee() error")
}
if resp := b.GetFee("XRPEUR"); resp != 0 {
t.Error("Test Failed - GetFee() error")
}
if resp := b.GetFee("XRPUSD"); resp != 0 {
t.Error("Test Failed - GetFee() error")
}
if resp := b.GetFee("EURUSD"); resp != 0 {
t.Error("Test Failed - GetFee() error")
}
if resp := b.GetFee("bla"); resp != 0 {
t.Error("Test Failed - GetFee() error")
}
@@ -90,7 +65,6 @@ func TestGetFee(t *testing.T) {
func TestGetTicker(t *testing.T) {
t.Parallel()
b := Bitstamp{}
_, err := b.GetTicker("BTCUSD", false)
if err != nil {
t.Error("Test Failed - GetTicker() error", err)
@@ -103,7 +77,6 @@ func TestGetTicker(t *testing.T) {
func TestGetOrderbook(t *testing.T) {
t.Parallel()
b := Bitstamp{}
_, err := b.GetOrderbook("BTCUSD")
if err != nil {
t.Error("Test Failed - GetOrderbook() error", err)
@@ -121,8 +94,6 @@ func TestGetTradingPairs(t *testing.T) {
func TestGetTransactions(t *testing.T) {
t.Parallel()
b := Bitstamp{}
value := url.Values{}
value.Set("time", "hour")
@@ -138,7 +109,6 @@ func TestGetTransactions(t *testing.T) {
func TestGetEURUSDConversionRate(t *testing.T) {
t.Parallel()
b := Bitstamp{}
_, err := b.GetEURUSDConversionRate()
if err != nil {
t.Error("Test Failed - GetEURUSDConversionRate() error", err)
@@ -147,24 +117,14 @@ func TestGetEURUSDConversionRate(t *testing.T) {
func TestGetBalance(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.GetBalance()
if err == nil {
if err != nil {
t.Error("Test Failed - GetBalance() error", err)
}
}
func TestGetUserTransactions(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.GetUserTransactions("")
if err == nil {
t.Error("Test Failed - GetUserTransactions() error", err)
@@ -178,10 +138,6 @@ func TestGetUserTransactions(t *testing.T) {
func TestGetOpenOrders(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.GetOpenOrders("btcusd")
if err == nil {
@@ -195,10 +151,6 @@ func TestGetOpenOrders(t *testing.T) {
func TestGetOrderStatus(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.GetOrderStatus(1337)
if err == nil {
@@ -208,10 +160,6 @@ func TestGetOrderStatus(t *testing.T) {
func TestCancelOrder(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
resp, err := b.CancelOrder(1337)
if err == nil || resp != false {
@@ -221,10 +169,6 @@ func TestCancelOrder(t *testing.T) {
func TestCancelAllOrders(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.CancelAllOrders()
if err == nil {
@@ -234,35 +178,15 @@ func TestCancelAllOrders(t *testing.T) {
func TestPlaceOrder(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.PlaceOrder("btcusd", 0.01, 1, true, true)
if err == nil {
t.Error("Test Failed - PlaceOrder() error")
}
_, err = b.PlaceOrder("btcusd", 0.01, 1, true, false)
if err == nil {
t.Error("Test Failed - PlaceOrder() error")
}
_, err = b.PlaceOrder("btcusd", 0.01, 1, false, false)
if err == nil {
t.Error("Test Failed - PlaceOrder() error")
}
_, err = b.PlaceOrder("wigwham", 0.01, 1, false, false)
if err == nil {
t.Error("Test Failed - PlaceOrder() error")
}
}
func TestGetWithdrawalRequests(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.GetWithdrawalRequests(0)
if err == nil {
@@ -276,72 +200,24 @@ func TestGetWithdrawalRequests(t *testing.T) {
func TestCryptoWithdrawal(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.CryptoWithdrawal(0, "bla", "btc", "", true)
if err == nil {
t.Error("Test Failed - CryptoWithdrawal() error", err)
}
_, err = b.CryptoWithdrawal(0, "bla", "btc", "", false)
if err == nil {
t.Error("Test Failed - CryptoWithdrawal() error", err)
}
_, err = b.CryptoWithdrawal(0, "bla", "ltc", "", false)
if err == nil {
t.Error("Test Failed - CryptoWithdrawal() error", err)
}
_, err = b.CryptoWithdrawal(0, "bla", "eth", "", false)
if err == nil {
t.Error("Test Failed - CryptoWithdrawal() error", err)
}
_, err = b.CryptoWithdrawal(0, "bla", "xrp", "someplace", false)
if err == nil {
t.Error("Test Failed - CryptoWithdrawal() error", err)
}
_, err = b.CryptoWithdrawal(0, "bla", "ding!", "", false)
if err == nil {
t.Error("Test Failed - CryptoWithdrawal() error", err)
}
}
func TestGetBitcoinDepositAddress(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.GetCryptoDepositAddress("btc")
if err == nil {
t.Error("Test Failed - GetCryptoDepositAddress() error", err)
}
_, err = b.GetCryptoDepositAddress("LTc")
if err == nil {
t.Error("Test Failed - GetCryptoDepositAddress() error", err)
}
_, err = b.GetCryptoDepositAddress("eth")
if err == nil {
t.Error("Test Failed - GetCryptoDepositAddress() error", err)
}
_, err = b.GetCryptoDepositAddress("xrp")
if err == nil {
t.Error("Test Failed - GetCryptoDepositAddress() error", err)
}
_, err = b.GetCryptoDepositAddress("wigwham")
if err == nil {
t.Error("Test Failed - GetCryptoDepositAddress() error")
}
}
func TestGetUnconfirmedBitcoinDeposits(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.GetUnconfirmedBitcoinDeposits()
if err == nil {
@@ -351,10 +227,6 @@ func TestGetUnconfirmedBitcoinDeposits(t *testing.T) {
func TestTransferAccountBalance(t *testing.T) {
t.Parallel()
b := Bitstamp{}
b.APIKey = apiKey
b.APISecret = apiSecret
b.ClientID = customerID
_, err := b.TransferAccountBalance(1, "", "", true)
if err == nil {