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"
"github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
@@ -33,12 +35,16 @@ const (
privateWithdrawCoinsToAddress = "WithdrawCoinsToAddress"
privateCreateCoupon = "CreateYobicode"
privateRedeemCoupon = "RedeemYobicode"
yobitAuthRate = 0
yobitUnauthRate = 0
)
// Yobit is the overarching type across the Yobit package
type Yobit struct {
exchange.Base
Ticker map[string]Ticker
*request.Handler
}
// SetDefaults sets current default value for Yobit
@@ -59,6 +65,8 @@ func (y *Yobit) SetDefaults() {
y.ConfigCurrencyPairFormat.Uppercase = true
y.AssetTypes = []string{ticker.Spot}
y.SupportsAutoPairUpdating = false
y.Handler = new(request.Handler)
y.SetRequestHandler(y.Name, yobitAuthRate, yobitUnauthRate, new(http.Client))
}
// Setup sets exchange configuration parameters for Yobit
@@ -100,7 +108,7 @@ func (y *Yobit) GetInfo() (Info, error) {
resp := Info{}
path := fmt.Sprintf("%s/%s/%s/", apiPublicURL, apiPublicVersion, publicInfo)
return resp, common.SendHTTPGetRequest(path, true, y.Verbose, &resp)
return resp, y.SendHTTPRequest(path, &resp)
}
// GetTicker returns a ticker for a specific currency
@@ -112,7 +120,7 @@ func (y *Yobit) GetTicker(symbol string) (map[string]Ticker, error) {
response := Response{}
path := fmt.Sprintf("%s/%s/%s/%s", apiPublicURL, apiPublicVersion, publicTicker, symbol)
return response.Data, common.SendHTTPGetRequest(path, true, y.Verbose, &response.Data)
return response.Data, y.SendHTTPRequest(path, &response.Data)
}
// GetDepth returns the depth for a specific currency
@@ -125,7 +133,7 @@ func (y *Yobit) GetDepth(symbol string) (Orderbook, error) {
path := fmt.Sprintf("%s/%s/%s/%s", apiPublicURL, apiPublicVersion, publicDepth, symbol)
return response.Data[symbol],
common.SendHTTPGetRequest(path, true, y.Verbose, &response.Data)
y.SendHTTPRequest(path, &response.Data)
}
// GetTrades returns the trades for a specific currency
@@ -137,14 +145,21 @@ func (y *Yobit) GetTrades(symbol string) ([]Trades, error) {
response := Response{}
path := fmt.Sprintf("%s/%s/%s/%s", apiPublicURL, apiPublicVersion, publicTrades, symbol)
return response.Data[symbol], common.SendHTTPGetRequest(path, true, y.Verbose, &response.Data)
return response.Data[symbol], y.SendHTTPRequest(path, &response.Data)
}
// GetAccountInfo returns a users account info
func (y *Yobit) GetAccountInfo() (AccountInfo, error) {
result := AccountInfo{}
return result, y.SendAuthenticatedHTTPRequest(privateAccountInfo, url.Values{}, &result)
err := y.SendAuthenticatedHTTPRequest(privateAccountInfo, url.Values{}, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// Trade places an order and returns the order ID if successful or an error
@@ -157,7 +172,14 @@ func (y *Yobit) Trade(pair, orderType string, amount, price float64) (int64, err
result := Trade{}
return int64(result.OrderID), y.SendAuthenticatedHTTPRequest(privateTrade, req, &result)
err := y.SendAuthenticatedHTTPRequest(privateTrade, req, &result)
if err != nil {
return int64(result.OrderID), err
}
if result.Error != "" {
return int64(result.OrderID), errors.New(result.Error)
}
return int64(result.OrderID), nil
}
// GetActiveOrders returns the active orders for a specific currency
@@ -186,12 +208,14 @@ func (y *Yobit) CancelOrder(OrderID int64) (bool, error) {
req.Add("order_id", strconv.FormatInt(OrderID, 10))
result := CancelOrder{}
err := y.SendAuthenticatedHTTPRequest(privateCancelOrder, req, &result)
err := y.SendAuthenticatedHTTPRequest(privateCancelOrder, req, &result)
if err != nil {
return false, err
}
if result.Error != "" {
return false, errors.New(result.Error)
}
return true, nil
}
@@ -219,7 +243,14 @@ func (y *Yobit) GetDepositAddress(coin string) (DepositAddress, error) {
result := DepositAddress{}
return result, y.SendAuthenticatedHTTPRequest(privateGetDepositAddress, req, &result)
err := y.SendAuthenticatedHTTPRequest(privateGetDepositAddress, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// WithdrawCoinsToAddress initiates a withdrawal to a specified address
@@ -231,7 +262,14 @@ func (y *Yobit) WithdrawCoinsToAddress(coin string, amount float64, address stri
result := WithdrawCoinsToAddress{}
return result, y.SendAuthenticatedHTTPRequest(privateWithdrawCoinsToAddress, req, &result)
err := y.SendAuthenticatedHTTPRequest(privateWithdrawCoinsToAddress, req, &result)
if err != nil {
return result, err
}
if result.Error != "" {
return result, errors.New(result.Error)
}
return result, nil
}
// CreateCoupon creates an exchange coupon for a sepcific currency
@@ -242,7 +280,14 @@ func (y *Yobit) CreateCoupon(currency string, amount float64) (CreateCoupon, err
var result CreateCoupon
return result, y.SendAuthenticatedHTTPRequest(privateCreateCoupon, req, &result)
err := y.SendAuthenticatedHTTPRequest(privateCreateCoupon, 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
@@ -252,7 +297,19 @@ func (y *Yobit) RedeemCoupon(coupon string) (RedeemCoupon, error) {
result := RedeemCoupon{}
return result, y.SendAuthenticatedHTTPRequest(privateRedeemCoupon, req, &result)
err := y.SendAuthenticatedHTTPRequest(privateRedeemCoupon, 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 (y *Yobit) SendHTTPRequest(path string, result interface{}) error {
return y.SendPayload("GET", path, nil, nil, result, false, y.Verbose)
}
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to Yobit
@@ -285,30 +342,5 @@ func (y *Yobit) SendAuthenticatedHTTPRequest(path string, params url.Values, res
headers["Sign"] = common.HexEncodeToString(hmac)
headers["Content-Type"] = "application/x-www-form-urlencoded"
resp, err := common.SendHTTPRequest(
"POST", apiPrivateURL, headers, strings.NewReader(encoded),
)
if err != nil {
return err
}
if y.Verbose {
log.Printf("Received raw: \n%s\n", resp)
}
response := Response{}
if err = common.JSONDecode([]byte(resp), &response); err != nil {
return errors.New("sendAuthenticatedHTTPRequest: Unable to JSON Unmarshal response." + err.Error())
}
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 y.SendPayload("POST", apiPrivateURL, headers, strings.NewReader(encoded), result, true, y.Verbose)
}

View File

@@ -33,12 +33,14 @@ func TestSetup(t *testing.T) {
}
func TestGetFee(t *testing.T) {
t.Parallel()
if y.GetFee() != 0.2 {
t.Error("Test Failed - GetFee() error")
}
}
func TestGetInfo(t *testing.T) {
t.Parallel()
_, err := y.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 := y.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 := y.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 := y.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 := y.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 := y.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 := y.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 := y.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 := y.Trade("", "buy", 0, 0)
if err == nil {
t.Error("Test Failed - Trade() error", err)
@@ -102,6 +112,7 @@ func TestTrade(t *testing.T) {
}
func TestGetTradeHistory(t *testing.T) {
t.Parallel()
_, err := y.GetTradeHistory(0, 0, 0, "", "", "", "")
if err == nil {
t.Error("Test Failed - GetTradeHistory() error", err)
@@ -109,6 +120,7 @@ func TestGetTradeHistory(t *testing.T) {
}
func TestWithdrawCoinsToAddress(t *testing.T) {
t.Parallel()
_, err := y.WithdrawCoinsToAddress("", 0, "")
if err == nil {
t.Error("Test Failed - WithdrawCoinsToAddress() error", err)
@@ -116,6 +128,7 @@ func TestWithdrawCoinsToAddress(t *testing.T) {
}
func TestGetDepositAddress(t *testing.T) {
t.Parallel()
_, err := y.GetDepositAddress("btc")
if err == nil {
t.Error("Test Failed - GetDepositAddress() error", err)
@@ -123,6 +136,7 @@ func TestGetDepositAddress(t *testing.T) {
}
func TestCreateYobicode(t *testing.T) {
t.Parallel()
_, err := y.CreateCoupon("bla", 0)
if err == nil {
t.Error("Test Failed - CreateYobicode() error", err)
@@ -130,7 +144,8 @@ func TestCreateYobicode(t *testing.T) {
}
func TestRedeemYobicode(t *testing.T) {
_, err := y.RedeemCoupon("bla")
t.Parallel()
_, err := y.RedeemCoupon("bla2")
if err == nil {
t.Error("Test Failed - RedeemYobicode() error", err)
}

View File

@@ -73,6 +73,7 @@ type AccountInfo struct {
TransactionCount int `json:"transaction_count"`
OpenOrders int `json:"open_orders"`
ServerTime float64 `json:"server_time"`
Error string `json:"error"`
}
// OrderInfo stores order information
@@ -90,6 +91,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
@@ -98,6 +100,7 @@ type Trade struct {
Remains float64 `json:"remains"`
OrderID float64 `json:"order_id"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}
// TradeHistory stores trade history
@@ -116,11 +119,13 @@ type DepositAddress struct {
Address string `json:"address"`
ProcessedAmount float64 `json:"processed_amount"`
ServerTime int64 `json:"server_time"`
Error string `json:"error"`
}
// WithdrawCoinsToAddress stores information for a withdrawcoins request
type WithdrawCoinsToAddress struct {
ServerTime int64 `json:"server_time"`
ServerTime int64 `json:"server_time"`
Error string `json:"error"`
}
// CreateCoupon stores information coupon information
@@ -128,6 +133,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
@@ -136,4 +142,5 @@ type RedeemCoupon struct {
CouponCurrency string `json:"couponCurrency"`
TransID int64 `json:"transID"`
Funds map[string]float64 `json:"funds"`
Error string `json:"error"`
}