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"
"strconv"
"strings"
@@ -12,6 +13,7 @@ import (
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
@@ -35,12 +37,16 @@ const (
wexCoinDepositAddress = "CoinDepositAddress"
wexCreateCoupon = "CreateCoupon"
wexRedeemCoupon = "RedeemCoupon"
wexAuthRate = 0
wexUnauthRate = 0
)
// WEX is the overarching type across the wex package
type WEX struct {
exchange.Base
Ticker map[string]Ticker
*request.Handler
}
// SetDefaults sets current default value for WEX
@@ -59,6 +65,8 @@ func (w *WEX) SetDefaults() {
w.ConfigCurrencyPairFormat.Uppercase = true
w.AssetTypes = []string{ticker.Spot}
w.SupportsAutoPairUpdating = false
w.Handler = new(request.Handler)
w.SetRequestHandler(w.Name, wexAuthRate, wexUnauthRate, new(http.Client))
}
// Setup sets exchange configuration parameters for WEX
@@ -100,7 +108,7 @@ func (w *WEX) GetInfo() (Info, error) {
resp := Info{}
req := fmt.Sprintf("%s/%s/%s/", wexAPIPublicURL, wexAPIPublicVersion, wexInfo)
return resp, common.SendHTTPGetRequest(req, true, w.Verbose, &resp)
return resp, w.SendHTTPRequest(req, &resp)
}
// GetTicker returns a ticker for a specific currency
@@ -112,7 +120,7 @@ func (w *WEX) GetTicker(symbol string) (map[string]Ticker, error) {
response := Response{}
req := fmt.Sprintf("%s/%s/%s/%s", wexAPIPublicURL, wexAPIPublicVersion, wexTicker, symbol)
return response.Data, common.SendHTTPGetRequest(req, true, w.Verbose, &response.Data)
return response.Data, w.SendHTTPRequest(req, &response.Data)
}
// GetDepth returns the depth for a specific currency
@@ -124,8 +132,7 @@ func (w *WEX) GetDepth(symbol string) (Orderbook, error) {
response := Response{}
req := fmt.Sprintf("%s/%s/%s/%s", wexAPIPublicURL, wexAPIPublicVersion, wexDepth, symbol)
return response.Data[symbol],
common.SendHTTPGetRequest(req, true, w.Verbose, &response.Data)
return response.Data[symbol], w.SendHTTPRequest(req, &response.Data)
}
// GetTrades returns the trades for a specific currency
@@ -137,16 +144,22 @@ func (w *WEX) GetTrades(symbol string) ([]Trades, error) {
response := Response{}
req := fmt.Sprintf("%s/%s/%s/%s", wexAPIPublicURL, wexAPIPublicVersion, wexTrades, symbol)
return response.Data[symbol],
common.SendHTTPGetRequest(req, true, w.Verbose, &response.Data)
return response.Data[symbol], w.SendHTTPRequest(req, &response.Data)
}
// GetAccountInfo returns a users account info
func (w *WEX) GetAccountInfo() (AccountInfo, error) {
var result AccountInfo
return result,
w.SendAuthenticatedHTTPRequest(wexAccountInfo, url.Values{}, &result)
err := w.SendAuthenticatedHTTPRequest(wexAccountInfo, url.Values{}, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// GetActiveOrders returns the active orders for a specific currency
@@ -175,12 +188,15 @@ func (w *WEX) CancelOrder(OrderID int64) (bool, error) {
req.Add("order_id", strconv.FormatInt(OrderID, 10))
var result CancelOrder
err := w.SendAuthenticatedHTTPRequest(wexCancelOrder, req, &result)
err := w.SendAuthenticatedHTTPRequest(wexCancelOrder, req, &result)
if err != nil {
return false, err
}
if result.Error != "" {
return false, errors.New(result.Error)
}
return true, nil
}
@@ -194,8 +210,15 @@ func (w *WEX) Trade(pair, orderType string, amount, price float64) (int64, error
var result Trade
return int64(result.OrderID),
w.SendAuthenticatedHTTPRequest(wexTrade, req, &result)
err := w.SendAuthenticatedHTTPRequest(wexTrade, req, &result)
if err != nil {
return 0, err
}
if result.Error != "" {
return 0, errors.New(result.Error)
}
return int64(result.OrderID), nil
}
// GetTransactionHistory returns the transaction history
@@ -241,7 +264,15 @@ func (w *WEX) WithdrawCoins(coin string, amount float64, address string) (Withdr
var result WithdrawCoins
return result, w.SendAuthenticatedHTTPRequest(wexWithdrawCoin, req, &result)
err := w.SendAuthenticatedHTTPRequest(wexWithdrawCoin, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// CoinDepositAddress returns the deposit address for a specific currency
@@ -251,8 +282,14 @@ func (w *WEX) CoinDepositAddress(coin string) (string, error) {
var result CoinDepositAddress
return result.Address,
w.SendAuthenticatedHTTPRequest(wexCoinDepositAddress, req, &result)
err := w.SendAuthenticatedHTTPRequest(wexCoinDepositAddress, req, &result)
if err != nil {
return result.Address, err
}
if result.Error != "" {
return result.Address, errors.New(result.Error)
}
return result.Address, nil
}
// CreateCoupon creates an exchange coupon for a sepcific currency
@@ -263,7 +300,14 @@ func (w *WEX) CreateCoupon(currency string, amount float64) (CreateCoupon, error
var result CreateCoupon
return result, w.SendAuthenticatedHTTPRequest(wexCreateCoupon, req, &result)
err := w.SendAuthenticatedHTTPRequest(wexCreateCoupon, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// RedeemCoupon redeems an exchange coupon
@@ -273,7 +317,19 @@ func (w *WEX) RedeemCoupon(coupon string) (RedeemCoupon, error) {
var result RedeemCoupon
return result, w.SendAuthenticatedHTTPRequest(wexRedeemCoupon, req, &result)
err := w.SendAuthenticatedHTTPRequest(wexRedeemCoupon, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (w *WEX) SendHTTPRequest(path string, result interface{}) error {
return w.SendPayload("GET", path, nil, nil, result, false, w.Verbose)
}
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to WEX
@@ -294,7 +350,10 @@ func (w *WEX) SendAuthenticatedHTTPRequest(method string, values url.Values, res
hmac := common.GetHMAC(common.HashSHA512, []byte(encoded), []byte(w.APISecret))
if w.Verbose {
log.Printf("Sending POST request to %s calling method %s with params %s\n", wexAPIPrivateURL, method, encoded)
log.Printf("Sending POST request to %s calling method %s with params %s\n",
wexAPIPrivateURL,
method,
encoded)
}
headers := make(map[string]string)
@@ -302,25 +361,5 @@ func (w *WEX) SendAuthenticatedHTTPRequest(method string, values url.Values, res
headers["Sign"] = common.HexEncodeToString(hmac)
headers["Content-Type"] = "application/x-www-form-urlencoded"
resp, err := common.SendHTTPRequest("POST", wexAPIPrivateURL, headers, strings.NewReader(encoded))
if err != nil {
return err
}
response := Response{}
err = common.JSONDecode([]byte(resp), &response)
if err != nil {
return err
}
if response.Success != 1 {
return errors.New(response.Error)
}
JSONEncoded, err := common.JSONEncode(response.Return)
if err != nil {
return err
}
return common.JSONDecode(JSONEncoded, &result)
return w.SendPayload("POST", wexAPIPrivateURL, headers, strings.NewReader(encoded), result, true, w.Verbose)
}

View File

@@ -33,12 +33,14 @@ func TestSetup(t *testing.T) {
}
func TestGetFee(t *testing.T) {
t.Parallel()
if w.GetFee() != 0.2 {
t.Error("Test Failed - GetFee() error")
}
}
func TestGetInfo(t *testing.T) {
t.Parallel()
_, err := w.GetInfo()
if err != nil {
t.Error("Test Failed - GetInfo() error")
@@ -46,6 +48,7 @@ func TestGetInfo(t *testing.T) {
}
func TestGetTicker(t *testing.T) {
t.Parallel()
_, err := w.GetTicker("btc_usd")
if err != nil {
t.Error("Test Failed - GetTicker() error", err)
@@ -53,6 +56,7 @@ func TestGetTicker(t *testing.T) {
}
func TestGetDepth(t *testing.T) {
t.Parallel()
_, err := w.GetDepth("btc_usd")
if err != nil {
t.Error("Test Failed - GetDepth() error", err)
@@ -60,6 +64,7 @@ func TestGetDepth(t *testing.T) {
}
func TestGetTrades(t *testing.T) {
t.Parallel()
_, err := w.GetTrades("btc_usd")
if err != nil {
t.Error("Test Failed - GetTrades() error", err)
@@ -67,6 +72,7 @@ func TestGetTrades(t *testing.T) {
}
func TestGetAccountInfo(t *testing.T) {
t.Parallel()
_, err := w.GetAccountInfo()
if err == nil {
t.Error("Test Failed - GetAccountInfo() error", err)
@@ -74,6 +80,7 @@ func TestGetAccountInfo(t *testing.T) {
}
func TestGetActiveOrders(t *testing.T) {
t.Parallel()
_, err := w.GetActiveOrders("")
if err == nil {
t.Error("Test Failed - GetActiveOrders() error", err)
@@ -81,6 +88,7 @@ func TestGetActiveOrders(t *testing.T) {
}
func TestGetOrderInfo(t *testing.T) {
t.Parallel()
_, err := w.GetOrderInfo(6196974)
if err == nil {
t.Error("Test Failed - GetOrderInfo() error", err)
@@ -88,6 +96,7 @@ func TestGetOrderInfo(t *testing.T) {
}
func TestCancelOrder(t *testing.T) {
t.Parallel()
_, err := w.CancelOrder(1337)
if err == nil {
t.Error("Test Failed - CancelOrder() error", err)
@@ -95,6 +104,7 @@ func TestCancelOrder(t *testing.T) {
}
func TestTrade(t *testing.T) {
t.Parallel()
_, err := w.Trade("", "buy", 0, 0)
if err == nil {
t.Error("Test Failed - Trade() error", err)
@@ -102,6 +112,7 @@ func TestTrade(t *testing.T) {
}
func TestGetTransactionHistory(t *testing.T) {
t.Parallel()
_, err := w.GetTransactionHistory(0, 0, 0, "", "", "")
if err == nil {
t.Error("Test Failed - GetTransactionHistory() error", err)
@@ -109,6 +120,7 @@ func TestGetTransactionHistory(t *testing.T) {
}
func TestGetTradeHistory(t *testing.T) {
t.Parallel()
_, err := w.GetTradeHistory(0, 0, 0, "", "", "", "")
if err == nil {
t.Error("Test Failed - GetTradeHistory() error", err)
@@ -116,6 +128,7 @@ func TestGetTradeHistory(t *testing.T) {
}
func TestWithdrawCoins(t *testing.T) {
t.Parallel()
_, err := w.WithdrawCoins("", 0, "")
if err == nil {
t.Error("Test Failed - WithdrawCoins() error", err)
@@ -123,6 +136,7 @@ func TestWithdrawCoins(t *testing.T) {
}
func TestCoinDepositAddress(t *testing.T) {
t.Parallel()
_, err := w.CoinDepositAddress("btc")
if err == nil {
t.Error("Test Failed - WithdrawCoins() error", err)
@@ -130,6 +144,7 @@ func TestCoinDepositAddress(t *testing.T) {
}
func TestCreateCoupon(t *testing.T) {
t.Parallel()
_, err := w.CreateCoupon("bla", 0)
if err == nil {
t.Error("Test Failed - CreateCoupon() error", err)
@@ -137,6 +152,7 @@ func TestCreateCoupon(t *testing.T) {
}
func TestRedeemCoupon(t *testing.T) {
t.Parallel()
_, err := w.RedeemCoupon("bla")
if err == nil {
t.Error("Test Failed - RedeemCoupon() error", err)

View File

@@ -72,6 +72,7 @@ type AccountInfo struct {
} `json:"rights"`
ServerTime float64 `json:"server_time"`
TransactionCount int `json:"transaction_count"`
Error string `json:"error"`
}
// OrderInfo stores order information
@@ -89,6 +90,7 @@ type OrderInfo struct {
type CancelOrder struct {
OrderID float64 `json:"order_id"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// Trade stores the trade information
@@ -97,6 +99,7 @@ type Trade struct {
Remains float64 `json:"remains"`
OrderID float64 `json:"order_id"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// TransHistory stores transaction history
@@ -123,6 +126,7 @@ type TradeHistory struct {
// CoinDepositAddress stores a curency deposit address
type CoinDepositAddress struct {
Address string `json:"address"`
Error string `json:"error"`
}
// WithdrawCoins stores information for a withdrawcoins request
@@ -130,6 +134,7 @@ type WithdrawCoins struct {
TID int64 `json:"tId"`
AmountSent float64 `json:"amountSent"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// CreateCoupon stores information coupon information
@@ -137,6 +142,7 @@ type CreateCoupon struct {
Coupon string `json:"coupon"`
TransID int64 `json:"transID"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// RedeemCoupon stores redeem coupon information
@@ -144,4 +150,5 @@ type RedeemCoupon struct {
CouponAmount float64 `json:"couponAmount,string"`
CouponCurrency string `json:"couponCurrency"`
TransID int64 `json:"transID"`
Error string `json:"error"`
}