From 82c5e411bc17136e10491d186a478023b7f66666 Mon Sep 17 00:00:00 2001 From: Mario Arranz Date: Thu, 2 May 2024 09:49:16 +0200 Subject: [PATCH] Add BalanceEx endpoint and update deps (#51) --- .golangci.yml | 1 - go.mod | 9 +++--- go.sum | 23 ++++++-------- rest/private_methods.go | 9 ++++++ rest/private_methods_test.go | 61 ++++++++++++++++++++++++++++++++++++ rest/responses.go | 12 +++++-- 6 files changed, 95 insertions(+), 20 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 9fa4990..4fa4f3d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -6,7 +6,6 @@ linters: - govet - prealloc - unconvert - - deadcode - varcheck - errcheck - ineffassign diff --git a/go.mod b/go.mod index a6954ea..903074d 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,17 @@ module github.com/aopoltorzhicky/go_kraken go 1.19 require ( - github.com/gorilla/websocket v1.5.0 + github.com/gorilla/websocket v1.5.1 github.com/pkg/errors v0.9.1 github.com/shopspring/decimal v1.3.1 - github.com/sirupsen/logrus v1.9.0 - github.com/stretchr/testify v1.8.1 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.9.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/sys v0.1.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index dc9db0d..db248f9 100644 --- a/go.sum +++ b/go.sum @@ -1,28 +1,25 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/rest/private_methods.go b/rest/private_methods.go index aad2362..1bc1f4a 100644 --- a/rest/private_methods.go +++ b/rest/private_methods.go @@ -19,6 +19,15 @@ func (api *Kraken) GetAccountBalances() (map[string]decimal.Decimal, error) { return response, nil } +// GetAccountBalancesEx - methods returns account balances +func (api *Kraken) GetAccountBalancesEx() (map[string]BalanceEx, error) { + response := make(map[string]BalanceEx) + if err := api.request("BalanceEx", true, nil, &response); err != nil { + return response, err + } + return response, nil +} + // GetTradeBalance - returns tradable balances info func (api *Kraken) GetTradeBalance(baseAsset string) (TradeBalanceResponse, error) { data := url.Values{} diff --git a/rest/private_methods_test.go b/rest/private_methods_test.go index 3e7034c..9e69711 100644 --- a/rest/private_methods_test.go +++ b/rest/private_methods_test.go @@ -15,6 +15,7 @@ var ( depositMethodsJSON = []byte(`{"error":[],"result":[{"method": "Ether (Hex)","limit": false,"fee": "0.0000000000","gen-address": true}]}`) depositStatusesJSON = []byte(`{"error":[],"result":[{"method": "Ether (Hex)","aclass": "currency","asset": "XETH","refid": "sometest1","txid": "sometest2","info": "sometest3","amount": "6.91","fee": "0.0000000000","time": 1617014556,"status": "Success"}]}`) balancesJSON = []byte(`{"error":[],"result":{"ZUSD":"435.9135","USDT":"2.00000000","BSV":"0.0000053898"}}`) + balancesExJSON = []byte(`{"error":[],"result":{"ZUSD":{"balance":25435.21,"hold_trade":8249.76},"XXBT":{"balance":1.2435,"hold_trade":0.8423}}}`) tradeBalancesJSON = []byte(`{"error":[],"result":{"eb":"33.50","tb":"33.50","m":"23.77","n":"4.3750","c":"11.8999","v":"12.2","e":"32.1","mf":"33.1","ml":"12.97"}}`) openOrdersJSON = []byte(`{"error":[],"result":{"open":{"OR3XZM-5EN2R-LS5X51":{"refid":null,"userref":null,"status":"open","opentm":1570622342.3552,"starttm":0,"expiretm":0,"descr":{"pair":"XBTEUR","type":"sell","ordertype":"limit","price":"7712.2","price2":"0","leverage":"4:1","order":"sell 1.10000000 XBTEUR @ limit 7712.2 with 4:1 leverage","close":""},"vol":"1.10000000","vol_exec":"0.00000000","cost":"0.00000","fee":"0.00000","price":"0.00000","stopprice":"0.00000","limitprice":"0.00000","misc":"","oflags":"fciq"}}}}`) closedOrdersJSON = []byte(`{"error":[],"result":{"closed":{"OK46ER-A2BXK-YOLKE1":{"refid":null,"userref":null,"status":"canceled","reason":"User requested","opentm":1570623817.6537,"closetm":1570623823.9012,"starttm":0,"expiretm":0,"descr":{"pair":"ETHEUR","type":"buy","ordertype":"limit","price":"160.87","price2":"0","leverage":"4:1","order":"buy 21.00000000 ETHEUR @ limit 160.87 with 4:1 leverage","close":""},"vol":"21.00000000","vol_exec":"0.00000000","cost":"0.00000","fee":"0.00000","price":"0.00000","stopprice":"0.00000","limitprice":"0.00000","misc":"","oflags":"fciq"}},"count":20}}`) @@ -175,6 +176,66 @@ func TestKraken_GetAccountBalances(t *testing.T) { } } +func TestKraken_GetAccountBalancesEx(t *testing.T) { + tests := []struct { + name string + err error + resp *http.Response + want map[string]BalanceEx + wantErr bool + }{ + { + name: "Kraken returns error", + err: ErrSomething, + resp: &http.Response{}, + want: make(map[string]BalanceEx), + wantErr: true, + }, { + name: "Get Account Balances Ex", + err: nil, + resp: &http.Response{ + StatusCode: 200, + Body: io.NopCloser(bytes.NewReader(balancesExJSON)), + }, + want: map[string]BalanceEx{ + "ZUSD": { + Balance: decimal.NewFromFloat(25435.21), + HoldTrade: decimal.NewFromFloat(8249.76), + }, + "XXBT": { + Balance: decimal.NewFromFloat(1.2435), + HoldTrade: decimal.NewFromFloat(0.8423), + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + api := &Kraken{ + client: &httpMock{ + Error: tt.err, + Response: tt.resp, + }, + } + got, err := api.GetAccountBalancesEx() + if (err != nil) != tt.wantErr { + t.Errorf("Kraken.GetAccountBalances() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.Len(t, got, len(tt.want)) + for name, balanceEx := range got { + wantBalanceEx, ok := tt.want[name] + if !ok { + t.Errorf("Kraken.GetAccountBalances() unknown asset: %s", name) + return + } + assert.Equal(t, wantBalanceEx.Balance, balanceEx.Balance) + } + }) + } +} + func TestKraken_GetTradeBalance(t *testing.T) { tests := []struct { name string diff --git a/rest/responses.go b/rest/responses.go index 13bb943..5d19ed6 100644 --- a/rest/responses.go +++ b/rest/responses.go @@ -212,7 +212,7 @@ func (item *OHLCResponse) UnmarshalJSON(buf []byte) error { if err != nil { continue } - close, err := decimal.NewFromString(candle[4].(string)) + clse, err := decimal.NewFromString(candle[4].(string)) if err != nil { continue } @@ -229,7 +229,7 @@ func (item *OHLCResponse) UnmarshalJSON(buf []byte) error { Open: open, High: high, Low: low, - Close: close, + Close: clse, VolumeWAP: vwap, Volume: vol, Count: int64(candle[7].(float64)), @@ -530,6 +530,14 @@ type SpreadResponse struct { XZECZUSD []Spread } +// BalanceEx - balance extended +type BalanceEx struct { + Balance decimal.Decimal `json:"balance"` + Credit decimal.Decimal `json:"credit"` + CreditUsed decimal.Decimal `json:"credit_used"` + HoldTrade decimal.Decimal `json:"hold_trade"` +} + // TradeBalanceResponse - response of get trade balance request type TradeBalanceResponse struct { EquivalentBalance float64 `json:"eb,string"`