mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Fixed minor linter issues in coinut. Fixed linter issues, increased code cov & expanded functionality in gdax. Added new function in nonce package.
This commit is contained in:
@@ -15,31 +15,33 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
COINUT_API_URL = "https://api.coinut.com"
|
||||
COINUT_API_VERSION = "1"
|
||||
COINUT_INSTRUMENTS = "inst_list"
|
||||
COINUT_TICKER = "inst_tick"
|
||||
COINUT_ORDERBOOK = "inst_order_book"
|
||||
COINUT_TRADES = "inst_trade"
|
||||
COINUT_BALANCE = "user_balance"
|
||||
COINUT_ORDER = "new_order"
|
||||
COINUT_ORDERS = "new_orders"
|
||||
COINUT_ORDERS_OPEN = "user_open_orders"
|
||||
COINUT_ORDER_CANCEL = "cancel_order"
|
||||
COINUT_ORDERS_CANCEL = "cancel_orders"
|
||||
COINUT_TRADE_HISTORY = "trade_history"
|
||||
COINUT_INDEX_TICKER = "index_tick"
|
||||
COINUT_OPTION_CHAIN = "option_chain"
|
||||
COINUT_POSITION_HISTORY = "position_history"
|
||||
COINUT_POSITION_OPEN = "user_open_positions"
|
||||
coinutAPIURL = "https://api.coinut.com"
|
||||
coinutAPIVersion = "1"
|
||||
coinutInstruments = "inst_list"
|
||||
coinutTicker = "inst_tick"
|
||||
coinutOrderbook = "inst_order_book"
|
||||
coinutTrades = "inst_trade"
|
||||
coinutBalance = "user_balance"
|
||||
coinutOrder = "new_order"
|
||||
coinutOrders = "new_orders"
|
||||
coinutOrdersOpen = "user_open_orders"
|
||||
coinutOrderCancel = "cancel_order"
|
||||
coinutOrdersCancel = "cancel_orders"
|
||||
coinutTradeHistory = "trade_history"
|
||||
coinutIndexTicker = "index_tick"
|
||||
coinutOptionChain = "option_chain"
|
||||
coinutPositionHistory = "position_history"
|
||||
coinutPositionOpen = "user_open_positions"
|
||||
)
|
||||
|
||||
// COINUT is the overarching type across the coinut package
|
||||
type COINUT struct {
|
||||
exchange.Base
|
||||
WebsocketConn *websocket.Conn
|
||||
InstrumentMap map[string]int
|
||||
}
|
||||
|
||||
// SetDefaults sets current default values
|
||||
func (c *COINUT) SetDefaults() {
|
||||
c.Name = "COINUT"
|
||||
c.Enabled = false
|
||||
@@ -56,6 +58,7 @@ func (c *COINUT) SetDefaults() {
|
||||
c.AssetTypes = []string{ticker.Spot}
|
||||
}
|
||||
|
||||
// Setup sets the current exchange configuration
|
||||
func (c *COINUT) Setup(exch config.ExchangeConfig) {
|
||||
if !exch.Enabled {
|
||||
c.SetEnabled(false)
|
||||
@@ -80,11 +83,12 @@ func (c *COINUT) Setup(exch config.ExchangeConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetInstruments returns instruments
|
||||
func (c *COINUT) GetInstruments() (CoinutInstruments, error) {
|
||||
var result CoinutInstruments
|
||||
params := make(map[string]interface{})
|
||||
params["sec_type"] = "SPOT"
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_INSTRUMENTS, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutInstruments, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -95,7 +99,7 @@ func (c *COINUT) GetInstrumentTicker(instrumentID int) (CoinutTicker, error) {
|
||||
var result CoinutTicker
|
||||
params := make(map[string]interface{})
|
||||
params["inst_id"] = instrumentID
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_TICKER, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutTicker, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -109,7 +113,7 @@ func (c *COINUT) GetInstrumentOrderbook(instrumentID, limit int) (CoinutOrderboo
|
||||
if limit > 0 {
|
||||
params["top_n"] = limit
|
||||
}
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_ORDERBOOK, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutOrderbook, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -120,7 +124,7 @@ func (c *COINUT) GetTrades(instrumentID int) (CoinutTrades, error) {
|
||||
var result CoinutTrades
|
||||
params := make(map[string]interface{})
|
||||
params["inst_id"] = instrumentID
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_TRADES, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutTrades, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -129,7 +133,7 @@ func (c *COINUT) GetTrades(instrumentID int) (CoinutTrades, error) {
|
||||
|
||||
func (c *COINUT) GetUserBalance() (CoinutUserBalance, error) {
|
||||
result := CoinutUserBalance{}
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_BALANCE, nil, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutBalance, nil, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -148,7 +152,7 @@ func (c *COINUT) NewOrder(instrumentID int, quantity, price float64, buy bool, o
|
||||
}
|
||||
params["client_ord_id"] = orderID
|
||||
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_ORDER, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutOrder, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -159,7 +163,7 @@ func (c *COINUT) NewOrders(orders []CoinutOrder) ([]CoinutOrdersBase, error) {
|
||||
var result CoinutOrdersResponse
|
||||
params := make(map[string]interface{})
|
||||
params["orders"] = orders
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_ORDERS, params, &result.Data)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutOrders, params, &result.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -170,7 +174,7 @@ func (c *COINUT) GetOpenOrders(instrumentID int) ([]CoinutOrdersResponse, error)
|
||||
var result []CoinutOrdersResponse
|
||||
params := make(map[string]interface{})
|
||||
params["inst_id"] = instrumentID
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_ORDERS_OPEN, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutOrdersOpen, params, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -182,7 +186,7 @@ func (c *COINUT) CancelOrder(instrumentID, orderID int) (bool, error) {
|
||||
params := make(map[string]interface{})
|
||||
params["inst_id"] = instrumentID
|
||||
params["order_id"] = orderID
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_ORDERS_CANCEL, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutOrdersCancel, params, &result)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -193,7 +197,7 @@ func (c *COINUT) CancelOrders(orders []CoinutCancelOrders) (CoinutCancelOrdersRe
|
||||
var result CoinutCancelOrdersResponse
|
||||
params := make(map[string]interface{})
|
||||
params["entries"] = orders
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_ORDERS_CANCEL, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutOrdersCancel, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -210,7 +214,7 @@ func (c *COINUT) GetTradeHistory(instrumentID, start, limit int) (CoinutTradeHis
|
||||
if limit >= 0 && start <= 100 {
|
||||
params["limit"] = limit
|
||||
}
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_TRADE_HISTORY, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutTradeHistory, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -221,7 +225,7 @@ func (c *COINUT) GetIndexTicker(asset string) (CoinutIndexTicker, error) {
|
||||
var result CoinutIndexTicker
|
||||
params := make(map[string]interface{})
|
||||
params["asset"] = asset
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_INDEX_TICKER, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutIndexTicker, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -232,7 +236,7 @@ func (c *COINUT) GetDerivativeInstruments(secType string) (interface{}, error) {
|
||||
var result interface{} //to-do
|
||||
params := make(map[string]interface{})
|
||||
params["sec_type"] = secType
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_INSTRUMENTS, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutInstruments, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -244,7 +248,7 @@ func (c *COINUT) GetOptionChain(asset, secType string, expiry int64) (CoinutOpti
|
||||
params := make(map[string]interface{})
|
||||
params["asset"] = asset
|
||||
params["sec_type"] = secType
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_OPTION_CHAIN, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutOptionChain, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -261,7 +265,7 @@ func (c *COINUT) GetPositionHistory(secType string, start, limit int) (CoinutPos
|
||||
if limit >= 0 {
|
||||
params["limit"] = limit
|
||||
}
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_POSITION_HISTORY, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutPositionHistory, params, &result)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -276,7 +280,7 @@ func (c *COINUT) GetOpenPosition(instrumentID int) ([]CoinutOpenPosition, error)
|
||||
params := make(map[string]interface{})
|
||||
params["inst_id"] = instrumentID
|
||||
|
||||
err := c.SendAuthenticatedHTTPRequest(COINUT_POSITION_OPEN, params, &result)
|
||||
err := c.SendAuthenticatedHTTPRequest(coinutPositionOpen, params, &result)
|
||||
if err != nil {
|
||||
return result.Positions, err
|
||||
}
|
||||
@@ -319,7 +323,10 @@ func (c *COINUT) SendAuthenticatedHTTPRequest(apiRequest string, params map[stri
|
||||
headers["X-SIGNATURE"] = common.HexEncodeToString(hmac)
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
resp, err := common.SendHTTPRequest("POST", COINUT_API_URL, headers, bytes.NewBuffer(payload))
|
||||
resp, err := common.SendHTTPRequest("POST", coinutAPIURL, headers, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Verbose {
|
||||
log.Printf("Received raw: \n%s", resp)
|
||||
|
||||
37
exchanges/coinut/coinut_test.go
Normal file
37
exchanges/coinut/coinut_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package coinut
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
)
|
||||
|
||||
const (
|
||||
apiKey = ""
|
||||
apiSecret = ""
|
||||
)
|
||||
|
||||
var c COINUT
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
c.SetDefaults()
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
exch := config.ExchangeConfig{}
|
||||
c.Setup(exch)
|
||||
|
||||
exch.Enabled = true
|
||||
exch.APIKey = apiKey
|
||||
exch.APISecret = apiSecret
|
||||
c.Setup(exch)
|
||||
}
|
||||
|
||||
// func TestGetInstruments(t *testing.T) {
|
||||
// c.Verbose = true
|
||||
// resp, err := c.GetInstruments()
|
||||
// if err == nil {
|
||||
// t.Error("Test failed - GetInstruments() error", err)
|
||||
// }
|
||||
// log.Println(resp)
|
||||
// }
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
@@ -16,28 +15,46 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
GDAX_API_URL = "https://api.gdax.com/"
|
||||
GDAX_API_VERSION = "0"
|
||||
GDAX_PRODUCTS = "products"
|
||||
GDAX_ORDERBOOK = "book"
|
||||
GDAX_TICKER = "ticker"
|
||||
GDAX_TRADES = "trades"
|
||||
GDAX_HISTORY = "candles"
|
||||
GDAX_STATS = "stats"
|
||||
GDAX_CURRENCIES = "currencies"
|
||||
GDAX_ACCOUNTS = "accounts"
|
||||
GDAX_LEDGER = "ledger"
|
||||
GDAX_HOLDS = "holds"
|
||||
GDAX_ORDERS = "orders"
|
||||
GDAX_FILLS = "fills"
|
||||
GDAX_TRANSFERS = "transfers"
|
||||
GDAX_REPORTS = "reports"
|
||||
gdaxAPIURL = "https://api.gdax.com/"
|
||||
gdaxAPIVersion = "0"
|
||||
gdaxProducts = "products"
|
||||
gdaxOrderbook = "book"
|
||||
gdaxTicker = "ticker"
|
||||
gdaxTrades = "trades"
|
||||
gdaxHistory = "candles"
|
||||
gdaxStats = "stats"
|
||||
gdaxCurrencies = "currencies"
|
||||
gdaxAccounts = "accounts"
|
||||
gdaxLedger = "ledger"
|
||||
gdaxHolds = "holds"
|
||||
gdaxOrders = "orders"
|
||||
gdaxFills = "fills"
|
||||
gdaxTransfers = "transfers"
|
||||
gdaxReports = "reports"
|
||||
gdaxTime = "time"
|
||||
gdaxMarginTransfer = "profiles/margin-transfer"
|
||||
gdaxFunding = "funding"
|
||||
gdaxFundingRepay = "funding/repay"
|
||||
gdaxPosition = "position"
|
||||
gdaxPositionClose = "position/close"
|
||||
gdaxPaymentMethod = "payment-methods"
|
||||
gdaxPaymentMethodDeposit = "deposits/payment-method"
|
||||
gdaxDepositCoinbase = "deposits/coinbase-account"
|
||||
gdaxWithdrawalPaymentMethod = "withdrawals/payment-method"
|
||||
gdaxWithdrawalCoinbase = "withdrawals/coinbase"
|
||||
gdaxWithdrawalCrypto = "withdrawals/crypto"
|
||||
gdaxCoinbaseAccounts = "coinbase-accounts"
|
||||
gdaxTrailingVolume = "users/self/trailing-volume"
|
||||
)
|
||||
|
||||
var sometin []string
|
||||
|
||||
// GDAX is the overarching type across the GDAX package
|
||||
type GDAX struct {
|
||||
exchange.Base
|
||||
}
|
||||
|
||||
// SetDefaults sets default values for the exchange
|
||||
func (g *GDAX) SetDefaults() {
|
||||
g.Name = "GDAX"
|
||||
g.Enabled = false
|
||||
@@ -54,6 +71,7 @@ func (g *GDAX) SetDefaults() {
|
||||
g.AssetTypes = []string{ticker.Spot}
|
||||
}
|
||||
|
||||
// Setup initialises the exchange paramaters with the current configuration
|
||||
func (g *GDAX) Setup(exch config.ExchangeConfig) {
|
||||
if !exch.Enabled {
|
||||
g.SetEnabled(false)
|
||||
@@ -78,42 +96,39 @@ func (g *GDAX) Setup(exch config.ExchangeConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetFee returns the current fee for the exchange
|
||||
func (g *GDAX) GetFee(maker bool) float64 {
|
||||
if maker {
|
||||
return g.MakerFee
|
||||
} else {
|
||||
return g.TakerFee
|
||||
}
|
||||
return g.TakerFee
|
||||
}
|
||||
|
||||
func (g *GDAX) GetProducts() ([]GDAXProduct, error) {
|
||||
products := []GDAXProduct{}
|
||||
err := common.SendHTTPGetRequest(GDAX_API_URL+GDAX_PRODUCTS, true, &products)
|
||||
// GetProducts returns supported currency pairs on the exchange with specific
|
||||
// information about the pair
|
||||
func (g *GDAX) GetProducts() ([]Product, error) {
|
||||
products := []Product{}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return products, nil
|
||||
return products,
|
||||
common.SendHTTPGetRequest(gdaxAPIURL+gdaxProducts, true, &products)
|
||||
}
|
||||
|
||||
// GetOrderbook returns orderbook by currency pair and level
|
||||
func (g *GDAX) GetOrderbook(symbol string, level int) (interface{}, error) {
|
||||
orderbook := GDAXOrderbookResponse{}
|
||||
path := ""
|
||||
orderbook := OrderbookResponse{}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/%s", gdaxAPIURL+gdaxProducts, symbol, gdaxOrderbook)
|
||||
if level > 0 {
|
||||
levelStr := strconv.Itoa(level)
|
||||
path = fmt.Sprintf("%s/%s/%s?level=%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_ORDERBOOK, levelStr)
|
||||
} else {
|
||||
path = fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_ORDERBOOK)
|
||||
path = fmt.Sprintf("%s/%s/%s?level=%s", gdaxAPIURL+gdaxProducts, symbol, gdaxOrderbook, levelStr)
|
||||
}
|
||||
|
||||
err := common.SendHTTPGetRequest(path, true, &orderbook)
|
||||
if err != nil {
|
||||
if err := common.SendHTTPGetRequest(path, true, &orderbook); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if level == 3 {
|
||||
ob := GDAXOrderbookL3{}
|
||||
ob := OrderbookL3{}
|
||||
ob.Sequence = orderbook.Sequence
|
||||
for _, x := range orderbook.Asks {
|
||||
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
||||
@@ -125,7 +140,7 @@ func (g *GDAX) GetOrderbook(symbol string, level int) (interface{}, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
ob.Asks = append(ob.Asks, GDAXOrderL3{Price: price, Amount: amount, OrderID: x[2].(string)})
|
||||
ob.Asks = append(ob.Asks, OrderL3{Price: price, Amount: amount, OrderID: x[2].(string)})
|
||||
}
|
||||
for _, x := range orderbook.Bids {
|
||||
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
||||
@@ -137,64 +152,65 @@ func (g *GDAX) GetOrderbook(symbol string, level int) (interface{}, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
ob.Bids = append(ob.Bids, GDAXOrderL3{Price: price, Amount: amount, OrderID: x[2].(string)})
|
||||
}
|
||||
return ob, nil
|
||||
} else {
|
||||
ob := GDAXOrderbookL1L2{}
|
||||
ob.Sequence = orderbook.Sequence
|
||||
for _, x := range orderbook.Asks {
|
||||
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ob.Asks = append(ob.Asks, GDAXOrderL1L2{Price: price, Amount: amount, NumOrders: x[2].(float64)})
|
||||
}
|
||||
for _, x := range orderbook.Bids {
|
||||
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ob.Bids = append(ob.Bids, GDAXOrderL1L2{Price: price, Amount: amount, NumOrders: x[2].(float64)})
|
||||
ob.Bids = append(ob.Bids, OrderL3{Price: price, Amount: amount, OrderID: x[2].(string)})
|
||||
}
|
||||
return ob, nil
|
||||
}
|
||||
}
|
||||
ob := OrderbookL1L2{}
|
||||
ob.Sequence = orderbook.Sequence
|
||||
for _, x := range orderbook.Asks {
|
||||
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
func (g *GDAX) GetTicker(symbol string) (GDAXTicker, error) {
|
||||
ticker := GDAXTicker{}
|
||||
path := fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_TICKER)
|
||||
err := common.SendHTTPGetRequest(path, true, &ticker)
|
||||
|
||||
if err != nil {
|
||||
return ticker, err
|
||||
ob.Asks = append(ob.Asks, OrderL1L2{Price: price, Amount: amount, NumOrders: x[2].(float64)})
|
||||
}
|
||||
return ticker, nil
|
||||
}
|
||||
for _, x := range orderbook.Bids {
|
||||
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
func (g *GDAX) GetTrades(symbol string) ([]GDAXTrade, error) {
|
||||
trades := []GDAXTrade{}
|
||||
path := fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_TRADES)
|
||||
err := common.SendHTTPGetRequest(path, true, &trades)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
ob.Bids = append(ob.Bids, OrderL1L2{Price: price, Amount: amount, NumOrders: x[2].(float64)})
|
||||
}
|
||||
return trades, nil
|
||||
return ob, nil
|
||||
}
|
||||
|
||||
func (g *GDAX) GetHistoricRates(symbol string, start, end, granularity int64) ([]GDAXHistory, error) {
|
||||
history := []GDAXHistory{}
|
||||
// GetTicker returns ticker by currency pair
|
||||
// currencyPair - example "BTC-USD"
|
||||
func (g *GDAX) GetTicker(currencyPair string) (Ticker, error) {
|
||||
ticker := Ticker{}
|
||||
path := fmt.Sprintf(
|
||||
"%s/%s/%s", gdaxAPIURL+gdaxProducts, currencyPair, gdaxTicker)
|
||||
|
||||
log.Println(path)
|
||||
return ticker, common.SendHTTPGetRequest(path, true, &ticker)
|
||||
}
|
||||
|
||||
// GetTrades listd the latest trades for a product
|
||||
// currencyPair - example "BTC-USD"
|
||||
func (g *GDAX) GetTrades(currencyPair string) ([]Trade, error) {
|
||||
trades := []Trade{}
|
||||
path := fmt.Sprintf(
|
||||
"%s/%s/%s", gdaxAPIURL+gdaxProducts, currencyPair, gdaxTrades)
|
||||
|
||||
return trades, common.SendHTTPGetRequest(path, true, &trades)
|
||||
}
|
||||
|
||||
// GetHistoricRates returns historic rates for a product. Rates are returned in
|
||||
// grouped buckets based on requested granularity.
|
||||
func (g *GDAX) GetHistoricRates(currencyPair string, start, end, granularity int64) ([]History, error) {
|
||||
var resp [][]interface{}
|
||||
history := []History{}
|
||||
values := url.Values{}
|
||||
|
||||
if start > 0 {
|
||||
@@ -209,97 +225,137 @@ func (g *GDAX) GetHistoricRates(symbol string, start, end, granularity int64) ([
|
||||
values.Set("granularity", strconv.FormatInt(granularity, 10))
|
||||
}
|
||||
|
||||
path := common.EncodeURLValues(fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_HISTORY), values)
|
||||
err := common.SendHTTPGetRequest(path, true, &history)
|
||||
path := common.EncodeURLValues(
|
||||
fmt.Sprintf("%s/%s/%s", gdaxAPIURL+gdaxProducts, currencyPair, gdaxHistory),
|
||||
values)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err := common.SendHTTPGetRequest(path, true, &resp); err != nil {
|
||||
return history, err
|
||||
}
|
||||
|
||||
for _, single := range resp {
|
||||
s := History{
|
||||
Time: int64(single[0].(float64)),
|
||||
Low: single[1].(float64),
|
||||
High: single[2].(float64),
|
||||
Open: single[3].(float64),
|
||||
Close: single[4].(float64),
|
||||
Volume: single[5].(float64),
|
||||
}
|
||||
history = append(history, s)
|
||||
}
|
||||
|
||||
return history, nil
|
||||
}
|
||||
|
||||
func (g *GDAX) GetStats(symbol string) (GDAXStats, error) {
|
||||
stats := GDAXStats{}
|
||||
path := fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_STATS)
|
||||
err := common.SendHTTPGetRequest(path, true, &stats)
|
||||
// GetStats returns a 24 hr stat for the product. Volume is in base currency
|
||||
// units. open, high, low are in quote currency units.
|
||||
func (g *GDAX) GetStats(currencyPair string) (Stats, error) {
|
||||
stats := Stats{}
|
||||
path := fmt.Sprintf(
|
||||
"%s/%s/%s", gdaxAPIURL+gdaxProducts, currencyPair, gdaxStats)
|
||||
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
return stats, nil
|
||||
return stats, common.SendHTTPGetRequest(path, true, &stats)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetCurrencies() ([]GDAXCurrency, error) {
|
||||
currencies := []GDAXCurrency{}
|
||||
err := common.SendHTTPGetRequest(GDAX_API_URL+GDAX_CURRENCIES, true, ¤cies)
|
||||
// GetCurrencies returns a list of supported currency on the exchange
|
||||
// Warning: Not all currencies may be currently in use for trading.
|
||||
func (g *GDAX) GetCurrencies() ([]Currency, error) {
|
||||
currencies := []Currency{}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return currencies, nil
|
||||
return currencies,
|
||||
common.SendHTTPGetRequest(gdaxAPIURL+gdaxCurrencies, true, ¤cies)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetAccounts() ([]GDAXAccountResponse, error) {
|
||||
resp := []GDAXAccountResponse{}
|
||||
err := g.SendAuthenticatedHTTPRequest("GET", GDAX_ACCOUNTS, nil, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
// GetServerTime returns the API server time
|
||||
func (g *GDAX) GetServerTime() (ServerTime, error) {
|
||||
serverTime := ServerTime{}
|
||||
|
||||
return serverTime,
|
||||
common.SendHTTPGetRequest(gdaxAPIURL+gdaxTime, true, &serverTime)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetAccount(account string) (GDAXAccountResponse, error) {
|
||||
resp := GDAXAccountResponse{}
|
||||
path := fmt.Sprintf("%s/%s", GDAX_ACCOUNTS, account)
|
||||
err := g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
return resp, nil
|
||||
// GetAccounts returns a list of trading accounts associated with the APIKEYS
|
||||
func (g *GDAX) GetAccounts() ([]AccountResponse, error) {
|
||||
resp := []AccountResponse{}
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", gdaxAccounts, nil, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetAccountHistory(accountID string) ([]GDAXAccountLedgerResponse, error) {
|
||||
resp := []GDAXAccountLedgerResponse{}
|
||||
path := fmt.Sprintf("%s/%s/%s", GDAX_ACCOUNTS, accountID, GDAX_LEDGER)
|
||||
err := g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
// GetAccount returns information for a single account. Use this endpoint when
|
||||
// account_id is known
|
||||
func (g *GDAX) GetAccount(accountID string) (AccountResponse, error) {
|
||||
resp := AccountResponse{}
|
||||
path := fmt.Sprintf("%s/%s", gdaxAccounts, accountID)
|
||||
|
||||
return resp, g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetHolds(accountID string) ([]GDAXAccountHolds, error) {
|
||||
resp := []GDAXAccountHolds{}
|
||||
path := fmt.Sprintf("%s/%s/%s", GDAX_ACCOUNTS, accountID, GDAX_HOLDS)
|
||||
err := g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
// GetAccountHistory returns a list of account activity. Account activity either
|
||||
// increases or decreases your account balance. Items are paginated and sorted
|
||||
// latest first.
|
||||
func (g *GDAX) GetAccountHistory(accountID string) ([]AccountLedgerResponse, error) {
|
||||
resp := []AccountLedgerResponse{}
|
||||
path := fmt.Sprintf("%s/%s/%s", gdaxAccounts, accountID, gdaxLedger)
|
||||
|
||||
return resp, g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) PlaceOrder(clientRef string, price, amount float64, side string, productID, stp string) (string, error) {
|
||||
// GetHolds returns the holds that are placed on an account for any active
|
||||
// orders or pending withdraw requests. As an order is filled, the hold amount
|
||||
// is updated. If an order is canceled, any remaining hold is removed. For a
|
||||
// withdraw, once it is completed, the hold is removed.
|
||||
func (g *GDAX) GetHolds(accountID string) ([]AccountHolds, error) {
|
||||
resp := []AccountHolds{}
|
||||
path := fmt.Sprintf("%s/%s/%s", gdaxAccounts, accountID, gdaxHolds)
|
||||
|
||||
return resp, g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
}
|
||||
|
||||
// PlaceLimitOrder places a new limit order. Orders can only be placed if the
|
||||
// account has sufficient funds. Once an order is placed, account funds
|
||||
// will be put on hold for the duration of the order. How much and which funds
|
||||
// are put on hold depends on the order type and parameters specified.
|
||||
//
|
||||
// GENERAL PARAMS
|
||||
// clientRef - [optional] Order ID selected by you to identify your order
|
||||
// side - buy or sell
|
||||
// productID - A valid product id
|
||||
// stp - [optional] Self-trade prevention flag
|
||||
//
|
||||
// LIMIT ORDER PARAMS
|
||||
// price - Price per bitcoin
|
||||
// amount - Amount of BTC to buy or sell
|
||||
// timeInforce - [optional] GTC, GTT, IOC, or FOK (default is GTC)
|
||||
// cancelAfter - [optional] min, hour, day * Requires time_in_force to be GTT
|
||||
// postOnly - [optional] Post only flag Invalid when time_in_force is IOC or FOK
|
||||
func (g *GDAX) PlaceLimitOrder(clientRef string, price, amount float64, side, timeInforce, cancelAfter, productID, stp string, postOnly bool) (string, error) {
|
||||
resp := GeneralizedOrderResponse{}
|
||||
request := make(map[string]interface{})
|
||||
|
||||
if clientRef != "" {
|
||||
request["client_oid"] = clientRef
|
||||
}
|
||||
|
||||
request["type"] = "limit"
|
||||
request["price"] = strconv.FormatFloat(price, 'f', -1, 64)
|
||||
request["size"] = strconv.FormatFloat(amount, 'f', -1, 64)
|
||||
request["side"] = side
|
||||
request["product_id"] = productID
|
||||
|
||||
if cancelAfter != "" {
|
||||
request["cancel_after"] = cancelAfter
|
||||
}
|
||||
if timeInforce != "" {
|
||||
request["time_in_foce"] = timeInforce
|
||||
}
|
||||
if clientRef != "" {
|
||||
request["client_oid"] = clientRef
|
||||
}
|
||||
if stp != "" {
|
||||
request["stp"] = stp
|
||||
}
|
||||
|
||||
type OrderResponse struct {
|
||||
ID string `json:"id"`
|
||||
if postOnly {
|
||||
request["post_only"] = postOnly
|
||||
}
|
||||
|
||||
resp := OrderResponse{}
|
||||
err := g.SendAuthenticatedHTTPRequest("POST", GDAX_ORDERS, request, &resp)
|
||||
err := g.SendAuthenticatedHTTPRequest("POST", gdaxOrders, request, &resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -307,98 +363,406 @@ func (g *GDAX) PlaceOrder(clientRef string, price, amount float64, side string,
|
||||
return resp.ID, nil
|
||||
}
|
||||
|
||||
// PlaceMarketOrder places a new market order.
|
||||
// Orders can only be placed if the account has sufficient funds. Once an order
|
||||
// is placed, account funds will be put on hold for the duration of the order.
|
||||
// How much and which funds are put on hold depends on the order type and
|
||||
// parameters specified.
|
||||
//
|
||||
// GENERAL PARAMS
|
||||
// clientRef - [optional] Order ID selected by you to identify your order
|
||||
// side - buy or sell
|
||||
// productID - A valid product id
|
||||
// stp - [optional] Self-trade prevention flag
|
||||
//
|
||||
// MARKET ORDER PARAMS
|
||||
// size - [optional]* Desired amount in BTC
|
||||
// funds [optional]* Desired amount of quote currency to use
|
||||
// * One of size or funds is required.
|
||||
func (g *GDAX) PlaceMarketOrder(clientRef string, size, funds float64, side string, productID, stp string) (string, error) {
|
||||
resp := GeneralizedOrderResponse{}
|
||||
request := make(map[string]interface{})
|
||||
request["side"] = side
|
||||
request["product_id"] = productID
|
||||
request["type"] = "market"
|
||||
|
||||
if size != 0 {
|
||||
request["size"] = strconv.FormatFloat(size, 'f', -1, 64)
|
||||
}
|
||||
if funds != 0 {
|
||||
request["funds"] = strconv.FormatFloat(funds, 'f', -1, 64)
|
||||
}
|
||||
if clientRef != "" {
|
||||
request["client_oid"] = clientRef
|
||||
}
|
||||
if stp != "" {
|
||||
request["stp"] = stp
|
||||
}
|
||||
|
||||
err := g.SendAuthenticatedHTTPRequest("POST", gdaxOrders, request, &resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return resp.ID, nil
|
||||
}
|
||||
|
||||
// PlaceMarginOrder places a new market order.
|
||||
// Orders can only be placed if the account has sufficient funds. Once an order
|
||||
// is placed, account funds will be put on hold for the duration of the order.
|
||||
// How much and which funds are put on hold depends on the order type and
|
||||
// parameters specified.
|
||||
//
|
||||
// GENERAL PARAMS
|
||||
// clientRef - [optional] Order ID selected by you to identify your order
|
||||
// side - buy or sell
|
||||
// productID - A valid product id
|
||||
// stp - [optional] Self-trade prevention flag
|
||||
//
|
||||
// MARGIN ORDER PARAMS
|
||||
// size - [optional]* Desired amount in BTC
|
||||
// funds - [optional]* Desired amount of quote currency to use
|
||||
func (g *GDAX) PlaceMarginOrder(clientRef string, size, funds float64, side string, productID, stp string) (string, error) {
|
||||
resp := GeneralizedOrderResponse{}
|
||||
request := make(map[string]interface{})
|
||||
request["side"] = side
|
||||
request["product_id"] = productID
|
||||
request["type"] = "margin"
|
||||
|
||||
if size != 0 {
|
||||
request["size"] = strconv.FormatFloat(size, 'f', -1, 64)
|
||||
}
|
||||
if funds != 0 {
|
||||
request["funds"] = strconv.FormatFloat(funds, 'f', -1, 64)
|
||||
}
|
||||
if clientRef != "" {
|
||||
request["client_oid"] = clientRef
|
||||
}
|
||||
if stp != "" {
|
||||
request["stp"] = stp
|
||||
}
|
||||
|
||||
err := g.SendAuthenticatedHTTPRequest("POST", gdaxOrders, request, &resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return resp.ID, nil
|
||||
}
|
||||
|
||||
// CancelOrder cancels order by orderID
|
||||
func (g *GDAX) CancelOrder(orderID string) error {
|
||||
path := fmt.Sprintf("%s/%s", GDAX_ORDERS, orderID)
|
||||
err := g.SendAuthenticatedHTTPRequest("DELETE", path, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
path := fmt.Sprintf("%s/%s", gdaxOrders, orderID)
|
||||
|
||||
return g.SendAuthenticatedHTTPRequest("DELETE", path, nil, nil)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetOrders(params url.Values) ([]GDAXOrdersResponse, error) {
|
||||
path := common.EncodeURLValues(GDAX_API_URL+GDAX_ORDERS, params)
|
||||
resp := []GDAXOrdersResponse{}
|
||||
err := g.SendAuthenticatedHTTPRequest("GET", common.GetURIPath(path), nil, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// CancelAllOrders cancels all open orders on the exchange and returns and array
|
||||
// of order IDs
|
||||
// currencyPair - [optional] all orders for a currencyPair string will be
|
||||
// canceled
|
||||
func (g *GDAX) CancelAllOrders(currencyPair string) ([]string, error) {
|
||||
var resp []string
|
||||
request := make(map[string]interface{})
|
||||
|
||||
if len(currencyPair) != 0 {
|
||||
request["product_id"] = currencyPair
|
||||
}
|
||||
return resp, nil
|
||||
return resp, g.SendAuthenticatedHTTPRequest("DELETE", gdaxOrders, request, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetOrder(orderID string) (GDAXOrderResponse, error) {
|
||||
path := fmt.Sprintf("%s/%s", GDAX_ORDERS, orderID)
|
||||
resp := GDAXOrderResponse{}
|
||||
err := g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
// GetOrders lists current open orders. Only open or un-settled orders are
|
||||
// returned. As soon as an order is no longer open and settled, it will no
|
||||
// longer appear in the default request.
|
||||
// status - can be a range of "open", "pending", "done" or "active"
|
||||
// currencyPair - [optional] for example "BTC-USD"
|
||||
func (g *GDAX) GetOrders(status []string, currencyPair string) ([]GeneralizedOrderResponse, error) {
|
||||
resp := []GeneralizedOrderResponse{}
|
||||
params := url.Values{}
|
||||
|
||||
for _, individualStatus := range status {
|
||||
params.Add("status", individualStatus)
|
||||
}
|
||||
return resp, nil
|
||||
if len(currencyPair) != 0 {
|
||||
params.Set("product_id", currencyPair)
|
||||
}
|
||||
|
||||
path := common.EncodeURLValues(gdaxAPIURL+gdaxOrders, params)
|
||||
path = common.GetURIPath(path)
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", path[1:], nil, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetFills(params url.Values) ([]GDAXFillResponse, error) {
|
||||
path := common.EncodeURLValues(GDAX_API_URL+GDAX_FILLS, params)
|
||||
resp := []GDAXFillResponse{}
|
||||
err := g.SendAuthenticatedHTTPRequest("GET", common.GetURIPath(path), nil, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
// GetOrder returns a single order by order id.
|
||||
func (g *GDAX) GetOrder(orderID string) (GeneralizedOrderResponse, error) {
|
||||
resp := GeneralizedOrderResponse{}
|
||||
path := fmt.Sprintf("%s/%s", gdaxOrders, orderID)
|
||||
|
||||
return resp, g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) Transfer(transferType string, amount float64, accountID string) error {
|
||||
// GetFills returns a list of recent fills
|
||||
func (g *GDAX) GetFills(orderID, currencyPair string) ([]FillResponse, error) {
|
||||
resp := []FillResponse{}
|
||||
params := url.Values{}
|
||||
|
||||
if len(orderID) != 0 {
|
||||
params.Set("order_id", orderID)
|
||||
}
|
||||
if len(currencyPair) != 0 {
|
||||
params.Set("product_id", currencyPair)
|
||||
}
|
||||
if len(params.Get("order_id")) == 0 && len(params.Get("product_id")) == 0 {
|
||||
return resp, errors.New("no paramaters set")
|
||||
}
|
||||
|
||||
path := common.EncodeURLValues(gdaxAPIURL+gdaxFills, params)
|
||||
uri := common.GetURIPath(path)
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", uri[1:], nil, &resp)
|
||||
}
|
||||
|
||||
// GetFundingRecords every order placed with a margin profile that draws funding
|
||||
// will create a funding record.
|
||||
//
|
||||
// status - "outstanding", "settled", or "rejected"
|
||||
func (g *GDAX) GetFundingRecords(status string) ([]Funding, error) {
|
||||
resp := []Funding{}
|
||||
params := url.Values{}
|
||||
params.Set("status", status)
|
||||
|
||||
path := common.EncodeURLValues(gdaxAPIURL+gdaxFunding, params)
|
||||
uri := common.GetURIPath(path)
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", uri[1:], nil, &resp)
|
||||
}
|
||||
|
||||
////////////////////////// Not receiving reply from server /////////////////
|
||||
// RepayFunding repays the older funding records first
|
||||
//
|
||||
// amount - amount of currency to repay
|
||||
// currency - currency, example USD
|
||||
// func (g *GDAX) RepayFunding(amount, currency string) (Funding, error) {
|
||||
// resp := Funding{}
|
||||
// params := make(map[string]interface{})
|
||||
// params["amount"] = amount
|
||||
// params["currency"] = currency
|
||||
//
|
||||
// return resp,
|
||||
// g.SendAuthenticatedHTTPRequest("POST", gdaxFundingRepay, params, &resp)
|
||||
// }
|
||||
|
||||
// MarginTransfer sends funds between a standard/default profile and a margin
|
||||
// profile.
|
||||
// A deposit will transfer funds from the default profile into the margin
|
||||
// profile. A withdraw will transfer funds from the margin profile to the
|
||||
// default profile. Withdraws will fail if they would set your margin ratio
|
||||
// below the initial margin ratio requirement.
|
||||
//
|
||||
// amount - the amount to transfer between the default and margin profile
|
||||
// transferType - either "deposit" or "withdraw"
|
||||
// profileID - The id of the margin profile to deposit or withdraw from
|
||||
// currency - currency to transfer, currently on "BTC" or "USD"
|
||||
func (g *GDAX) MarginTransfer(amount float64, transferType, profileID, currency string) (MarginTransfer, error) {
|
||||
resp := MarginTransfer{}
|
||||
request := make(map[string]interface{})
|
||||
request["type"] = transferType
|
||||
request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64)
|
||||
request["GDAX_account_id"] = accountID
|
||||
request["currency"] = currency
|
||||
request["margin_profile_id"] = profileID
|
||||
|
||||
err := g.SendAuthenticatedHTTPRequest("POST", GDAX_TRANSFERS, request, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("POST", gdaxMarginTransfer, request, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetReport(reportType, startDate, endDate string) (GDAXReportResponse, error) {
|
||||
// GetPosition returns an overview of account profile.
|
||||
func (g *GDAX) GetPosition() (AccountOverview, error) {
|
||||
resp := AccountOverview{}
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", gdaxPosition, nil, &resp)
|
||||
}
|
||||
|
||||
// ClosePosition closes a position and allowing you to repay position as well
|
||||
// repayOnly - allows the position to be repaid
|
||||
func (g *GDAX) ClosePosition(repayOnly bool) (AccountOverview, error) {
|
||||
resp := AccountOverview{}
|
||||
request := make(map[string]interface{})
|
||||
request["repay_only"] = repayOnly
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("POST", gdaxPositionClose, request, &resp)
|
||||
}
|
||||
|
||||
// GetPayMethods returns a full list of payment methods
|
||||
func (g *GDAX) GetPayMethods() ([]PaymentMethod, error) {
|
||||
resp := []PaymentMethod{}
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", gdaxPaymentMethod, nil, &resp)
|
||||
}
|
||||
|
||||
// DepositViaPaymentMethod deposits funds from a payment method. See the Payment
|
||||
// Methods section for retrieving your payment methods.
|
||||
//
|
||||
// amount - The amount to deposit
|
||||
// currency - The type of currency
|
||||
// paymentID - ID of the payment method
|
||||
func (g *GDAX) DepositViaPaymentMethod(amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) {
|
||||
resp := DepositWithdrawalInfo{}
|
||||
req := make(map[string]interface{})
|
||||
req["amount"] = amount
|
||||
req["currency"] = currency
|
||||
req["payment_method_id"] = paymentID
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("POST", gdaxPaymentMethodDeposit, req, &resp)
|
||||
}
|
||||
|
||||
// DepositViaCoinbase deposits funds from a coinbase account. Move funds between
|
||||
// a Coinbase account and GDAX trading account within daily limits. Moving
|
||||
// funds between Coinbase and GDAX is instant and free. See the Coinbase
|
||||
// Accounts section for retrieving your Coinbase accounts.
|
||||
//
|
||||
// amount - The amount to deposit
|
||||
// currency - The type of currency
|
||||
// accountID - ID of the coinbase account
|
||||
func (g *GDAX) DepositViaCoinbase(amount float64, currency, accountID string) (DepositWithdrawalInfo, error) {
|
||||
resp := DepositWithdrawalInfo{}
|
||||
req := make(map[string]interface{})
|
||||
req["amount"] = amount
|
||||
req["currency"] = currency
|
||||
req["coinbase_account_id"] = accountID
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("POST", gdaxDepositCoinbase, req, &resp)
|
||||
}
|
||||
|
||||
// WithdrawViaPaymentMethod withdraws funds to a payment method
|
||||
//
|
||||
// amount - The amount to withdraw
|
||||
// currency - The type of currency
|
||||
// paymentID - ID of the payment method
|
||||
func (g *GDAX) WithdrawViaPaymentMethod(amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) {
|
||||
resp := DepositWithdrawalInfo{}
|
||||
req := make(map[string]interface{})
|
||||
req["amount"] = amount
|
||||
req["currency"] = currency
|
||||
req["payment_method_id"] = paymentID
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("POST", gdaxWithdrawalPaymentMethod, req, &resp)
|
||||
}
|
||||
|
||||
///////////////////////// NO ROUTE FOUND ERROR ////////////////////////////////
|
||||
// WithdrawViaCoinbase withdraws funds to a coinbase account.
|
||||
//
|
||||
// amount - The amount to withdraw
|
||||
// currency - The type of currency
|
||||
// accountID - ID of the coinbase account
|
||||
// func (g *GDAX) WithdrawViaCoinbase(amount float64, currency, accountID string) (DepositWithdrawalInfo, error) {
|
||||
// resp := DepositWithdrawalInfo{}
|
||||
// req := make(map[string]interface{})
|
||||
// req["amount"] = amount
|
||||
// req["currency"] = currency
|
||||
// req["coinbase_account_id"] = accountID
|
||||
//
|
||||
// return resp,
|
||||
// g.SendAuthenticatedHTTPRequest("POST", gdaxWithdrawalCoinbase, req, &resp)
|
||||
// }
|
||||
|
||||
// WithdrawCrypto withdraws funds to a crypto address
|
||||
//
|
||||
// amount - The amount to withdraw
|
||||
// currency - The type of currency
|
||||
// cryptoAddress - A crypto address of the recipient
|
||||
func (g *GDAX) WithdrawCrypto(amount float64, currency, cryptoAddress string) (DepositWithdrawalInfo, error) {
|
||||
resp := DepositWithdrawalInfo{}
|
||||
req := make(map[string]interface{})
|
||||
req["amount"] = amount
|
||||
req["currency"] = currency
|
||||
req["crypto_address"] = cryptoAddress
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("POST", gdaxWithdrawalCrypto, req, &resp)
|
||||
}
|
||||
|
||||
// GetCoinbaseAccounts returns a list of coinbase accounts
|
||||
func (g *GDAX) GetCoinbaseAccounts() ([]CoinbaseAccounts, error) {
|
||||
resp := []CoinbaseAccounts{}
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", gdaxCoinbaseAccounts, nil, &resp)
|
||||
}
|
||||
|
||||
// GetReport returns batches of historic information about your account in
|
||||
// various human and machine readable forms.
|
||||
//
|
||||
// reportType - "fills" or "account"
|
||||
// startDate - Starting date for the report (inclusive)
|
||||
// endDate - Ending date for the report (inclusive)
|
||||
// currencyPair - ID of the product to generate a fills report for.
|
||||
// E.g. BTC-USD. *Required* if type is fills
|
||||
// accountID - ID of the account to generate an account report for. *Required*
|
||||
// if type is account
|
||||
// format - pdf or csv (defualt is pdf)
|
||||
// email - [optional] Email address to send the report to
|
||||
func (g *GDAX) GetReport(reportType, startDate, endDate, currencyPair, accountID, format, email string) (Report, error) {
|
||||
resp := Report{}
|
||||
request := make(map[string]interface{})
|
||||
request["type"] = reportType
|
||||
request["start_date"] = startDate
|
||||
request["end_date"] = endDate
|
||||
request["format"] = "pdf"
|
||||
|
||||
resp := GDAXReportResponse{}
|
||||
err := g.SendAuthenticatedHTTPRequest("POST", GDAX_REPORTS, request, &resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
if len(currencyPair) != 0 {
|
||||
request["product_id"] = currencyPair
|
||||
}
|
||||
return resp, nil
|
||||
if len(accountID) != 0 {
|
||||
request["account_id"] = accountID
|
||||
}
|
||||
if format == "csv" {
|
||||
request["format"] = format
|
||||
}
|
||||
if len(email) != 0 {
|
||||
request["email"] = email
|
||||
}
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("POST", gdaxReports, request, &resp)
|
||||
}
|
||||
|
||||
func (g *GDAX) GetReportStatus(reportID string) (GDAXReportResponse, error) {
|
||||
path := fmt.Sprintf("%s/%s", GDAX_REPORTS, reportID)
|
||||
resp := GDAXReportResponse{}
|
||||
err := g.SendAuthenticatedHTTPRequest("POST", path, nil, &resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
return resp, nil
|
||||
// GetReportStatus once a report request has been accepted for processing, the
|
||||
// status is available by polling the report resource endpoint.
|
||||
func (g *GDAX) GetReportStatus(reportID string) (Report, error) {
|
||||
resp := Report{}
|
||||
path := fmt.Sprintf("%s/%s", gdaxReports, reportID)
|
||||
|
||||
return resp, g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
||||
}
|
||||
|
||||
// GetTrailingVolume this request will return your 30-day trailing volume for
|
||||
// all products.
|
||||
func (g *GDAX) GetTrailingVolume() ([]Volume, error) {
|
||||
resp := []Volume{}
|
||||
|
||||
return resp,
|
||||
g.SendAuthenticatedHTTPRequest("GET", gdaxTrailingVolume, nil, &resp)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP reque
|
||||
func (g *GDAX) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}) (err error) {
|
||||
if !g.AuthenticatedAPISupport {
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, g.Name)
|
||||
}
|
||||
|
||||
if g.Nonce.Get() == 0 {
|
||||
g.Nonce.Set(time.Now().Unix())
|
||||
} else {
|
||||
g.Nonce.Inc()
|
||||
}
|
||||
|
||||
payload := []byte("")
|
||||
|
||||
if params != nil {
|
||||
payload, err = common.JSONEncode(params)
|
||||
|
||||
if err != nil {
|
||||
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
|
||||
}
|
||||
@@ -408,26 +772,34 @@ func (g *GDAX) SendAuthenticatedHTTPRequest(method, path string, params map[stri
|
||||
}
|
||||
}
|
||||
|
||||
message := g.Nonce.String() + method + "/" + path + string(payload)
|
||||
nonce := g.Nonce.Evaluate()
|
||||
message := nonce + method + "/" + path + string(payload)
|
||||
hmac := common.GetHMAC(common.HashSHA256, []byte(message), []byte(g.APISecret))
|
||||
headers := make(map[string]string)
|
||||
headers["CB-ACCESS-SIGN"] = common.Base64Encode([]byte(hmac))
|
||||
headers["CB-ACCESS-TIMESTAMP"] = g.Nonce.String()
|
||||
headers["CB-ACCESS-TIMESTAMP"] = nonce
|
||||
headers["CB-ACCESS-KEY"] = g.APIKey
|
||||
headers["CB-ACCESS-PASSPHRASE"] = g.ClientID
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
resp, err := common.SendHTTPRequest(method, GDAX_API_URL+path, headers, bytes.NewBuffer(payload))
|
||||
resp, err := common.SendHTTPRequest(method, gdaxAPIURL+path, headers, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if g.Verbose {
|
||||
log.Printf("Received raw: \n%s\n", resp)
|
||||
}
|
||||
|
||||
err = common.JSONDecode([]byte(resp), &result)
|
||||
type initialResponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
initialCheck := initialResponse{}
|
||||
|
||||
if err != nil {
|
||||
return errors.New("unable to JSON Unmarshal response")
|
||||
err = common.JSONDecode([]byte(resp), &initialCheck)
|
||||
if err == nil && len(initialCheck.Message) != 0 {
|
||||
return errors.New(initialCheck.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
return common.JSONDecode([]byte(resp), &result)
|
||||
}
|
||||
|
||||
300
exchanges/gdax/gdax_test.go
Normal file
300
exchanges/gdax/gdax_test.go
Normal file
@@ -0,0 +1,300 @@
|
||||
package gdax
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
)
|
||||
|
||||
var g GDAX
|
||||
|
||||
// Please supply your APIKeys here for better testing
|
||||
const (
|
||||
apiKey = ""
|
||||
apiSecret = ""
|
||||
clientID = "" //passphrase you made at API CREATION
|
||||
)
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
g.SetDefaults()
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.dat")
|
||||
gdxConfig, err := cfg.GetExchangeConfig("Bitfinex")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GDAX Setup() init error")
|
||||
}
|
||||
|
||||
g.Setup(gdxConfig)
|
||||
}
|
||||
|
||||
func TestGetFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
if g.GetFee(false) == 0 {
|
||||
t.Error("Test failed - GetFee() error")
|
||||
}
|
||||
if g.GetFee(true) != 0 {
|
||||
t.Error("Test failed - GetFee() error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetProducts(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetProducts()
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetProducts() error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetTicker("BTC-USD")
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetTicker() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetTrades("BTC-USD")
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetTrades() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHistoricRates(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetHistoricRates("BTC-USD", 0, 0, 0)
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetHistoricRates() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStats(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetStats("BTC-USD")
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetStats() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrencies(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetCurrencies()
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetCurrencies() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServerTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetServerTime()
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetServerTime() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetAccounts()
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetAccounts() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccount(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetAccount("234cb213-ac6f-4ed8-b7b6-e62512930945")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetAccount() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetAccountHistory("234cb213-ac6f-4ed8-b7b6-e62512930945")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetAccountHistory() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHolds(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetHolds("234cb213-ac6f-4ed8-b7b6-e62512930945")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetHolds() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlaceLimitOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.PlaceLimitOrder("", 0, 0, "buy", "", "", "BTC-USD", "", false)
|
||||
if err == nil {
|
||||
t.Error("Test failed - PlaceLimitOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlaceMarketOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.PlaceMarketOrder("", 1, 0, "buy", "BTC-USD", "")
|
||||
if err == nil {
|
||||
t.Error("Test failed - PlaceMarketOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
err := g.CancelOrder("1337")
|
||||
if err == nil {
|
||||
t.Error("Test failed - CancelOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelAllOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.CancelAllOrders("BTC-USD")
|
||||
if err == nil {
|
||||
t.Error("Test failed - CancelAllOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetOrders([]string{"open", "done"}, "BTC-USD")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetOrder("1337")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFills(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetFills("1337", "BTC-USD")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetFills() error", err)
|
||||
}
|
||||
_, err = g.GetFills("", "")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetFills() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFundingRecords(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetFundingRecords("rejected")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetFundingRecords() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// func TestRepayFunding(t *testing.T) {
|
||||
// g.Verbose = true
|
||||
// _, err := g.RepayFunding("1", "BTC")
|
||||
// if err != nil {
|
||||
// t.Error("Test failed - RepayFunding() error", err)
|
||||
// }
|
||||
// }
|
||||
|
||||
func TestMarginTransfer(t *testing.T) { //invalid sig issue
|
||||
t.Parallel()
|
||||
_, err := g.MarginTransfer(1, "withdraw", "45fa9e3b-00ba-4631-b907-8a98cbdf21be", "BTC")
|
||||
if err == nil {
|
||||
t.Error("Test failed - MarginTransfer() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPosition(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetPosition()
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetPosition() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClosePosition(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.ClosePosition(false)
|
||||
if err == nil {
|
||||
t.Error("Test failed - ClosePosition() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPayMethods(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetPayMethods()
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetPayMethods() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDepositViaPaymentMethod(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.DepositViaPaymentMethod(1, "BTC", "1337")
|
||||
if err == nil {
|
||||
t.Error("Test failed - DepositViaPaymentMethod() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDepositViaCoinbase(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.DepositViaCoinbase(1, "BTC", "1337")
|
||||
if err == nil {
|
||||
t.Error("Test failed - DepositViaCoinbase() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawViaPaymentMethod(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.WithdrawViaPaymentMethod(1, "BTC", "1337")
|
||||
if err == nil {
|
||||
t.Error("Test failed - WithdrawViaPaymentMethod() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// func TestWithdrawViaCoinbase(t *testing.T) { // No Route found error
|
||||
// _, err := g.WithdrawViaCoinbase(1, "BTC", "c13cd0fc-72ca-55e9-843b-b84ef628c198")
|
||||
// if err != nil {
|
||||
// t.Error("Test failed - WithdrawViaCoinbase() error", err)
|
||||
// }
|
||||
// }
|
||||
|
||||
func TestWithdrawCrypto(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.WithdrawCrypto(1, "BTC", "1337")
|
||||
if err == nil {
|
||||
t.Error("Test failed - WithdrawViaCoinbase() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCoinbaseAccounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetCoinbaseAccounts()
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetCoinbaseAccounts() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetReportStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetReportStatus("1337")
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetReportStatus() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTrailingVolume(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := g.GetTrailingVolume()
|
||||
if err == nil {
|
||||
t.Error("Test failed - GetTrailingVolume() error", err)
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,7 @@
|
||||
package gdax
|
||||
|
||||
type GDAXTicker struct {
|
||||
TradeID int64 `json:"trade_id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
Time string `json:"time"`
|
||||
}
|
||||
|
||||
type GDAXProduct struct {
|
||||
// Product holds product information
|
||||
type Product struct {
|
||||
ID string `json:"id"`
|
||||
BaseCurrency string `json:"base_currency"`
|
||||
QuoteCurrency string `json:"quote_currency"`
|
||||
@@ -17,37 +11,16 @@ type GDAXProduct struct {
|
||||
DisplayName string `json:"string"`
|
||||
}
|
||||
|
||||
type GDAXOrderL1L2 struct {
|
||||
Price float64
|
||||
Amount float64
|
||||
NumOrders float64
|
||||
// Ticker holds basic ticker information
|
||||
type Ticker struct {
|
||||
TradeID int64 `json:"trade_id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
Time string `json:"time"`
|
||||
}
|
||||
|
||||
type GDAXOrderL3 struct {
|
||||
Price float64
|
||||
Amount float64
|
||||
OrderID string
|
||||
}
|
||||
|
||||
type GDAXOrderbookL1L2 struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
Bids []GDAXOrderL1L2 `json:"bids"`
|
||||
Asks []GDAXOrderL1L2 `json:"asks"`
|
||||
}
|
||||
|
||||
type GDAXOrderbookL3 struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
Bids []GDAXOrderL3 `json:"bids"`
|
||||
Asks []GDAXOrderL3 `json:"asks"`
|
||||
}
|
||||
|
||||
type GDAXOrderbookResponse struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
Bids [][]interface{} `json:"bids"`
|
||||
Asks [][]interface{} `json:"asks"`
|
||||
}
|
||||
|
||||
type GDAXTrade struct {
|
||||
// Trade holds executed trade information
|
||||
type Trade struct {
|
||||
TradeID int64 `json:"trade_id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
@@ -55,37 +28,52 @@ type GDAXTrade struct {
|
||||
Side string `json:"side"`
|
||||
}
|
||||
|
||||
type GDAXStats struct {
|
||||
// History holds historic rate information
|
||||
type History struct {
|
||||
Time int64 `json:"time"`
|
||||
Low float64 `json:"low"`
|
||||
High float64 `json:"high"`
|
||||
Open float64 `json:"open"`
|
||||
Close float64 `json:"close"`
|
||||
Volume float64 `json:"volume"`
|
||||
}
|
||||
|
||||
// Stats holds last 24 hr data for gdax
|
||||
type Stats struct {
|
||||
Open float64 `json:"open,string"`
|
||||
High float64 `json:"high,string"`
|
||||
Low float64 `json:"low,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
}
|
||||
|
||||
type GDAXCurrency struct {
|
||||
// Currency holds singular currency product information
|
||||
type Currency struct {
|
||||
ID string
|
||||
Name string
|
||||
MinSize float64 `json:"min_size,string"`
|
||||
}
|
||||
|
||||
type GDAXHistory struct {
|
||||
Time int64
|
||||
Low float64
|
||||
High float64
|
||||
Open float64
|
||||
Close float64
|
||||
Volume float64
|
||||
// ServerTime holds current requested server time information
|
||||
type ServerTime struct {
|
||||
ISO string `json:"iso"`
|
||||
Epoch float64 `json:"epoch"`
|
||||
}
|
||||
|
||||
type GDAXAccountResponse struct {
|
||||
ID string `json:"id"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
Hold float64 `json:"hold,string"`
|
||||
Available float64 `json:"available,string"`
|
||||
Currency string `json:"currency"`
|
||||
// AccountResponse holds the details for the trading accounts
|
||||
type AccountResponse struct {
|
||||
ID string `json:"id"`
|
||||
Currency string `json:"currency"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
Available float64 `json:"available,string"`
|
||||
Hold float64 `json:"hold,string"`
|
||||
ProfileID string `json:"profile_id"`
|
||||
MarginEnabled bool `json:"margin_enabled"`
|
||||
FundedAmount float64 `json:"funded_amount,string"`
|
||||
DefaultAmount float64 `json:"default_amount,string"`
|
||||
}
|
||||
|
||||
type GDAXAccountLedgerResponse struct {
|
||||
// AccountLedgerResponse holds account history information
|
||||
type AccountLedgerResponse struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
@@ -94,7 +82,8 @@ type GDAXAccountLedgerResponse struct {
|
||||
Details interface{} `json:"details"`
|
||||
}
|
||||
|
||||
type GDAXAccountHolds struct {
|
||||
// AccountHolds contains the hold information about an account
|
||||
type AccountHolds struct {
|
||||
ID string `json:"id"`
|
||||
AccountID string `json:"account_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
@@ -104,48 +93,182 @@ type GDAXAccountHolds struct {
|
||||
Reference string `json:"ref"`
|
||||
}
|
||||
|
||||
type GDAXOrdersResponse struct {
|
||||
ID string `json:"id"`
|
||||
Size float64 `json:"size,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
ProductID string `json:"product_id"`
|
||||
Status string `json:"status"`
|
||||
FilledSize float64 `json:"filled_size,string"`
|
||||
FillFees float64 `json:"fill_fees,string"`
|
||||
Settled bool `json:"settled"`
|
||||
Side string `json:"side"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
// GeneralizedOrderResponse is the generalized return type across order
|
||||
// placement and information collation
|
||||
type GeneralizedOrderResponse struct {
|
||||
ID string `json:"id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
ProductID string `json:"product_id"`
|
||||
Side string `json:"side"`
|
||||
Stp string `json:"stp"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"time_in_force"`
|
||||
PostOnly bool `json:"post_only"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
FillFees float64 `json:"fill_fees,string"`
|
||||
FilledSize float64 `json:"filled_size,string"`
|
||||
ExecutedValue float64 `json:"executed_value,string"`
|
||||
Status string `json:"status"`
|
||||
Settled bool `json:"settled"`
|
||||
Funds float64 `json:"funds,string"`
|
||||
SpecifiedFunds float64 `json:"specified_funds,string"`
|
||||
DoneReason string `json:"done_reason"`
|
||||
DoneAt string `json:"done_at"`
|
||||
}
|
||||
|
||||
type GDAXOrderResponse struct {
|
||||
ID string `json:"id"`
|
||||
Size float64 `json:"size,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
DoneReason string `json:"done_reason"`
|
||||
Status string `json:"status"`
|
||||
Settled bool `json:"settled"`
|
||||
FilledSize float64 `json:"filled_size,string"`
|
||||
ProductID string `json:"product_id"`
|
||||
FillFees float64 `json:"fill_fees,string"`
|
||||
Side string `json:"side"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
DoneAt string `json:"done_at"`
|
||||
// Funding holds funding data
|
||||
type Funding struct {
|
||||
ID string `json:"id"`
|
||||
OrderID string `json:"order_id"`
|
||||
ProfileID string `json:"profile_id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Currency string `json:"currency"`
|
||||
RepaidAmount float64 `json:"repaid_amount"`
|
||||
DefaultAmount float64 `json:"default_amount,string"`
|
||||
RepaidDefault bool `json:"repaid_default"`
|
||||
}
|
||||
|
||||
type GDAXFillResponse struct {
|
||||
TradeID int `json:"trade_id"`
|
||||
ProductID string `json:"product_id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
OrderID string `json:"order_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Liquidity string `json:"liquidity"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Settled bool `json:"settled"`
|
||||
Side string `json:"side"`
|
||||
// MarginTransfer holds margin transfer details
|
||||
type MarginTransfer struct {
|
||||
CreatedAt string `json:"created_at"`
|
||||
ID string `json:"id"`
|
||||
UserID string `json:"user_id"`
|
||||
ProfileID string `json:"profile_id"`
|
||||
MarginProfileID string `json:"margin_profile_id"`
|
||||
Type string `json:"type"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Currency string `json:"currency"`
|
||||
AccountID string `json:"account_id"`
|
||||
MarginAccountID string `json:"margin_account_id"`
|
||||
MarginProductID string `json:"margin_product_id"`
|
||||
Status string `json:"status"`
|
||||
Nonce int `json:"nonce"`
|
||||
}
|
||||
|
||||
type GDAXReportResponse struct {
|
||||
// AccountOverview holds account information returned from position
|
||||
type AccountOverview struct {
|
||||
Status string `json:"status"`
|
||||
Funding struct {
|
||||
MaxFundingValue float64 `json:"max_funding_value,string"`
|
||||
FundingValue float64 `json:"funding_value,string"`
|
||||
OldestOutstanding struct {
|
||||
ID string `json:"id"`
|
||||
OrderID string `json:"order_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Currency string `json:"currency"`
|
||||
AccountID string `json:"account_id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
} `json:"oldest_outstanding"`
|
||||
} `json:"funding"`
|
||||
Accounts struct {
|
||||
LTC Account `json:"LTC"`
|
||||
ETH Account `json:"ETH"`
|
||||
USD Account `json:"USD"`
|
||||
BTC Account `json:"BTC"`
|
||||
} `json:"accounts"`
|
||||
MarginCall struct {
|
||||
Active bool `json:"active"`
|
||||
Price float64 `json:"price,string"`
|
||||
Side string `json:"side"`
|
||||
Size float64 `json:"size,string"`
|
||||
Funds float64 `json:"funds,string"`
|
||||
} `json:"margin_call"`
|
||||
UserID string `json:"user_id"`
|
||||
ProfileID string `json:"profile_id"`
|
||||
Position struct {
|
||||
Type string `json:"type"`
|
||||
Size float64 `json:"size,string"`
|
||||
Complement float64 `json:"complement,string"`
|
||||
MaxSize float64 `json:"max_size,string"`
|
||||
} `json:"position"`
|
||||
ProductID string `json:"product_id"`
|
||||
}
|
||||
|
||||
// Account is a sub-type for account overview
|
||||
type Account struct {
|
||||
ID string `json:"id"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
Hold float64 `json:"hold,string"`
|
||||
FundedAmount float64 `json:"funded_amount,string"`
|
||||
DefaultAmount float64 `json:"default_amount,string"`
|
||||
}
|
||||
|
||||
// PaymentMethod holds payment method information
|
||||
type PaymentMethod struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Currency string `json:"currency"`
|
||||
PrimaryBuy bool `json:"primary_buy"`
|
||||
PrimarySell bool `json:"primary_sell"`
|
||||
AllowBuy bool `json:"allow_buy"`
|
||||
AllowSell bool `json:"allow_sell"`
|
||||
AllowDeposits bool `json:"allow_deposits"`
|
||||
AllowWithdraw bool `json:"allow_withdraw"`
|
||||
Limits struct {
|
||||
Buy []LimitInfo `json:"buy"`
|
||||
InstantBuy []LimitInfo `json:"instant_buy"`
|
||||
Sell []LimitInfo `json:"sell"`
|
||||
Deposit []LimitInfo `json:"deposit"`
|
||||
} `json:"limits"`
|
||||
}
|
||||
|
||||
// LimitInfo is a sub-type for payment method
|
||||
type LimitInfo struct {
|
||||
PeriodInDays int `json:"period_in_days"`
|
||||
Total struct {
|
||||
Amount float64 `json:"amount,string"`
|
||||
Currency string `json:"currency"`
|
||||
} `json:"total"`
|
||||
}
|
||||
|
||||
// DepositWithdrawalInfo holds returned deposit information
|
||||
type DepositWithdrawalInfo struct {
|
||||
ID string `json:"id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Currency string `json:"currency"`
|
||||
PayoutAt string `json:"payout_at"`
|
||||
}
|
||||
|
||||
// CoinbaseAccounts holds coinbase account information
|
||||
type CoinbaseAccounts struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
Currency string `json:"currency"`
|
||||
Type string `json:"type"`
|
||||
Primary bool `json:"primary"`
|
||||
Active bool `json:"active"`
|
||||
WireDepositInformation struct {
|
||||
AccountNumber string `json:"account_number"`
|
||||
RoutingNumber string `json:"routing_number"`
|
||||
BankName string `json:"bank_name"`
|
||||
BankAddress string `json:"bank_address"`
|
||||
BankCountry struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
} `json:"bank_country"`
|
||||
AccountName string `json:"account_name"`
|
||||
AccountAddress string `json:"account_address"`
|
||||
Reference string `json:"reference"`
|
||||
} `json:"wire_deposit_information"`
|
||||
SepaDepositInformation struct {
|
||||
Iban string `json:"iban"`
|
||||
Swift string `json:"swift"`
|
||||
BankName string `json:"bank_name"`
|
||||
BankAddress string `json:"bank_address"`
|
||||
BankCountryName string `json:"bank_country_name"`
|
||||
AccountName string `json:"account_name"`
|
||||
AccountAddress string `json:"account_address"`
|
||||
Reference string `json:"reference"`
|
||||
} `json:"sep_deposit_information"`
|
||||
}
|
||||
|
||||
// Report holds historical information
|
||||
type Report struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
@@ -159,12 +282,71 @@ type GDAXReportResponse struct {
|
||||
} `json:"params"`
|
||||
}
|
||||
|
||||
type GDAXWebsocketSubscribe struct {
|
||||
// Volume type contains trailing volume information
|
||||
type Volume struct {
|
||||
ProductID string `json:"product_id"`
|
||||
ExchangeVolume float64 `json:"exchange_volume,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
RecordedAt string `json:"recorded_at"`
|
||||
}
|
||||
|
||||
// OrderL1L2 is a type used in layer conversion
|
||||
type OrderL1L2 struct {
|
||||
Price float64
|
||||
Amount float64
|
||||
NumOrders float64
|
||||
}
|
||||
|
||||
// OrderL3 is a type used in layer conversion
|
||||
type OrderL3 struct {
|
||||
Price float64
|
||||
Amount float64
|
||||
OrderID string
|
||||
}
|
||||
|
||||
// OrderbookL1L2 holds level 1 and 2 order book information
|
||||
type OrderbookL1L2 struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
Bids []OrderL1L2 `json:"bids"`
|
||||
Asks []OrderL1L2 `json:"asks"`
|
||||
}
|
||||
|
||||
// OrderbookL3 holds level 3 order book information
|
||||
type OrderbookL3 struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
Bids []OrderL3 `json:"bids"`
|
||||
Asks []OrderL3 `json:"asks"`
|
||||
}
|
||||
|
||||
// OrderbookResponse is a generalized response for order books
|
||||
type OrderbookResponse struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
Bids [][]interface{} `json:"bids"`
|
||||
Asks [][]interface{} `json:"asks"`
|
||||
}
|
||||
|
||||
// FillResponse contains fill information from the exchange
|
||||
type FillResponse struct {
|
||||
TradeID int `json:"trade_id"`
|
||||
ProductID string `json:"product_id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
OrderID string `json:"order_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Liquidity string `json:"liquidity"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Settled bool `json:"settled"`
|
||||
Side string `json:"side"`
|
||||
}
|
||||
|
||||
// WebsocketSubscribe takes in subscription information
|
||||
type WebsocketSubscribe struct {
|
||||
Type string `json:"type"`
|
||||
ProductID string `json:"product_id"`
|
||||
}
|
||||
|
||||
type GDAXWebsocketReceived struct {
|
||||
// WebsocketReceived holds websocket received values
|
||||
type WebsocketReceived struct {
|
||||
Type string `json:"type"`
|
||||
Time string `json:"time"`
|
||||
Sequence int `json:"sequence"`
|
||||
@@ -174,7 +356,8 @@ type GDAXWebsocketReceived struct {
|
||||
Side string `json:"side"`
|
||||
}
|
||||
|
||||
type GDAXWebsocketOpen struct {
|
||||
// WebsocketOpen collates open orders
|
||||
type WebsocketOpen struct {
|
||||
Type string `json:"type"`
|
||||
Time string `json:"time"`
|
||||
Sequence int `json:"sequence"`
|
||||
@@ -184,7 +367,8 @@ type GDAXWebsocketOpen struct {
|
||||
Side string `json:"side"`
|
||||
}
|
||||
|
||||
type GDAXWebsocketDone struct {
|
||||
// WebsocketDone holds finished order information
|
||||
type WebsocketDone struct {
|
||||
Type string `json:"type"`
|
||||
Time string `json:"time"`
|
||||
Sequence int `json:"sequence"`
|
||||
@@ -195,7 +379,8 @@ type GDAXWebsocketDone struct {
|
||||
RemainingSize float64 `json:"remaining_size,string"`
|
||||
}
|
||||
|
||||
type GDAXWebsocketMatch struct {
|
||||
// WebsocketMatch holds match information
|
||||
type WebsocketMatch struct {
|
||||
Type string `json:"type"`
|
||||
TradeID int `json:"trade_id"`
|
||||
Sequence int `json:"sequence"`
|
||||
@@ -207,7 +392,8 @@ type GDAXWebsocketMatch struct {
|
||||
Side string `json:"side"`
|
||||
}
|
||||
|
||||
type GDAXWebsocketChange struct {
|
||||
// WebsocketChange holds change information
|
||||
type WebsocketChange struct {
|
||||
Type string `json:"type"`
|
||||
Time string `json:"time"`
|
||||
Sequence int `json:"sequence"`
|
||||
|
||||
@@ -13,7 +13,7 @@ const (
|
||||
)
|
||||
|
||||
func (g *GDAX) WebsocketSubscribe(product string, conn *websocket.Conn) error {
|
||||
subscribe := GDAXWebsocketSubscribe{"subscribe", product}
|
||||
subscribe := WebsocketSubscribe{"subscribe", product}
|
||||
json, err := common.JSONEncode(subscribe)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -82,35 +82,35 @@ func (g *GDAX) WebsocketClient() {
|
||||
log.Println(string(resp))
|
||||
break
|
||||
case "received":
|
||||
received := GDAXWebsocketReceived{}
|
||||
received := WebsocketReceived{}
|
||||
err := common.JSONDecode(resp, &received)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
case "open":
|
||||
open := GDAXWebsocketOpen{}
|
||||
open := WebsocketOpen{}
|
||||
err := common.JSONDecode(resp, &open)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
case "done":
|
||||
done := GDAXWebsocketDone{}
|
||||
done := WebsocketDone{}
|
||||
err := common.JSONDecode(resp, &done)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
case "match":
|
||||
match := GDAXWebsocketMatch{}
|
||||
match := WebsocketMatch{}
|
||||
err := common.JSONDecode(resp, &match)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
case "change":
|
||||
change := GDAXWebsocketChange{}
|
||||
change := WebsocketChange{}
|
||||
err := common.JSONDecode(resp, &change)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
|
||||
@@ -113,7 +113,7 @@ func (g *GDAX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
obNew := orderbookNew.(GDAXOrderbookL1L2)
|
||||
obNew := orderbookNew.(OrderbookL1L2)
|
||||
|
||||
for x := range obNew.Bids {
|
||||
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: obNew.Bids[x].Amount, Price: obNew.Bids[x].Price})
|
||||
|
||||
@@ -3,6 +3,7 @@ package nonce
|
||||
import (
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Nonce struct holds the nonce value
|
||||
@@ -47,3 +48,15 @@ func (n *Nonce) String() string {
|
||||
n.mtx.Unlock()
|
||||
return result
|
||||
}
|
||||
|
||||
// Evaluate returns a nonce while evaluating in a single locked call
|
||||
func (n *Nonce) Evaluate() string {
|
||||
n.mtx.Lock()
|
||||
defer n.mtx.Unlock()
|
||||
if n.n == 0 {
|
||||
n.n = time.Now().Unix()
|
||||
return strconv.FormatInt(n.n, 10)
|
||||
}
|
||||
n.n = n.n + 1
|
||||
return strconv.FormatInt(n.n, 10)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user