diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000000..f7937adc377 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,83 @@ +run: + deadline: 30s + issues-exit-code: 1 + tests: true + skip-dirs: + - vendor + - web + - testdata + +linters: + disable-all: true + enable: +# defaults + - govet +# - errcheck + - staticcheck +# - unused + - gosimple + - structcheck +# - varcheck + - ineffassign +# - deadcode + - typecheck + - goimports + - govet + +# disabled by default linters + - golint + - stylecheck + - gosec +# - interfacer + - unconvert +# - dupl + - goconst +# - gocyclo + - gofmt + - goimports +# - maligned + - depguard + - misspell +# - lll + - unparam + - nakedret +# - prealloc + - scopelint + - gocritic +# - gochecknoinits +# - gochecknoglobals + +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0 + goconst: + min-occurrences: 6 + depguard: + list-type: blacklist +# lll: +# line-length: 80 # NOTE: we'll enforce this at a later point + gocritic: + enabled-tags: + - performance + - style + - experimental + disabled-checks: + - wrapperFunc + - hugeParam + - importShadow + - rangeValCopy + - methodExprCall + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 + + exclude-rules: + - text: "weak cryptographic primitive" + linters: + - gosec + +service: + golangci-lint-version: 1.15.x \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index b836e806f5b..34222c8563a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ matrix: - language: go go: - - 1.11.x + - 1.12.x env: - GO111MODULE=on install: true diff --git a/Makefile b/Makefile index ae83236b3ba..693a5bf11ac 100644 --- a/Makefile +++ b/Makefile @@ -1,38 +1,15 @@ LDFLAGS = -ldflags "-w -s" GCTPKG = github.com/thrasher-/gocryptotrader -LINTPKG = gopkg.in/alecthomas/gometalinter.v2 -LINTBIN = $(GOPATH)/bin/gometalinter.v2 -ENABLELLL = false -LINTOPTS = \ - --disable-all \ - --enable=gofmt \ - --enable=vet \ - --enable=vetshadow \ - --enable=misspell \ - --enable=golint \ - --enable=ineffassign \ - --enable=goconst \ - --enable=structcheck \ - --enable=unparam \ - --enable=gosimple \ - --enable=unconvert -ifeq ($(ENABLELLL), true) -LINTOPTS += \ - --enable=lll \ - --line-length=80 -endif -LINTOPTS += \ - --deadline=5m ./... | \ - tee /dev/stderr +LINTPKG = github.com/golangci/golangci-lint/cmd/golangci-lint@v1.15.0 +LINTBIN = $(GOPATH)/bin/golangci-lint get: GO111MODULE=on go get $(GCTPKG) linter: GO111MODULE=on go get $(GCTPKG) - GO111MODULE=off go get -u $(LINTPKG) - $(LINTBIN) --install - test -z "$$($(LINTBIN) $(LINTOPTS))" + GO111MODULE=on go get $(LINTPKG) + test -z "$$($(LINTBIN) run --verbose | tee /dev/stderr)" check: linter test @@ -46,4 +23,10 @@ install: GO111MODULE=on go install $(LDFLAGS) fmt: - gofmt -l -w -s $(shell find . -type f -name '*.go') \ No newline at end of file + gofmt -l -w -s $(shell find . -type f -name '*.go') + +update_deps: + GO111MODULE=on go mod verify + GO111MODULE=on go mod tidy + rm -rf vendor + GO111MODULE=on go mod vendor \ No newline at end of file diff --git a/common/common.go b/common/common.go index ea8d0532b9e..ccffdf8bc58 100644 --- a/common/common.go +++ b/common/common.go @@ -2,9 +2,9 @@ package common import ( "crypto/hmac" - "crypto/md5" + "crypto/md5" // nolint:gosec "crypto/rand" - "crypto/sha1" + "crypto/sha1" // nolint:gosec "crypto/sha256" "crypto/sha512" "encoding/base64" @@ -38,11 +38,11 @@ var ( // ErrNotYetImplemented defines a common error across the code base that // alerts of a function that has not been completed or tied into main code - ErrNotYetImplemented = errors.New("Not Yet Implemented") + ErrNotYetImplemented = errors.New("not yet implemented") // ErrFunctionNotSupported defines a standardised error for an unsupported // wrapper function by an API - ErrFunctionNotSupported = errors.New("Unsupported Wrapper Function") + ErrFunctionNotSupported = errors.New("unsupported wrapper function") ) // Const declarations for common.go operations @@ -91,9 +91,9 @@ func GetRandomSalt(input []byte, saltLen int) ([]byte, error) { // GetMD5 returns a MD5 hash of a byte array func GetMD5(input []byte) []byte { - hash := md5.New() - hash.Write(input) - return hash.Sum(nil) + m := md5.New() // nolint:gosec + m.Write(input) + return m.Sum(nil) } // GetSHA512 returns a SHA512 hash of a byte array @@ -113,40 +113,30 @@ func GetSHA256(input []byte) []byte { // GetHMAC returns a keyed-hash message authentication code using the desired // hashtype func GetHMAC(hashType int, input, key []byte) []byte { - var hash func() hash.Hash + var hasher func() hash.Hash switch hashType { case HashSHA1: - { - hash = sha1.New - } + hasher = sha1.New case HashSHA256: - { - hash = sha256.New - } + hasher = sha256.New case HashSHA512: - { - hash = sha512.New - } + hasher = sha512.New case HashSHA512_384: - { - hash = sha512.New384 - } + hasher = sha512.New384 case HashMD5: - { - hash = md5.New - } + hasher = md5.New } - hmac := hmac.New(hash, key) - hmac.Write(input) - return hmac.Sum(nil) + h := hmac.New(hasher, key) + h.Write(input) + return h.Sum(nil) } // Sha1ToHex takes a string, sha1 hashes it and return a hex string of the // result func Sha1ToHex(data string) string { - h := sha1.New() + h := sha1.New() // nolint:gosec h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)) } @@ -172,7 +162,7 @@ func Base64Encode(input []byte) string { // StringSliceDifference concatenates slices together based on its index and // returns an individual string array -func StringSliceDifference(slice1 []string, slice2 []string) []string { +func StringSliceDifference(slice1, slice2 []string) []string { var diff []string for i := 0; i < 2; i++ { for _, s1 := range slice1 { @@ -256,8 +246,8 @@ func TrimString(input, cutset string) string { } // ReplaceString replaces a string with another -func ReplaceString(input, old, new string, n int) string { - return strings.Replace(input, old, new, n) +func ReplaceString(input, old, newStr string, n int) string { + return strings.Replace(input, old, newStr, n) } // StringToUpper changes strings to uppercase @@ -312,7 +302,7 @@ func IsValidCryptoAddress(address, crypto string) (bool, error) { case "eth": return regexp.MatchString("^0x[a-km-z0-9]{40}$", address) default: - return false, errors.New("Invalid crypto currency") + return false, errors.New("invalid crypto currency") } } @@ -353,7 +343,7 @@ func CalculateNetProfit(amount, priceThen, priceNow, costs float64) float64 { // SendHTTPRequest sends a request using the http package and returns a response // as a string and an error -func SendHTTPRequest(method, path string, headers map[string]string, body io.Reader) (string, error) { +func SendHTTPRequest(method, urlPath string, headers map[string]string, body io.Reader) (string, error) { result := strings.ToUpper(method) if result != http.MethodPost && result != http.MethodGet && result != http.MethodDelete { @@ -362,7 +352,7 @@ func SendHTTPRequest(method, path string, headers map[string]string, body io.Rea initialiseHTTPClient() - req, err := http.NewRequest(method, path, body) + req, err := http.NewRequest(method, urlPath, body) if err != nil { return "", err } @@ -389,14 +379,14 @@ func SendHTTPRequest(method, path string, headers map[string]string, body io.Rea // SendHTTPGetRequest sends a simple get request using a url string & JSON // decodes the response into a struct pointer you have supplied. Returns an error // on failure. -func SendHTTPGetRequest(url string, jsonDecode, isVerbose bool, result interface{}) error { +func SendHTTPGetRequest(urlPath string, jsonDecode, isVerbose bool, result interface{}) error { if isVerbose { - log.Debugf("Raw URL: %s", url) + log.Debugf("Raw URL: %s", urlPath) } initialiseHTTPClient() - res, err := HTTPClient.Get(url) + res, err := HTTPClient.Get(urlPath) if err != nil { return err } @@ -411,7 +401,7 @@ func SendHTTPGetRequest(url string, jsonDecode, isVerbose bool, result interface } if isVerbose { - log.Debugf("Raw Resp: %s", string(contents[:])) + log.Debugf("Raw Resp: %s", string(contents)) } defer res.Body.Close() @@ -441,12 +431,12 @@ func JSONDecode(data []byte, to interface{}) error { // EncodeURLValues concatenates url values onto a url string and returns a // string -func EncodeURLValues(url string, values url.Values) string { - path := url +func EncodeURLValues(urlPath string, values url.Values) string { + u := urlPath if len(values) > 0 { - path += "?" + values.Encode() + u += "?" + values.Encode() } - return path + return u } // ExtractHost returns the hostname out of a string @@ -466,16 +456,16 @@ func ExtractPort(host string) int { } // OutputCSV dumps data into a file as comma-separated values -func OutputCSV(path string, data [][]string) error { - _, err := ReadFile(path) +func OutputCSV(filePath string, data [][]string) error { + _, err := ReadFile(filePath) if err != nil { - errTwo := WriteFile(path, nil) + errTwo := WriteFile(filePath, nil) if errTwo != nil { return errTwo } } - file, err := os.Create(path) + file, err := os.Create(filePath) if err != nil { return err } @@ -508,8 +498,8 @@ func UnixTimestampStrToTime(timeStr string) (time.Time, error) { } // ReadFile reads a file and returns read data as byte array. -func ReadFile(path string) ([]byte, error) { - return ioutil.ReadFile(path) +func ReadFile(file string) ([]byte, error) { + return ioutil.ReadFile(file) } // WriteFile writes selected data to a file and returns an error @@ -570,7 +560,7 @@ func FloatFromString(raw interface{}) (float64, error) { } flt, err := strconv.ParseFloat(str, 64) if err != nil { - return 0, fmt.Errorf("Could not convert value: %s Error: %s", str, err) + return 0, fmt.Errorf("could not convert value: %s Error: %s", str, err) } return flt, nil } diff --git a/common/common_test.go b/common/common_test.go index fbe2aae8e7d..90a796c4d2b 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -2,7 +2,6 @@ package common import ( "bytes" - "fmt" "net/url" "reflect" "strings" @@ -579,12 +578,12 @@ func TestSendHTTPGetRequest(t *testing.T) { TotalOut int `json:"totalOut"` } `json:"ETH"` } - url := `https://api.ethplorer.io/getAddressInfo/0xff71cb760666ab06aa73f34995b42dd4b85ea07b?apiKey=freekey` + ethURL := `https://api.ethplorer.io/getAddressInfo/0xff71cb760666ab06aa73f34995b42dd4b85ea07b?apiKey=freekey` result := test{} var badresult int - err := SendHTTPGetRequest(url, true, true, &result) + err := SendHTTPGetRequest(ethURL, true, true, &result) if err != nil { t.Errorf("Test failed - common SendHTTPGetRequest error: %s", err) } @@ -592,7 +591,7 @@ func TestSendHTTPGetRequest(t *testing.T) { if err == nil { t.Error("Test failed - common SendHTTPGetRequest error") } - err = SendHTTPGetRequest(url, false, false, &result) + err = SendHTTPGetRequest(ethURL, false, false, &result) if err != nil { t.Errorf("Test failed - common SendHTTPGetRequest error: %s", err) } @@ -600,7 +599,7 @@ func TestSendHTTPGetRequest(t *testing.T) { if err == nil { t.Error("Test failed = common SendHTTPGetRequest error: Ignored unexpected status code") } - err = SendHTTPGetRequest(url, true, false, &badresult) + err = SendHTTPGetRequest(ethURL, true, false, &badresult) if err == nil { t.Error("Test failed - common SendHTTPGetRequest error: Unmarshalled into bad type") } @@ -663,11 +662,8 @@ func TestJSONDecode(t *testing.T) { func TestEncodeURLValues(t *testing.T) { urlstring := "https://www.test.com" - expectedOutput := `https://www.test.com?env=TEST%2FDATABASE&format=json&q=SELECT+%2A+from+yahoo.finance.xchange+WHERE+pair+in+%28%22BTC%2CUSD%22%29` + expectedOutput := `https://www.test.com?env=TEST%2FDATABASE&format=json` values := url.Values{} - values.Set("q", fmt.Sprintf( - "SELECT * from yahoo.finance.xchange WHERE pair in (\"%s\")", "BTC,USD"), - ) values.Set("format", "json") values.Set("env", "TEST/DATABASE") @@ -718,8 +714,7 @@ func TestOutputCSV(t *testing.T) { data := [][]string{} rowOne := []string{"Appended", "to", "two", "dimensional", "array"} rowTwo := []string{"Appended", "to", "two", "dimensional", "array", "two"} - data = append(data, rowOne) - data = append(data, rowTwo) + data = append(data, rowOne, rowTwo) err := OutputCSV(path, data) if err != nil { diff --git a/communications/base/base.go b/communications/base/base.go index 13541bf2039..19fc2ef1c43 100644 --- a/communications/base/base.go +++ b/communications/base/base.go @@ -9,7 +9,7 @@ import ( "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) -//global vars contain staged update data that will be sent to the communication +// global vars contain staged update data that will be sent to the communication // mediums var ( TickerStaged map[string]map[string]map[string]ticker.Price @@ -92,9 +92,9 @@ func (b *Base) GetTicker(exchangeName string) string { } var tickerPrices []ticker.Price - for _, x := range tickerPrice { - for _, y := range x { - tickerPrices = append(tickerPrices, y) + for x := range tickerPrice { + for y := range tickerPrice[x] { + tickerPrices = append(tickerPrices, tickerPrice[x][y]) } } diff --git a/communications/base/base_interface.go b/communications/base/base_interface.go index 9762074f08a..a02ae7d6a40 100644 --- a/communications/base/base_interface.go +++ b/communications/base/base_interface.go @@ -14,7 +14,7 @@ type IComm []ICommunicate // ICommunicate enforces standard functions across communication packages type ICommunicate interface { - Setup(config config.CommunicationsConfig) + Setup(config *config.CommunicationsConfig) Connect() error PushEvent(Event) error IsEnabled() bool @@ -68,7 +68,7 @@ func (c IComm) GetEnabledCommunicationMediums() { } // StageTickerData stages updated ticker data for the communications package -func (c IComm) StageTickerData(exchangeName, assetType string, tickerPrice ticker.Price) { +func (c IComm) StageTickerData(exchangeName, assetType string, tickerPrice *ticker.Price) { m.Lock() defer m.Unlock() @@ -80,12 +80,12 @@ func (c IComm) StageTickerData(exchangeName, assetType string, tickerPrice ticke TickerStaged[exchangeName][assetType] = make(map[string]ticker.Price) } - TickerStaged[exchangeName][assetType][tickerPrice.CurrencyPair] = tickerPrice + TickerStaged[exchangeName][assetType][tickerPrice.CurrencyPair] = *tickerPrice } // StageOrderbookData stages updated orderbook data for the communications // package -func (c IComm) StageOrderbookData(exchangeName, assetType string, orderbook orderbook.Base) { +func (c IComm) StageOrderbookData(exchangeName, assetType string, ob *orderbook.Base) { m.Lock() defer m.Unlock() @@ -97,12 +97,12 @@ func (c IComm) StageOrderbookData(exchangeName, assetType string, orderbook orde OrderbookStaged[exchangeName][assetType] = make(map[string]Orderbook) } - _, totalAsks := orderbook.CalculateTotalAsks() - _, totalBids := orderbook.CalculateTotalBids() + _, totalAsks := ob.CalculateTotalAsks() + _, totalBids := ob.CalculateTotalBids() - OrderbookStaged[exchangeName][assetType][orderbook.CurrencyPair] = Orderbook{ - CurrencyPair: orderbook.CurrencyPair, + OrderbookStaged[exchangeName][assetType][ob.CurrencyPair] = Orderbook{ + CurrencyPair: ob.CurrencyPair, TotalAsks: totalAsks, TotalBids: totalBids, - LastUpdated: orderbook.LastUpdated.String()} + LastUpdated: ob.LastUpdated.String()} } diff --git a/communications/communications.go b/communications/communications.go index ef4bba067b4..df93e493d70 100644 --- a/communications/communications.go +++ b/communications/communications.go @@ -15,30 +15,30 @@ type Communications struct { } // NewComm sets up and returns a pointer to a Communications object -func NewComm(config config.CommunicationsConfig) *Communications { +func NewComm(cfg *config.CommunicationsConfig) *Communications { var comm Communications - if config.TelegramConfig.Enabled { + if cfg.TelegramConfig.Enabled { Telegram := new(telegram.Telegram) - Telegram.Setup(config) + Telegram.Setup(cfg) comm.IComm = append(comm.IComm, Telegram) } - if config.SMSGlobalConfig.Enabled { + if cfg.SMSGlobalConfig.Enabled { SMSGlobal := new(smsglobal.SMSGlobal) - SMSGlobal.Setup(config) + SMSGlobal.Setup(cfg) comm.IComm = append(comm.IComm, SMSGlobal) } - if config.SMTPConfig.Enabled { + if cfg.SMTPConfig.Enabled { SMTP := new(smtpservice.SMTPservice) - SMTP.Setup(config) + SMTP.Setup(cfg) comm.IComm = append(comm.IComm, SMTP) } - if config.SlackConfig.Enabled { + if cfg.SlackConfig.Enabled { Slack := new(slack.Slack) - Slack.Setup(config) + Slack.Setup(cfg) comm.IComm = append(comm.IComm, Slack) } diff --git a/communications/communications_test.go b/communications/communications_test.go index 3a3d1634685..04e1c632eda 100644 --- a/communications/communications_test.go +++ b/communications/communications_test.go @@ -7,19 +7,19 @@ import ( ) func TestNewComm(t *testing.T) { - var config config.CommunicationsConfig - communications := NewComm(config) + var cfg config.CommunicationsConfig + communications := NewComm(&cfg) if len(communications.IComm) != 0 { t.Errorf("Test failed, communications NewComm, expected len 0, got len %d", len(communications.IComm)) } - config.TelegramConfig.Enabled = true - config.SMSGlobalConfig.Enabled = true - config.SMTPConfig.Enabled = true - config.SlackConfig.Enabled = true - communications = NewComm(config) + cfg.TelegramConfig.Enabled = true + cfg.SMSGlobalConfig.Enabled = true + cfg.SMTPConfig.Enabled = true + cfg.SlackConfig.Enabled = true + communications = NewComm(&cfg) if len(communications.IComm) != 4 { t.Errorf("Test failed, communications NewComm, expected len 4, got len %d", diff --git a/communications/slack/slack.go b/communications/slack/slack.go index 35e90aff6cb..0f322f26be2 100644 --- a/communications/slack/slack.go +++ b/communications/slack/slack.go @@ -59,12 +59,12 @@ type Slack struct { // Setup takes in a slack configuration, sets bots target channel and // sets verification token to access workspace -func (s *Slack) Setup(config config.CommunicationsConfig) { - s.Name = config.SlackConfig.Name - s.Enabled = config.SlackConfig.Enabled - s.Verbose = config.SlackConfig.Verbose - s.TargetChannel = config.SlackConfig.TargetChannel - s.VerificationToken = config.SlackConfig.VerificationToken +func (s *Slack) Setup(cfg *config.CommunicationsConfig) { + s.Name = cfg.SlackConfig.Name + s.Enabled = cfg.SlackConfig.Enabled + s.Verbose = cfg.SlackConfig.Verbose + s.TargetChannel = cfg.SlackConfig.TargetChannel + s.VerificationToken = cfg.SlackConfig.VerificationToken } // Connect connects to the service @@ -92,9 +92,9 @@ func (s *Slack) GetChannelsString() []string { } // GetUsernameByID returns a users name by ID -func (s *Slack) GetUsernameByID(ID string) string { +func (s *Slack) GetUsernameByID(id string) string { for i := range s.Details.Users { - if s.Details.Users[i].ID == ID { + if s.Details.Users[i].ID == id { return s.Details.Users[i].Name } } @@ -117,7 +117,7 @@ func (s *Slack) GetGroupIDByName(group string) (string, error) { return s.Details.Groups[i].ID, nil } } - return "", errors.New("Channel not found") + return "", errors.New("channel not found") } // GetChannelIDByName returns a channel ID by its corresponding name @@ -127,7 +127,7 @@ func (s *Slack) GetChannelIDByName(channel string) (string, error) { return s.Details.Channels[i].ID, nil } } - return "", errors.New("Channel not found") + return "", errors.New("channel not found") } // GetUsersInGroup returns a list of users currently in a group @@ -263,7 +263,7 @@ func (s *Slack) handlePresenceChange(resp []byte) error { func (s *Slack) handleMessageResponse(resp []byte, data WebsocketResponse) error { if data.ReplyTo != 0 { - return fmt.Errorf("ReplyTo != 0") + return errors.New("reply to is != 0") } var msg Message err := common.JSONDecode(resp, &msg) @@ -276,7 +276,7 @@ func (s *Slack) handleMessageResponse(resp []byte, data WebsocketResponse) error msg.User, msg.Text) } if string(msg.Text[0]) == "!" { - return s.HandleMessage(msg) + return s.HandleMessage(&msg) } return nil } @@ -287,7 +287,7 @@ func (s *Slack) handleErrorResponse(data WebsocketResponse) error { } if s.WebsocketConn == nil { - return errors.New("Websocket connection is nil") + return errors.New("websocket connection is nil") } if err := s.WebsocketConn.Close(); err != nil { @@ -298,7 +298,7 @@ func (s *Slack) handleErrorResponse(data WebsocketResponse) error { s.Connected = false return s.NewConnection() } - return fmt.Errorf("Unknown error '%s'", data.Error.Msg) + return fmt.Errorf("unknown error '%s'", data.Error.Msg) } func (s *Slack) handleHelloResponse() { @@ -352,13 +352,17 @@ func (s *Slack) WebsocketSend(eventType, text string) error { return err } if s.WebsocketConn == nil { - return errors.New("Websocket not connected") + return errors.New("websocket not connected") } return s.WebsocketConn.WriteMessage(websocket.TextMessage, data) } // HandleMessage handles incoming messages and/or commands from slack -func (s *Slack) HandleMessage(msg Message) error { +func (s *Slack) HandleMessage(msg *Message) error { + if msg == nil { + return errors.New("msg is nil") + } + msg.Text = common.StringToLower(msg.Text) switch { case common.StringContains(msg.Text, cmdStatus): diff --git a/communications/slack/slack_test.go b/communications/slack/slack_test.go index d8efa1a5446..fb2c50890b1 100644 --- a/communications/slack/slack_test.go +++ b/communications/slack/slack_test.go @@ -43,7 +43,8 @@ func TestSetup(t *testing.T) { cfg := config.GetConfig() cfg.LoadConfig(config.ConfigTestFile) - s.Setup(cfg.GetCommunicationsConfig()) + commsCfg := cfg.GetCommunicationsConfig() + s.Setup(&commsCfg) s.Verbose = true } @@ -103,7 +104,7 @@ func TestGetChannelsString(t *testing.T) { func TestGetUsernameByID(t *testing.T) { username := s.GetUsernameByID("1337") - if len(username) != 0 { + if username != "" { t.Error("test failed - slack GetUsernameByID() error") } @@ -144,7 +145,7 @@ func TestGetUsernameByID(t *testing.T) { func TestGetIDByName(t *testing.T) { id, err := s.GetIDByName("batman") - if err == nil || len(id) != 0 { + if err == nil || id != "" { t.Error("test failed - slack GetIDByName() error") } @@ -161,7 +162,7 @@ func TestGetIDByName(t *testing.T) { func TestGetGroupIDByName(t *testing.T) { id, err := s.GetGroupIDByName("batman") - if err == nil || len(id) != 0 { + if err == nil || id != "" { t.Error("test failed - slack GetGroupIDByName() error") } @@ -179,7 +180,7 @@ func TestGetGroupIDByName(t *testing.T) { func TestGetChannelIDByName(t *testing.T) { id, err := s.GetChannelIDByName("1337") - if err == nil || len(id) != 0 { + if err == nil || id != "" { t.Error("test failed - slack GetChannelIDByName() error") } @@ -264,7 +265,7 @@ func TestHandleMessageResponse(t *testing.T) { data.ReplyTo = 1 err := s.handleMessageResponse(nil, data) - if err.Error() != "ReplyTo != 0" { + if err.Error() != "reply to is != 0" { t.Errorf("test failed - slack handleMessageResponse(), Incorrect Error: %s", err) } @@ -341,7 +342,7 @@ func TestWebsocketSend(t *testing.T) { } func TestHandleMessage(t *testing.T) { - var msg Message + msg := &Message{} err := s.HandleMessage(msg) if err == nil { diff --git a/communications/smsglobal/smsglobal.go b/communications/smsglobal/smsglobal.go index a359ee00820..2d23c44ea78 100644 --- a/communications/smsglobal/smsglobal.go +++ b/communications/smsglobal/smsglobal.go @@ -33,20 +33,20 @@ type SMSGlobal struct { // Setup takes in a SMSGlobal configuration, sets username, password and // and recipient list -func (s *SMSGlobal) Setup(config config.CommunicationsConfig) { - s.Name = config.SMSGlobalConfig.Name - s.Enabled = config.SMSGlobalConfig.Enabled - s.Verbose = config.SMSGlobalConfig.Verbose - s.Username = config.SMSGlobalConfig.Username - s.Password = config.SMSGlobalConfig.Password +func (s *SMSGlobal) Setup(cfg *config.CommunicationsConfig) { + s.Name = cfg.SMSGlobalConfig.Name + s.Enabled = cfg.SMSGlobalConfig.Enabled + s.Verbose = cfg.SMSGlobalConfig.Verbose + s.Username = cfg.SMSGlobalConfig.Username + s.Password = cfg.SMSGlobalConfig.Password var contacts []Contact - for x := range config.SMSGlobalConfig.Contacts { + for x := range cfg.SMSGlobalConfig.Contacts { contacts = append(contacts, Contact{ - Name: config.SMSGlobalConfig.Contacts[x].Name, - Number: config.SMSGlobalConfig.Contacts[x].Number, - Enabled: config.SMSGlobalConfig.Contacts[x].Enabled, + Name: cfg.SMSGlobalConfig.Contacts[x].Name, + Number: cfg.SMSGlobalConfig.Contacts[x].Number, + Enabled: cfg.SMSGlobalConfig.Contacts[x].Enabled, }, ) } diff --git a/communications/smsglobal/smsglobal_test.go b/communications/smsglobal/smsglobal_test.go index fe8051a4fd8..8344e6ffaad 100644 --- a/communications/smsglobal/smsglobal_test.go +++ b/communications/smsglobal/smsglobal_test.go @@ -13,7 +13,8 @@ var s SMSGlobal func TestSetup(t *testing.T) { cfg := config.GetConfig() cfg.LoadConfig("../../testdata/configtest.json") - s.Setup(cfg.GetCommunicationsConfig()) + commsCfg := cfg.GetCommunicationsConfig() + s.Setup(&commsCfg) } func TestConnect(t *testing.T) { diff --git a/communications/smtpservice/smtpservice.go b/communications/smtpservice/smtpservice.go index e6e35af69e8..79a46264c46 100644 --- a/communications/smtpservice/smtpservice.go +++ b/communications/smtpservice/smtpservice.go @@ -27,15 +27,15 @@ type SMTPservice struct { // Setup takes in a SMTP configuration and sets SMTP server details and // recipient list -func (s *SMTPservice) Setup(config config.CommunicationsConfig) { - s.Name = config.SMTPConfig.Name - s.Enabled = config.SMTPConfig.Enabled - s.Verbose = config.SMTPConfig.Verbose - s.Host = config.SMTPConfig.Host - s.Port = config.SMTPConfig.Port - s.AccountName = config.SMTPConfig.AccountName - s.AccountPassword = config.SMTPConfig.AccountPassword - s.RecipientList = config.SMTPConfig.RecipientList +func (s *SMTPservice) Setup(cfg *config.CommunicationsConfig) { + s.Name = cfg.SMTPConfig.Name + s.Enabled = cfg.SMTPConfig.Enabled + s.Verbose = cfg.SMTPConfig.Verbose + s.Host = cfg.SMTPConfig.Host + s.Port = cfg.SMTPConfig.Port + s.AccountName = cfg.SMTPConfig.AccountName + s.AccountPassword = cfg.SMTPConfig.AccountPassword + s.RecipientList = cfg.SMTPConfig.RecipientList } // Connect connects to service diff --git a/communications/smtpservice/smtpservice_test.go b/communications/smtpservice/smtpservice_test.go index 0e8002e7922..0788541f5ea 100644 --- a/communications/smtpservice/smtpservice_test.go +++ b/communications/smtpservice/smtpservice_test.go @@ -12,7 +12,8 @@ var s SMTPservice func TestSetup(t *testing.T) { cfg := config.GetConfig() cfg.LoadConfig("../../testdata/configtest.json") - s.Setup(cfg.GetCommunicationsConfig()) + commsCfg := cfg.GetCommunicationsConfig() + s.Setup(&commsCfg) } func TestConnect(t *testing.T) { diff --git a/communications/telegram/telegram.go b/communications/telegram/telegram.go index e442fc3a31c..8fbdd83ad56 100644 --- a/communications/telegram/telegram.go +++ b/communications/telegram/telegram.go @@ -52,11 +52,11 @@ type Telegram struct { } // Setup takes in a Telegram configuration and sets verification token -func (t *Telegram) Setup(config config.CommunicationsConfig) { - t.Name = config.TelegramConfig.Name - t.Enabled = config.TelegramConfig.Enabled - t.Token = config.TelegramConfig.VerificationToken - t.Verbose = config.TelegramConfig.Verbose +func (t *Telegram) Setup(cfg *config.CommunicationsConfig) { + t.Name = cfg.TelegramConfig.Name + t.Enabled = cfg.TelegramConfig.Enabled + t.Token = cfg.TelegramConfig.VerificationToken + t.Verbose = cfg.TelegramConfig.Verbose } // Connect starts an initial connection diff --git a/communications/telegram/telegram_test.go b/communications/telegram/telegram_test.go index ef658bdab27..277439badc1 100644 --- a/communications/telegram/telegram_test.go +++ b/communications/telegram/telegram_test.go @@ -7,12 +7,17 @@ import ( "github.com/thrasher-/gocryptotrader/config" ) +const ( + testErrNotFound = "Not Found" +) + var T Telegram func TestSetup(t *testing.T) { cfg := config.GetConfig() cfg.LoadConfig("../../testdata/configtest.json") - T.Setup(cfg.GetCommunicationsConfig()) + commsCfg := cfg.GetCommunicationsConfig() + T.Setup(&commsCfg) if T.Name != "Telegram" || T.Enabled || T.Token != "testest" || T.Verbose { t.Error("test failed - telegram Setup() error, unexpected setup values", @@ -34,7 +39,7 @@ func TestPushEvent(t *testing.T) { } T.AuthorisedClients = append(T.AuthorisedClients, 1337) err = T.PushEvent(base.Event{}) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram PushEvent() error, expected 'Not found' got '%s'", err) } @@ -44,42 +49,42 @@ func TestHandleMessages(t *testing.T) { t.Parallel() chatID := int64(1337) err := T.HandleMessages(cmdHelp, chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } err = T.HandleMessages(cmdStart, chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } err = T.HandleMessages(cmdOrders, chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } err = T.HandleMessages(cmdStatus, chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } err = T.HandleMessages(cmdTicker, chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } err = T.HandleMessages(cmdSettings, chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } err = T.HandleMessages(cmdPortfolio, chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } err = T.HandleMessages("Not a command", chatID) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram HandleMessages() error, expected 'Not found' got '%s'", err) } @@ -96,7 +101,7 @@ func TestGetUpdates(t *testing.T) { func TestTestConnection(t *testing.T) { t.Parallel() err := T.TestConnection() - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram TestConnection() error, expected 'Not found' got '%s'", err) } @@ -105,7 +110,7 @@ func TestTestConnection(t *testing.T) { func TestSendMessage(t *testing.T) { t.Parallel() err := T.SendMessage("Test message", int64(1337)) - if err.Error() != "Not Found" { + if err.Error() != testErrNotFound { t.Errorf("test failed - telegram SendMessage() error, expected 'Not found' got '%s'", err) } diff --git a/config/config.go b/config/config.go index 457e2cd05fb..8e651c934e9 100644 --- a/config/config.go +++ b/config/config.go @@ -37,25 +37,20 @@ const ( // Constants here hold some messages const ( - ErrExchangeNameEmpty = "Exchange #%d in config: Exchange name is empty." - ErrExchangeAvailablePairsEmpty = "Exchange %s: Available pairs is empty." - ErrExchangeEnabledPairsEmpty = "Exchange %s: Enabled pairs is empty." - ErrExchangeBaseCurrenciesEmpty = "Exchange %s: Base currencies is empty." - ErrExchangeNotFound = "Exchange %s: Not found." - ErrNoEnabledExchanges = "No Exchanges enabled." - ErrCryptocurrenciesEmpty = "Cryptocurrencies variable is empty." - ErrFailureOpeningConfig = "Fatal error opening %s file. Error: %s" - ErrCheckingConfigValues = "Fatal error checking config values. Error: %s" - ErrSavingConfigBytesMismatch = "Config file %q bytes comparison doesn't match, read %s expected %s." - WarningSMSGlobalDefaultOrEmptyValues = "WARNING -- SMS Support disabled due to default or empty Username/Password values." - WarningSSMSGlobalSMSContactDefaultOrEmptyValues = "WARNING -- SMS contact #%d Name/Number disabled due to default or empty values." - WarningSSMSGlobalSMSNoContacts = "WARNING -- SMS Support disabled due to no enabled contacts." - WarningWebserverCredentialValuesEmpty = "WARNING -- Webserver support disabled due to empty Username/Password values." - WarningWebserverListenAddressInvalid = "WARNING -- Webserver support disabled due to invalid listen address." - WarningWebserverRootWebFolderNotFound = "WARNING -- Webserver support disabled due to missing web folder." - WarningExchangeAuthAPIDefaultOrEmptyValues = "WARNING -- Exchange %s: Authenticated API support disabled due to default/empty APIKey/Secret/ClientID values." - WarningCurrencyExchangeProvider = "WARNING -- Currency exchange provider invalid valid. Reset to Fixer." - WarningPairsLastUpdatedThresholdExceeded = "WARNING -- Exchange %s: Last manual update of available currency pairs has exceeded %d days. Manual update required!" + ErrExchangeNameEmpty = "exchange #%d name is empty" + ErrExchangeAvailablePairsEmpty = "exchange %s avaiable pairs is emtpy" + ErrExchangeEnabledPairsEmpty = "exchange %s enabled pairs is empty" + ErrExchangeBaseCurrenciesEmpty = "exchange %s base currencies is empty" + ErrExchangeNotFound = "exchange %s not found" + ErrNoEnabledExchanges = "no exchanges enabled" + ErrCryptocurrenciesEmpty = "cryptocurrencies variable is empty" + ErrFailureOpeningConfig = "fatal error opening %s file. Error: %s" + ErrCheckingConfigValues = "fatal error checking config values. Error: %s" + ErrSavingConfigBytesMismatch = "config file %q bytes comparison doesn't match, read %s expected %s" + WarningWebserverCredentialValuesEmpty = "webserver support disabled due to empty Username/Password values" + WarningWebserverListenAddressInvalid = "webserver support disabled due to invalid listen address" + WarningExchangeAuthAPIDefaultOrEmptyValues = "exchange %s authenticated API support disabled due to default/empty APIKey/Secret/ClientID values" + WarningPairsLastUpdatedThresholdExceeded = "exchange %s last manual update of available currency pairs has exceeded %d days. Manual update required!" ) // Constants here define unset default values displayed in the config.json @@ -257,20 +252,21 @@ func (c *Config) GetCurrencyConfig() CurrencyConfig { // GetExchangeBankAccounts returns banking details associated with an exchange // for depositing funds -func (c *Config) GetExchangeBankAccounts(exchangeName string, depositingCurrency string) (BankAccount, error) { +func (c *Config) GetExchangeBankAccounts(exchangeName, depositingCurrency string) (BankAccount, error) { m.Lock() defer m.Unlock() - for _, exch := range c.Exchanges { - if exch.Name == exchangeName { - for _, account := range exch.BankAccounts { - if common.StringContains(account.SupportedCurrencies, depositingCurrency) { - return account, nil + for x := range c.Exchanges { + if c.Exchanges[x].Name == exchangeName { + for y := range c.Exchanges[x].BankAccounts { + if common.StringContains(c.Exchanges[x].BankAccounts[y].SupportedCurrencies, + depositingCurrency) { + return c.Exchanges[x].BankAccounts[y], nil } } } } - return BankAccount{}, fmt.Errorf("Exchange %s bank details not found for %s", + return BankAccount{}, fmt.Errorf("exchange %s bank details not found for %s", exchangeName, depositingCurrency) } @@ -287,19 +283,21 @@ func (c *Config) UpdateExchangeBankAccounts(exchangeName string, bankCfg []BankA return nil } } - return fmt.Errorf("UpdateExchangeBankAccounts() error exchange %s not found", + return fmt.Errorf("exchange %s not found", exchangeName) } // GetClientBankAccounts returns banking details used for a given exchange // and currency -func (c *Config) GetClientBankAccounts(exchangeName string, targetCurrency string) (BankAccount, error) { +func (c *Config) GetClientBankAccounts(exchangeName, targetCurrency string) (BankAccount, error) { m.Lock() defer m.Unlock() - for _, bank := range c.BankAccounts { - if (common.StringContains(bank.SupportedExchanges, exchangeName) || bank.SupportedExchanges == "ALL") && common.StringContains(bank.SupportedCurrencies, targetCurrency) { - return bank, nil + for x := range c.BankAccounts { + if (common.StringContains(c.BankAccounts[x].SupportedExchanges, exchangeName) || + c.BankAccounts[x].SupportedExchanges == "ALL") && + common.StringContains(c.BankAccounts[x].SupportedCurrencies, targetCurrency) { + return c.BankAccounts[x], nil } } @@ -309,13 +307,13 @@ func (c *Config) GetClientBankAccounts(exchangeName string, targetCurrency strin } // UpdateClientBankAccounts updates the configuration for a bank -func (c *Config) UpdateClientBankAccounts(bankCfg BankAccount) error { +func (c *Config) UpdateClientBankAccounts(bankCfg *BankAccount) error { m.Lock() defer m.Unlock() for i := range c.BankAccounts { if c.BankAccounts[i].BankName == bankCfg.BankName && c.BankAccounts[i].AccountNumber == bankCfg.AccountNumber { - c.BankAccounts[i] = bankCfg + c.BankAccounts[i] = *bankCfg return nil } } @@ -378,9 +376,9 @@ func (c *Config) GetCommunicationsConfig() CommunicationsConfig { // UpdateCommunicationsConfig sets a new updated version of a Communications // configuration -func (c *Config) UpdateCommunicationsConfig(config CommunicationsConfig) { +func (c *Config) UpdateCommunicationsConfig(config *CommunicationsConfig) { m.Lock() - c.Communications = config + c.Communications = *config m.Unlock() } @@ -563,7 +561,7 @@ func (c *Config) CheckPairConsistency(exchName string) error { exchCfg.EnabledPairs = common.JoinStrings(pair.PairsToStringArray(pairs), ",") } - err = c.UpdateExchangeConfig(exchCfg) + err = c.UpdateExchangeConfig(&exchCfg) if err != nil { return err } @@ -710,12 +708,12 @@ func (c *Config) GetPrimaryForexProvider() string { } // UpdateExchangeConfig updates exchange configurations -func (c *Config) UpdateExchangeConfig(e ExchangeConfig) error { +func (c *Config) UpdateExchangeConfig(e *ExchangeConfig) error { m.Lock() defer m.Unlock() for i := range c.Exchanges { if c.Exchanges[i].Name == e.Name { - c.Exchanges[i] = e + c.Exchanges[i] = *e return nil } } @@ -769,11 +767,11 @@ func (c *Config) CheckExchangeConfigValues() error { exch.APIKey == DefaultUnsetAPIKey || exch.APISecret == DefaultUnsetAPISecret { c.Exchanges[i].AuthenticatedAPISupport = false - log.Warn(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name) + log.Warnf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name) } else if exch.Name == "ITBIT" || exch.Name == "Bitstamp" || exch.Name == "COINUT" || exch.Name == "CoinbasePro" { if exch.ClientID == "" || exch.ClientID == "ClientID" { c.Exchanges[i].AuthenticatedAPISupport = false - log.Warn(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name) + log.Warnf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name) } } } @@ -798,27 +796,32 @@ func (c *Config) CheckExchangeConfigValues() error { if len(exch.BankAccounts) == 0 { c.Exchanges[i].BankAccounts = append(c.Exchanges[i].BankAccounts, BankAccount{}) } else { - for _, bankAccount := range exch.BankAccounts { + for y := range c.Exchanges[i].BankAccounts { + bankAccount := &c.Exchanges[i].BankAccounts[y] if bankAccount.Enabled { if bankAccount.BankName == "" || bankAccount.BankAddress == "" { - return fmt.Errorf("banking details for %s is enabled but variables not set", + log.Warnf("banking details for %s is enabled but variables not set", exch.Name) + bankAccount.Enabled = false } if bankAccount.AccountName == "" || bankAccount.AccountNumber == "" { - return fmt.Errorf("banking account details for %s variables not set", + log.Warnf("banking account details for %s variables not set", exch.Name) + bankAccount.Enabled = false } if bankAccount.SupportedCurrencies == "" { - return fmt.Errorf("banking account details for %s acceptable funding currencies not set", + log.Warnf("banking account details for %s acceptable funding currencies not set", exch.Name) + bankAccount.Enabled = false } if bankAccount.BSBNumber == "" && bankAccount.IBAN == "" && bankAccount.SWIFTCode == "" { - return fmt.Errorf("banking account details for %s critical banking numbers not set", + log.Warnf("banking account details for %s critical banking numbers not set", exch.Name) + bankAccount.Enabled = false } } } @@ -954,8 +957,8 @@ func (c *Config) CheckCurrencyConfigValues() error { } } - if len(c.Currency.Cryptocurrencies) == 0 { - if len(c.Cryptocurrencies) != 0 { + if c.Currency.Cryptocurrencies == "" { + if c.Cryptocurrencies != "" { c.Currency.Cryptocurrencies = c.Cryptocurrencies c.Cryptocurrencies = "" } else { @@ -1038,7 +1041,7 @@ func (c *Config) RetrieveConfigCurrencyPairs(enabledOnly bool) error { // CheckLoggerConfig checks to see logger values are present and valid in config // if not creates a default instance of the logger -func (c *Config) CheckLoggerConfig() (err error) { +func (c *Config) CheckLoggerConfig() error { m.Lock() defer m.Unlock() @@ -1065,13 +1068,13 @@ func (c *Config) CheckLoggerConfig() (err error) { if len(c.Logging.File) > 0 { logPath := path.Join(common.GetDefaultDataDir(runtime.GOOS), "logs") - err = common.CheckDir(logPath, true) + err := common.CheckDir(logPath, true) if err != nil { - return + return err } log.LogPath = logPath } - return + return nil } // GetFilePath returns the desired config file or the default config file name @@ -1272,7 +1275,7 @@ func (c *Config) CheckConfig() error { if c.Webserver.Enabled { err = c.CheckWebserverConfigValues() if err != nil { - log.Errorf(ErrCheckingConfigValues, err) + log.Warnf(ErrCheckingConfigValues, err) c.Webserver.Enabled = false } } diff --git a/config/config_encryption.go b/config/config_encryption.go index 76c47666ce9..638fa5314e6 100644 --- a/config/config_encryption.go +++ b/config/config_encryption.go @@ -23,7 +23,7 @@ const ( // SaltRandomLength is the number of random bytes to append after the prefix string SaltRandomLength = 12 - errAESBlockSize = "The config file data is too small for the AES required block size" + errAESBlockSize = "config file data is too small for the AES required block size" ) var ( diff --git a/config/config_test.go b/config/config_test.go index 9e1cf23a1fe..c322ac970d3 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -96,12 +96,12 @@ func TestUpdateClientBankAccounts(t *testing.T) { t.Error("Test failed. UpdateClientBankAccounts LoadConfig error", err) } b := BankAccount{Enabled: false, BankName: "test", AccountNumber: "0234"} - err = cfg.UpdateClientBankAccounts(b) + err = cfg.UpdateClientBankAccounts(&b) if err != nil { t.Error("Test failed. UpdateClientBankAccounts error", err) } - err = cfg.UpdateClientBankAccounts(BankAccount{}) + err = cfg.UpdateClientBankAccounts(&BankAccount{}) if err == nil { t.Error("Test failed. UpdateClientBankAccounts error") } @@ -181,7 +181,7 @@ func TestUpdateCommunicationsConfig(t *testing.T) { if err != nil { t.Error("Test failed. UpdateCommunicationsConfig LoadConfig error", err) } - cfg.UpdateCommunicationsConfig(CommunicationsConfig{SlackConfig: SlackConfig{Name: "TEST"}}) + cfg.UpdateCommunicationsConfig(&CommunicationsConfig{SlackConfig: SlackConfig{Name: "TEST"}}) if cfg.Communications.SlackConfig.Name != "TEST" { t.Error("Test failed. UpdateCommunicationsConfig LoadConfig error") } @@ -327,7 +327,7 @@ func TestCheckPairConsistency(t *testing.T) { } tec.EnabledPairs = "DOGE_LTC,BTC_LTC" - err = cfg.UpdateExchangeConfig(tec) + err = cfg.UpdateExchangeConfig(&tec) if err != nil { t.Error("Test failed. CheckPairConsistency Update config failed, error:", err) } @@ -451,7 +451,7 @@ func TestGetDisabledExchanges(t *testing.T) { } exchCfg.Enabled = false - err = cfg.UpdateExchangeConfig(exchCfg) + err = cfg.UpdateExchangeConfig(&exchCfg) if err != nil { t.Errorf( "Test failed. TestGetDisabledExchanges. UpdateExchangeConfig Error: %s", err.Error(), @@ -495,6 +495,9 @@ func TestGetConfigCurrencyPairFormat(t *testing.T) { } exchFmt, err := cfg.GetConfigCurrencyPairFormat("Yobit") + if err != nil { + t.Errorf("Test failed. TestGetConfigCurrencyPairFormat err: %s", err) + } if !exchFmt.Uppercase || exchFmt.Delimiter != "_" { t.Errorf( "Test failed. TestGetConfigCurrencyPairFormat. Invalid values", @@ -519,6 +522,9 @@ func TestGetRequestCurrencyPairFormat(t *testing.T) { } exchFmt, err := cfg.GetRequestCurrencyPairFormat("Yobit") + if err != nil { + t.Errorf("Test failed. TestGetRequestCurrencyPairFormat. Err: %s", err) + } if exchFmt.Uppercase || exchFmt.Delimiter != "_" || exchFmt.Separator != "-" { t.Errorf( "Test failed. TestGetRequestCurrencyPairFormat. Invalid values", @@ -624,14 +630,14 @@ func TestUpdateExchangeConfig(t *testing.T) { ) } e.APIKey = "test1234" - err3 := UpdateExchangeConfig.UpdateExchangeConfig(e) + err3 := UpdateExchangeConfig.UpdateExchangeConfig(&e) if err3 != nil { t.Errorf( "Test failed. UpdateExchangeConfig.UpdateExchangeConfig: %s", err.Error(), ) } e.Name = "testyTest" - err = UpdateExchangeConfig.UpdateExchangeConfig(e) + err = UpdateExchangeConfig.UpdateExchangeConfig(&e) if err == nil { t.Error("Test failed. UpdateExchangeConfig.UpdateExchangeConfig Error") } @@ -923,7 +929,7 @@ func TestUpdateConfig(t *testing.T) { if err != nil { t.Errorf("Test failed. %s", err) } - if len(c.Currency.Cryptocurrencies) == 0 { + if c.Currency.Cryptocurrencies == "" { t.Fatalf("Test failed. Cryptocurrencies should have been repopulated") } } diff --git a/currency/coinmarketcap/coinmarketcap.go b/currency/coinmarketcap/coinmarketcap.go index 9da94681586..2ec08a6fd22 100644 --- a/currency/coinmarketcap/coinmarketcap.go +++ b/currency/coinmarketcap/coinmarketcap.go @@ -175,11 +175,11 @@ func (c *Coinmarketcap) GetCryptocurrencyHistoricalListings() ([]CryptocurrencyH // return resp.Data, err // } - // if resp.Status.ErrorCode != 0 { + //nolint:gocritic if resp.Status.ErrorCode != 0 { // return resp.Data, errors.New(resp.Status.ErrorMessage) // } - // return resp.Data, nil + //nolint:gocritic return resp.Data, nil } // GetCryptocurrencyLatestListing returns a paginated list of all diff --git a/currency/coinmarketcap/coinmarketcap_test.go b/currency/coinmarketcap/coinmarketcap_test.go index 67d35f495b9..336f8512884 100644 --- a/currency/coinmarketcap/coinmarketcap_test.go +++ b/currency/coinmarketcap/coinmarketcap_test.go @@ -251,14 +251,9 @@ func TestGetExchangeHistoricalListings(t *testing.T) { c.SetDefaults() TestSetup(t) _, err := c.GetExchangeHistoricalListings() - if areAPICredtionalsSet(Basic) { - if err == nil { - t.Error("Test Failed - GetExchangeHistoricalListings() error cannot be nil") - } - } else { - if err == nil { - t.Error("Test Failed - GetExchangeHistoricalListings() error cannot be nil") - } + if err == nil { + // TODO: update this once the feature above is implemented + t.Error("Test Failed - GetExchangeHistoricalListings() error cannot be nil") } } @@ -266,14 +261,9 @@ func TestGetExchangeLatestListings(t *testing.T) { c.SetDefaults() TestSetup(t) _, err := c.GetExchangeLatestListings() - if areAPICredtionalsSet(Basic) { - if err == nil { - t.Error("Test Failed - GetExchangeLatestListings() error cannot be nil") - } - } else { - if err == nil { - t.Error("Test Failed - GetExchangeLatestListings() error cannot be nil") - } + if err == nil { + // TODO: update this once the feature above is implemented + t.Error("Test Failed - GetExchangeHistoricalListings() error cannot be nil") } } diff --git a/currency/currency.go b/currency/currency.go index 2f4813ebaa1..68059b01f2d 100644 --- a/currency/currency.go +++ b/currency/currency.go @@ -179,7 +179,7 @@ func ConvertCurrency(amount float64, from, to string) (float64, error) { var ok bool resultFrom, ok = FXRates[baseCurr+from] if !ok { - return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", from, from, to) + return 0, fmt.Errorf("currency conversion failed. Unable to find %s in currency map [%s -> %s]", from, from, to) } return amount / resultFrom, nil } @@ -189,7 +189,7 @@ func ConvertCurrency(amount float64, from, to string) (float64, error) { var ok bool resultTo, ok = FXRates[baseCurr+to] if !ok { - return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", to, from, to) + return 0, fmt.Errorf("currency conversion failed. Unable to find %s in currency map [%s -> %s]", to, from, to) } return resultTo * amount, nil } @@ -197,13 +197,13 @@ func ConvertCurrency(amount float64, from, to string) (float64, error) { // Otherwise convert to base currency, then to the target currency resultFrom, ok := FXRates[baseCurr+from] if !ok { - return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", from, from, to) + return 0, fmt.Errorf("currency conversion failed. Unable to find %s in currency map [%s -> %s]", from, from, to) } converted := amount / resultFrom resultTo, ok = FXRates[baseCurr+to] if !ok { - return 0, fmt.Errorf("Currency conversion failed. Unable to find %s in currency map [%s -> %s]", to, from, to) + return 0, fmt.Errorf("currency conversion failed. Unable to find %s in currency map [%s -> %s]", to, from, to) } return converted * resultTo, nil @@ -238,17 +238,17 @@ func SeedCryptocurrencyMarketData(settings coinmarketcap.Settings) error { return err } - for _, data := range cryptoData { + for x := range cryptoData { var active bool - if data.IsActive == 1 { + if cryptoData[x].IsActive == 1 { active = true } TotalCryptocurrencies = append(TotalCryptocurrencies, Data{ - ID: data.ID, - Name: data.Name, - Symbol: data.Symbol, - Slug: data.Slug, + ID: cryptoData[x].ID, + Name: cryptoData[x].Name, + Symbol: cryptoData[x].Symbol, + Slug: cryptoData[x].Slug, Active: active, LastUpdated: time.Now(), }) diff --git a/currency/currency_test.go b/currency/currency_test.go index d4478a97e1c..e8320cfc2c4 100644 --- a/currency/currency_test.go +++ b/currency/currency_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/thrasher-/gocryptotrader/currency/pair" + "github.com/thrasher-/gocryptotrader/currency/symbol" ) func TestSetDefaults(t *testing.T) { @@ -75,7 +76,7 @@ func TestIsDefaultCurrency(t *testing.T) { func TestIsDefaultCryptocurrency(t *testing.T) { t.Parallel() - var str1, str2, str3 string = "BTC", "btc", "dogs123" + var str1, str2, str3 string = symbol.BTC, symbol.BTC, "dogs123" if !IsDefaultCryptocurrency(str1) { t.Errorf( @@ -103,7 +104,7 @@ func TestIsFiatCurrency(t *testing.T) { } FiatCurrencies = []string{"USD", "AUD"} - var str1, str2, str3 string = "BTC", "USD", "birds123" + var str1, str2, str3 string = symbol.BTC, "USD", "birds123" if IsFiatCurrency(str1) { t.Errorf( @@ -127,8 +128,8 @@ func TestIsCryptocurrency(t *testing.T) { t.Error("Test failed. TestIsCryptocurrency returned true on an empty string") } - CryptoCurrencies = []string{"BTC", "LTC", "DASH"} - var str1, str2, str3 string = "USD", "BTC", "pterodactyl123" + CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH} + var str1, str2, str3 string = "USD", symbol.BTC, "pterodactyl123" if IsCryptocurrency(str1) { t.Errorf( @@ -152,14 +153,14 @@ func TestIsCryptoPair(t *testing.T) { t.Error("Test failed. TestIsCryptocurrency returned true on an empty string") } - CryptoCurrencies = []string{"BTC", "LTC", "DASH"} + CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH} FiatCurrencies = []string{"USD"} - if !IsCryptoPair(pair.NewCurrencyPair("BTC", "LTC")) { + if !IsCryptoPair(pair.NewCurrencyPair(symbol.BTC, symbol.LTC)) { t.Error("Test Failed. TestIsCryptoPair. Expected true result") } - if IsCryptoPair(pair.NewCurrencyPair("BTC", "USD")) { + if IsCryptoPair(pair.NewCurrencyPair(symbol.BTC, "USD")) { t.Error("Test Failed. TestIsCryptoPair. Expected false result") } } @@ -169,33 +170,33 @@ func TestIsCryptoFiatPair(t *testing.T) { t.Error("Test failed. TestIsCryptocurrency returned true on an empty string") } - CryptoCurrencies = []string{"BTC", "LTC", "DASH"} + CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH} FiatCurrencies = []string{"USD"} - if !IsCryptoFiatPair(pair.NewCurrencyPair("BTC", "USD")) { + if !IsCryptoFiatPair(pair.NewCurrencyPair(symbol.BTC, "USD")) { t.Error("Test Failed. TestIsCryptoPair. Expected true result") } - if IsCryptoFiatPair(pair.NewCurrencyPair("BTC", "LTC")) { + if IsCryptoFiatPair(pair.NewCurrencyPair(symbol.BTC, symbol.LTC)) { t.Error("Test Failed. TestIsCryptoPair. Expected false result") } } func TestIsFiatPair(t *testing.T) { - CryptoCurrencies = []string{"BTC", "LTC", "DASH"} + CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH} FiatCurrencies = []string{"USD", "AUD", "EUR"} if !IsFiatPair(pair.NewCurrencyPair("AUD", "USD")) { t.Error("Test Failed. TestIsFiatPair. Expected true result") } - if IsFiatPair(pair.NewCurrencyPair("BTC", "AUD")) { + if IsFiatPair(pair.NewCurrencyPair(symbol.BTC, "AUD")) { t.Error("Test Failed. TestIsFiatPair. Expected false result") } } func TestUpdate(t *testing.T) { - CryptoCurrencies = []string{"BTC", "LTC", "DASH"} + CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH} FiatCurrencies = []string{"USD", "AUD"} Update([]string{"ETH"}, true) diff --git a/currency/forexprovider/base/base_interface.go b/currency/forexprovider/base/base_interface.go index 4eb7da518d7..4ce3d44dcb6 100644 --- a/currency/forexprovider/base/base_interface.go +++ b/currency/forexprovider/base/base_interface.go @@ -2,6 +2,7 @@ package base import ( "errors" + "fmt" log "github.com/thrasher-/gocryptotrader/logger" ) @@ -36,10 +37,10 @@ func (fxp IFXProviders) GetCurrencyData(baseCurrency, symbols string) (map[strin return rates, nil } } - return nil, errors.New("ForexProvider error GetCurrencyData() failed to acquire data") + return nil, fmt.Errorf("forex provider %s unable to acquire rates data", fxp[x].GetName()) } return rates, nil } } - return nil, errors.New("ForexProvider error GetCurrencyData() no providers enabled") + return nil, errors.New("no forex providers enabled") } diff --git a/currency/forexprovider/currencyconverterapi/currencyconverterapi.go b/currency/forexprovider/currencyconverterapi/currencyconverterapi.go index b4d0b6b947d..1c731808e7c 100644 --- a/currency/forexprovider/currencyconverterapi/currencyconverterapi.go +++ b/currency/forexprovider/currencyconverterapi/currencyconverterapi.go @@ -164,11 +164,11 @@ func (c *CurrencyConverter) SendHTTPRequest(endPoint string, values url.Values, path = fmt.Sprintf("%s%s%s?", APIEndpointURL, APIEndpointVersion, endPoint) values.Set("apiKey", c.APIKey) } - path = path + values.Encode() + path += values.Encode() err := common.SendHTTPGetRequest(path, true, c.Verbose, &result) if err != nil { - return fmt.Errorf("Currency converter API SendHTTPRequest error %s with path %s", + return fmt.Errorf("currency converter API SendHTTPRequest error %s with path %s", err, path) } diff --git a/currency/forexprovider/currencylayer/currencylayer.go b/currency/forexprovider/currencylayer/currencylayer.go index 5b87dea13ff..fb52231cd58 100644 --- a/currency/forexprovider/currencylayer/currencylayer.go +++ b/currency/forexprovider/currencylayer/currencylayer.go @@ -142,7 +142,7 @@ func (c *CurrencyLayer) Convert(from, to, date string, amount float64) (float64, // QueryTimeFrame returns historical exchange rates for a time-period. // (maximum range: 365 days) -func (c *CurrencyLayer) QueryTimeFrame(startDate, endDate, base string, currencies []string) (map[string]interface{}, error) { +func (c *CurrencyLayer) QueryTimeFrame(startDate, endDate, baseCurrency string, currencies []string) (map[string]interface{}, error) { if c.APIKeyLvl >= AccountPro { return nil, errors.New("insufficient API privileges, upgrade to basic to use this function") } @@ -152,7 +152,7 @@ func (c *CurrencyLayer) QueryTimeFrame(startDate, endDate, base string, currenci v := url.Values{} v.Set("start_date", startDate) v.Set("end_date", endDate) - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("currencies", common.JoinStrings(currencies, ",")) err := c.SendHTTPRequest(APIEndpointTimeframe, v, &resp) @@ -169,7 +169,7 @@ func (c *CurrencyLayer) QueryTimeFrame(startDate, endDate, base string, currenci // QueryCurrencyChange returns the change (both margin and percentage) of one or // more currencies, relative to a Source Currency, within a specific // time-frame (optional). -func (c *CurrencyLayer) QueryCurrencyChange(startDate, endDate, base string, currencies []string) (map[string]Changes, error) { +func (c *CurrencyLayer) QueryCurrencyChange(startDate, endDate, baseCurrency string, currencies []string) (map[string]Changes, error) { if c.APIKeyLvl != AccountEnterprise { return nil, errors.New("insufficient API privileges, upgrade to basic to use this function") } @@ -178,7 +178,7 @@ func (c *CurrencyLayer) QueryCurrencyChange(startDate, endDate, base string, cur v := url.Values{} v.Set("start_date", startDate) v.Set("end_date", endDate) - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("currencies", common.JoinStrings(currencies, ",")) err := c.SendHTTPRequest(APIEndpointChange, v, &resp) @@ -203,7 +203,7 @@ func (c *CurrencyLayer) SendHTTPRequest(endPoint string, values url.Values, resu } else { path = fmt.Sprintf("%s%s%s", APIEndpointURLSSL, endPoint, "?") } - path = path + values.Encode() + path += values.Encode() return common.SendHTTPGetRequest(path, true, c.Verbose, result) } diff --git a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go index e31f91cd900..abb13712461 100644 --- a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go +++ b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go @@ -86,20 +86,20 @@ func (e *ExchangeRates) GetLatestRates(baseCurrency, symbols string) (Rates, err // GetHistoricalRates returns historical exchange rate data for all available or // a specific set of currencies. // date - YYYY-MM-DD [required] A date in the past -// base - USD [optional] The base currency to use for forex rates, defaults to EUR +// baseCurrency - USD [optional] The base currency to use for forex rates, defaults to EUR // symbols - AUD,USD [optional] The symbols to query the forex rates for, default is // all supported currencies -func (e *ExchangeRates) GetHistoricalRates(date, base string, symbols []string) (HistoricalRates, error) { +func (e *ExchangeRates) GetHistoricalRates(date, baseCurrency string, symbols []string) (HistoricalRates, error) { var resp HistoricalRates v := url.Values{} if len(symbols) > 0 { - s := cleanCurrencies(base, strings.Join(symbols, ",")) + s := cleanCurrencies(baseCurrency, strings.Join(symbols, ",")) v.Set("symbols", s) } - if len(base) > 0 { - v.Set("base", base) + if len(baseCurrency) > 0 { + v.Set("base", baseCurrency) } return resp, e.SendHTTPRequest(date, v, &resp) @@ -109,12 +109,12 @@ func (e *ExchangeRates) GetHistoricalRates(date, base string, symbols []string) // specified dates for all available or a specific set of currencies. // startDate - YYYY-MM-DD [required] A date in the past // endDate - YYYY-MM-DD [required] A date in the past but greater than the startDate -// base - USD [optional] The base currency to use for forex rates, defaults to EUR +// baseCurrency - USD [optional] The base currency to use for forex rates, defaults to EUR // symbols - AUD,USD [optional] The symbols to query the forex rates for, default is // all supported currencies -func (e *ExchangeRates) GetTimeSeriesRates(startDate, endDate, base string, symbols []string) (TimeSeriesRates, error) { +func (e *ExchangeRates) GetTimeSeriesRates(startDate, endDate, baseCurrency string, symbols []string) (TimeSeriesRates, error) { var resp TimeSeriesRates - if len(startDate) == 0 || len(endDate) == 0 { + if startDate == "" || endDate == "" { return resp, errors.New("startDate and endDate params must be set") } @@ -122,12 +122,12 @@ func (e *ExchangeRates) GetTimeSeriesRates(startDate, endDate, base string, symb v.Set("start_at", startDate) v.Set("end_at", endDate) - if len(base) > 0 { - v.Set("base", base) + if len(baseCurrency) > 0 { + v.Set("base", baseCurrency) } if len(symbols) > 0 { - s := cleanCurrencies(base, strings.Join(symbols, ",")) + s := cleanCurrencies(baseCurrency, strings.Join(symbols, ",")) v.Set("symbols", s) } @@ -155,7 +155,7 @@ func (e *ExchangeRates) SendHTTPRequest(endPoint string, values url.Values, resu path := common.EncodeURLValues(exchangeRatesAPI+"/"+endPoint, values) err := common.SendHTTPGetRequest(path, true, e.Verbose, &result) if err != nil { - return fmt.Errorf("ExchangeRatesAPI SendHTTPRequest error %s with path %s", + return fmt.Errorf("exchangeRatesAPI SendHTTPRequest error %s with path %s", err, path) } diff --git a/currency/forexprovider/fixer.io/fixer.go b/currency/forexprovider/fixer.io/fixer.go index bd5afe5508c..87a5d94d0b5 100644 --- a/currency/forexprovider/fixer.io/fixer.go +++ b/currency/forexprovider/fixer.io/fixer.go @@ -71,13 +71,13 @@ func (f *Fixer) GetRates(baseCurrency, symbols string) (map[string]float64, erro // GetLatestRates returns real-time exchange rate data for all available or a // specific set of currencies. NOTE DEFAULT BASE CURRENCY IS EUR -func (f *Fixer) GetLatestRates(base, symbols string) (map[string]float64, error) { +func (f *Fixer) GetLatestRates(baseCurrency, symbols string) (map[string]float64, error) { var resp Rates v := url.Values{} if f.APIKeyLvl > fixerAPIFree { - v.Add("base", base) + v.Add("base", baseCurrency) } v.Add("symbols", symbols) @@ -98,14 +98,14 @@ func (f *Fixer) GetLatestRates(base, symbols string) (map[string]float64, error) // date - YYYY-MM-DD [required] A date in the past // base - USD [optional] // symbols - the desired symbols -func (f *Fixer) GetHistoricalRates(date, base string, symbols []string) (map[string]float64, error) { +func (f *Fixer) GetHistoricalRates(date, baseCurrency string, symbols []string) (map[string]float64, error) { var resp Rates v := url.Values{} v.Set("symbols", common.JoinStrings(symbols, ",")) - if len(base) > 0 { - v.Set("base", base) + if baseCurrency != "" { + v.Set("base", baseCurrency) } err := f.SendOpenHTTPRequest(date, v, &resp) @@ -154,7 +154,7 @@ func (f *Fixer) ConvertCurrency(from, to, date string, amount float64) (float64, // GetTimeSeriesData returns daily historical exchange rate data between two // specified dates for all available or a specific set of currencies. -func (f *Fixer) GetTimeSeriesData(startDate, endDate, base string, symbols []string) (map[string]interface{}, error) { +func (f *Fixer) GetTimeSeriesData(startDate, endDate, baseCurrency string, symbols []string) (map[string]interface{}, error) { if f.APIKeyLvl < fixerAPIProfessional { return nil, errors.New("insufficient API privileges, upgrade to professional to use this function") } @@ -164,7 +164,7 @@ func (f *Fixer) GetTimeSeriesData(startDate, endDate, base string, symbols []str v := url.Values{} v.Set("start_date", startDate) v.Set("end_date", endDate) - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("symbols", common.JoinStrings(symbols, ",")) err := f.SendOpenHTTPRequest(fixerAPITimeSeries, v, &resp) @@ -180,7 +180,7 @@ func (f *Fixer) GetTimeSeriesData(startDate, endDate, base string, symbols []str // GetFluctuationData returns fluctuation data between two specified dates for // all available or a specific set of currencies. -func (f *Fixer) GetFluctuationData(startDate, endDate, base string, symbols []string) (map[string]Flux, error) { +func (f *Fixer) GetFluctuationData(startDate, endDate, baseCurrency string, symbols []string) (map[string]Flux, error) { if f.APIKeyLvl < fixerAPIProfessionalPlus { return nil, errors.New("insufficient API privileges, upgrade to professional plus or enterprise to use this function") } @@ -190,7 +190,7 @@ func (f *Fixer) GetFluctuationData(startDate, endDate, base string, symbols []st v := url.Values{} v.Set("start_date", startDate) v.Set("end_date", endDate) - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("symbols", common.JoinStrings(symbols, ",")) err := f.SendOpenHTTPRequest(fixerAPIFluctuation, v, &resp) diff --git a/currency/forexprovider/openexchangerates/openexchangerates.go b/currency/forexprovider/openexchangerates/openexchangerates.go index 65dbd7fc00f..13f50c27f43 100644 --- a/currency/forexprovider/openexchangerates/openexchangerates.go +++ b/currency/forexprovider/openexchangerates/openexchangerates.go @@ -71,11 +71,11 @@ func (o *OXR) GetRates(baseCurrency, symbols string) (map[string]float64, error) // GetLatest returns the latest exchange rates available from the Open Exchange // Rates -func (o *OXR) GetLatest(base, symbols string, prettyPrint, showAlternative bool) (map[string]float64, error) { +func (o *OXR) GetLatest(baseCurrency, symbols string, prettyPrint, showAlternative bool) (map[string]float64, error) { var resp Latest v := url.Values{} - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("symbols", symbols) v.Set("prettyprint", strconv.FormatBool(prettyPrint)) v.Set("show_alternative", strconv.FormatBool(showAlternative)) @@ -92,11 +92,11 @@ func (o *OXR) GetLatest(base, symbols string, prettyPrint, showAlternative bool) // GetHistoricalRates returns historical exchange rates for any date available // from the Open Exchange Rates API. -func (o *OXR) GetHistoricalRates(date, base string, symbols []string, prettyPrint, showAlternative bool) (map[string]float64, error) { +func (o *OXR) GetHistoricalRates(date, baseCurrency string, symbols []string, prettyPrint, showAlternative bool) (map[string]float64, error) { var resp Latest v := url.Values{} - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("symbols", common.JoinStrings(symbols, ",")) v.Set("prettyprint", strconv.FormatBool(prettyPrint)) v.Set("show_alternative", strconv.FormatBool(showAlternative)) @@ -127,7 +127,7 @@ func (o *OXR) GetCurrencies(showInactive, prettyPrint, showAlternative bool) (ma // GetTimeSeries returns historical exchange rates for a given time period, // where available. -func (o *OXR) GetTimeSeries(base, startDate, endDate string, symbols []string, prettyPrint, showAlternative bool) (map[string]interface{}, error) { +func (o *OXR) GetTimeSeries(baseCurrency, startDate, endDate string, symbols []string, prettyPrint, showAlternative bool) (map[string]interface{}, error) { if o.APIKeyLvl < APIEnterpriseAccess { return nil, errors.New("upgrade account, insufficient access") } @@ -135,7 +135,7 @@ func (o *OXR) GetTimeSeries(base, startDate, endDate string, symbols []string, p var resp TimeSeries v := url.Values{} - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("start", startDate) v.Set("end", endDate) v.Set("symbols", common.JoinStrings(symbols, ",")) @@ -175,7 +175,7 @@ func (o *OXR) ConvertCurrency(amount float64, from, to string) (float64, error) // GetOHLC returns historical Open, High Low, Close (OHLC) and Average exchange // rates for a given time period, ranging from 1 month to 1 minute, where // available. -func (o *OXR) GetOHLC(startTime, period, base string, symbols []string, prettyPrint bool) (map[string]interface{}, error) { +func (o *OXR) GetOHLC(startTime, period, baseCurrency string, symbols []string, prettyPrint bool) (map[string]interface{}, error) { if o.APIKeyLvl < APIUnlimitedAccess { return nil, errors.New("upgrade account, insufficient access") } @@ -185,7 +185,7 @@ func (o *OXR) GetOHLC(startTime, period, base string, symbols []string, prettyPr v := url.Values{} v.Set("start_time", startTime) v.Set("period", period) - v.Set("base", base) + v.Set("base", baseCurrency) v.Set("symbols", common.JoinStrings(symbols, ",")) v.Set("prettyprint", strconv.FormatBool(prettyPrint)) diff --git a/currency/pair/pair.go b/currency/pair/pair.go index 36f55363725..4a548107504 100644 --- a/currency/pair/pair.go +++ b/currency/pair/pair.go @@ -205,8 +205,7 @@ func CopyPairFormat(p CurrencyPair, pairs []CurrencyPair, exact bool) CurrencyPa } // FindPairDifferences returns pairs which are new or have been removed -func FindPairDifferences(oldPairs, newPairs []string) ([]string, []string) { - var newPs, removedPs []string +func FindPairDifferences(oldPairs, newPairs []string) (newPs, removedPs []string) { for x := range newPairs { if newPairs[x] == "" { continue diff --git a/currency/pair/pair_test.go b/currency/pair/pair_test.go index 3d738e38e31..5c513a7eb01 100644 --- a/currency/pair/pair_test.go +++ b/currency/pair/pair_test.go @@ -286,11 +286,9 @@ func TestNewCurrencyPairFromString(t *testing.T) { func TestContains(t *testing.T) { pairOne := NewCurrencyPair("BTC", "USD") - pairTwo := NewCurrencyPair("LTC", "USD") var pairs []CurrencyPair - pairs = append(pairs, pairOne) - pairs = append(pairs, pairTwo) + pairs = append(pairs, pairOne, NewCurrencyPair("LTC", "USD")) if !Contains(pairs, pairOne, true) { t.Errorf("Test failed. TestContains: Expected pair was not found") @@ -315,9 +313,9 @@ func TestContainsCurrency(t *testing.T) { func TestRemovePairsByFilter(t *testing.T) { var pairs []CurrencyPair - pairs = append(pairs, NewCurrencyPair("BTC", "USD")) - pairs = append(pairs, NewCurrencyPair("LTC", "USD")) - pairs = append(pairs, NewCurrencyPair("LTC", "USDT")) + pairs = append(pairs, NewCurrencyPair("BTC", "USD"), + NewCurrencyPair("LTC", "USD"), + NewCurrencyPair("LTC", "USDT")) pairs = RemovePairsByFilter(pairs, "USDT") if Contains(pairs, NewCurrencyPair("LTC", "USDT"), true) { @@ -346,11 +344,9 @@ func TestFormatPairs(t *testing.T) { func TestCopyPairFormat(t *testing.T) { pairOne := NewCurrencyPair("BTC", "USD") pairOne.Delimiter = "-" - pairTwo := NewCurrencyPair("LTC", "USD") var pairs []CurrencyPair - pairs = append(pairs, pairOne) - pairs = append(pairs, pairTwo) + pairs = append(pairs, pairOne, NewCurrencyPair("LTC", "USD")) testPair := NewCurrencyPair("BTC", "USD") testPair.Delimiter = "~" diff --git a/events/events.go b/events/events.go index 9d3cc2ba9b8..8e68d4b551e 100644 --- a/events/events.go +++ b/events/events.go @@ -60,35 +60,35 @@ func SetComms(commsP *communications.Communications) { // AddEvent adds an event to the Events chain and returns an index/eventID // and an error -func AddEvent(Exchange, Item, Condition string, CurrencyPair pair.CurrencyPair, Asset, Action string) (int, error) { - err := IsValidEvent(Exchange, Item, Condition, Action) +func AddEvent(exchange, item, condition string, currencyPair pair.CurrencyPair, asset, action string) (int, error) { + err := IsValidEvent(exchange, item, condition, action) if err != nil { return 0, err } - Event := &Event{} + evt := &Event{} if len(Events) == 0 { - Event.ID = 0 + evt.ID = 0 } else { - Event.ID = len(Events) + 1 + evt.ID = len(Events) + 1 } - Event.Exchange = Exchange - Event.Item = Item - Event.Condition = Condition - Event.Pair = CurrencyPair - Event.Asset = Asset - Event.Action = Action - Event.Executed = false - Events = append(Events, Event) - return Event.ID, nil + evt.Exchange = exchange + evt.Item = item + evt.Condition = condition + evt.Pair = currencyPair + evt.Asset = asset + evt.Action = action + evt.Executed = false + Events = append(Events, evt) + return evt.ID, nil } // RemoveEvent deletes and event by its ID -func RemoveEvent(EventID int) bool { +func RemoveEvent(eventID int) bool { for i, x := range Events { - if x.ID == EventID { + if x.ID == eventID { Events = append(Events[:i], Events[i+1:]...) return true } @@ -98,9 +98,8 @@ func RemoveEvent(EventID int) bool { // GetEventCounter displays the emount of total events on the chain and the // events that have been executed. -func GetEventCounter() (int, int) { - total := len(Events) - executed := 0 +func GetEventCounter() (total, executed int) { + total = len(Events) for _, x := range Events { if x.Executed { @@ -154,78 +153,67 @@ func (e *Event) CheckCondition() bool { switch condition[0] { case greaterThan: - { - if lastPrice > targetPrice { - return e.ExecuteAction() - } + if lastPrice > targetPrice { + return e.ExecuteAction() } case greaterThanOrEqual: - { - if lastPrice >= targetPrice { - return e.ExecuteAction() - } + if lastPrice >= targetPrice { + return e.ExecuteAction() } case lessThan: - { - if lastPrice < targetPrice { - return e.ExecuteAction() - } + if lastPrice < targetPrice { + return e.ExecuteAction() } case lessThanOrEqual: - { - if lastPrice <= targetPrice { - return e.ExecuteAction() - } + if lastPrice <= targetPrice { + return e.ExecuteAction() } case isEqual: - { - if lastPrice == targetPrice { - return e.ExecuteAction() - } + if lastPrice == targetPrice { + return e.ExecuteAction() } } return false } // IsValidEvent checks the actions to be taken and returns an error if incorrect -func IsValidEvent(Exchange, Item, Condition, Action string) error { - Exchange = common.StringToUpper(Exchange) - Item = common.StringToUpper(Item) - Action = common.StringToUpper(Action) +func IsValidEvent(exchange, item, condition, action string) error { + exchange = common.StringToUpper(exchange) + item = common.StringToUpper(item) + action = common.StringToUpper(action) - if !IsValidExchange(Exchange) { + if !IsValidExchange(exchange) { return errExchangeDisabled } - if !IsValidItem(Item) { + if !IsValidItem(item) { return errInvalidItem } - if !common.StringContains(Condition, ",") { + if !common.StringContains(condition, ",") { return errInvalidCondition } - condition := common.SplitStrings(Condition, ",") + c := common.SplitStrings(condition, ",") - if !IsValidCondition(condition[0]) || len(condition[1]) == 0 { + if !IsValidCondition(c[0]) || c[1] == "" { return errInvalidCondition } - if common.StringContains(Action, ",") { - action := common.SplitStrings(Action, ",") + if common.StringContains(action, ",") { + a := common.SplitStrings(action, ",") - if action[0] != actionSMSNotify { + if a[0] != actionSMSNotify { return errInvalidAction } - if action[1] != "ALL" { - comms.PushEvent(base.Event{Type: action[1]}) - } - } else { - if Action != actionConsolePrint && Action != actionTest { - return errInvalidAction + if a[1] != "ALL" { + comms.PushEvent(base.Event{Type: a[1]}) } + } else if action != actionConsolePrint && action != actionTest { + return errInvalidAction } + return nil } @@ -252,11 +240,11 @@ func CheckEvents() { } // IsValidExchange validates the exchange -func IsValidExchange(Exchange string) bool { - Exchange = common.StringToUpper(Exchange) +func IsValidExchange(exchange string) bool { + exchange = common.StringToUpper(exchange) cfg := config.GetConfig() - for _, x := range cfg.Exchanges { - if x.Name == Exchange && x.Enabled { + for x := range cfg.Exchanges { + if cfg.Exchanges[x].Name == exchange && cfg.Exchanges[x].Enabled { return true } } @@ -264,8 +252,8 @@ func IsValidExchange(Exchange string) bool { } // IsValidCondition validates passed in condition -func IsValidCondition(Condition string) bool { - switch Condition { +func IsValidCondition(condition string) bool { + switch condition { case greaterThan, greaterThanOrEqual, lessThan, lessThanOrEqual, isEqual: return true } @@ -273,9 +261,9 @@ func IsValidCondition(Condition string) bool { } // IsValidAction validates passed in action -func IsValidAction(Action string) bool { - Action = common.StringToUpper(Action) - switch Action { +func IsValidAction(action string) bool { + action = common.StringToUpper(action) + switch action { case actionSMSNotify, actionConsolePrint, actionTest: return true } @@ -283,11 +271,7 @@ func IsValidAction(Action string) bool { } // IsValidItem validates passed in Item -func IsValidItem(Item string) bool { - Item = common.StringToUpper(Item) - switch Item { - case itemPrice: - return true - } - return false +func IsValidItem(item string) bool { + item = common.StringToUpper(item) + return (item == itemPrice) } diff --git a/exchange.go b/exchange.go index e7fdf3d119b..c9c45f6f9d6 100644 --- a/exchange.go +++ b/exchange.go @@ -106,7 +106,7 @@ func UnloadExchange(name string) error { } exchCfg.Enabled = false - err = bot.config.UpdateExchangeConfig(exchCfg) + err = bot.config.UpdateExchangeConfig(&exchCfg) if err != nil { return err } @@ -219,7 +219,8 @@ func LoadExchange(name string, useWG bool, wg *sync.WaitGroup) error { // SetupExchanges sets up the exchanges used by the bot func SetupExchanges() { var wg sync.WaitGroup - for _, exch := range bot.config.Exchanges { + for x := range bot.config.Exchanges { + exch := &bot.config.Exchanges[x] if CheckExchangeExists(exch.Name) { e := GetExchangeByName(exch.Name) if e == nil { diff --git a/exchanges/alphapoint/alphapoint.go b/exchanges/alphapoint/alphapoint.go index 4b78da3de22..22e6fa8d9d8 100644 --- a/exchanges/alphapoint/alphapoint.go +++ b/exchanges/alphapoint/alphapoint.go @@ -67,11 +67,11 @@ func (a *Alphapoint) SetDefaults() { // GetTicker returns current ticker information from Alphapoint for a selected // currency pair ie "BTCUSD" func (a *Alphapoint) GetTicker(currencyPair string) (Ticker, error) { - request := make(map[string]interface{}) - request["productPair"] = currencyPair + req := make(map[string]interface{}) + req["productPair"] = currencyPair response := Ticker{} - err := a.SendHTTPRequest(http.MethodPost, alphapointTicker, request, &response) + err := a.SendHTTPRequest(http.MethodPost, alphapointTicker, req, &response) if err != nil { return response, err } @@ -88,13 +88,13 @@ func (a *Alphapoint) GetTicker(currencyPair string) (Ticker, error) { // 0 (default: 0) // Count: specifies the number of trades to return (default: 10) func (a *Alphapoint) GetTrades(currencyPair string, startIndex, count int) (Trades, error) { - request := make(map[string]interface{}) - request["ins"] = currencyPair - request["startIndex"] = startIndex - request["Count"] = count + req := make(map[string]interface{}) + req["ins"] = currencyPair + req["startIndex"] = startIndex + req["Count"] = count response := Trades{} - err := a.SendHTTPRequest(http.MethodPost, alphapointTrades, request, &response) + err := a.SendHTTPRequest(http.MethodPost, alphapointTrades, req, &response) if err != nil { return response, err } @@ -109,13 +109,13 @@ func (a *Alphapoint) GetTrades(currencyPair string, startIndex, count int) (Trad // StartDate - specifies the starting time in epoch time, type is long // EndDate - specifies the end time in epoch time, type is long func (a *Alphapoint) GetTradesByDate(currencyPair string, startDate, endDate int64) (Trades, error) { - request := make(map[string]interface{}) - request["ins"] = currencyPair - request["startDate"] = startDate - request["endDate"] = endDate + req := make(map[string]interface{}) + req["ins"] = currencyPair + req["startDate"] = startDate + req["endDate"] = endDate response := Trades{} - err := a.SendHTTPRequest(http.MethodPost, alphapointTradesByDate, request, &response) + err := a.SendHTTPRequest(http.MethodPost, alphapointTradesByDate, req, &response) if err != nil { return response, err } @@ -128,11 +128,11 @@ func (a *Alphapoint) GetTradesByDate(currencyPair string, startDate, endDate int // GetOrderbook fetches the current orderbook for a given currency pair // CurrencyPair - trade pair (ex: “BTCUSD”) func (a *Alphapoint) GetOrderbook(currencyPair string) (Orderbook, error) { - request := make(map[string]interface{}) - request["productPair"] = currencyPair + req := make(map[string]interface{}) + req["productPair"] = currencyPair response := Orderbook{} - err := a.SendHTTPRequest(http.MethodPost, alphapointOrderbook, request, &response) + err := a.SendHTTPRequest(http.MethodPost, alphapointOrderbook, req, &response) if err != nil { return response, err } @@ -183,17 +183,17 @@ func (a *Alphapoint) CreateAccount(firstName, lastName, email, phone, password s ) } - request := make(map[string]interface{}) - request["firstname"] = firstName - request["lastname"] = lastName - request["email"] = email - request["phone"] = phone - request["password"] = password + req := make(map[string]interface{}) + req["firstname"] = firstName + req["lastname"] = lastName + req["email"] = email + req["phone"] = phone + req["password"] = password response := Response{} - err := a.SendAuthenticatedHTTPRequest(http.MethodPost, alphapointCreateAccount, request, &response) + err := a.SendAuthenticatedHTTPRequest(http.MethodPost, alphapointCreateAccount, req, &response) if err != nil { - return fmt.Errorf("Alphapoint Error - CreateAccount HTTPRequest - reason: %s", err) + return fmt.Errorf("unable to create account. Reason: %s", err) } if !response.IsAccepted { return errors.New(response.RejectReason) @@ -254,13 +254,13 @@ func (a *Alphapoint) SetUserInfo(firstName, lastName, cell2FACountryCode, cell2F }, } - request := make(map[string]interface{}) - request["userInfoKVP"] = userInfoKVPs + req := make(map[string]interface{}) + req["userInfoKVP"] = userInfoKVPs err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointUserInfo, - request, + req, &response, ) if err != nil { @@ -296,16 +296,16 @@ func (a *Alphapoint) GetAccountInformation() (AccountInfo, error) { // StartIndex - Starting index, if less than 0 then start from the beginning // Count - Returns last trade, (Default: 30) func (a *Alphapoint) GetAccountTrades(currencyPair string, startIndex, count int) (Trades, error) { - request := make(map[string]interface{}) - request["ins"] = currencyPair - request["startIndex"] = startIndex - request["count"] = count + req := make(map[string]interface{}) + req["ins"] = currencyPair + req["startIndex"] = startIndex + req["count"] = count response := Trades{} err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointAccountTrades, - request, + req, &response, ) if err != nil { @@ -339,17 +339,17 @@ func (a *Alphapoint) GetDepositAddresses() ([]DepositAddresses, error) { // amount - Amount (ex: “.011”) // address - Withdraw address func (a *Alphapoint) WithdrawCoins(symbol, product, address string, amount float64) error { - request := make(map[string]interface{}) - request["ins"] = symbol - request["product"] = product - request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - request["sendToAddress"] = address + req := make(map[string]interface{}) + req["ins"] = symbol + req["product"] = product + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["sendToAddress"] = address response := Response{} err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointWithdraw, - request, + req, &response, ) if err != nil { @@ -377,18 +377,18 @@ func (a *Alphapoint) convertOrderTypeToOrderTypeNumber(orderType string) (orderT // price - Price in USD func (a *Alphapoint) CreateOrder(symbol, side, orderType string, quantity, price float64) (int64, error) { orderTypeNumber := a.convertOrderTypeToOrderTypeNumber(orderType) - request := make(map[string]interface{}) - request["ins"] = symbol - request["side"] = side - request["orderType"] = orderTypeNumber - request["qty"] = strconv.FormatFloat(quantity, 'f', -1, 64) - request["px"] = strconv.FormatFloat(price, 'f', -1, 64) + req := make(map[string]interface{}) + req["ins"] = symbol + req["side"] = side + req["orderType"] = orderTypeNumber + req["qty"] = strconv.FormatFloat(quantity, 'f', -1, 64) + req["px"] = strconv.FormatFloat(price, 'f', -1, 64) response := Response{} err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointCreateOrder, - request, + req, &response, ) if err != nil { @@ -408,17 +408,17 @@ func (a *Alphapoint) CreateOrder(symbol, side, orderType string, quantity, price // book. A buy order will be modified to the highest bid and a sell order will // be modified to the lowest ask price. “1” means "Execute now", which will // convert a limit order into a market order. -func (a *Alphapoint) ModifyExistingOrder(symbol string, OrderID, action int64) (int64, error) { - request := make(map[string]interface{}) - request["ins"] = symbol - request["serverOrderId"] = OrderID - request["modifyAction"] = action +func (a *Alphapoint) ModifyExistingOrder(symbol string, orderID, action int64) (int64, error) { + req := make(map[string]interface{}) + req["ins"] = symbol + req["serverOrderId"] = orderID + req["modifyAction"] = action response := Response{} err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointModifyOrder, - request, + req, &response, ) if err != nil { @@ -433,16 +433,16 @@ func (a *Alphapoint) ModifyExistingOrder(symbol string, OrderID, action int64) ( // CancelExistingOrder cancels an order that has not been executed. // symbol - Instrument code (ex: “BTCUSD”) // OrderId - Order id (ex: 1000) -func (a *Alphapoint) CancelExistingOrder(OrderID int64, OMSID string) (int64, error) { - request := make(map[string]interface{}) - request["OrderId"] = OrderID - request["OMSId"] = OMSID +func (a *Alphapoint) CancelExistingOrder(orderID int64, omsid string) (int64, error) { + req := make(map[string]interface{}) + req["OrderId"] = orderID + req["OMSId"] = omsid response := Response{} err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointCancelOrder, - request, + req, &response, ) if err != nil { @@ -456,15 +456,15 @@ func (a *Alphapoint) CancelExistingOrder(OrderID int64, OMSID string) (int64, er // CancelAllExistingOrders cancels all open orders by symbol // symbol - Instrument code (ex: “BTCUSD”) -func (a *Alphapoint) CancelAllExistingOrders(OMSID string) error { - request := make(map[string]interface{}) - request["OMSId"] = OMSID +func (a *Alphapoint) CancelAllExistingOrders(omsid string) error { + req := make(map[string]interface{}) + req["OMSId"] = omsid response := Response{} err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointCancelAllOrders, - request, + req, &response, ) if err != nil { @@ -501,17 +501,17 @@ func (a *Alphapoint) GetOrders() ([]OpenOrders, error) { // quantity - Quantity // price - Price in USD func (a *Alphapoint) GetOrderFee(symbol, side string, quantity, price float64) (float64, error) { - request := make(map[string]interface{}) - request["ins"] = symbol - request["side"] = side - request["qty"] = strconv.FormatFloat(quantity, 'f', -1, 64) - request["px"] = strconv.FormatFloat(price, 'f', -1, 64) + req := make(map[string]interface{}) + req["ins"] = symbol + req["side"] = side + req["qty"] = strconv.FormatFloat(quantity, 'f', -1, 64) + req["px"] = strconv.FormatFloat(price, 'f', -1, 64) response := Response{} err := a.SendAuthenticatedHTTPRequest( http.MethodPost, alphapointOrderFee, - request, + req, &response, ) if err != nil { @@ -531,7 +531,7 @@ func (a *Alphapoint) SendHTTPRequest(method, path string, data map[string]interf PayloadJSON, err := common.JSONEncode(data) if err != nil { - return errors.New("SendHTTPRequest: Unable to JSON request") + return errors.New("unable to JSON request") } return a.SendPayload(method, path, headers, bytes.NewBuffer(PayloadJSON), result, false, a.Verbose) @@ -559,7 +559,7 @@ func (a *Alphapoint) SendAuthenticatedHTTPRequest(method, path string, data map[ PayloadJSON, err := common.JSONEncode(data) if err != nil { - return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request") + return errors.New("unable to JSON request") } return a.SendPayload(method, path, headers, bytes.NewBuffer(PayloadJSON), result, true, a.Verbose) diff --git a/exchanges/alphapoint/alphapoint_websocket.go b/exchanges/alphapoint/alphapoint_websocket.go index 261014c4a57..7e4295f2c26 100644 --- a/exchanges/alphapoint/alphapoint_websocket.go +++ b/exchanges/alphapoint/alphapoint_websocket.go @@ -42,8 +42,7 @@ func (a *Alphapoint) WebsocketClient() { break } - switch msgType { - case websocket.TextMessage: + if msgType == websocket.TextMessage { type MsgType struct { MessageType string `json:"messageType"` } @@ -55,8 +54,7 @@ func (a *Alphapoint) WebsocketClient() { continue } - switch msgType.MessageType { - case "Ticker": + if msgType.MessageType == "Ticker" { ticker := WebsocketTicker{} err = common.JSONDecode(resp, &ticker) if err != nil { diff --git a/exchanges/alphapoint/alphapoint_wrapper.go b/exchanges/alphapoint/alphapoint_wrapper.go index c04efa7a1df..9eb6f00b2a8 100644 --- a/exchanges/alphapoint/alphapoint_wrapper.go +++ b/exchanges/alphapoint/alphapoint_wrapper.go @@ -8,7 +8,7 @@ import ( "github.com/thrasher-/gocryptotrader/common" "github.com/thrasher-/gocryptotrader/currency/pair" - "github.com/thrasher-/gocryptotrader/exchanges" + exchange "github.com/thrasher-/gocryptotrader/exchanges" "github.com/thrasher-/gocryptotrader/exchanges/orderbook" "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) @@ -133,7 +133,7 @@ func (a *Alphapoint) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, o // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (a *Alphapoint) ModifyOrder(action exchange.ModifyOrder) (string, error) { +func (a *Alphapoint) ModifyOrder(_ exchange.ModifyOrder) (string, error) { return "", common.ErrNotYetImplemented } diff --git a/exchanges/anx/anx.go b/exchanges/anx/anx.go index ccf816060f3..6931f58e6fd 100644 --- a/exchanges/anx/anx.go +++ b/exchanges/anx/anx.go @@ -75,7 +75,7 @@ func (a *ANX) SetDefaults() { a.WebsocketInit() } -//Setup is run on startup to setup exchange with config values +// Setup is run on startup to setup exchange with config values func (a *ANX) Setup(exch config.ExchangeConfig) { if !exch.Enabled { a.SetEnabled(false) @@ -129,32 +129,30 @@ func (a *ANX) GetCurrencies() (CurrenciesStore, error) { // GetTicker returns the current ticker func (a *ANX) GetTicker(currency string) (Ticker, error) { - var ticker Ticker + var t Ticker path := fmt.Sprintf("%sapi/2/%s/%s", a.APIUrl, currency, anxTicker) - - return ticker, a.SendHTTPRequest(path, &ticker) + return t, a.SendHTTPRequest(path, &t) } // GetDepth returns current orderbook depth. func (a *ANX) GetDepth(currency string) (Depth, error) { var depth Depth path := fmt.Sprintf("%sapi/2/%s/%s", a.APIUrl, currency, anxDepth) - return depth, a.SendHTTPRequest(path, &depth) } // GetAPIKey returns a new generated API key set. -func (a *ANX) GetAPIKey(username, password, otp, deviceID string) (string, string, error) { - request := make(map[string]interface{}) - request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)[0:13] - request["username"] = username - request["password"] = password +func (a *ANX) GetAPIKey(username, password, otp, deviceID string) (apiKey, apiSecret string, err error) { + req := make(map[string]interface{}) + req["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)[0:13] + req["username"] = username + req["password"] = password if otp != "" { - request["otp"] = otp + req["otp"] = otp } - request["deviceId"] = deviceID + req["deviceId"] = deviceID type APIKeyResponse struct { APIKey string `json:"apiKey"` @@ -164,21 +162,23 @@ func (a *ANX) GetAPIKey(username, password, otp, deviceID string) (string, strin } var response APIKeyResponse - err := a.SendAuthenticatedHTTPRequest(anxAPIKey, request, &response) + err = a.SendAuthenticatedHTTPRequest(anxAPIKey, req, &response) if err != nil { - return "", "", err + return apiKey, apiSecret, err } if response.ResultCode != "OK" { - return "", "", errors.New("Response code is not OK: " + response.ResultCode) + return apiKey, apiSecret, errors.New("Response code is not OK: " + response.ResultCode) } - return response.APIKey, response.APISecret, nil + apiKey = response.APIKey + apiSecret = response.APISecret + return apiKey, apiSecret, err } // GetDataToken returns token data func (a *ANX) GetDataToken() (string, error) { - request := make(map[string]interface{}) + req := make(map[string]interface{}) type DataTokenResponse struct { ResultCode string `json:"resultCode"` @@ -188,7 +188,7 @@ func (a *ANX) GetDataToken() (string, error) { } var response DataTokenResponse - err := a.SendAuthenticatedHTTPRequest(anxDataToken, request, &response) + err := a.SendAuthenticatedHTTPRequest(anxDataToken, req, &response) if err != nil { return "", err } @@ -200,10 +200,10 @@ func (a *ANX) GetDataToken() (string, error) { } // NewOrder sends a new order request to the exchange. -func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, tradedCurrencyAmount float64, settlementCurrency string, settlementCurrencyAmount float64, limitPriceSettlement float64, +func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, tradedCurrencyAmount float64, settlementCurrency string, settlementCurrencyAmount, limitPriceSettlement float64, replace bool, replaceUUID string, replaceIfActive bool) (string, error) { - request := make(map[string]interface{}) + req := make(map[string]interface{}) var order Order order.OrderType = orderType order.BuyTradedCurrency = buy @@ -223,7 +223,7 @@ func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, traded order.ReplaceOnlyIfActive = replaceIfActive } - request["order"] = order + req["order"] = order type OrderResponse struct { OrderID string `json:"orderId"` @@ -232,7 +232,7 @@ func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, traded } var response OrderResponse - err := a.SendAuthenticatedHTTPRequest(anxOrderNew, request, &response) + err := a.SendAuthenticatedHTTPRequest(anxOrderNew, req, &response) if err != nil { return "", err } @@ -246,11 +246,11 @@ func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, traded // CancelOrderByIDs cancels orders, requires already knowing order IDs // There is no existing API call to retrieve orderIds func (a *ANX) CancelOrderByIDs(orderIds []string) (OrderCancelResponse, error) { - request := make(map[string]interface{}) - request["orderIds"] = orderIds + req := make(map[string]interface{}) + req["orderIds"] = orderIds var response OrderCancelResponse - err := a.SendAuthenticatedHTTPRequest(anxOrderCancel, request, &response) + err := a.SendAuthenticatedHTTPRequest(anxOrderCancel, req, &response) if response.ResultCode != "OK" { return response, errors.New(response.ResultCode) } @@ -260,8 +260,8 @@ func (a *ANX) CancelOrderByIDs(orderIds []string) (OrderCancelResponse, error) { // GetOrderList retrieves orders from the exchange func (a *ANX) GetOrderList(isActiveOrdersOnly bool) ([]OrderResponse, error) { - request := make(map[string]interface{}) - request["activeOnly"] = isActiveOrdersOnly + req := make(map[string]interface{}) + req["activeOnly"] = isActiveOrdersOnly type OrderListResponse struct { Timestamp int64 `json:"timestamp"` @@ -270,7 +270,7 @@ func (a *ANX) GetOrderList(isActiveOrdersOnly bool) ([]OrderResponse, error) { OrderResponses []OrderResponse `json:"orders"` } var response OrderListResponse - err := a.SendAuthenticatedHTTPRequest(anxOrderList, request, &response) + err := a.SendAuthenticatedHTTPRequest(anxOrderList, req, &response) if err != nil { return nil, err } @@ -285,8 +285,8 @@ func (a *ANX) GetOrderList(isActiveOrdersOnly bool) ([]OrderResponse, error) { // OrderInfo returns information about a specific order func (a *ANX) OrderInfo(orderID string) (OrderResponse, error) { - request := make(map[string]interface{}) - request["orderId"] = orderID + req := make(map[string]interface{}) + req["orderId"] = orderID type OrderInfoResponse struct { Order OrderResponse `json:"order"` @@ -295,7 +295,7 @@ func (a *ANX) OrderInfo(orderID string) (OrderResponse, error) { } var response OrderInfoResponse - err := a.SendAuthenticatedHTTPRequest(anxOrderInfo, request, &response) + err := a.SendAuthenticatedHTTPRequest(anxOrderInfo, req, &response) if err != nil { return OrderResponse{}, err @@ -310,13 +310,13 @@ func (a *ANX) OrderInfo(orderID string) (OrderResponse, error) { // Send withdraws a currency to an address func (a *ANX) Send(currency, address, otp, amount string) (string, error) { - request := make(map[string]interface{}) - request["ccy"] = currency - request["amount"] = amount - request["address"] = address + req := make(map[string]interface{}) + req["ccy"] = currency + req["amount"] = amount + req["address"] = address if otp != "" { - request["otp"] = otp + req["otp"] = otp } type SendResponse struct { @@ -326,7 +326,7 @@ func (a *ANX) Send(currency, address, otp, amount string) (string, error) { } var response SendResponse - err := a.SendAuthenticatedHTTPRequest(anxSend, request, &response) + err := a.SendAuthenticatedHTTPRequest(anxSend, req, &response) if err != nil { return "", err @@ -341,9 +341,9 @@ func (a *ANX) Send(currency, address, otp, amount string) (string, error) { // CreateNewSubAccount generates a new sub account func (a *ANX) CreateNewSubAccount(currency, name string) (string, error) { - request := make(map[string]interface{}) - request["ccy"] = currency - request["customRef"] = name + req := make(map[string]interface{}) + req["ccy"] = currency + req["customRef"] = name type SubaccountResponse struct { SubAccount string `json:"subAccount"` @@ -352,7 +352,7 @@ func (a *ANX) CreateNewSubAccount(currency, name string) (string, error) { } var response SubaccountResponse - err := a.SendAuthenticatedHTTPRequest(anxSubaccountNew, request, &response) + err := a.SendAuthenticatedHTTPRequest(anxSubaccountNew, req, &response) if err != nil { return "", err @@ -366,12 +366,12 @@ func (a *ANX) CreateNewSubAccount(currency, name string) (string, error) { } // GetDepositAddressByCurrency returns a deposit address for a specific currency -func (a *ANX) GetDepositAddressByCurrency(currency, name string, new bool) (string, error) { - request := make(map[string]interface{}) - request["ccy"] = currency +func (a *ANX) GetDepositAddressByCurrency(currency, name string, newAddr bool) (string, error) { + req := make(map[string]interface{}) + req["ccy"] = currency if name != "" { - request["subAccount"] = name + req["subAccount"] = name } type AddressResponse struct { @@ -383,11 +383,11 @@ func (a *ANX) GetDepositAddressByCurrency(currency, name string, new bool) (stri var response AddressResponse path := anxReceieveAddress - if new { + if newAddr { path = anxCreateAddress } - err := a.SendAuthenticatedHTTPRequest(path, request, &response) + err := a.SendAuthenticatedHTTPRequest(path, req, &response) if err != nil { return "", err } @@ -417,17 +417,17 @@ func (a *ANX) SendAuthenticatedHTTPRequest(path string, params map[string]interf a.Nonce.Inc() } - request := make(map[string]interface{}) - request["nonce"] = a.Nonce.String()[0:13] + req := make(map[string]interface{}) + req["nonce"] = a.Nonce.String()[0:13] path = fmt.Sprintf("api/%s/%s", anxAPIVersion, path) for key, value := range params { - request[key] = value + req[key] = value } - PayloadJSON, err := common.JSONEncode(request) + PayloadJSON, err := common.JSONEncode(req) if err != nil { - return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request") + return errors.New("unable to JSON request") } if a.Verbose { @@ -483,7 +483,7 @@ func getInternationalBankWithdrawalFee(currency string, amount float64) float64 if currency == symbol.HKD { fee = 250 + (WithdrawalFees[currency] * amount) } - //TODO, other fiat currencies require consultation with ANXPRO + // TODO, other fiat currencies require consultation with ANXPRO return fee } diff --git a/exchanges/anx/anx_test.go b/exchanges/anx/anx_test.go index a2ae50b388f..03eb88c6d56 100644 --- a/exchanges/anx/anx_test.go +++ b/exchanges/anx/anx_test.go @@ -71,13 +71,13 @@ func TestSetup(t *testing.T) { if a.Websocket.IsEnabled() { t.Error("Test Failed - ANX Setup() incorrect values set") } - if len(a.BaseCurrencies) <= 0 { + if len(a.BaseCurrencies) == 0 { t.Error("Test Failed - ANX Setup() incorrect values set") } - if len(a.AvailablePairs) <= 0 { + if len(a.AvailablePairs) == 0 { t.Error("Test Failed - ANX Setup() incorrect values set") } - if len(a.EnabledPairs) <= 0 { + if len(a.EnabledPairs) == 0 { t.Error("Test Failed - ANX Setup() incorrect values set") } } diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index 3b606fd1757..ecf2a482be3 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -648,7 +648,7 @@ func (b *Binance) CheckLimit(limit int) error { return nil } } - return errors.New("Incorrect limit values - valid values are 5, 10, 20, 50, 100, 500, 1000") + return errors.New("incorrect limit values - valid values are 5, 10, 20, 50, 100, 500, 1000") } // CheckSymbol checks value against a variable list @@ -659,7 +659,7 @@ func (b *Binance) CheckSymbol(symbol string) error { return nil } } - return errors.New("Incorrect symbol values - please check available pairs in configuration") + return errors.New("incorrect symbol values - please check available pairs in configuration") } // CheckIntervals checks value against a variable list @@ -669,7 +669,7 @@ func (b *Binance) CheckIntervals(interval string) error { return nil } } - return errors.New(`Incorrect interval values - valid values are "1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","1d","3d","1w","1M"`) + return errors.New(`incorrect interval values - valid values are "1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","1d","3d","1w","1M"`) } // SetValues sets the default valid values @@ -766,7 +766,7 @@ func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string return resp.ID, nil } -//GetDepositAddressForCurrency retrieves the wallet address for a given currency +// GetDepositAddressForCurrency retrieves the wallet address for a given currency func (b *Binance) GetDepositAddressForCurrency(currency string) (string, error) { path := fmt.Sprintf("%s%s", b.APIUrl, depositAddress) diff --git a/exchanges/binance/binance_types.go b/exchanges/binance/binance_types.go index f9f22c26810..df1d389a2af 100644 --- a/exchanges/binance/binance_types.go +++ b/exchanges/binance/binance_types.go @@ -290,8 +290,8 @@ type NewOrderRequest struct { Quantity float64 Price float64 NewClientOrderID string - StopPrice float64 //Used with STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. - IcebergQty float64 //Used with LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT to create an iceberg order. + StopPrice float64 // Used with STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. + IcebergQty float64 // Used with LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT to create an iceberg order. NewOrderRespType string } diff --git a/exchanges/binance/binance_websocket.go b/exchanges/binance/binance_websocket.go index 56dd04ae7fc..f877db32b7b 100644 --- a/exchanges/binance/binance_websocket.go +++ b/exchanges/binance/binance_websocket.go @@ -109,7 +109,7 @@ func (b *Binance) UpdateLocalCache(ob WebsocketDepthStream) error { priceToBeUpdated.Amount, _ = strconv.ParseFloat(asks.(string), 64) } } - updateAsk = append(updateBid, priceToBeUpdated) + updateAsk = append(updateAsk, priceToBeUpdated) } updatedTime := time.Unix(ob.Timestamp, 0) @@ -132,7 +132,7 @@ func (b *Binance) WSConnect() error { var Dialer websocket.Dialer var err error - ticker := strings.ToLower( + tick := strings.ToLower( strings.Replace( strings.Join(b.EnabledPairs, "@ticker/"), "-", "", -1)) + "@ticker" trade := strings.ToLower( @@ -147,7 +147,7 @@ func (b *Binance) WSConnect() error { wsurl := b.Websocket.GetWebsocketURL() + "/stream?streams=" + - ticker + + tick + "/" + trade + "/" + @@ -220,8 +220,7 @@ func (b *Binance) WsHandleData() { return } - switch read.Type { - case websocket.TextMessage: + if read.Type == websocket.TextMessage { multiStreamData := MultiStreamData{} err = common.JSONDecode(read.Raw, &multiStreamData) if err != nil { @@ -230,7 +229,8 @@ func (b *Binance) WsHandleData() { continue } - if strings.Contains(multiStreamData.Stream, "trade") { + switch multiStreamData.Stream { + case "trade": trade := TradeStream{} err := common.JSONDecode(multiStreamData.Data, &trade) @@ -264,8 +264,7 @@ func (b *Binance) WsHandleData() { Side: trade.EventType, } continue - - } else if strings.Contains(multiStreamData.Stream, "ticker") { + case "ticker": t := TickerStream{} err := common.JSONDecode(multiStreamData.Data, &t) @@ -289,8 +288,7 @@ func (b *Binance) WsHandleData() { b.Websocket.DataHandler <- wsTicker continue - - } else if strings.Contains(multiStreamData.Stream, "kline") { + case "kline": kline := KlineStream{} err := common.JSONDecode(multiStreamData.Data, &kline) @@ -317,8 +315,7 @@ func (b *Binance) WsHandleData() { b.Websocket.DataHandler <- wsKline continue - - } else if common.StringContains(multiStreamData.Stream, "depth") { + case "depth": depth := WebsocketDepthStream{} err := common.JSONDecode(multiStreamData.Data, &depth) diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index 17997efc4fe..d905cbf7f24 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -76,16 +76,17 @@ func (b *Binance) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pr for _, x := range b.GetEnabledCurrencies() { curr := exchange.FormatExchangeCurrency(b.Name, x) for y := range tick { - if tick[y].Symbol == curr.String() { - tickerPrice.Pair = x - tickerPrice.Ask = tick[y].AskPrice - tickerPrice.Bid = tick[y].BidPrice - tickerPrice.High = tick[y].HighPrice - tickerPrice.Last = tick[y].LastPrice - tickerPrice.Low = tick[y].LowPrice - tickerPrice.Volume = tick[y].Volume - ticker.ProcessTicker(b.Name, x, tickerPrice, assetType) + if tick[y].Symbol != curr.String() { + continue } + tickerPrice.Pair = x + tickerPrice.Ask = tick[y].AskPrice + tickerPrice.Bid = tick[y].BidPrice + tickerPrice.High = tick[y].HighPrice + tickerPrice.Last = tick[y].LastPrice + tickerPrice.Low = tick[y].LowPrice + tickerPrice.Volume = tick[y].Volume + ticker.ProcessTicker(b.Name, x, tickerPrice, assetType) } } return ticker.GetTicker(b.Name, p, assetType) @@ -192,13 +193,14 @@ func (b *Binance) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde } var requestParamsOrderType RequestParamsOrderType - if orderType == exchange.MarketOrderType { + switch orderType { + case exchange.MarketOrderType: requestParamsOrderType = BinanceRequestParamsOrderMarket - } else if orderType == exchange.LimitOrderType { + case exchange.LimitOrderType: requestParamsOrderType = BinanceRequestParamsOrderLimit - } else { + default: submitOrderResponse.IsOrderPlaced = false - return submitOrderResponse, errors.New("Unsupported order type") + return submitOrderResponse, errors.New("unsupported order type") } var orderRequest = NewOrderRequest{ @@ -306,8 +308,8 @@ func (b *Binance) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) // GetActiveOrders retrieves any orders that are active/open func (b *Binance) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("At least one currency is required to fetch order history") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("at least one currency is required to fetch order history") } var orders []exchange.OrderDetail @@ -346,8 +348,8 @@ func (b *Binance) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([ // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (b *Binance) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("At least one currency is required to fetch order history") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("at least one currency is required to fetch order history") } var orders []exchange.OrderDetail diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index 73d3c9987ef..45ebcdef986 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -210,43 +210,43 @@ func (b *Bitfinex) GetTicker(symbol string) (Ticker, error) { } // GetTickerV2 returns ticker information -func (b *Bitfinex) GetTickerV2(symbol string) (Tickerv2, error) { +func (b *Bitfinex) GetTickerV2(symb string) (Tickerv2, error) { var response []interface{} - var ticker Tickerv2 + var tick Tickerv2 - path := fmt.Sprintf("%s/v%s/%s/%s", b.APIUrl, bitfinexAPIVersion2, bitfinexTickerV2, symbol) + path := fmt.Sprintf("%s/v%s/%s/%s", b.APIUrl, bitfinexAPIVersion2, bitfinexTickerV2, symb) err := b.SendHTTPRequest(path, &response, b.Verbose) if err != nil { - return ticker, err + return tick, err } if len(response) > 10 { - ticker.FlashReturnRate = response[0].(float64) - ticker.Bid = response[1].(float64) - ticker.BidSize = response[2].(float64) - ticker.BidPeriod = int64(response[3].(float64)) - ticker.Ask = response[4].(float64) - ticker.AskSize = response[5].(float64) - ticker.AskPeriod = int64(response[6].(float64)) - ticker.DailyChange = response[7].(float64) - ticker.DailyChangePerc = response[8].(float64) - ticker.Last = response[9].(float64) - ticker.Volume = response[10].(float64) - ticker.High = response[11].(float64) - ticker.Low = response[12].(float64) + tick.FlashReturnRate = response[0].(float64) + tick.Bid = response[1].(float64) + tick.BidSize = response[2].(float64) + tick.BidPeriod = int64(response[3].(float64)) + tick.Ask = response[4].(float64) + tick.AskSize = response[5].(float64) + tick.AskPeriod = int64(response[6].(float64)) + tick.DailyChange = response[7].(float64) + tick.DailyChangePerc = response[8].(float64) + tick.Last = response[9].(float64) + tick.Volume = response[10].(float64) + tick.High = response[11].(float64) + tick.Low = response[12].(float64) } else { - ticker.Bid = response[0].(float64) - ticker.BidSize = response[1].(float64) - ticker.Ask = response[2].(float64) - ticker.AskSize = response[3].(float64) - ticker.DailyChange = response[4].(float64) - ticker.DailyChangePerc = response[5].(float64) - ticker.Last = response[6].(float64) - ticker.Volume = response[7].(float64) - ticker.High = response[8].(float64) - ticker.Low = response[9].(float64) + tick.Bid = response[0].(float64) + tick.BidSize = response[1].(float64) + tick.Ask = response[2].(float64) + tick.AskSize = response[3].(float64) + tick.DailyChange = response[4].(float64) + tick.DailyChangePerc = response[5].(float64) + tick.Last = response[6].(float64) + tick.Volume = response[7].(float64) + tick.High = response[8].(float64) + tick.Low = response[9].(float64) } - return ticker, nil + return tick, nil } // GetTickersV2 returns ticker information for multiple symbols @@ -438,13 +438,13 @@ func (b *Bitfinex) GetTradesV2(currencyPair string, timestampStart, timestampEnd if tempHistory.Amount < 0 { tempHistory.Type = "SELL" - tempHistory.Amount = tempHistory.Amount * -1 + tempHistory.Amount *= -1 } actualHistory = append(actualHistory, tempHistory) } - //re-order index + // re-order index if reOrderResp { orderedHistory := make([]TradeStructureV2, len(actualHistory)) for i, quickRange := range actualHistory { @@ -521,18 +521,18 @@ func (b *Bitfinex) GetAccountSummary() (AccountSummary, error) { // NewDeposit returns a new deposit address // Method - Example methods accepted: “bitcoin”, “litecoin”, “ethereum”, -//“tethers", "ethereumc", "zcash", "monero", "iota", "bcash" +// “tethers", "ethereumc", "zcash", "monero", "iota", "bcash" // WalletName - accepted: “trading”, “exchange”, “deposit” // renew - Default is 0. If set to 1, will return a new unused deposit address func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResponse, error) { response := DepositResponse{} - request := make(map[string]interface{}) - request["method"] = method - request["wallet_name"] = walletName - request["renew"] = renew + req := make(map[string]interface{}) + req["method"] = method + req["wallet_name"] = walletName + req["renew"] = renew return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexDeposit, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexDeposit, req, &response) } // GetKeyPermissions checks the permissions of the key being used to generate @@ -567,31 +567,31 @@ func (b *Bitfinex) GetAccountBalance() ([]Balance, error) { // WalletTo - example "deposit" func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo string) ([]WalletTransfer, error) { response := []WalletTransfer{} - request := make(map[string]interface{}) - request["amount"] = amount - request["currency"] = currency - request["walletfrom"] = walletFrom - request["walletTo"] = walletTo + req := make(map[string]interface{}) + req["amount"] = amount + req["currency"] = currency + req["walletfrom"] = walletFrom + req["walletTo"] = walletTo return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexTransfer, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexTransfer, req, &response) } // WithdrawCryptocurrency requests a withdrawal from one of your wallets. // For FIAT, use WithdrawFIAT func (b *Bitfinex) WithdrawCryptocurrency(withdrawType, wallet, address, currency, paymentID string, amount float64) ([]Withdrawal, error) { response := []Withdrawal{} - request := make(map[string]interface{}) - request["withdraw_type"] = withdrawType - request["walletselected"] = wallet - request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - request["address"] = address + req := make(map[string]interface{}) + req["withdraw_type"] = withdrawType + req["walletselected"] = wallet + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["address"] = address if currency == symbol.XMR { - request["paymend_id"] = paymentID + req["paymend_id"] = paymentID } return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexWithdrawal, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexWithdrawal, req, &response) } // WithdrawFIAT requests a withdrawal from one of your wallets. @@ -601,85 +601,85 @@ func (b *Bitfinex) WithdrawFIAT(withdrawType, wallet, wireCurrency, intermediaryBankName, intermediaryBankAddress, intermediaryBankCity, intermediaryBankCountry, intermediaryBankSwift string, amount, accountNumber, intermediaryBankAccountNumber float64, isExpressWire, requiresIntermediaryBank bool) ([]Withdrawal, error) { response := []Withdrawal{} - request := make(map[string]interface{}) - request["withdraw_type"] = withdrawType - request["walletselected"] = wallet - request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - request["account_name"] = accountName - request["account_number"] = strconv.FormatFloat(accountNumber, 'f', -1, 64) - request["bank_name"] = bankName - request["bank_address"] = bankAddress - request["bank_city"] = bankCity - request["bank_country"] = bankCountry - request["expressWire"] = isExpressWire - request["swift"] = swift - request["detail_payment"] = transactionMessage - request["currency"] = wireCurrency - request["account_address"] = bankAddress + req := make(map[string]interface{}) + req["withdraw_type"] = withdrawType + req["walletselected"] = wallet + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["account_name"] = accountName + req["account_number"] = strconv.FormatFloat(accountNumber, 'f', -1, 64) + req["bank_name"] = bankName + req["bank_address"] = bankAddress + req["bank_city"] = bankCity + req["bank_country"] = bankCountry + req["expressWire"] = isExpressWire + req["swift"] = swift + req["detail_payment"] = transactionMessage + req["currency"] = wireCurrency + req["account_address"] = bankAddress if requiresIntermediaryBank { - request["intermediary_bank_name"] = intermediaryBankName - request["intermediary_bank_address"] = intermediaryBankAddress - request["intermediary_bank_city"] = intermediaryBankCity - request["intermediary_bank_country"] = intermediaryBankCountry - request["intermediary_bank_account"] = strconv.FormatFloat(intermediaryBankAccountNumber, 'f', -1, 64) - request["intermediary_bank_swift"] = intermediaryBankSwift + req["intermediary_bank_name"] = intermediaryBankName + req["intermediary_bank_address"] = intermediaryBankAddress + req["intermediary_bank_city"] = intermediaryBankCity + req["intermediary_bank_country"] = intermediaryBankCountry + req["intermediary_bank_account"] = strconv.FormatFloat(intermediaryBankAccountNumber, 'f', -1, 64) + req["intermediary_bank_swift"] = intermediaryBankSwift } return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexWithdrawal, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexWithdrawal, req, &response) } // NewOrder submits a new order and returns a order information // Major Upgrade needed on this function to include all query params -func (b *Bitfinex) NewOrder(currencyPair string, amount float64, price float64, buy bool, Type string, hidden bool) (Order, error) { +func (b *Bitfinex) NewOrder(currencyPair string, amount, price float64, buy bool, orderType string, hidden bool) (Order, error) { response := Order{} - request := make(map[string]interface{}) - request["symbol"] = currencyPair - request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - request["price"] = strconv.FormatFloat(price, 'f', -1, 64) - request["exchange"] = "bitfinex" - request["type"] = Type - request["is_hidden"] = hidden + req := make(map[string]interface{}) + req["symbol"] = currencyPair + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["price"] = strconv.FormatFloat(price, 'f', -1, 64) + req["exchange"] = "bitfinex" + req["type"] = orderType + req["is_hidden"] = hidden if buy { - request["side"] = "buy" + req["side"] = "buy" } else { - request["side"] = "sell" + req["side"] = "sell" } return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderNew, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderNew, req, &response) } // NewOrderMulti allows several new orders at once func (b *Bitfinex) NewOrderMulti(orders []PlaceOrder) (OrderMultiResponse, error) { response := OrderMultiResponse{} - request := make(map[string]interface{}) - request["orders"] = orders + req := make(map[string]interface{}) + req["orders"] = orders return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderNewMulti, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderNewMulti, req, &response) } // CancelExistingOrder cancels a single order by OrderID -func (b *Bitfinex) CancelExistingOrder(OrderID int64) (Order, error) { +func (b *Bitfinex) CancelExistingOrder(orderID int64) (Order, error) { response := Order{} - request := make(map[string]interface{}) - request["order_id"] = OrderID + req := make(map[string]interface{}) + req["order_id"] = orderID return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancel, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancel, req, &response) } // CancelMultipleOrders cancels multiple orders -func (b *Bitfinex) CancelMultipleOrders(OrderIDs []int64) (string, error) { +func (b *Bitfinex) CancelMultipleOrders(orderIDs []int64) (string, error) { response := GenericResponse{} - request := make(map[string]interface{}) - request["order_ids"] = OrderIDs + req := make(map[string]interface{}) + req["order_ids"] = orderIDs return response.Result, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancelMulti, request, nil) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancelMulti, req, nil) } // CancelAllExistingOrders cancels all active and open orders @@ -691,45 +691,45 @@ func (b *Bitfinex) CancelAllExistingOrders() (string, error) { } // ReplaceOrder replaces an older order with a new order -func (b *Bitfinex) ReplaceOrder(OrderID int64, Symbol string, Amount float64, Price float64, Buy bool, Type string, Hidden bool) (Order, error) { +func (b *Bitfinex) ReplaceOrder(orderID int64, symbol string, amount, price float64, buy bool, orderType string, hidden bool) (Order, error) { response := Order{} - request := make(map[string]interface{}) - request["order_id"] = OrderID - request["symbol"] = Symbol - request["amount"] = strconv.FormatFloat(Amount, 'f', -1, 64) - request["price"] = strconv.FormatFloat(Price, 'f', -1, 64) - request["exchange"] = "bitfinex" - request["type"] = Type - request["is_hidden"] = Hidden - - if Buy { - request["side"] = "buy" + req := make(map[string]interface{}) + req["order_id"] = orderID + req["symbol"] = symbol + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["price"] = strconv.FormatFloat(price, 'f', -1, 64) + req["exchange"] = "bitfinex" + req["type"] = orderType + req["is_hidden"] = hidden + + if buy { + req["side"] = "buy" } else { - request["side"] = "sell" + req["side"] = "sell" } return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancelReplace, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancelReplace, req, &response) } // GetOrderStatus returns order status information -func (b *Bitfinex) GetOrderStatus(OrderID int64) (Order, error) { +func (b *Bitfinex) GetOrderStatus(orderID int64) (Order, error) { orderStatus := Order{} - request := make(map[string]interface{}) - request["order_id"] = OrderID + req := make(map[string]interface{}) + req["order_id"] = orderID return orderStatus, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderStatus, request, &orderStatus) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderStatus, req, &orderStatus) } // GetInactiveOrders returns order status information func (b *Bitfinex) GetInactiveOrders() ([]Order, error) { var response []Order - request := make(map[string]interface{}) - request["limit"] = "100" + req := make(map[string]interface{}) + req["limit"] = "100" return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexInactiveOrders, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexInactiveOrders, req, &response) } // GetOpenOrders returns all active orders and statuses @@ -749,10 +749,10 @@ func (b *Bitfinex) GetActivePositions() ([]Position, error) { } // ClaimPosition allows positions to be claimed -func (b *Bitfinex) ClaimPosition(PositionID int) (Position, error) { +func (b *Bitfinex) ClaimPosition(positionID int) (Position, error) { response := Position{} - request := make(map[string]interface{}) - request["position_id"] = PositionID + req := make(map[string]interface{}) + req["position_id"] = positionID return response, b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexClaimPosition, nil, nil) @@ -761,103 +761,103 @@ func (b *Bitfinex) ClaimPosition(PositionID int) (Position, error) { // GetBalanceHistory returns balance history for the account func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince, timeUntil time.Time, limit int, wallet string) ([]BalanceHistory, error) { response := []BalanceHistory{} - request := make(map[string]interface{}) - request["currency"] = symbol + req := make(map[string]interface{}) + req["currency"] = symbol if !timeSince.IsZero() { - request["since"] = timeSince + req["since"] = timeSince } if !timeUntil.IsZero() { - request["until"] = timeUntil + req["until"] = timeUntil } if limit > 0 { - request["limit"] = limit + req["limit"] = limit } if len(wallet) > 0 { - request["wallet"] = wallet + req["wallet"] = wallet } return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexHistory, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexHistory, req, &response) } // GetMovementHistory returns an array of past deposits and withdrawals func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUntil time.Time, limit int) ([]MovementHistory, error) { response := []MovementHistory{} - request := make(map[string]interface{}) - request["currency"] = symbol + req := make(map[string]interface{}) + req["currency"] = symbol if len(method) > 0 { - request["method"] = method + req["method"] = method } if !timeSince.IsZero() { - request["since"] = timeSince + req["since"] = timeSince } if !timeUntil.IsZero() { - request["until"] = timeUntil + req["until"] = timeUntil } if limit > 0 { - request["limit"] = limit + req["limit"] = limit } return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexHistoryMovements, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexHistoryMovements, req, &response) } // GetTradeHistory returns past executed trades func (b *Bitfinex) GetTradeHistory(currencyPair string, timestamp, until time.Time, limit, reverse int) ([]TradeHistory, error) { response := []TradeHistory{} - request := make(map[string]interface{}) - request["currency"] = currencyPair - request["timestamp"] = timestamp + req := make(map[string]interface{}) + req["currency"] = currencyPair + req["timestamp"] = timestamp if !until.IsZero() { - request["until"] = until + req["until"] = until } if limit > 0 { - request["limit"] = limit + req["limit"] = limit } if reverse > 0 { - request["reverse"] = reverse + req["reverse"] = reverse } return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexTradeHistory, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexTradeHistory, req, &response) } // NewOffer submits a new offer func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, direction string) (Offer, error) { response := Offer{} - request := make(map[string]interface{}) - request["currency"] = symbol - request["amount"] = amount - request["rate"] = rate - request["period"] = period - request["direction"] = direction + req := make(map[string]interface{}) + req["currency"] = symbol + req["amount"] = amount + req["rate"] = rate + req["period"] = period + req["direction"] = direction return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOfferNew, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOfferNew, req, &response) } // CancelOffer cancels offer by offerID -func (b *Bitfinex) CancelOffer(OfferID int64) (Offer, error) { +func (b *Bitfinex) CancelOffer(offerID int64) (Offer, error) { response := Offer{} - request := make(map[string]interface{}) - request["offer_id"] = OfferID + req := make(map[string]interface{}) + req["offer_id"] = offerID return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOfferCancel, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOfferCancel, req, &response) } // GetOfferStatus checks offer status whether it has been cancelled, execute or // is still active -func (b *Bitfinex) GetOfferStatus(OfferID int64) (Offer, error) { +func (b *Bitfinex) GetOfferStatus(offerID int64) (Offer, error) { response := Offer{} - request := make(map[string]interface{}) - request["offer_id"] = OfferID + req := make(map[string]interface{}) + req["offer_id"] = offerID return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderStatus, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderStatus, req, &response) } // GetActiveCredits returns all available credits @@ -903,13 +903,13 @@ func (b *Bitfinex) GetMarginTotalTakenFunds() ([]MarginTotalTakenFunds, error) { } // CloseMarginFunding closes an unused or used taken fund -func (b *Bitfinex) CloseMarginFunding(SwapID int64) (Offer, error) { +func (b *Bitfinex) CloseMarginFunding(swapID int64) (Offer, error) { response := Offer{} - request := make(map[string]interface{}) - request["swap_id"] = SwapID + req := make(map[string]interface{}) + req["swap_id"] = swapID return response, - b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexMarginClose, request, &response) + b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexMarginClose, req, &response) } // SendHTTPRequest sends an unauthenticated request @@ -930,17 +930,17 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[ b.Nonce.Inc() } - request := make(map[string]interface{}) - request["request"] = fmt.Sprintf("%s%s", bitfinexAPIVersion, path) - request["nonce"] = b.Nonce.String() + req := make(map[string]interface{}) + req["request"] = fmt.Sprintf("%s%s", bitfinexAPIVersion, path) + req["nonce"] = b.Nonce.String() for key, value := range params { - request[key] = value + req[key] = value } - PayloadJSON, err := common.JSONEncode(request) + PayloadJSON, err := common.JSONEncode(req) if err != nil { - return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request") + return errors.New("sendAuthenticatedAPIRequest: unable to JSON request") } if b.Verbose { @@ -996,14 +996,14 @@ func (b *Bitfinex) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { // GetCryptocurrencyWithdrawalFee returns an estimate of fee based on type of transaction func (b *Bitfinex) GetCryptocurrencyWithdrawalFee(currency string, accountFees AccountFees) (fee float64, err error) { - switch accountFees.Withdraw[currency].(type) { + switch result := accountFees.Withdraw[currency].(type) { case string: - fee, err = strconv.ParseFloat(accountFees.Withdraw[currency].(string), 64) + fee, err = strconv.ParseFloat(result, 64) if err != nil { return 0, err } case float64: - fee = accountFees.Withdraw[currency].(float64) + fee = result } return fee, nil diff --git a/exchanges/bitfinex/bitfinex_websocket.go b/exchanges/bitfinex/bitfinex_websocket.go index abd319d5faf..6136ce09ac4 100644 --- a/exchanges/bitfinex/bitfinex_websocket.go +++ b/exchanges/bitfinex/bitfinex_websocket.go @@ -54,10 +54,10 @@ var pongReceive chan struct{} // WsPingHandler sends a ping request to the websocket server func (b *Bitfinex) WsPingHandler() error { - request := make(map[string]string) - request["event"] = "ping" + req := make(map[string]string) + req["event"] = "ping" - return b.WsSend(request) + return b.WsSend(req) } // WsSend sends data to the websocket server @@ -71,42 +71,42 @@ func (b *Bitfinex) WsSend(data interface{}) error { // WsSubscribe subscribes to the websocket channel func (b *Bitfinex) WsSubscribe(channel string, params map[string]string) error { - request := make(map[string]string) - request["event"] = "subscribe" - request["channel"] = channel + req := make(map[string]string) + req["event"] = "subscribe" + req["channel"] = channel if len(params) > 0 { for k, v := range params { - request[k] = v + req[k] = v } } - return b.WsSend(request) + return b.WsSend(req) } // WsSendAuth sends a autheticated event payload func (b *Bitfinex) WsSendAuth() error { - request := make(map[string]interface{}) + req := make(map[string]interface{}) payload := "AUTH" + strconv.FormatInt(time.Now().UnixNano(), 10)[:13] - request["event"] = "auth" - request["apiKey"] = b.APIKey + req["event"] = "auth" + req["apiKey"] = b.APIKey - request["authSig"] = common.HexEncodeToString( + req["authSig"] = common.HexEncodeToString( common.GetHMAC( common.HashSHA512_384, []byte(payload), []byte(b.APISecret))) - request["authPayload"] = payload + req["authPayload"] = payload - return b.WsSend(request) + return b.WsSend(req) } // WsSendUnauth sends an unauthenticated payload func (b *Bitfinex) WsSendUnauth() error { - request := make(map[string]string) - request["event"] = "unauth" + req := make(map[string]string) + req["event"] = "unauth" - return b.WsSend(request) + return b.WsSend(req) } // WsAddSubscriptionChannel adds a new subscription channel to the @@ -145,12 +145,12 @@ func (b *Bitfinex) WsConnect() error { b.WebsocketConn, _, err = Dialer.Dial(b.Websocket.GetWebsocketURL(), http.Header{}) if err != nil { - return fmt.Errorf("Unable to connect to Websocket. Error: %s", err) + return fmt.Errorf("unable to connect to Websocket. Error: %s", err) } _, resp, err := b.WebsocketConn.ReadMessage() if err != nil { - return fmt.Errorf("Unable to read from Websocket. Error: %s", err) + return fmt.Errorf("unable to read from Websocket. Error: %s", err) } var hs WebsocketHandshake @@ -234,8 +234,7 @@ func (b *Bitfinex) WsDataHandler() { return } - switch stream.Type { - case websocket.TextMessage: + if stream.Type == websocket.TextMessage { var result interface{} common.JSONDecode(stream.Raw, &result) @@ -482,7 +481,7 @@ func (b *Bitfinex) WsDataHandler() { newAmount := trades[0].Amount if newAmount < 0 { side = "SELL" - newAmount = newAmount * -1 + newAmount *= -1 } b.Websocket.DataHandler <- exchange.TradeData{ diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index 013118dd1bf..6e8ecd80e1e 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -243,7 +243,7 @@ func (b *Bitfinex) WithdrawCryptocurrencyFunds(withdrawRequest exchange.Withdraw return "", err } if len(resp) == 0 { - return "", errors.New("No withdrawID returned. Check order status") + return "", errors.New("no withdrawID returned. Check order status") } return fmt.Sprintf("%v", resp[0].WithdrawalID), err @@ -268,7 +268,7 @@ func (b *Bitfinex) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest) ( return "", err } if len(resp) == 0 { - return "", errors.New("No withdrawID returned. Check order status") + return "", errors.New("no withdrawID returned. Check order status") } var withdrawalSuccesses string @@ -332,13 +332,14 @@ func (b *Bitfinex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ( ExecutedAmount: order.ExecutedAmount, } - if order.IsLive { + switch { + case order.IsLive: orderDetail.Status = string(exchange.ActiveOrderStatus) - } else if order.IsCancelled { + case order.IsCancelled: orderDetail.Status = string(exchange.CancelledOrderStatus) - } else if order.IsHidden { + case order.IsHidden: orderDetail.Status = string(exchange.HiddenOrderStatus) - } else { + default: orderDetail.Status = string(exchange.UnknownOrderStatus) } @@ -391,13 +392,14 @@ func (b *Bitfinex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ( CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol), } - if order.IsLive { + switch { + case order.IsLive: orderDetail.Status = string(exchange.ActiveOrderStatus) - } else if order.IsCancelled { + case order.IsCancelled: orderDetail.Status = string(exchange.CancelledOrderStatus) - } else if order.IsHidden { + case order.IsHidden: orderDetail.Status = string(exchange.HiddenOrderStatus) - } else { + default: orderDetail.Status = string(exchange.UnknownOrderStatus) } diff --git a/exchanges/bitflyer/bitflyer.go b/exchanges/bitflyer/bitflyer.go index f3535135e23..ce9aa6332e7 100644 --- a/exchanges/bitflyer/bitflyer.go +++ b/exchanges/bitflyer/bitflyer.go @@ -251,10 +251,10 @@ func (b *Bitflyer) GetExchangeStatus() (string, error) { // GetChats returns trollbox chat log // Note: returns vary from instant to infinty -func (b *Bitflyer) GetChats(FromDate string) ([]ChatLog, error) { +func (b *Bitflyer) GetChats(fromDate string) ([]ChatLog, error) { var resp []ChatLog v := url.Values{} - v.Set("from_date", FromDate) + v.Set("from_date", fromDate) path := fmt.Sprintf("%s%s?%s", b.APIUrl, pubGetChats, v.Encode()) return resp, b.SendHTTPRequest(path, &resp) @@ -386,9 +386,9 @@ func (b *Bitflyer) SendHTTPRequest(path string, result interface{}) error { // if you have access and update the authenticated requests // TODO: Fill out this function once API access is obtained func (b *Bitflyer) SendAuthHTTPRequest() { - //headers := make(map[string]string) - //headers["ACCESS-KEY"] = b.APIKey - //headers["ACCESS-TIMESTAMP"] = strconv.FormatInt(time.Now().UnixNano(), 10) + // headers := make(map[string]string) + // headers["ACCESS-KEY"] = b.APIKey + // headers["ACCESS-TIMESTAMP"] = strconv.FormatInt(time.Now().UnixNano(), 10) } // GetFee returns an estimate of fee based on type of transaction @@ -411,28 +411,22 @@ func (b *Bitflyer) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { } // calculateTradingFee returns fee when performing a trade -func calculateTradingFee(purchasePrice float64, amount float64) float64 { +func calculateTradingFee(purchasePrice, amount float64) float64 { fee := 0.0015 // bitflyer has fee tiers, but does not disclose them via API, so the largest has to be assumed return fee * amount * purchasePrice } func getDepositFee(bankTransactionType exchange.InternationalBankTransactionType, currency string) (fee float64) { - switch bankTransactionType { - case exchange.WireTransfer: - switch currency { - case symbol.JPY: - fee = 324 - } + if bankTransactionType == exchange.WireTransfer && currency == symbol.JPY { + fee = 324 } return fee } func getWithdrawalFee(bankTransactionType exchange.InternationalBankTransactionType, currency string, amount float64) (fee float64) { - switch bankTransactionType { - case exchange.WireTransfer: - switch currency { - case symbol.JPY: + if bankTransactionType == exchange.WireTransfer { + if currency == symbol.JPY { if amount < 30000 { fee = 540 } else { diff --git a/exchanges/bitflyer/bitflyer_test.go b/exchanges/bitflyer/bitflyer_test.go index 4d3dd9d459a..446e78c5796 100644 --- a/exchanges/bitflyer/bitflyer_test.go +++ b/exchanges/bitflyer/bitflyer_test.go @@ -5,11 +5,10 @@ import ( "testing" "github.com/thrasher-/gocryptotrader/common" - "github.com/thrasher-/gocryptotrader/currency/symbol" - "github.com/thrasher-/gocryptotrader/exchanges" - "github.com/thrasher-/gocryptotrader/config" "github.com/thrasher-/gocryptotrader/currency/pair" + "github.com/thrasher-/gocryptotrader/currency/symbol" + exchange "github.com/thrasher-/gocryptotrader/exchanges" ) // Please supply your own keys here for due diligence testing diff --git a/exchanges/bithumb/bithumb.go b/exchanges/bithumb/bithumb.go index 24b1a547b28..bb63f44147f 100644 --- a/exchanges/bithumb/bithumb.go +++ b/exchanges/bithumb/bithumb.go @@ -307,7 +307,7 @@ func (b *Bithumb) GetAccountBalance(c string) (FullBalance, error) { fullBalance.Xcoin[c] = val default: - return fullBalance, fmt.Errorf("GetAccountBalance error tag name %s unhandled", + return fullBalance, fmt.Errorf("getaccountbalance error tag name %s unhandled", splitTag) } } @@ -597,7 +597,7 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(path string, params url.Values, r err = common.JSONDecode(intermediary, &errCapture) if err == nil { if errCapture.Status != "" && errCapture.Status != "0000" { - return fmt.Errorf("SendAuthenticatedHTTPRequest error Code:%s Message:%s", + return fmt.Errorf("sendAuthenticatedAPIRequest error code: %s message:%s", errCapture.Status, errCode[errCapture.Status]) } @@ -627,9 +627,8 @@ func (b *Bithumb) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { } // calculateTradingFee returns fee when performing a trade -func calculateTradingFee(purchasePrice float64, amount float64) float64 { +func calculateTradingFee(purchasePrice, amount float64) float64 { fee := 0.0015 - return fee * amount * purchasePrice } diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index 6eb881861c6..435a562b693 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -53,7 +53,7 @@ func (b *Bithumb) GetTradingPairs() ([]string, error) { } for x := range currencies { - currencies[x] = currencies[x] + "KRW" + currencies[x] += "KRW" } return currencies, nil @@ -136,7 +136,7 @@ func (b *Bithumb) GetAccountInfo() (exchange.AccountInfo, error) { for key, totalAmount := range bal.Total { hold, ok := bal.InUse[key] if !ok { - return info, fmt.Errorf("GetAccountInfo error - in use item not found for currency %s", + return info, fmt.Errorf("getAccountInfo error - in use item not found for currency %s", key) } @@ -270,10 +270,10 @@ func (b *Bithumb) WithdrawCryptocurrencyFunds(withdrawRequest exchange.WithdrawR // withdrawal is submitted func (b *Bithumb) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest) (string, error) { if math.Mod(withdrawRequest.Amount, 1) != 0 { - return "", errors.New("KRW withdrawals do not support decimal places") + return "", errors.New("currency KRW does not support decimal places") } if withdrawRequest.Currency.String() != symbol.KRW { - return "", errors.New("Only KRW supported") + return "", errors.New("only KRW is supported") } bankDetails := fmt.Sprintf("%v_%v", withdrawRequest.BankCode, withdrawRequest.BankName) bankAccountNumber := strconv.FormatFloat(withdrawRequest.BankAccountNumber, 'f', -1, 64) diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index 13a6e906c4d..258d1f6a394 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -939,8 +939,7 @@ func (b *Bitmex) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { var fee float64 var err error - switch feeBuilder.FeeType { - case exchange.CryptocurrencyTradeFee: + if feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount, feeBuilder.IsMaker) } if fee < 0 { @@ -950,7 +949,7 @@ func (b *Bitmex) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { } // calculateTradingFee returns the fee for trading any currency on Bittrex -func calculateTradingFee(purchasePrice float64, amount float64, isMaker bool) float64 { +func calculateTradingFee(purchasePrice, amount float64, isMaker bool) float64 { var fee = 0.000750 if isMaker { diff --git a/exchanges/bitmex/bitmex_parameters.go b/exchanges/bitmex/bitmex_parameters.go index 60f736c9c50..807a5821d56 100644 --- a/exchanges/bitmex/bitmex_parameters.go +++ b/exchanges/bitmex/bitmex_parameters.go @@ -86,7 +86,7 @@ func StructValsToURLVals(v interface{}) (url.Values, error) { // APIKeyParams contains all the parameters to send to the API endpoint type APIKeyParams struct { - //API Key ID (public component). + // API Key ID (public component). APIKeyID string `json:"apiKeyID,omitempty"` } @@ -160,7 +160,7 @@ type ChatSendParams struct { // VerifyData verifies outgoing data sets func (p ChatSendParams) VerifyData() error { if p.ChannelID == 0 || p.Message == "" { - return errors.New("ChatSendParams error params not correctly set") + return errors.New("chatSendParams error params not correctly set") } return nil } @@ -287,7 +287,7 @@ type OrderNewParams struct { // are specified. OrdType string `json:"ordType,omitempty"` - //OrderQty Order quantity in units of the instrument (i.e. contracts). + // OrderQty Order quantity in units of the instrument (i.e. contracts). OrderQty float64 `json:"orderQty,omitempty"` // PegOffsetValue - [Optional] trailing offset from the current price for diff --git a/exchanges/bitmex/bitmex_websocket.go b/exchanges/bitmex/bitmex_websocket.go index 5431da5ed6a..3acc7bae692 100644 --- a/exchanges/bitmex/bitmex_websocket.go +++ b/exchanges/bitmex/bitmex_websocket.go @@ -206,17 +206,18 @@ func (b *Bitmex) wsHandleIncomingData() { if decodedResp.Success { if b.Verbose { if len(quickCapture) == 3 { - log.Debugf("Bitmex Websocket: Successfully subscribed to %s", - decodedResp.Subscribe) + log.Debugf("%s websocket: Successfully subscribed to %s", + b.Name, decodedResp.Subscribe) } else { - log.Debugf("Bitmex Websocket: Successfully authenticated websocket connection") + log.Debugf("%s websocket: Successfully authenticated websocket connection", + b.Name) } } continue } - b.Websocket.DataHandler <- fmt.Errorf("Bitmex websocket error: Unable to subscribe %s", - decodedResp.Subscribe) + b.Websocket.DataHandler <- fmt.Errorf("%s websocket error: Unable to subscribe %s", + b.Name, decodedResp.Subscribe) } else if _, ok := quickCapture["table"]; ok { var decodedResp WebsocketMainResponse @@ -291,8 +292,8 @@ func (b *Bitmex) wsHandleIncomingData() { b.Websocket.DataHandler <- announcement.Data default: - b.Websocket.DataHandler <- fmt.Errorf("Bitmex websocket error: Table unknown - %s", - decodedResp.Table) + b.Websocket.DataHandler <- fmt.Errorf("%s websocket error: Table unknown - %s", + b.Name, decodedResp.Table) } } } @@ -411,15 +412,11 @@ func (b *Bitmex) websocketSubscribe() error { subscriber.Arguments = append(subscriber.Arguments, bitmexWSAnnouncement) for _, contract := range contracts { - // Orderbook subscribe - subscriber.Arguments = append(subscriber.Arguments, - bitmexWSOrderbookL2+":"+contract.Pair().String()) - - // Trade subscribe + // Orderbook and Trade subscribe + // NOTE more added here in future subscriber.Arguments = append(subscriber.Arguments, + bitmexWSOrderbookL2+":"+contract.Pair().String(), bitmexWSTrade+":"+contract.Pair().String()) - - // NOTE more added here in future } return b.WebsocketConn.WriteJSON(subscriber) @@ -432,14 +429,11 @@ func (b *Bitmex) websocketSendAuth() error { hmac := common.GetHMAC(common.HashSHA256, []byte("GET/realtime"+newTimestamp), []byte(b.APISecret)) - signature := common.HexEncodeToString(hmac) var sendAuth WebsocketRequest sendAuth.Command = "authKeyExpires" - sendAuth.Arguments = append(sendAuth.Arguments, b.APIKey) - sendAuth.Arguments = append(sendAuth.Arguments, timestamp) - sendAuth.Arguments = append(sendAuth.Arguments, signature) - + sendAuth.Arguments = append(sendAuth.Arguments, b.APIKey, timestamp, + signature) return b.WebsocketConn.WriteJSON(sendAuth) } diff --git a/exchanges/bitmex/bitmex_wrapper.go b/exchanges/bitmex/bitmex_wrapper.go index 8c22cc66362..4bc0c23dcc8 100644 --- a/exchanges/bitmex/bitmex_wrapper.go +++ b/exchanges/bitmex/bitmex_wrapper.go @@ -2,6 +2,7 @@ package bitmex import ( "errors" + "fmt" "math" "sync" "time" @@ -63,7 +64,7 @@ func (b *Bitmex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pri } if len(tick) == 0 { - return tickerPrice, errors.New("Bitmex REST error: no ticker return") + return tickerPrice, fmt.Errorf("%s REST error: no ticker return", b.Name) } tickerPrice.Pair = p @@ -153,9 +154,7 @@ func (b *Bitmex) GetAccountInfo() (exchange.AccountInfo, error) { // GetFundingHistory returns funding history, deposits and // withdrawals func (b *Bitmex) GetFundingHistory() ([]exchange.FundHistory, error) { - var fundHistory []exchange.FundHistory - // b.GetFullFundingHistory() - return fundHistory, common.ErrNotYetImplemented + return nil, common.ErrNotYetImplemented } // GetExchangeHistory returns historic trade data since exchange opening. diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index 17439787a34..5cf036aa841 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -192,7 +192,7 @@ func getInternationalBankDepositFee(amount float64) float64 { } // CalculateTradingFee returns fee on a currency pair -func (b *Bitstamp) CalculateTradingFee(currency string, purchasePrice float64, amount float64) float64 { +func (b *Bitstamp) CalculateTradingFee(currency string, purchasePrice, amount float64) float64 { var fee float64 switch currency { @@ -233,7 +233,7 @@ func (b *Bitstamp) GetTicker(currency string, hourly bool) (Ticker, error) { // GetOrderbook Returns a JSON dictionary with "bids" and "asks". Each is a list // of open orders and each order is represented as a list holding the price and -//the amount. +// the amount. func (b *Bitstamp) GetOrderbook(currency string) (Orderbook, error) { type response struct { Timestamp int64 `json:"timestamp,string"` @@ -415,20 +415,20 @@ func (b *Bitstamp) GetOpenOrders(currencyPair string) ([]Order, error) { } // GetOrderStatus returns an the status of an order by its ID -func (b *Bitstamp) GetOrderStatus(OrderID int64) (OrderStatus, error) { +func (b *Bitstamp) GetOrderStatus(orderID int64) (OrderStatus, error) { resp := OrderStatus{} req := url.Values{} - req.Add("id", strconv.FormatInt(OrderID, 10)) + req.Add("id", strconv.FormatInt(orderID, 10)) return resp, b.SendAuthenticatedHTTPRequest(bitstampAPIOrderStatus, false, req, &resp) } // CancelExistingOrder cancels order by ID -func (b *Bitstamp) CancelExistingOrder(OrderID int64) (bool, error) { +func (b *Bitstamp) CancelExistingOrder(orderID int64) (bool, error) { result := false var req = url.Values{} - req.Add("id", strconv.FormatInt(OrderID, 10)) + req.Add("id", strconv.FormatInt(orderID, 10)) return result, b.SendAuthenticatedHTTPRequest(bitstampAPICancelOrder, true, req, &result) @@ -443,7 +443,7 @@ func (b *Bitstamp) CancelAllExistingOrders() (bool, error) { } // PlaceOrder places an order on the exchange. -func (b *Bitstamp) PlaceOrder(currencyPair string, price float64, amount float64, buy, market bool) (Order, error) { +func (b *Bitstamp) PlaceOrder(currencyPair string, price, amount float64, buy, market bool) (Order, error) { var req = url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) req.Add("price", strconv.FormatFloat(price, 'f', -1, 64)) diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index 0b2d7ca3d18..7d425d7f080 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -254,10 +254,11 @@ func TestGetOpenOrders(t *testing.T) { func TestGetOrderStatus(t *testing.T) { t.Parallel() - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" { + + if !areTestAPIKeysSet() { t.Skip() } + _, err := b.GetOrderStatus(1337) if err == nil { t.Error("Test Failed - GetOpenOrders() error") @@ -284,10 +285,11 @@ func TestCancelAllExistingOrders(t *testing.T) { func TestPlaceOrder(t *testing.T) { t.Parallel() - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" { + + if !areTestAPIKeysSet() { t.Skip() } + _, err := b.PlaceOrder("btcusd", 0.01, 1, true, true) if err == nil { t.Error("Test Failed - PlaceOrder() error") @@ -309,8 +311,8 @@ func TestGetWithdrawalRequests(t *testing.T) { func TestCryptoWithdrawal(t *testing.T) { t.Parallel() - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" { + + if !areTestAPIKeysSet() { t.Skip() } @@ -340,14 +342,16 @@ func TestGetUnconfirmedBitcoinDeposits(t *testing.T) { func TestTransferAccountBalance(t *testing.T) { t.Parallel() - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" { + + if !areTestAPIKeysSet() { t.Skip() } + _, err := b.TransferAccountBalance(1, "", "", true) if err == nil { t.Error("Test Failed - TransferAccountBalance() error", err) } + _, err = b.TransferAccountBalance(1, "btc", "", false) if err == nil { t.Error("Test Failed - TransferAccountBalance() error", err) diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index fbd0de7545d..a21c22a8c76 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -43,8 +43,8 @@ func (b *Bitstamp) Run() { if pairs[x].Trading != "Enabled" { continue } - pair := strings.Split(pairs[x].Name, "/") - currencies = append(currencies, pair[0]+pair[1]) + p := strings.Split(pairs[x].Name, "/") + currencies = append(currencies, p[0]+p[1]) } err = b.UpdateCurrencies(currencies, false, false) if err != nil { @@ -128,32 +128,28 @@ func (b *Bitstamp) GetAccountInfo() (exchange.AccountInfo, error) { return response, err } - var currencies []exchange.AccountCurrencyInfo - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "BTC", - TotalValue: accountBalance.BTCAvailable, - Hold: accountBalance.BTCReserved, - }) - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "XRP", - TotalValue: accountBalance.XRPAvailable, - Hold: accountBalance.XRPReserved, - }) - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "USD", - TotalValue: accountBalance.USDAvailable, - Hold: accountBalance.USDReserved, - }) - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "EUR", - TotalValue: accountBalance.EURAvailable, - Hold: accountBalance.EURReserved, - }) - + var currencies = []exchange.AccountCurrencyInfo{ + { + CurrencyName: "BTC", + TotalValue: accountBalance.BTCAvailable, + Hold: accountBalance.BTCReserved, + }, + { + CurrencyName: "XRP", + TotalValue: accountBalance.XRPAvailable, + Hold: accountBalance.XRPReserved, + }, + { + CurrencyName: "USD", + TotalValue: accountBalance.USDAvailable, + Hold: accountBalance.USDReserved, + }, + { + CurrencyName: "EUR", + TotalValue: accountBalance.EURAvailable, + Hold: accountBalance.EURReserved, + }, + } response.Accounts = append(response.Accounts, exchange.Account{ Currencies: currencies, }) @@ -215,7 +211,7 @@ func (b *Bitstamp) CancelOrder(order exchange.OrderCancellation) error { func (b *Bitstamp) CancelAllOrders(_ exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) { isCancelAllSuccessful, err := b.CancelAllExistingOrders() if !isCancelAllSuccessful { - err = errors.New("Cancel all failed. Bitstamp provides no further information. Check order status to verify") + err = errors.New("cancel all orders failed. Bitstamp provides no further information. Check order status to verify") } return exchange.CancelAllOrdersResponse{}, err @@ -337,39 +333,42 @@ func (b *Bitstamp) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ( var orders []exchange.OrderDetail for _, order := range resp { - if order.Type == 2 { - quoteCurrency := "" - baseCurrency := "" - if order.BTC > 0 { - baseCurrency = symbol.BTC - } else if order.XRP > 0 { - baseCurrency = symbol.XRP - } else { - log.Warnf("No quote currency found for OrderID '%v'", order.OrderID) - } - - if order.USD > 0 { - quoteCurrency = symbol.USD - } else if order.EUR > 0 { - quoteCurrency = symbol.EUR - } else { - log.Warnf("No quote currency found for OrderID '%v'", order.OrderID) - } - - var currPair pair.CurrencyPair - if quoteCurrency != "" && baseCurrency != "" { - currPair = pair.NewCurrencyPairWithDelimiter(baseCurrency, quoteCurrency, b.ConfigCurrencyPairFormat.Delimiter) - } - orderDate := time.Unix(order.Date, 0) + if order.Type != 2 { + continue + } + quoteCurrency := "" + baseCurrency := "" + + switch { + case order.BTC > 0: + baseCurrency = symbol.BTC + case order.XRP > 0: + baseCurrency = symbol.XRP + default: + log.Warnf("no base currency found for OrderID '%v'", order.OrderID) + } - orders = append(orders, exchange.OrderDetail{ - ID: fmt.Sprintf("%v", order.OrderID), - OrderDate: orderDate, - Exchange: b.Name, - CurrencyPair: currPair, - }) + switch { + case order.USD > 0: + quoteCurrency = symbol.USD + case order.EUR > 0: + quoteCurrency = symbol.EUR + default: + log.Warnf("no quote currency found for orderID '%v'", order.OrderID) + } + var currPair pair.CurrencyPair + if quoteCurrency != "" && baseCurrency != "" { + currPair = pair.NewCurrencyPairWithDelimiter(baseCurrency, quoteCurrency, b.ConfigCurrencyPairFormat.Delimiter) } + orderDate := time.Unix(order.Date, 0) + + orders = append(orders, exchange.OrderDetail{ + ID: fmt.Sprintf("%v", order.OrderID), + OrderDate: orderDate, + Exchange: b.Name, + CurrencyPair: currPair, + }) } exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks) diff --git a/exchanges/bittrex/bittrex.go b/exchanges/bittrex/bittrex.go index 15a27199b72..3757a0904d1 100644 --- a/exchanges/bittrex/bittrex.go +++ b/exchanges/bittrex/bittrex.go @@ -159,19 +159,19 @@ func (b *Bittrex) GetCurrencies() (Currency, error) { // GetTicker sends a public get request and returns current ticker information // on the supplied currency. Example currency input param "btc-ltc". func (b *Bittrex) GetTicker(currencyPair string) (Ticker, error) { - ticker := Ticker{} + tick := Ticker{} path := fmt.Sprintf("%s/%s?market=%s", b.APIUrl, bittrexAPIGetTicker, common.StringToUpper(currencyPair), ) - if err := b.SendHTTPRequest(path, &ticker); err != nil { - return ticker, err + if err := b.SendHTTPRequest(path, &tick); err != nil { + return tick, err } - if !ticker.Success { - return ticker, errors.New(ticker.Message) + if !tick.Success { + return tick, errors.New(tick.Message) } - return ticker, nil + return tick, nil } // GetMarketSummaries is used to get the last 24 hour summary of all active @@ -553,8 +553,7 @@ func (b *Bittrex) GetWithdrawalFee(currency string) (float64, error) { } // calculateTradingFee returns the fee for trading any currency on Bittrex -func calculateTradingFee(purchasePrice float64, amount float64) float64 { +func calculateTradingFee(purchasePrice, amount float64) float64 { var fee = 0.0025 - return fee * purchasePrice * amount } diff --git a/exchanges/bittrex/bittrex_wrapper.go b/exchanges/bittrex/bittrex_wrapper.go index 7329a13f404..786bddc53ec 100644 --- a/exchanges/bittrex/bittrex_wrapper.go +++ b/exchanges/bittrex/bittrex_wrapper.go @@ -100,16 +100,17 @@ func (b *Bittrex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pr for _, x := range b.GetEnabledCurrencies() { curr := exchange.FormatExchangeCurrency(b.Name, x) for y := range tick.Result { - if tick.Result[y].MarketName == curr.String() { - tickerPrice.Pair = x - tickerPrice.High = tick.Result[y].High - tickerPrice.Low = tick.Result[y].Low - tickerPrice.Ask = tick.Result[y].Ask - tickerPrice.Bid = tick.Result[y].Bid - tickerPrice.Last = tick.Result[y].Last - tickerPrice.Volume = tick.Result[y].Volume - ticker.ProcessTicker(b.GetName(), x, tickerPrice, assetType) + if tick.Result[y].MarketName != curr.String() { + continue } + tickerPrice.Pair = x + tickerPrice.High = tick.Result[y].High + tickerPrice.Low = tick.Result[y].Low + tickerPrice.Ask = tick.Result[y].Ask + tickerPrice.Bid = tick.Result[y].Bid + tickerPrice.Last = tick.Result[y].Last + tickerPrice.Volume = tick.Result[y].Volume + ticker.ProcessTicker(b.GetName(), x, tickerPrice, assetType) } } return ticker.GetTicker(b.Name, p, assetType) diff --git a/exchanges/btcc/btcc_websocket.go b/exchanges/btcc/btcc_websocket.go index 81a7badd59f..8fc00199640 100644 --- a/exchanges/btcc/btcc_websocket.go +++ b/exchanges/btcc/btcc_websocket.go @@ -383,12 +383,12 @@ func (b *BTCC) WsProcessOrderbookSnapshot(ob WsOrderbookSnapshot) error { var asks, bids []orderbook.Item for _, data := range ob.List { var newSize float64 - switch data.Size.(type) { + switch result := data.Size.(type) { case float64: - newSize = data.Size.(float64) + newSize = result case string: var err error - newSize, err = strconv.ParseFloat(data.Size.(string), 64) + newSize, err = strconv.ParseFloat(result, 64) if err != nil { return err } @@ -430,12 +430,12 @@ func (b *BTCC) WsProcessOrderbookUpdate(ob WsOrderbookSnapshot) error { var asks, bids []orderbook.Item for _, data := range ob.List { var newSize float64 - switch data.Size.(type) { + switch d := data.Size.(type) { case float64: - newSize = data.Size.(float64) + newSize = d case string: var err error - newSize, err = strconv.ParseFloat(data.Size.(string), 64) + newSize, err = strconv.ParseFloat(d, 64) if err != nil { return err } @@ -485,26 +485,26 @@ func (b *BTCC) WsProcessOldOrderbookSnapshot(ob WsOrderbookSnapshotOld, symbol s data := ask.([]interface{}) var price, amount float64 - switch data[0].(type) { + switch d := data[0].(type) { case string: var err error - price, err = strconv.ParseFloat(data[0].(string), 64) + price, err = strconv.ParseFloat(d, 64) if err != nil { return err } case float64: - price = data[0].(float64) + price = d } - switch data[0].(type) { + switch d := data[0].(type) { case string: var err error - amount, err = strconv.ParseFloat(data[0].(string), 64) + amount, err = strconv.ParseFloat(d, 64) if err != nil { return err } case float64: - amount = data[0].(float64) + amount = d } asks = append(asks, orderbook.Item{ @@ -517,26 +517,26 @@ func (b *BTCC) WsProcessOldOrderbookSnapshot(ob WsOrderbookSnapshotOld, symbol s data := bid.([]interface{}) var price, amount float64 - switch data[1].(type) { + switch d := data[1].(type) { case string: var err error - price, err = strconv.ParseFloat(data[1].(string), 64) + price, err = strconv.ParseFloat(d, 64) if err != nil { return err } case float64: - price = data[1].(float64) + price = d } - switch data[1].(type) { + switch d := data[1].(type) { case string: var err error - amount, err = strconv.ParseFloat(data[1].(string), 64) + amount, err = strconv.ParseFloat(d, 64) if err != nil { return err } case float64: - amount = data[1].(float64) + amount = d } bids = append(bids, orderbook.Item{ @@ -546,7 +546,6 @@ func (b *BTCC) WsProcessOldOrderbookSnapshot(ob WsOrderbookSnapshotOld, symbol s } p := pair.NewCurrencyPairFromString(symbol) - err := b.Websocket.Orderbook.Update(bids, asks, p, time.Now(), b.GetName(), "SPOT") if err != nil { return err diff --git a/exchanges/btcc/btcc_wrapper.go b/exchanges/btcc/btcc_wrapper.go index 06558626113..29246ba30e7 100644 --- a/exchanges/btcc/btcc_wrapper.go +++ b/exchanges/btcc/btcc_wrapper.go @@ -1,7 +1,6 @@ package btcc import ( - "errors" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -55,7 +54,7 @@ func (b *BTCC) Run() { log.Errorf("%s failed to update enabled currencies. %s\n", b.Name, err) } - err = cfg.UpdateExchangeConfig(exchCfg) + err = cfg.UpdateExchangeConfig(&exchCfg) if err != nil { log.Errorf("%s failed to update config. %s\n", b.Name, err) return @@ -65,96 +64,44 @@ func (b *BTCC) Run() { // UpdateTicker updates and returns the ticker for a currency pair func (b *BTCC) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) { - // var tickerPrice ticker.Price - // tick, err := b.GetTicker(exchange.FormatExchangeCurrency(b.GetName(), p).String()) - // if err != nil { - // return tickerPrice, err - // } - // tickerPrice.Pair = p - // tickerPrice.Ask = tick.AskPrice - // tickerPrice.Bid = tick.BidPrice - // tickerPrice.Low = tick.Low - // tickerPrice.Last = tick.Last - // tickerPrice.Volume = tick.Volume24H - // tickerPrice.High = tick.High - // ticker.ProcessTicker(b.GetName(), p, tickerPrice, assetType) - // return ticker.GetTicker(b.Name, p, assetType) - return ticker.Price{}, errors.New("REST NOT SUPPORTED") + return ticker.Price{}, common.ErrFunctionNotSupported } // GetTickerPrice returns the ticker for a currency pair func (b *BTCC) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) { - // tickerNew, err := ticker.GetTicker(b.GetName(), p, assetType) - // if err != nil { - // return b.UpdateTicker(p, assetType) - // } - // return tickerNew, nil - return ticker.Price{}, errors.New("REST NOT SUPPORTED") + return ticker.Price{}, common.ErrFunctionNotSupported } // GetOrderbookEx returns the orderbook for a currency pair func (b *BTCC) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) { - // ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType) - // if err != nil { - // return b.UpdateOrderbook(p, assetType) - // } - // return ob, nil - return orderbook.Base{}, errors.New("REST NOT SUPPORTED") + return orderbook.Base{}, common.ErrFunctionNotSupported } // UpdateOrderbook updates and returns the orderbook for a currency pair func (b *BTCC) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) { - // var orderBook orderbook.Base - // orderbookNew, err := b.GetOrderBook(exchange.FormatExchangeCurrency(b.GetName(), p).String(), 100) - // if err != nil { - // return orderBook, err - // } - - // for x := range orderbookNew.Bids { - // data := orderbookNew.Bids[x] - // orderBook.Bids = append(orderBook.Bids, orderbook.Item{Price: data[0], Amount: data[1]}) - // } - - // for x := range orderbookNew.Asks { - // data := orderbookNew.Asks[x] - // orderBook.Asks = append(orderBook.Asks, orderbook.Item{Price: data[0], Amount: data[1]}) - // } - - // orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType) - // return orderbook.GetOrderbook(b.Name, p, assetType) - return orderbook.Base{}, errors.New("REST NOT SUPPORTED") + return orderbook.Base{}, common.ErrFunctionNotSupported } // GetAccountInfo : Retrieves balances for all enabled currencies for // the Kraken exchange - TODO func (b *BTCC) GetAccountInfo() (exchange.AccountInfo, error) { - // var response exchange.AccountInfo - // response.ExchangeName = b.GetName() - // return response, nil - return exchange.AccountInfo{}, errors.New("REST NOT SUPPORTED") + return exchange.AccountInfo{}, common.ErrFunctionNotSupported } // GetFundingHistory returns funding history, deposits and // withdrawals func (b *BTCC) GetFundingHistory() ([]exchange.FundHistory, error) { - // var fundHistory []exchange.FundHistory - // return fundHistory, common.ErrFunctionNotSupported - return nil, errors.New("REST NOT SUPPORTED") + return nil, common.ErrFunctionNotSupported } // GetExchangeHistory returns historic trade data since exchange opening. func (b *BTCC) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) { - // var resp []exchange.TradeHistory - - // return resp, common.ErrNotYetImplemented - return nil, errors.New("REST NOT SUPPORTED") + return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order func (b *BTCC) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) { - var submitOrderResponse exchange.SubmitOrderResponse - - return submitOrderResponse, common.ErrNotYetImplemented + return exchange.SubmitOrderResponse{}, common.ErrNotYetImplemented } // ModifyOrder will allow of changing orderbook placement and limit to @@ -175,8 +122,7 @@ func (b *BTCC) CancelAllOrders(orderCancellation exchange.OrderCancellation) (ex // GetOrderInfo returns information on a current open order func (b *BTCC) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) { - var orderDetail exchange.OrderDetail - return orderDetail, common.ErrNotYetImplemented + return exchange.OrderDetail{}, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency diff --git a/exchanges/btcmarkets/btcmarkets.go b/exchanges/btcmarkets/btcmarkets.go index 009226ae11e..f7ce7c2ce2b 100644 --- a/exchanges/btcmarkets/btcmarkets.go +++ b/exchanges/btcmarkets/btcmarkets.go @@ -140,13 +140,13 @@ func (b *BTCMarkets) GetMarkets() ([]Market, error) { // GetTicker returns a ticker // symbol - example "btc" or "ltc" func (b *BTCMarkets) GetTicker(firstPair, secondPair string) (Ticker, error) { - ticker := Ticker{} + tick := Ticker{} path := fmt.Sprintf("%s/market/%s/%s/tick", b.APIUrl, common.StringToUpper(firstPair), common.StringToUpper(secondPair)) - return ticker, b.SendHTTPRequest(path, &ticker) + return tick, b.SendHTTPRequest(path, &tick) } // GetOrderbook returns current orderbook @@ -237,19 +237,19 @@ func (b *BTCMarkets) CancelExistingOrder(orderID []int64) ([]ResponseDetails, er // since - since a time example "33434568724" // historic - if false just normal Orders open func (b *BTCMarkets) GetOrders(currency, instrument string, limit, since int64, historic bool) ([]Order, error) { - request := make(map[string]interface{}) + req := make(map[string]interface{}) if currency != "" { - request["currency"] = common.StringToUpper(currency) + req["currency"] = common.StringToUpper(currency) } if instrument != "" { - request["instrument"] = common.StringToUpper(instrument) + req["instrument"] = common.StringToUpper(instrument) } if limit != 0 { - request["limit"] = limit + req["limit"] = limit } if since != 0 { - request["since"] = since + req["since"] = since } path := btcMarketsOrderOpen @@ -259,7 +259,7 @@ func (b *BTCMarkets) GetOrders(currency, instrument string, limit, since int64, resp := Response{} - err := b.SendAuthenticatedRequest(http.MethodPost, path, request, &resp) + err := b.SendAuthenticatedRequest(http.MethodPost, path, req, &resp) if err != nil { return nil, err } @@ -269,14 +269,14 @@ func (b *BTCMarkets) GetOrders(currency, instrument string, limit, since int64, } for _, order := range resp.Orders { - order.Price = order.Price / common.SatoshisPerBTC - order.OpenVolume = order.OpenVolume / common.SatoshisPerBTC - order.Volume = order.Volume / common.SatoshisPerBTC + order.Price /= common.SatoshisPerBTC + order.OpenVolume /= common.SatoshisPerBTC + order.Volume /= common.SatoshisPerBTC for _, trade := range order.Trades { - trade.Fee = trade.Fee / common.SatoshisPerBTC - trade.Price = trade.Price / common.SatoshisPerBTC - trade.Volume = trade.Volume / common.SatoshisPerBTC + trade.Fee /= common.SatoshisPerBTC + trade.Price /= common.SatoshisPerBTC + trade.Volume /= common.SatoshisPerBTC } } @@ -289,11 +289,11 @@ func (b *BTCMarkets) GetOpenOrders() ([]Order, error) { Response Orders []Order `json:"orders"` } - request := make(map[string]interface{}) + req := make(map[string]interface{}) var resp marketsResp path := fmt.Sprintf("/v2/order/open") - err := b.SendAuthenticatedRequest(http.MethodGet, path, request, &resp) + err := b.SendAuthenticatedRequest(http.MethodGet, path, req, &resp) if err != nil { return nil, err } @@ -303,14 +303,14 @@ func (b *BTCMarkets) GetOpenOrders() ([]Order, error) { } for _, order := range resp.Orders { - order.Price = order.Price / common.SatoshisPerBTC - order.OpenVolume = order.OpenVolume / common.SatoshisPerBTC - order.Volume = order.Volume / common.SatoshisPerBTC + order.Price /= common.SatoshisPerBTC + order.OpenVolume /= common.SatoshisPerBTC + order.Volume /= common.SatoshisPerBTC for _, trade := range order.Trades { - trade.Fee = trade.Fee / common.SatoshisPerBTC - trade.Price = trade.Price / common.SatoshisPerBTC - trade.Volume = trade.Volume / common.SatoshisPerBTC + trade.Fee /= common.SatoshisPerBTC + trade.Price /= common.SatoshisPerBTC + trade.Volume /= common.SatoshisPerBTC } } @@ -338,14 +338,14 @@ func (b *BTCMarkets) GetOrderDetail(orderID []int64) ([]Order, error) { } for i := range resp.Orders { - resp.Orders[i].Price = resp.Orders[i].Price / common.SatoshisPerBTC - resp.Orders[i].OpenVolume = resp.Orders[i].OpenVolume / common.SatoshisPerBTC - resp.Orders[i].Volume = resp.Orders[i].Volume / common.SatoshisPerBTC + resp.Orders[i].Price /= common.SatoshisPerBTC + resp.Orders[i].OpenVolume /= common.SatoshisPerBTC + resp.Orders[i].Volume /= common.SatoshisPerBTC for x := range resp.Orders[i].Trades { - resp.Orders[i].Trades[x].Fee = resp.Orders[i].Trades[x].Fee / common.SatoshisPerBTC - resp.Orders[i].Trades[x].Price = resp.Orders[i].Trades[x].Price / common.SatoshisPerBTC - resp.Orders[i].Trades[x].Volume = resp.Orders[i].Trades[x].Volume / common.SatoshisPerBTC + resp.Orders[i].Trades[x].Fee /= common.SatoshisPerBTC + resp.Orders[i].Trades[x].Price /= common.SatoshisPerBTC + resp.Orders[i].Trades[x].Volume /= common.SatoshisPerBTC } } return resp.Orders, nil @@ -362,8 +362,8 @@ func (b *BTCMarkets) GetAccountBalance() ([]AccountBalance, error) { // All values are returned in Satoshis, even for fiat currencies. for i := range balance { - balance[i].Balance = balance[i].Balance / common.SatoshisPerBTC - balance[i].PendingFunds = balance[i].PendingFunds / common.SatoshisPerBTC + balance[i].Balance /= common.SatoshisPerBTC + balance[i].PendingFunds /= common.SatoshisPerBTC } return balance, nil } @@ -431,7 +431,7 @@ func (b *BTCMarkets) SendHTTPRequest(path string, result interface{}) error { } // SendAuthenticatedRequest sends an authenticated HTTP request -func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data interface{}, result interface{}) (err error) { +func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data, result interface{}) (err error) { if !b.AuthenticatedAPISupport { return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name) } @@ -441,7 +441,7 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data interfa } else { b.Nonce.Inc() } - var request string + var req string payload := []byte("") if data != nil { @@ -449,15 +449,15 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data interfa if err != nil { return err } - request = path + "\n" + b.Nonce.String()[0:13] + "\n" + string(payload) + req = path + "\n" + b.Nonce.String()[0:13] + "\n" + string(payload) } else { - request = path + "\n" + b.Nonce.String()[0:13] + "\n" + req = path + "\n" + b.Nonce.String()[0:13] + "\n" } - hmac := common.GetHMAC(common.HashSHA512, []byte(request), []byte(b.APISecret)) + hmac := common.GetHMAC(common.HashSHA512, []byte(req), []byte(b.APISecret)) if b.Verbose { - log.Debugf("Sending %s request to URL %s with params %s\n", reqType, b.APIUrl+path, request) + log.Debugf("Sending %s request to URL %s with params %s\n", reqType, b.APIUrl+path, req) } headers := make(map[string]string) diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index 0a6614e62a0..2adcd4bfe0e 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -285,7 +285,7 @@ func (b *BTCMarkets) WithdrawCryptocurrencyFunds(withdrawRequest exchange.Withdr // withdrawal is submitted func (b *BTCMarkets) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest) (string, error) { if withdrawRequest.Currency != symbol.AUD { - return "", errors.New("Only AUD supported for withdrawals") + return "", errors.New("only AUD is supported for withdrawals") } return b.WithdrawAUD(withdrawRequest.BankAccountName, fmt.Sprintf("%v", withdrawRequest.BankAccountNumber), withdrawRequest.BankName, fmt.Sprintf("%v", withdrawRequest.BankCode), withdrawRequest.Amount) } @@ -363,8 +363,8 @@ func (b *BTCMarkets) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (b *BTCMarkets) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Requires at least one currency pair to retrieve history") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("requires at least one currency pair to retrieve history") } var respOrders []Order diff --git a/exchanges/coinbasepro/coinbasepro.go b/exchanges/coinbasepro/coinbasepro.go index e9849b7b182..3880e8718d6 100644 --- a/exchanges/coinbasepro/coinbasepro.go +++ b/exchanges/coinbasepro/coinbasepro.go @@ -224,11 +224,10 @@ func (c *CoinbasePro) GetOrderbook(symbol string, level int) (interface{}, error // GetTicker returns ticker by currency pair // currencyPair - example "BTC-USD" func (c *CoinbasePro) GetTicker(currencyPair string) (Ticker, error) { - ticker := Ticker{} + tick := Ticker{} path := fmt.Sprintf( "%s/%s/%s", c.APIUrl+coinbaseproProducts, currencyPair, coinbaseproTicker) - - return ticker, c.SendHTTPRequest(path, &ticker) + return tick, c.SendHTTPRequest(path, &tick) } // GetTrades listd the latest trades for a product @@ -370,30 +369,30 @@ func (c *CoinbasePro) GetHolds(accountID string) ([]AccountHolds, error) { // postOnly - [optional] Post only flag Invalid when time_in_force is IOC or FOK func (c *CoinbasePro) PlaceLimitOrder(clientRef string, price, amount float64, side, timeInforce, cancelAfter, productID, stp string, postOnly bool) (string, error) { resp := GeneralizedOrderResponse{} - request := make(map[string]interface{}) - 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 + req := make(map[string]interface{}) + req["type"] = "limit" + req["price"] = strconv.FormatFloat(price, 'f', -1, 64) + req["size"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["side"] = side + req["product_id"] = productID if cancelAfter != "" { - request["cancel_after"] = cancelAfter + req["cancel_after"] = cancelAfter } if timeInforce != "" { - request["time_in_foce"] = timeInforce + req["time_in_foce"] = timeInforce } if clientRef != "" { - request["client_oid"] = clientRef + req["client_oid"] = clientRef } if stp != "" { - request["stp"] = stp + req["stp"] = stp } if postOnly { - request["post_only"] = postOnly + req["post_only"] = postOnly } - err := c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproOrders, request, &resp) + err := c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -417,27 +416,27 @@ func (c *CoinbasePro) PlaceLimitOrder(clientRef string, price, amount float64, s // size - [optional]* Desired amount in BTC // funds [optional]* Desired amount of quote currency to use // * One of size or funds is required. -func (c *CoinbasePro) PlaceMarketOrder(clientRef string, size, funds float64, side string, productID, stp string) (string, error) { +func (c *CoinbasePro) PlaceMarketOrder(clientRef string, size, funds float64, side, productID, stp string) (string, error) { resp := GeneralizedOrderResponse{} - request := make(map[string]interface{}) - request["side"] = side - request["product_id"] = productID - request["type"] = "market" + req := make(map[string]interface{}) + req["side"] = side + req["product_id"] = productID + req["type"] = "market" if size != 0 { - request["size"] = strconv.FormatFloat(size, 'f', -1, 64) + req["size"] = strconv.FormatFloat(size, 'f', -1, 64) } if funds != 0 { - request["funds"] = strconv.FormatFloat(funds, 'f', -1, 64) + req["funds"] = strconv.FormatFloat(funds, 'f', -1, 64) } if clientRef != "" { - request["client_oid"] = clientRef + req["client_oid"] = clientRef } if stp != "" { - request["stp"] = stp + req["stp"] = stp } - err := c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproOrders, request, &resp) + err := c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -460,27 +459,27 @@ func (c *CoinbasePro) PlaceMarketOrder(clientRef string, size, funds float64, si // MARGIN ORDER PARAMS // size - [optional]* Desired amount in BTC // funds - [optional]* Desired amount of quote currency to use -func (c *CoinbasePro) PlaceMarginOrder(clientRef string, size, funds float64, side string, productID, stp string) (string, error) { +func (c *CoinbasePro) PlaceMarginOrder(clientRef string, size, funds float64, side, productID, stp string) (string, error) { resp := GeneralizedOrderResponse{} - request := make(map[string]interface{}) - request["side"] = side - request["product_id"] = productID - request["type"] = "margin" + req := make(map[string]interface{}) + req["side"] = side + req["product_id"] = productID + req["type"] = "margin" if size != 0 { - request["size"] = strconv.FormatFloat(size, 'f', -1, 64) + req["size"] = strconv.FormatFloat(size, 'f', -1, 64) } if funds != 0 { - request["funds"] = strconv.FormatFloat(funds, 'f', -1, 64) + req["funds"] = strconv.FormatFloat(funds, 'f', -1, 64) } if clientRef != "" { - request["client_oid"] = clientRef + req["client_oid"] = clientRef } if stp != "" { - request["stp"] = stp + req["stp"] = stp } - err := c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproOrders, request, &resp) + err := c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -501,12 +500,12 @@ func (c *CoinbasePro) CancelExistingOrder(orderID string) error { // canceled func (c *CoinbasePro) CancelAllExistingOrders(currencyPair string) ([]string, error) { var resp []string - request := make(map[string]interface{}) + req := make(map[string]interface{}) if len(currencyPair) > 0 { - request["product_id"] = currencyPair + req["product_id"] = currencyPair } - return resp, c.SendAuthenticatedHTTPRequest(http.MethodDelete, coinbaseproOrders, request, &resp) + return resp, c.SendAuthenticatedHTTPRequest(http.MethodDelete, coinbaseproOrders, req, &resp) } // GetOrders lists current open orders. Only open or un-settled orders are @@ -521,7 +520,7 @@ func (c *CoinbasePro) GetOrders(status []string, currencyPair string) ([]General for _, individualStatus := range status { params.Add("status", individualStatus) } - if len(currencyPair) != 0 { + if currencyPair != "" { params.Set("product_id", currencyPair) } @@ -545,13 +544,13 @@ func (c *CoinbasePro) GetFills(orderID, currencyPair string) ([]FillResponse, er resp := []FillResponse{} params := url.Values{} - if len(orderID) != 0 { + if orderID != "" { params.Set("order_id", orderID) } - if len(currencyPair) != 0 { + if currencyPair != "" { params.Set("product_id", currencyPair) } - if len(params.Get("order_id")) == 0 && len(params.Get("product_id")) == 0 { + if params.Get("order_id") == "" && params.Get("product_id") == "" { return resp, errors.New("no parameters set") } @@ -578,7 +577,7 @@ func (c *CoinbasePro) GetFundingRecords(status string) ([]Funding, error) { c.SendAuthenticatedHTTPRequest(http.MethodGet, uri[1:], nil, &resp) } -////////////////////////// Not receiving reply from server ///////////////// +// //////////////////////// Not receiving reply from server ///////////////// // RepayFunding repays the older funding records first // // amount - amount of currency to repay @@ -606,14 +605,14 @@ func (c *CoinbasePro) GetFundingRecords(status string) ([]Funding, error) { // currency - currency to transfer, currently on "BTC" or "USD" func (c *CoinbasePro) 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["currency"] = currency - request["margin_profile_id"] = profileID + req := make(map[string]interface{}) + req["type"] = transferType + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["currency"] = currency + req["margin_profile_id"] = profileID return resp, - c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproMarginTransfer, request, &resp) + c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproMarginTransfer, req, &resp) } // GetPosition returns an overview of account profile. @@ -628,11 +627,11 @@ func (c *CoinbasePro) GetPosition() (AccountOverview, error) { // repayOnly - allows the position to be repaid func (c *CoinbasePro) ClosePosition(repayOnly bool) (AccountOverview, error) { resp := AccountOverview{} - request := make(map[string]interface{}) - request["repay_only"] = repayOnly + req := make(map[string]interface{}) + req["repay_only"] = repayOnly return resp, - c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproPositionClose, request, &resp) + c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproPositionClose, req, &resp) } // GetPayMethods returns a full list of payment methods @@ -695,7 +694,7 @@ func (c *CoinbasePro) WithdrawViaPaymentMethod(amount float64, currency, payment c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproWithdrawalPaymentMethod, req, &resp) } -///////////////////////// NO ROUTE FOUND ERROR //////////////////////////////// +// /////////////////////// NO ROUTE FOUND ERROR //////////////////////////////// // WithdrawViaCoinbase withdraws funds to a coinbase account. // // amount - The amount to withdraw @@ -750,27 +749,27 @@ func (c *CoinbasePro) GetCoinbaseAccounts() ([]CoinbaseAccounts, error) { // email - [optional] Email address to send the report to func (c *CoinbasePro) 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" + req := make(map[string]interface{}) + req["type"] = reportType + req["start_date"] = startDate + req["end_date"] = endDate + req["format"] = "pdf" - if len(currencyPair) != 0 { - request["product_id"] = currencyPair + if currencyPair != "" { + req["product_id"] = currencyPair } - if len(accountID) != 0 { - request["account_id"] = accountID + if accountID != "" { + req["account_id"] = accountID } if format == "csv" { - request["format"] = format + req["format"] = format } - if len(email) != 0 { - request["email"] = email + if email != "" { + req["email"] = email } return resp, - c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproReports, request, &resp) + c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproReports, req, &resp) } // GetReportStatus once a report request has been accepted for processing, the @@ -807,7 +806,7 @@ func (c *CoinbasePro) SendAuthenticatedHTTPRequest(method, path string, params m if params != nil { payload, err = common.JSONEncode(params) if err != nil { - return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request") + return errors.New("sendAuthenticatedHTTPRequest: Unable to JSON request") } if c.Verbose { @@ -855,19 +854,19 @@ func (c *CoinbasePro) calculateTradingFee(trailingVolume []Volume, firstCurrency var fee float64 for _, i := range trailingVolume { if strings.EqualFold(i.ProductID, firstCurrency+delimiter+secondCurrency) { - if isMaker { + switch { + case isMaker: fee = 0 - } else if i.Volume <= 10000000 { + case i.Volume <= 10000000: fee = 0.003 - } else if i.Volume > 10000000 && i.Volume <= 100000000 { + case i.Volume > 10000000 && i.Volume <= 100000000: fee = 0.002 - } else if i.Volume > 100000000 { + case i.Volume > 100000000: fee = 0.001 } break } } - return fee * amount * purchasePrice } diff --git a/exchanges/coinbasepro/coinbasepro_test.go b/exchanges/coinbasepro/coinbasepro_test.go index 18adeee6644..4b4f44684d1 100644 --- a/exchanges/coinbasepro/coinbasepro_test.go +++ b/exchanges/coinbasepro/coinbasepro_test.go @@ -16,7 +16,7 @@ var c CoinbasePro const ( apiKey = "" apiSecret = "" - clientID = "" //passphrase you made at API CREATION + clientID = "" // passphrase you made at API CREATION canManipulateRealOrders = false ) diff --git a/exchanges/coinbasepro/coinbasepro_websocket.go b/exchanges/coinbasepro/coinbasepro_websocket.go index 8a75faba4d7..6c4d33b81b2 100644 --- a/exchanges/coinbasepro/coinbasepro_websocket.go +++ b/exchanges/coinbasepro/coinbasepro_websocket.go @@ -28,30 +28,29 @@ func (c *CoinbasePro) WebsocketSubscriber() error { currencies = append(currencies, currency) } - var channels []WsChannels - channels = append(channels, WsChannels{ - Name: "heartbeat", - ProductIDs: currencies, - }) - - channels = append(channels, WsChannels{ - Name: "ticker", - ProductIDs: currencies, - }) - - channels = append(channels, WsChannels{ - Name: "level2", - ProductIDs: currencies, - }) + var channels = []WsChannels{ + { + Name: "heartbeat", + ProductIDs: currencies, + }, + { + Name: "ticker", + ProductIDs: currencies, + }, + { + Name: "level2", + ProductIDs: currencies, + }, + } subscribe := WebsocketSubscribe{Type: "subscribe", Channels: channels} - json, err := common.JSONEncode(subscribe) + data, err := common.JSONEncode(subscribe) if err != nil { return err } - return c.WebsocketConn.WriteMessage(websocket.TextMessage, json) + return c.WebsocketConn.WriteMessage(websocket.TextMessage, data) } // WsConnect initiates a websocket connection diff --git a/exchanges/coinbasepro/coinbasepro_wrapper.go b/exchanges/coinbasepro/coinbasepro_wrapper.go index 87258fd4d4c..b6663f58b84 100644 --- a/exchanges/coinbasepro/coinbasepro_wrapper.go +++ b/exchanges/coinbasepro/coinbasepro_wrapper.go @@ -158,13 +158,14 @@ func (c *CoinbasePro) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, var submitOrderResponse exchange.SubmitOrderResponse var response string var err error - if orderType == exchange.MarketOrderType { - response, err = c.PlaceMarginOrder("", amount, amount, side.ToString(), p.Pair().String(), "") - } else if orderType == exchange.LimitOrderType { + switch orderType { + case exchange.MarketOrderType: + response, err = c.PlaceMarginOrder("", amount, amount, side.ToString(), p.Pair().String(), "") + case exchange.LimitOrderType: response, err = c.PlaceLimitOrder("", price, amount, side.ToString(), "", "", p.Pair().String(), "", false) - } else { - err = errors.New("not supported") + default: + err = errors.New("order type not supported") } if response != "" { @@ -229,8 +230,8 @@ func (c *CoinbasePro) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest break } } - if len(selectedWithdrawalMethod.ID) <= 0 { - return "", fmt.Errorf("Could not find payment method '%v'. Check the name via the website and try again", withdrawRequest.BankName) + if selectedWithdrawalMethod.ID == "" { + return "", fmt.Errorf("could not find payment method '%v'. Check the name via the website and try again", withdrawRequest.BankName) } resp, err := c.WithdrawViaPaymentMethod(withdrawRequest.Amount, withdrawRequest.Currency.String(), selectedWithdrawalMethod.ID) diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index 45e2f0f33c9..839c94641ec 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -8,6 +8,7 @@ import ( "net/http" "time" + "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/gorilla/websocket" "github.com/thrasher-/gocryptotrader/common" "github.com/thrasher-/gocryptotrader/config" @@ -56,7 +57,7 @@ func (c *COINUT) SetDefaults() { c.Name = "COINUT" c.Enabled = false c.Verbose = false - c.TakerFee = 0.1 //spot + c.TakerFee = 0.1 // spot c.MakerFee = 0 c.Verbose = false c.RESTPollingDelay = 10 @@ -286,7 +287,7 @@ func (c *COINUT) GetIndexTicker(asset string) (IndexTicker, error) { // GetDerivativeInstruments returns a list of derivative instruments func (c *COINUT) GetDerivativeInstruments(secType string) (interface{}, error) { - var result interface{} //to-do + var result interface{} // to-do params := make(map[string]interface{}) params["sec_type"] = secType @@ -331,7 +332,7 @@ func (c *COINUT) GetOpenPositions(instrumentID int) ([]OpenPosition, error) { c.SendHTTPRequest(coinutPositionOpen, params, true, &result) } -//to-do: user position update via websocket +// to-do: user position update via websocket // SendHTTPRequest sends either an authenticated or unauthenticated HTTP request func (c *COINUT) SendHTTPRequest(apiRequest string, params map[string]interface{}, authenticated bool, result interface{}) (err error) { @@ -353,7 +354,7 @@ func (c *COINUT) SendHTTPRequest(apiRequest string, params map[string]interface{ payload, err := common.JSONEncode(params) if err != nil { - return errors.New("SenddHTTPRequest: Unable to JSON request") + return errors.New("sendHTTPRequest: Unable to JSON request") } if c.Verbose { @@ -409,12 +410,13 @@ func (c *COINUT) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { func (c *COINUT) calculateTradingFee(firstCurrency, secondCurrency string, purchasePrice, amount float64, isMaker bool) float64 { var fee float64 - if isMaker { + + switch { + case isMaker: fee = 0 - } else if currency.IsCryptocurrency(firstCurrency) && !currency.IsCryptocurrency(secondCurrency) || - !currency.IsCryptocurrency(firstCurrency) && currency.IsCryptocurrency(secondCurrency) { + case currency.IsCryptoFiatPair(pair.NewCurrencyPair(firstCurrency, secondCurrency)): fee = 0.002 - } else { + default: fee = 0.001 } @@ -424,19 +426,20 @@ func (c *COINUT) calculateTradingFee(firstCurrency, secondCurrency string, purch func getInternationalBankWithdrawalFee(currency string, amount float64) float64 { var fee float64 - if currency == symbol.USD { + switch currency { + case symbol.USD: if amount*0.001 < 10 { fee = 10 } else { fee = amount * 0.001 } - } else if currency == symbol.CAD { + case symbol.CAD: if amount*0.005 < 10 { fee = 2 } else { fee = amount * 0.005 } - } else if currency == symbol.SGD { + case symbol.SGD: if amount*0.001 < 10 { fee = 10 } else { diff --git a/exchanges/coinut/coinut_websocket.go b/exchanges/coinut/coinut_websocket.go index 4b5e2594242..4528aaf7a23 100644 --- a/exchanges/coinut/coinut_websocket.go +++ b/exchanges/coinut/coinut_websocket.go @@ -230,7 +230,7 @@ func (c *COINUT) GetNonce() int64 { // WsSetInstrumentList fetches instrument list and propagates a local cache func (c *COINUT) WsSetInstrumentList() error { - request, err := common.JSONEncode(wsRequest{ + req, err := common.JSONEncode(wsRequest{ Request: "inst_list", SecType: "SPOT", Nonce: c.GetNonce(), @@ -240,7 +240,7 @@ func (c *COINUT) WsSetInstrumentList() error { return err } - err = c.WebsocketConn.WriteMessage(websocket.TextMessage, request) + err = c.WebsocketConn.WriteMessage(websocket.TextMessage, req) if err != nil { return err } @@ -292,14 +292,14 @@ func (c *COINUT) WsSubscribe() error { return err } - orderbook := wsRequest{ + ob := wsRequest{ Request: "inst_order_book", InstID: instrumentListByString[p.Pair().String()], Subscribe: true, Nonce: c.GetNonce(), } - objson, err := common.JSONEncode(orderbook) + objson, err := common.JSONEncode(ob) if err != nil { return err } diff --git a/exchanges/coinut/coinut_wrapper.go b/exchanges/coinut/coinut_wrapper.go index 21ceb223cf0..25affd80a74 100644 --- a/exchanges/coinut/coinut_wrapper.go +++ b/exchanges/coinut/coinut_wrapper.go @@ -62,77 +62,64 @@ func (c *COINUT) GetAccountInfo() (exchange.AccountInfo, error) { return info, err } - var balances []exchange.AccountCurrencyInfo - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.BCH, - TotalValue: bal.BCH, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.BTC, - TotalValue: bal.BTC, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.BTG, - TotalValue: bal.BTG, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.CAD, - TotalValue: bal.CAD, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.ETC, - TotalValue: bal.ETC, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.ETH, - TotalValue: bal.ETH, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.LCH, - TotalValue: bal.LCH, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.LTC, - TotalValue: bal.LTC, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.MYR, - TotalValue: bal.MYR, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.SGD, - TotalValue: bal.SGD, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.USD, - TotalValue: bal.USD, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.USDT, - TotalValue: bal.USDT, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.XMR, - TotalValue: bal.XMR, - }) - - balances = append(balances, exchange.AccountCurrencyInfo{ - CurrencyName: symbol.ZEC, - TotalValue: bal.ZEC, - }) - + var balances = []exchange.AccountCurrencyInfo{ + { + CurrencyName: symbol.BCH, + TotalValue: bal.BCH, + }, + { + CurrencyName: symbol.BTC, + TotalValue: bal.BTC, + }, + { + CurrencyName: symbol.BTG, + TotalValue: bal.BTG, + }, + { + CurrencyName: symbol.CAD, + TotalValue: bal.CAD, + }, + { + CurrencyName: symbol.ETC, + TotalValue: bal.ETC, + }, + { + CurrencyName: symbol.ETH, + TotalValue: bal.ETH, + }, + { + CurrencyName: symbol.LCH, + TotalValue: bal.LCH, + }, + { + CurrencyName: symbol.LTC, + TotalValue: bal.LTC, + }, + { + CurrencyName: symbol.MYR, + TotalValue: bal.MYR, + }, + { + CurrencyName: symbol.SGD, + TotalValue: bal.SGD, + }, + { + CurrencyName: symbol.USD, + TotalValue: bal.USD, + }, + { + CurrencyName: symbol.USDT, + TotalValue: bal.USDT, + }, + { + CurrencyName: symbol.XMR, + TotalValue: bal.XMR, + }, + { + CurrencyName: symbol.ZEC, + TotalValue: bal.ZEC, + }, + } info.Exchange = c.GetName() info.Accounts = append(info.Accounts, exchange.Account{ Currencies: balances, @@ -233,11 +220,12 @@ func (c *COINUT) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order currencyArray := instruments.Instruments[p.Pair().String()] currencyID := currencyArray[0].InstID - if orderType == exchange.LimitOrderType { + switch orderType { + case exchange.LimitOrderType: APIresponse, err = c.NewOrder(currencyID, amount, price, isBuyOrder, clientIDUint) - } else if orderType == exchange.MarketOrderType { + case exchange.MarketOrderType: APIresponse, err = c.NewOrder(currencyID, amount, 0, isBuyOrder, clientIDUint) - } else { + default: return submitOrderResponse, errors.New("unsupported order type") } @@ -251,7 +239,7 @@ func (c *COINUT) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order case OrderRejectResponse: orderResult := apiResp submitOrderResponse.OrderID = fmt.Sprintf("%v", orderResult.OrderID) - err = fmt.Errorf("OrderID: %v was rejected: %v", orderResult.OrderID, orderResult.Reasons) + err = fmt.Errorf("orderID: %v was rejected: %v", orderResult.OrderID, orderResult.Reasons) } if err == nil { diff --git a/exchanges/exchange.go b/exchanges/exchange.go index 710c31f280d..6477fb69d06 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -21,11 +21,11 @@ import ( ) const ( - warningBase64DecryptSecretKeyFailed = "WARNING -- Exchange %s unable to base64 decode secret key.. Disabling Authenticated API support." + warningBase64DecryptSecretKeyFailed = "exchange %s unable to base64 decode secret key.. Disabling Authenticated API support" // nolint:gosec // WarningAuthenticatedRequestWithoutCredentialsSet error message for authenticated request without credentials set - WarningAuthenticatedRequestWithoutCredentialsSet = "WARNING -- Exchange %s authenticated HTTP request called but not supported due to unset/default API keys." + WarningAuthenticatedRequestWithoutCredentialsSet = "exchange %s authenticated HTTP request called but not supported due to unset/default API keys" // ErrExchangeNotFound is a stand for an error message - ErrExchangeNotFound = "Exchange not found in dataset" + ErrExchangeNotFound = "exchange not found in dataset" // DefaultHTTPTimeout is the default HTTP/HTTPS Timeout for exchange requests DefaultHTTPTimeout = time.Second * 15 ) @@ -77,7 +77,7 @@ type SubmitOrderResponse struct { // FeeBuilder is the type which holds all parameters required to calculate a fee for an exchange type FeeBuilder struct { FeeType FeeType - //Used for calculating crypto trading fees, deposits & withdrawals + // Used for calculating crypto trading fees, deposits & withdrawals FirstCurrency string SecondCurrency string Delimiter string @@ -439,7 +439,7 @@ func (e *Base) SetAutoPairDefaults() error { } if update { - return cfg.UpdateExchangeConfig(exch) + return cfg.UpdateExchangeConfig(&exch) } return nil } @@ -470,12 +470,12 @@ func (e *Base) SetAssetTypes() error { exch.AssetTypes = common.JoinStrings(e.AssetTypes, ",") update = true } else { - exch.AssetTypes = common.JoinStrings(e.AssetTypes, ",") + e.AssetTypes = common.SplitStrings(exch.AssetTypes, ",") update = true } if update { - return cfg.UpdateExchangeConfig(exch) + return cfg.UpdateExchangeConfig(&exch) } return nil @@ -571,7 +571,7 @@ func (e *Base) SetCurrencyPairFormat() error { } if update { - return cfg.UpdateExchangeConfig(exch) + return cfg.UpdateExchangeConfig(&exch) } return nil } @@ -676,23 +676,23 @@ func (e *Base) IsEnabled() bool { } // SetAPIKeys is a method that sets the current API keys for the exchange -func (e *Base) SetAPIKeys(APIKey, APISecret, ClientID string, b64Decode bool) { +func (e *Base) SetAPIKeys(apiKey, apiSecret, clientID string, b64Decode bool) { if !e.AuthenticatedAPISupport { return } - e.APIKey = APIKey - e.ClientID = ClientID + e.APIKey = apiKey + e.ClientID = clientID if b64Decode { - result, err := common.Base64Decode(APISecret) + result, err := common.Base64Decode(apiSecret) if err != nil { e.AuthenticatedAPISupport = false log.Warn(warningBase64DecryptSecretKeyFailed, e.Name) } e.APISecret = string(result) } else { - e.APISecret = APISecret + e.APISecret = apiSecret } } @@ -723,7 +723,7 @@ func (e *Base) SetCurrencies(pairs []pair.CurrencyPair, enabledPairs bool) error e.AvailablePairs = pairsStr } - return cfg.UpdateExchangeConfig(exchCfg) + return cfg.UpdateExchangeConfig(&exchCfg) } // UpdateCurrencies updates the exchange currency pairs for either enabledPairs or @@ -779,7 +779,7 @@ func (e *Base) UpdateCurrencies(exchangeProducts []string, enabled, force bool) exch.AvailablePairs = common.JoinStrings(products, ",") e.AvailablePairs = products } - return cfg.UpdateExchangeConfig(exch) + return cfg.UpdateExchangeConfig(&exch) } return nil } @@ -860,7 +860,7 @@ func (o OrderSide) ToString() string { // SetAPIURL sets configuration API URL for an exchange func (e *Base) SetAPIURL(ec config.ExchangeConfig) error { if ec.APIURL == "" || ec.APIURLSecondary == "" { - return errors.New("SetAPIURL error variable zero value") + return errors.New("empty config API URLs") } if ec.APIURL != config.APIURLNonDefaultMessage { e.APIUrl = ec.APIURL @@ -1039,7 +1039,7 @@ func FilterOrdersByTickRange(orders *[]OrderDetail, startTicks, endTicks time.Ti // FilterOrdersByCurrencies removes any OrderDetails that do not match the provided currency list // It is forgiving in that the provided currencies can match quote or base currencies func FilterOrdersByCurrencies(orders *[]OrderDetail, currencies []pair.CurrencyPair) { - if len(currencies) <= 0 { + if len(currencies) == 0 { return } diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index 1087038d506..6b54c3700ce 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -14,6 +14,11 @@ import ( "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) +const ( + defaultTestExchange = "ANX" + defaultTestCurrencyPair = "BTC-USD" +) + func TestSupportsRESTTickerBatchUpdates(t *testing.T) { b := Base{ Name: "RAWR", @@ -133,7 +138,7 @@ func TestSetAutoPairDefaults(t *testing.T) { } exch.SupportsAutoPairUpdates = false - err = cfg.UpdateExchangeConfig(exch) + err = cfg.UpdateExchangeConfig(&exch) if err != nil { t.Fatalf("Test failed. TestSetAutoPairDefaults update config failed. Error %s", err) } @@ -211,7 +216,7 @@ func TestSetAssetTypes(t *testing.T) { t.Fatal("Test failed. TestSetAssetTypes returned nil error for a non-existent exchange") } - b.Name = "ANX" + b.Name = defaultTestExchange b.AssetTypes = []string{"SPOT"} err = b.SetAssetTypes() if err != nil { @@ -224,7 +229,7 @@ func TestSetAssetTypes(t *testing.T) { } exch.AssetTypes = "" - err = cfg.UpdateExchangeConfig(exch) + err = cfg.UpdateExchangeConfig(&exch) if err != nil { t.Fatalf("Test failed. TestSetAssetTypes update config failed. Error %s", err) } @@ -316,7 +321,7 @@ func TestSetCurrencyPairFormat(t *testing.T) { t.Fatal("Test failed. TestSetCurrencyPairFormat returned nil error for a non-existent exchange") } - b.Name = "ANX" + b.Name = defaultTestExchange err = b.SetCurrencyPairFormat() if err != nil { t.Fatalf("Test failed. TestSetCurrencyPairFormat. Error %s", err) @@ -329,7 +334,7 @@ func TestSetCurrencyPairFormat(t *testing.T) { exch.ConfigCurrencyPairFormat = nil exch.RequestCurrencyPairFormat = nil - err = cfg.UpdateExchangeConfig(exch) + err = cfg.UpdateExchangeConfig(&exch) if err != nil { t.Fatalf("Test failed. TestSetCurrencyPairFormat update config failed. Error %s", err) } @@ -349,13 +354,13 @@ func TestSetCurrencyPairFormat(t *testing.T) { } if b.ConfigCurrencyPairFormat.Delimiter != "" && - b.ConfigCurrencyPairFormat.Index != "BTC" && + b.ConfigCurrencyPairFormat.Index != symbol.BTC && b.ConfigCurrencyPairFormat.Uppercase { t.Fatal("Test failed. TestSetCurrencyPairFormat ConfigCurrencyPairFormat values are incorrect") } if b.RequestCurrencyPairFormat.Delimiter != "" && - b.RequestCurrencyPairFormat.Index != "BTC" && + b.RequestCurrencyPairFormat.Index != symbol.BTC && b.RequestCurrencyPairFormat.Uppercase { t.Fatal("Test failed. TestSetCurrencyPairFormat RequestCurrencyPairFormat values are incorrect") } @@ -393,7 +398,7 @@ func TestGetEnabledCurrencies(t *testing.T) { Name: "TESTNAME", } - b.EnabledPairs = []string{"BTC-USD"} + b.EnabledPairs = []string{defaultTestCurrencyPair} format := config.CurrencyPairFormatConfig{ Delimiter: "-", Index: "", @@ -402,29 +407,29 @@ func TestGetEnabledCurrencies(t *testing.T) { b.RequestCurrencyPairFormat = format b.ConfigCurrencyPairFormat = format c := b.GetEnabledCurrencies() - if c[0].Pair().String() != "BTC-USD" { + if c[0].Pair().String() != defaultTestCurrencyPair { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } format.Delimiter = "~" b.RequestCurrencyPairFormat = format c = b.GetEnabledCurrencies() - if c[0].Pair().String() != "BTC-USD" { + if c[0].Pair().String() != defaultTestCurrencyPair { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } format.Delimiter = "" b.ConfigCurrencyPairFormat = format c = b.GetEnabledCurrencies() - if c[0].Pair().String() != "BTC-USD" { + if c[0].Pair().String() != defaultTestCurrencyPair { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } b.EnabledPairs = []string{"BTCDOGE"} - format.Index = "BTC" + format.Index = symbol.BTC b.ConfigCurrencyPairFormat = format c = b.GetEnabledCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != "DOGE" { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } @@ -432,23 +437,23 @@ func TestGetEnabledCurrencies(t *testing.T) { b.RequestCurrencyPairFormat.Delimiter = "" b.ConfigCurrencyPairFormat.Delimiter = "_" c = b.GetEnabledCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != symbol.USD { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } b.EnabledPairs = []string{"BTCDOGE"} b.RequestCurrencyPairFormat.Delimiter = "" b.ConfigCurrencyPairFormat.Delimiter = "" - b.ConfigCurrencyPairFormat.Index = "BTC" + b.ConfigCurrencyPairFormat.Index = symbol.BTC c = b.GetEnabledCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != "DOGE" { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } b.EnabledPairs = []string{"BTCUSD"} b.ConfigCurrencyPairFormat.Index = "" c = b.GetEnabledCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != symbol.USD { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } } @@ -458,7 +463,7 @@ func TestGetAvailableCurrencies(t *testing.T) { Name: "TESTNAME", } - b.AvailablePairs = []string{"BTC-USD"} + b.AvailablePairs = []string{defaultTestCurrencyPair} format := config.CurrencyPairFormatConfig{ Delimiter: "-", Index: "", @@ -467,29 +472,29 @@ func TestGetAvailableCurrencies(t *testing.T) { b.RequestCurrencyPairFormat = format b.ConfigCurrencyPairFormat = format c := b.GetAvailableCurrencies() - if c[0].Pair().String() != "BTC-USD" { + if c[0].Pair().String() != defaultTestCurrencyPair { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } format.Delimiter = "~" b.RequestCurrencyPairFormat = format c = b.GetAvailableCurrencies() - if c[0].Pair().String() != "BTC-USD" { + if c[0].Pair().String() != defaultTestCurrencyPair { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } format.Delimiter = "" b.ConfigCurrencyPairFormat = format c = b.GetAvailableCurrencies() - if c[0].Pair().String() != "BTC-USD" { + if c[0].Pair().String() != defaultTestCurrencyPair { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } b.AvailablePairs = []string{"BTCDOGE"} - format.Index = "BTC" + format.Index = symbol.BTC b.ConfigCurrencyPairFormat = format c = b.GetAvailableCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != "DOGE" { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } @@ -497,23 +502,23 @@ func TestGetAvailableCurrencies(t *testing.T) { b.RequestCurrencyPairFormat.Delimiter = "" b.ConfigCurrencyPairFormat.Delimiter = "_" c = b.GetAvailableCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != symbol.USD { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } b.AvailablePairs = []string{"BTCDOGE"} b.RequestCurrencyPairFormat.Delimiter = "" b.ConfigCurrencyPairFormat.Delimiter = "" - b.ConfigCurrencyPairFormat.Index = "BTC" + b.ConfigCurrencyPairFormat.Index = symbol.BTC c = b.GetAvailableCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "DOGE" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != "DOGE" { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } b.AvailablePairs = []string{"BTCUSD"} b.ConfigCurrencyPairFormat.Index = "" c = b.GetAvailableCurrencies() - if c[0].FirstCurrency.String() != "BTC" && c[0].SecondCurrency.String() != "USD" { + if c[0].FirstCurrency.String() != symbol.BTC && c[0].SecondCurrency.String() != symbol.USD { t.Error("Test Failed - Exchange GetAvailableCurrencies() incorrect string") } } @@ -523,8 +528,8 @@ func TestSupportsCurrency(t *testing.T) { Name: "TESTNAME", } - b.AvailablePairs = []string{"BTC-USD", "ETH-USD"} - b.EnabledPairs = []string{"BTC-USD"} + b.AvailablePairs = []string{defaultTestCurrencyPair, "ETH-USD"} + b.EnabledPairs = []string{defaultTestCurrencyPair} format := config.CurrencyPairFormatConfig{ Delimiter: "-", @@ -534,11 +539,11 @@ func TestSupportsCurrency(t *testing.T) { b.RequestCurrencyPairFormat = format b.ConfigCurrencyPairFormat = format - if !b.SupportsCurrency(pair.NewCurrencyPair("BTC", "USD"), true) { + if !b.SupportsCurrency(pair.NewCurrencyPair(symbol.BTC, symbol.USD), true) { t.Error("Test Failed - Exchange SupportsCurrency() incorrect value") } - if !b.SupportsCurrency(pair.NewCurrencyPair("ETH", "USD"), false) { + if !b.SupportsCurrency(pair.NewCurrencyPair("ETH", symbol.USD), false) { t.Error("Test Failed - Exchange SupportsCurrency() incorrect value") } @@ -585,9 +590,10 @@ func TestGetAndFormatExchangeCurrencies(t *testing.T) { t.Fatalf("Failed to load config file. Error: %s", err) } - var pairs []pair.CurrencyPair - pairs = append(pairs, pair.NewCurrencyPairDelimiter("BTC_USD", "_")) - pairs = append(pairs, pair.NewCurrencyPairDelimiter("LTC_BTC", "_")) + var pairs = []pair.CurrencyPair{ + pair.NewCurrencyPairDelimiter("BTC_USD", "_"), + pair.NewCurrencyPairDelimiter("LTC_BTC", "_"), + } actual, err := GetAndFormatExchangeCurrencies("Yobit", pairs) if err != nil { @@ -613,9 +619,9 @@ func TestFormatExchangeCurrency(t *testing.T) { t.Fatalf("Failed to load config file. Error: %s", err) } - pair := pair.NewCurrencyPair("BTC", "USD") - expected := "BTC-USD" - actual := FormatExchangeCurrency("CoinbasePro", pair) + p := pair.NewCurrencyPair(symbol.BTC, symbol.USD) + expected := defaultTestCurrencyPair + actual := FormatExchangeCurrency("CoinbasePro", p) if actual.String() != expected { t.Errorf("Test failed - Exchange TestFormatExchangeCurrency %s != %s", @@ -630,8 +636,8 @@ func TestFormatCurrency(t *testing.T) { t.Fatalf("Failed to load config file. Error: %s", err) } - currency := pair.NewCurrencyPair("btc", "usd") - expected := "BTC-USD" + currency := pair.NewCurrencyPair(symbol.BTC, symbol.USD) + expected := defaultTestCurrencyPair actual := FormatCurrency(currency).String() if actual != expected { t.Errorf("Test failed - Exchange TestFormatCurrency %s != %s", @@ -699,12 +705,12 @@ func TestSetCurrencies(t *testing.T) { t.Fatal("Test failed. TestSetCurrencies returned nil error on non-existent exchange") } - anxCfg, err := cfg.GetExchangeConfig("ANX") + anxCfg, err := cfg.GetExchangeConfig(defaultTestExchange) if err != nil { t.Fatal("Test failed. TestSetCurrencies failed to load config") } - UAC.Name = "ANX" + UAC.Name = defaultTestExchange UAC.ConfigCurrencyPairFormat.Delimiter = anxCfg.ConfigCurrencyPairFormat.Delimiter UAC.SetCurrencies([]pair.CurrencyPair{newPair}, true) if !pair.Contains(UAC.GetEnabledCurrencies(), newPair, true) { @@ -729,8 +735,8 @@ func TestUpdateCurrencies(t *testing.T) { t.Fatal("Test failed. TestUpdateEnabledCurrencies failed to load config") } - UAC := Base{Name: "ANX"} - exchangeProducts := []string{"ltc", "btc", "usd", "aud", ""} + UAC := Base{Name: defaultTestExchange} + exchangeProducts := []string{"ltc", symbol.BTC, symbol.USD, "aud", ""} // Test updating exchange products for an exchange which doesn't exist UAC.Name = "Blah" @@ -740,27 +746,27 @@ func TestUpdateCurrencies(t *testing.T) { } // Test updating exchange products - UAC.Name = "ANX" + UAC.Name = defaultTestExchange err = UAC.UpdateCurrencies(exchangeProducts, true, false) if err != nil { t.Errorf("Test Failed - Exchange TestUpdateCurrencies error: %s", err) } // Test updating the same new products, diff should be 0 - UAC.Name = "ANX" + UAC.Name = defaultTestExchange err = UAC.UpdateCurrencies(exchangeProducts, true, false) if err != nil { t.Errorf("Test Failed - Exchange TestUpdateCurrencies error: %s", err) } // Test force updating to only one product - exchangeProducts = []string{"btc"} + exchangeProducts = []string{symbol.BTC} err = UAC.UpdateCurrencies(exchangeProducts, true, true) if err != nil { t.Errorf("Test Failed - Forced Exchange TestUpdateCurrencies error: %s", err) } - exchangeProducts = []string{"ltc", "btc", "usd", "aud"} + exchangeProducts = []string{"ltc", symbol.BTC, symbol.USD, "aud"} // Test updating exchange products for an exchange which doesn't exist UAC.Name = "Blah" err = UAC.UpdateCurrencies(exchangeProducts, false, false) @@ -769,21 +775,21 @@ func TestUpdateCurrencies(t *testing.T) { } // Test updating exchange products - UAC.Name = "ANX" + UAC.Name = defaultTestExchange err = UAC.UpdateCurrencies(exchangeProducts, false, false) if err != nil { t.Errorf("Test Failed - Exchange UpdateCurrencies() error: %s", err) } // Test updating the same new products, diff should be 0 - UAC.Name = "ANX" + UAC.Name = defaultTestExchange err = UAC.UpdateCurrencies(exchangeProducts, false, false) if err != nil { t.Errorf("Test Failed - Exchange UpdateCurrencies() error: %s", err) } // Test force updating to only one product - exchangeProducts = []string{"btc"} + exchangeProducts = []string{symbol.BTC} err = UAC.UpdateCurrencies(exchangeProducts, false, true) if err != nil { t.Errorf("Test Failed - Forced Exchange UpdateCurrencies() error: %s", err) @@ -848,7 +854,7 @@ func TestAPIURL(t *testing.T) { } func TestSupportsWithdrawPermissions(t *testing.T) { - UAC := Base{Name: "ANX"} + UAC := Base{Name: defaultTestExchange} UAC.APIWithdrawPermissions = AutoWithdrawCrypto | AutoWithdrawCryptoWithAPIPermission withdrawPermissions := UAC.SupportsWithdrawPermissions(AutoWithdrawCrypto) @@ -884,7 +890,7 @@ func TestFormatWithdrawPermissions(t *testing.T) { t.Fatal("Test failed. TestUpdateEnabledCurrencies failed to load config") } - UAC := Base{Name: "ANX"} + UAC := Base{Name: defaultTestExchange} UAC.APIWithdrawPermissions = AutoWithdrawCrypto | AutoWithdrawCryptoWithAPIPermission | AutoWithdrawCryptoWithSetup | @@ -933,14 +939,14 @@ func TestOrderTypes(t *testing.T) { } func TestFilterOrdersByType(t *testing.T) { - var orders []OrderDetail - - orders = append(orders, OrderDetail{ - OrderType: ImmediateOrCancelOrderType, - }) - orders = append(orders, OrderDetail{ - OrderType: LimitOrderType, - }) + var orders = []OrderDetail{ + { + OrderType: ImmediateOrCancelOrderType, + }, + { + OrderType: LimitOrderType, + }, + } FilterOrdersByType(&orders, AnyOrderType) if len(orders) != 2 { @@ -959,15 +965,15 @@ func TestFilterOrdersByType(t *testing.T) { } func TestFilterOrdersBySide(t *testing.T) { - var orders []OrderDetail - - orders = append(orders, OrderDetail{ - OrderSide: BuyOrderSide, - }) - orders = append(orders, OrderDetail{ - OrderSide: SellOrderSide, - }) - orders = append(orders, OrderDetail{}) + var orders = []OrderDetail{ + { + OrderSide: BuyOrderSide, + }, + { + OrderSide: SellOrderSide, + }, + {}, + } FilterOrdersBySide(&orders, AnyOrderSide) if len(orders) != 3 { @@ -986,17 +992,17 @@ func TestFilterOrdersBySide(t *testing.T) { } func TestFilterOrdersByTickRange(t *testing.T) { - var orders []OrderDetail - - orders = append(orders, OrderDetail{ - OrderDate: time.Unix(100, 0), - }) - orders = append(orders, OrderDetail{ - OrderDate: time.Unix(110, 0), - }) - orders = append(orders, OrderDetail{ - OrderDate: time.Unix(111, 0), - }) + var orders = []OrderDetail{ + { + OrderDate: time.Unix(100, 0), + }, + { + OrderDate: time.Unix(110, 0), + }, + { + OrderDate: time.Unix(111, 0), + }, + } FilterOrdersByTickRange(&orders, time.Unix(0, 0), time.Unix(0, 0)) if len(orders) != 3 { @@ -1020,17 +1026,17 @@ func TestFilterOrdersByTickRange(t *testing.T) { } func TestFilterOrdersByCurrencies(t *testing.T) { - var orders []OrderDetail - - orders = append(orders, OrderDetail{ - CurrencyPair: pair.NewCurrencyPair(symbol.BTC, symbol.USD), - }) - orders = append(orders, OrderDetail{ - CurrencyPair: pair.NewCurrencyPair(symbol.LTC, symbol.EUR), - }) - orders = append(orders, OrderDetail{ - CurrencyPair: pair.NewCurrencyPair(symbol.DOGE, symbol.RUB), - }) + var orders = []OrderDetail{ + { + CurrencyPair: pair.NewCurrencyPair(symbol.BTC, symbol.USD), + }, + { + CurrencyPair: pair.NewCurrencyPair(symbol.LTC, symbol.EUR), + }, + { + CurrencyPair: pair.NewCurrencyPair(symbol.DOGE, symbol.RUB), + }, + } currencies := []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USD), pair.NewCurrencyPair(symbol.LTC, symbol.EUR), pair.NewCurrencyPair(symbol.DOGE, symbol.RUB)} FilterOrdersByCurrencies(&orders, currencies) diff --git a/exchanges/exchange_websocket.go b/exchanges/exchange_websocket.go index f0aa0c09bd2..e54f94008f8 100644 --- a/exchanges/exchange_websocket.go +++ b/exchanges/exchange_websocket.go @@ -246,12 +246,12 @@ func (w *Websocket) Shutdown() error { } // SetWebsocketURL sets websocket URL -func (w *Websocket) SetWebsocketURL(URL string) { - if URL == "" || URL == config.WebsocketURLNonDefaultMessage { +func (w *Websocket) SetWebsocketURL(websocketURL string) { + if websocketURL == "" || websocketURL == config.WebsocketURLNonDefaultMessage { w.runningURL = w.defaultURL return } - w.runningURL = URL + w.runningURL = websocketURL } // GetWebsocketURL returns the running websocket URL @@ -293,12 +293,12 @@ func (w *Websocket) IsEnabled() bool { } // SetProxyAddress sets websocket proxy address -func (w *Websocket) SetProxyAddress(URL string) error { - if w.proxyAddr == URL { +func (w *Websocket) SetProxyAddress(proxyAddr string) error { + if w.proxyAddr == proxyAddr { return errors.New("exchange_websocket.go error - Setting proxy address - same address") } - w.proxyAddr = URL + w.proxyAddr = proxyAddr if !w.init && w.enabled { if w.connected { @@ -401,7 +401,7 @@ func (w *WebsocketOrderbookLocal) Update(bidTargets, askTargets []orderbook.Item if orderbookAddress.Bids[y].Price == bidTargets[x].Price { if bidTargets[x].Amount == 0 { // Delete - orderbookAddress.Asks = append(orderbookAddress.Bids[:y], + orderbookAddress.Bids = append(orderbookAddress.Bids[:y], orderbookAddress.Bids[y+1:]...) return } diff --git a/exchanges/exmo/exmo.go b/exchanges/exmo/exmo.go index 738acb41526..64ce31ceeec 100644 --- a/exchanges/exmo/exmo.go +++ b/exchanges/exmo/exmo.go @@ -119,9 +119,9 @@ func (e *EXMO) GetTrades(symbol string) (map[string][]Trades, error) { v := url.Values{} v.Set("pair", symbol) result := make(map[string][]Trades) - url := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoTrades) + urlPath := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoTrades) - return result, e.SendHTTPRequest(common.EncodeURLValues(url, v), &result) + return result, e.SendHTTPRequest(common.EncodeURLValues(urlPath, v), &result) } // GetOrderbook returns the orderbook for a symbol or symbols @@ -129,9 +129,9 @@ func (e *EXMO) GetOrderbook(symbol string) (map[string]Orderbook, error) { v := url.Values{} v.Set("pair", symbol) result := make(map[string]Orderbook) - url := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoOrderbook) + urlPath := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoOrderbook) - return result, e.SendHTTPRequest(common.EncodeURLValues(url, v), &result) + return result, e.SendHTTPRequest(common.EncodeURLValues(urlPath, v), &result) } // GetTicker returns the ticker for a symbol or symbols @@ -139,25 +139,24 @@ func (e *EXMO) GetTicker(symbol string) (map[string]Ticker, error) { v := url.Values{} v.Set("pair", symbol) result := make(map[string]Ticker) - url := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoTicker) + urlPath := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoTicker) - return result, e.SendHTTPRequest(common.EncodeURLValues(url, v), &result) + return result, e.SendHTTPRequest(common.EncodeURLValues(urlPath, v), &result) } // GetPairSettings returns the pair settings for a symbol or symbols func (e *EXMO) GetPairSettings() (map[string]PairSettings, error) { result := make(map[string]PairSettings) - url := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoPairSettings) + urlPath := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoPairSettings) - return result, e.SendHTTPRequest(url, &result) + return result, e.SendHTTPRequest(urlPath, &result) } // GetCurrency returns a list of currencies func (e *EXMO) GetCurrency() ([]string, error) { result := []string{} - url := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoCurrency) - - return result, e.SendHTTPRequest(url, &result) + urlPath := fmt.Sprintf("%s/v%s/%s", e.APIUrl, exmoAPIVersion, exmoCurrency) + return result, e.SendHTTPRequest(urlPath, &result) } // GetUserInfo returns the user info @@ -445,11 +444,12 @@ func getInternationalBankWithdrawalFee(currency string, amount float64, bankTran switch bankTransactionType { case exchange.WireTransfer: - if currency == symbol.RUB { + switch currency { + case symbol.RUB: fee = 3200 - } else if currency == symbol.PLN { + case symbol.PLN: fee = 125 - } else if currency == symbol.TRY { + case symbol.TRY: fee = 0 } case exchange.PerfectMoney: @@ -513,11 +513,12 @@ func getInternationalBankDepositFee(currency string, amount float64, bankTransac var fee float64 switch bankTransactionType { case exchange.WireTransfer: - if currency == symbol.RUB { + switch currency { + case symbol.RUB: fee = 1600 - } else if currency == symbol.PLN { + case symbol.PLN: fee = 30 - } else if currency == symbol.TRY { + case symbol.TRY: fee = 0 } case exchange.Neteller: diff --git a/exchanges/exmo/exmo_wrapper.go b/exchanges/exmo/exmo_wrapper.go index 384b42dcd8a..34adb54e8ec 100644 --- a/exchanges/exmo/exmo_wrapper.go +++ b/exchanges/exmo/exmo_wrapper.go @@ -188,16 +188,17 @@ func (e *EXMO) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exch func (e *EXMO) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) { var submitOrderResponse exchange.SubmitOrderResponse var oT string - if orderType == exchange.LimitOrderType { - return submitOrderResponse, errors.New("Unsupported order type") - } else if orderType == exchange.MarketOrderType { - if side == exchange.BuyOrderSide { - oT = "market_buy" - } else { + + switch orderType { + case exchange.LimitOrderType: + return submitOrderResponse, errors.New("unsupported order type") + case exchange.MarketOrderType: + oT = "market_buy" + if side == exchange.SellOrderSide { oT = "market_sell" } - } else { - return submitOrderResponse, errors.New("Unsupported order type") + default: + return submitOrderResponse, errors.New("unsupported order type") } response, err := e.CreateOrder(p.Pair().String(), oT, price, amount) @@ -332,8 +333,8 @@ func (e *EXMO) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]ex // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (e *EXMO) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } var allTrades []UserTrades diff --git a/exchanges/gateio/gateio.go b/exchanges/gateio/gateio.go index 3acbc4e6371..6190eb119aa 100644 --- a/exchanges/gateio/gateio.go +++ b/exchanges/gateio/gateio.go @@ -131,9 +131,9 @@ func (g *Gateio) Setup(exch config.ExchangeConfig) { func (g *Gateio) GetSymbols() ([]string, error) { var result []string - url := fmt.Sprintf("%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioSymbol) + urlPath := fmt.Sprintf("%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioSymbol) - err := g.SendHTTPRequest(url, &result) + err := g.SendHTTPRequest(urlPath, &result) if err != nil { return nil, nil } @@ -148,11 +148,11 @@ func (g *Gateio) GetMarketInfo() (MarketInfoResponse, error) { Pairs []interface{} `json:"pairs"` } - url := fmt.Sprintf("%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioMarketInfo) + urlPath := fmt.Sprintf("%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioMarketInfo) var res response var result MarketInfoResponse - err := g.SendHTTPRequest(url, &res) + err := g.SendHTTPRequest(urlPath, &res) if err != nil { return result, err } @@ -189,17 +189,17 @@ func (g *Gateio) GetLatestSpotPrice(symbol string) (float64, error) { // GetTicker returns a ticker for the supplied symbol // updated every 10 seconds func (g *Gateio) GetTicker(symbol string) (TickerResponse, error) { - url := fmt.Sprintf("%s/%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioTicker, symbol) + urlPath := fmt.Sprintf("%s/%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioTicker, symbol) var res TickerResponse - return res, g.SendHTTPRequest(url, &res) + return res, g.SendHTTPRequest(urlPath, &res) } // GetTickers returns tickers for all symbols func (g *Gateio) GetTickers() (map[string]TickerResponse, error) { - url := fmt.Sprintf("%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioTickers) + urlPath := fmt.Sprintf("%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioTickers) resp := make(map[string]TickerResponse) - err := g.SendHTTPRequest(url, &resp) + err := g.SendHTTPRequest(urlPath, &resp) if err != nil { return nil, err } @@ -208,10 +208,10 @@ func (g *Gateio) GetTickers() (map[string]TickerResponse, error) { // GetOrderbook returns the orderbook data for a suppled symbol func (g *Gateio) GetOrderbook(symbol string) (Orderbook, error) { - url := fmt.Sprintf("%s/%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioOrderbook, symbol) + urlPath := fmt.Sprintf("%s/%s/%s/%s", g.APIUrlSecondary, gateioAPIVersion, gateioOrderbook, symbol) var resp OrderbookResponse - err := g.SendHTTPRequest(url, &resp) + err := g.SendHTTPRequest(urlPath, &resp) if err != nil { return Orderbook{}, err } @@ -270,7 +270,7 @@ func (g *Gateio) GetOrderbook(symbol string) (Orderbook, error) { // GetSpotKline returns kline data for the most recent time period func (g *Gateio) GetSpotKline(arg KlinesRequestParams) ([]*KLineResponse, error) { - url := fmt.Sprintf("%s/%s/%s/%s?group_sec=%d&range_hour=%d", + urlPath := fmt.Sprintf("%s/%s/%s/%s?group_sec=%d&range_hour=%d", g.APIUrlSecondary, gateioAPIVersion, gateioKline, @@ -279,7 +279,7 @@ func (g *Gateio) GetSpotKline(arg KlinesRequestParams) ([]*KLineResponse, error) arg.HourSize) var rawKlines map[string]interface{} - err := g.SendHTTPRequest(url, &rawKlines) + err := g.SendHTTPRequest(urlPath, &rawKlines) if err != nil { return nil, err } @@ -357,8 +357,8 @@ func (g *Gateio) SpotNewOrder(arg SpotNewOrderRequestParams) (SpotNewOrderRespon strconv.FormatFloat(arg.Amount, 'f', -1, 64), ) - strRequestURL := fmt.Sprintf("%s/%s", gateioOrder, arg.Type) - return result, g.SendAuthenticatedHTTPRequest(http.MethodPost, strRequestURL, params, &result) + urlPath := fmt.Sprintf("%s/%s", gateioOrder, arg.Type) + return result, g.SendAuthenticatedHTTPRequest(http.MethodPost, urlPath, params, &result) } // CancelExistingOrder cancels an order given the supplied orderID and symbol @@ -472,11 +472,11 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(method, endpoint, param string, re hmac := common.GetHMAC(common.HashSHA512, []byte(param), []byte(g.APISecret)) headers["sign"] = common.HexEncodeToString(hmac) - url := fmt.Sprintf("%s/%s/%s", g.APIUrl, gateioAPIVersion, endpoint) + urlPath := fmt.Sprintf("%s/%s/%s", g.APIUrl, gateioAPIVersion, endpoint) var intermidiary json.RawMessage - err := g.SendPayload(method, url, headers, strings.NewReader(param), &intermidiary, true, g.Verbose) + err := g.SendPayload(method, urlPath, headers, strings.NewReader(param), &intermidiary, true, g.Verbose) if err != nil { return err } @@ -489,7 +489,8 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(method, endpoint, param string, re if err := common.JSONDecode(intermidiary, &errCap); err == nil { if !errCap.Result { - return fmt.Errorf("GateIO auth request error, code: %d message: %s", + return fmt.Errorf("%s auth request error, code: %d message: %s", + g.Name, errCap.Code, errCap.Message) } @@ -514,7 +515,7 @@ func (g *Gateio) GetFee(feeBuilder exchange.FeeBuilder) (fee float64, err error) } } if feeForPair == 0 { - return 0, fmt.Errorf("Currency: '%s' failed to find fee data", currencyPair) + return 0, fmt.Errorf("currency '%s' failed to find fee data", currencyPair) } fee = calculateTradingFee(feeForPair, feeBuilder.PurchasePrice, feeBuilder.Amount) case exchange.CryptocurrencyWithdrawalFee: diff --git a/exchanges/gateio/gateio_websocket.go b/exchanges/gateio/gateio_websocket.go index 0b1e0afddc1..425d081d3ed 100644 --- a/exchanges/gateio/gateio_websocket.go +++ b/exchanges/gateio/gateio_websocket.go @@ -305,7 +305,7 @@ func (g *Gateio) WsHandleData() { } open, _ := strconv.ParseFloat(data[1].(string), 64) - close, _ := strconv.ParseFloat(data[2].(string), 64) + closePrice, _ := strconv.ParseFloat(data[2].(string), 64) high, _ := strconv.ParseFloat(data[3].(string), 64) low, _ := strconv.ParseFloat(data[4].(string), 64) volume, _ := strconv.ParseFloat(data[5].(string), 64) @@ -316,7 +316,7 @@ func (g *Gateio) WsHandleData() { AssetType: "SPOT", Exchange: g.GetName(), OpenPrice: open, - ClosePrice: close, + ClosePrice: closePrice, HighPrice: high, LowPrice: low, Volume: volume, diff --git a/exchanges/gateio/gateio_wrapper.go b/exchanges/gateio/gateio_wrapper.go index 1a4c5eb0e17..bbc7461ac1e 100644 --- a/exchanges/gateio/gateio_wrapper.go +++ b/exchanges/gateio/gateio_wrapper.go @@ -247,7 +247,7 @@ func (g *Gateio) CancelAllOrders(_ exchange.OrderCancellation) (exchange.CancelA return cancelAllOrdersResponse, err } - var uniqueSymbols map[string]string + uniqueSymbols := make(map[string]string) for _, openOrder := range openOrders.Orders { uniqueSymbols[openOrder.CurrencyPair] = openOrder.CurrencyPair } @@ -280,8 +280,11 @@ func (g *Gateio) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) ( if addr == gateioGenerateAddress { time.Sleep(10 * time.Second) addr, err = g.GetCryptoDepositAddress(cryptocurrency.String()) + if err != nil { + return "", err + } if addr == gateioGenerateAddress { - return "", errors.New("address not generated in time") + return "", errors.New("new deposit address is being generated, please retry again shortly") } return addr, nil } diff --git a/exchanges/gemini/gemini.go b/exchanges/gemini/gemini.go index 13273da72db..4a25f353a62 100644 --- a/exchanges/gemini/gemini.go +++ b/exchanges/gemini/gemini.go @@ -300,15 +300,15 @@ func (g *Gemini) NewOrder(symbol string, amount, price float64, side, orderType return 0, err } - request := make(map[string]interface{}) - request["symbol"] = symbol - request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - request["price"] = strconv.FormatFloat(price, 'f', -1, 64) - request["side"] = side - request["type"] = orderType + req := make(map[string]interface{}) + req["symbol"] = symbol + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req["price"] = strconv.FormatFloat(price, 'f', -1, 64) + req["side"] = side + req["type"] = orderType response := Order{} - err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiOrderNew, request, &response) + err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiOrderNew, req, &response) if err != nil { return 0, err } @@ -317,12 +317,12 @@ func (g *Gemini) NewOrder(symbol string, amount, price float64, side, orderType // CancelExistingOrder will cancel an order. If the order is already canceled, the // message will succeed but have no effect. -func (g *Gemini) CancelExistingOrder(OrderID int64) (Order, error) { - request := make(map[string]interface{}) - request["order_id"] = OrderID +func (g *Gemini) CancelExistingOrder(orderID int64) (Order, error) { + req := make(map[string]interface{}) + req["order_id"] = orderID response := Order{} - err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiOrderCancel, request, &response) + err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiOrderCancel, req, &response) if err != nil { return Order{}, err } @@ -337,10 +337,10 @@ func (g *Gemini) CancelExistingOrder(OrderID int64) (Order, error) { // sessions owned by this account, including interactive orders placed through // the UI. If sessions = true will only cancel the order that is called on this // session asssociated with the APIKEY -func (g *Gemini) CancelExistingOrders(CancelBySession bool) (OrderResult, error) { +func (g *Gemini) CancelExistingOrders(cancelBySession bool) (OrderResult, error) { response := OrderResult{} path := geminiOrderCancelAll - if CancelBySession { + if cancelBySession { path = geminiOrderCancelSession } @@ -356,12 +356,12 @@ func (g *Gemini) CancelExistingOrders(CancelBySession bool) (OrderResult, error) // GetOrderStatus returns the status for an order func (g *Gemini) GetOrderStatus(orderID int64) (Order, error) { - request := make(map[string]interface{}) - request["order_id"] = orderID + req := make(map[string]interface{}) + req["order_id"] = orderID response := Order{} - err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiOrderStatus, request, &response) + err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiOrderStatus, req, &response) if err != nil { return response, err } @@ -398,15 +398,15 @@ func (g *Gemini) GetOrders() ([]Order, error) { // timestamp - [optional] Only return trades on or after this timestamp. func (g *Gemini) GetTradeHistory(currencyPair string, timestamp int64) ([]TradeHistory, error) { response := []TradeHistory{} - request := make(map[string]interface{}) - request["symbol"] = currencyPair + req := make(map[string]interface{}) + req["symbol"] = currencyPair if timestamp != 0 { - request["timestamp"] = timestamp + req["timestamp"] = timestamp } return response, - g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiMyTrades, request, &response) + g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiMyTrades, req, &response) } // GetNotionalVolume returns the volume in price currency that has been traded across all pairs over a period of 30 days @@ -436,13 +436,13 @@ func (g *Gemini) GetBalances() ([]Balance, error) { // GetCryptoDepositAddress returns a deposit address func (g *Gemini) GetCryptoDepositAddress(depositAddlabel, currency string) (DepositAddress, error) { response := DepositAddress{} - request := make(map[string]interface{}) + req := make(map[string]interface{}) if len(depositAddlabel) > 0 { - request["label"] = depositAddlabel + req["label"] = depositAddlabel } - err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiDeposit+"/"+currency+"/"+geminiNewAddress, request, &response) + err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiDeposit+"/"+currency+"/"+geminiNewAddress, req, &response) if err != nil { return response, err } @@ -455,11 +455,11 @@ func (g *Gemini) GetCryptoDepositAddress(depositAddlabel, currency string) (Depo // WithdrawCrypto withdraws crypto currency to a whitelisted address func (g *Gemini) WithdrawCrypto(address, currency string, amount float64) (WithdrawalAddress, error) { response := WithdrawalAddress{} - request := make(map[string]interface{}) - request["address"] = address - request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + req := make(map[string]interface{}) + req["address"] = address + req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiWithdraw+common.StringToLower(currency), request, &response) + err := g.SendAuthenticatedHTTPRequest(http.MethodPost, geminiWithdraw+common.StringToLower(currency), req, &response) if err != nil { return response, err } @@ -501,17 +501,17 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(method, path string, params map[st } headers := make(map[string]string) - request := make(map[string]interface{}) - request["request"] = fmt.Sprintf("/v%s/%s", geminiAPIVersion, path) - request["nonce"] = g.Nonce.GetValue(g.Name, false) + req := make(map[string]interface{}) + req["request"] = fmt.Sprintf("/v%s/%s", geminiAPIVersion, path) + req["nonce"] = g.Nonce.GetValue(g.Name, false) for key, value := range params { - request[key] = value + req[key] = value } - PayloadJSON, err := common.JSONEncode(request) + PayloadJSON, err := common.JSONEncode(req) if err != nil { - return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request") + return errors.New("sendAuthenticatedHTTPRequest: Unable to JSON request") } if g.Verbose { diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index 2e2ee1214c7..c615d036b2b 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -284,8 +284,8 @@ func (g *Gemini) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([] // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (g *Gemini) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } var trades []TradeHistory diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index dd422d6c89f..2231c02294a 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -265,8 +265,8 @@ func (h *HitBTC) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) { // GetActiveOrders retrieves any orders that are active/open func (h *HitBTC) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } var allOrders []OrderHistoryResponse @@ -308,8 +308,8 @@ func (h *HitBTC) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([] // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (h *HitBTC) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } var allOrders []OrderHistoryResponse diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index 8e2849d406b..f8176aa6c84 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -164,9 +164,9 @@ func (h *HUOBI) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketHistoryKline) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketHistoryKline) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -184,9 +184,9 @@ func (h *HUOBI) GetMarketDetailMerged(symbol string) (DetailMerged, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketDetailMerged) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketDetailMerged) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -208,9 +208,9 @@ func (h *HUOBI) GetDepth(obd OrderBookDataRequestParams) (Orderbook, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketDepth) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketDepth) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return result.Depth, errors.New(result.ErrorMessage) } @@ -230,9 +230,9 @@ func (h *HUOBI) GetTrades(symbol string) ([]Trade, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketTrade) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketTrade) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -249,7 +249,7 @@ func (h *HUOBI) GetLatestSpotPrice(symbol string) (float64, error) { return 0, err } if len(list) == 0 { - return 0, errors.New("The length of the list is 0") + return 0, errors.New("the length of the list is 0") } return list[0].Trades[0].Price, nil @@ -270,9 +270,9 @@ func (h *HUOBI) GetTradeHistory(symbol, size string) ([]TradeHistory, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketTradeHistory) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketTradeHistory) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -290,9 +290,9 @@ func (h *HUOBI) GetMarketDetail(symbol string) (Detail, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketDetail) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobiMarketDetail) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -307,9 +307,9 @@ func (h *HUOBI) GetSymbols() ([]Symbol, error) { } var result response - url := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobiAPIVersion, huobiSymbols) + urlPath := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobiAPIVersion, huobiSymbols) - err := h.SendHTTPRequest(url, &result) + err := h.SendHTTPRequest(urlPath, &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -324,9 +324,9 @@ func (h *HUOBI) GetCurrencies() ([]string, error) { } var result response - url := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobiAPIVersion, huobiCurrencies) + urlPath := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobiAPIVersion, huobiCurrencies) - err := h.SendHTTPRequest(url, &result) + err := h.SendHTTPRequest(urlPath, &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -341,9 +341,9 @@ func (h *HUOBI) GetTimestamp() (int64, error) { } var result response - url := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobiAPIVersion, huobiTimestamp) + urlPath := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobiAPIVersion, huobiTimestamp) - err := h.SendHTTPRequest(url, &result) + err := h.SendHTTPRequest(urlPath, &result) if result.ErrorMessage != "" { return 0, errors.New(result.ErrorMessage) } @@ -476,7 +476,7 @@ func (h *HUOBI) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrder err := h.SendAuthenticatedHTTPRequest(http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result) if result.Data.FailedCount > 0 { - return result, fmt.Errorf("There were %v failed order cancellations", result.Data.FailedCount) + return result, fmt.Errorf("there were %v failed order cancellations", result.Data.FailedCount) } return result, err @@ -835,7 +835,7 @@ func (h *HUOBI) SendHTTPRequest(path string, result interface{}) error { } // SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API -func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, data interface{}, result interface{}) error { +func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, data, result interface{}) error { if !h.AuthenticatedAPISupport { return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, h.Name) } @@ -869,23 +869,23 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url pemKey := strings.NewReader(h.APIAuthPEMKey) pemBytes, err := ioutil.ReadAll(pemKey) if err != nil { - return fmt.Errorf("Huobi unable to ioutil.ReadAll PEM key: %s", err) + return fmt.Errorf("%s unable to ioutil.ReadAll PEM key: %s", h.Name, err) } block, _ := pem.Decode(pemBytes) if block == nil { - return fmt.Errorf("Huobi block is nil") + return fmt.Errorf("%s PEM block is nil", h.Name) } x509Encoded := block.Bytes privKey, err := x509.ParseECPrivateKey(x509Encoded) if err != nil { - return fmt.Errorf("Huobi unable to ParseECPrivKey: %s", err) + return fmt.Errorf("%s unable to ParseECPrivKey: %s", h.Name, err) } r, s, err := ecdsa.Sign(rand.Reader, privKey, common.GetSHA256([]byte(signature))) if err != nil { - return fmt.Errorf("Huobi unable to sign: %s", err) + return fmt.Errorf("%s unable to sign: %s", h.Name, err) } privSig := r.Bytes() @@ -893,28 +893,28 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url values.Set("PrivateSignature", common.Base64Encode(privSig)) } - url := fmt.Sprintf("%s%s", h.APIUrl, endpoint) - url = common.EncodeURLValues(url, values) + urlPath := common.EncodeURLValues( + fmt.Sprintf("%s%s", h.APIUrl, endpoint), values, + ) var body []byte if data != nil { encoded, err := json.Marshal(data) if err != nil { - return fmt.Errorf("Huobi unable to marshal data: %s", err) + return fmt.Errorf("%s unable to marshal data: %s", h.Name, err) } body = encoded } - return h.SendPayload(method, url, headers, bytes.NewReader(body), result, true, h.Verbose) + return h.SendPayload(method, urlPath, headers, bytes.NewReader(body), result, true, h.Verbose) } // GetFee returns an estimate of fee based on type of transaction func (h *HUOBI) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { var fee float64 - switch feeBuilder.FeeType { - case exchange.CryptocurrencyTradeFee: + if feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount) } if fee < 0 { diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index 8de3ff9060c..61fce83a1c5 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -53,7 +53,7 @@ func (h *HUOBI) Run() { exchCfg.BaseCurrencies = "USD" h.BaseCurrencies = []string{"USD"} - errCNY = cfg.UpdateExchangeConfig(exchCfg) + errCNY = cfg.UpdateExchangeConfig(&exchCfg) if errCNY != nil { log.Errorf("%s failed to update config. %s\n", h.Name, errCNY) return @@ -165,7 +165,7 @@ func (h *HUOBI) GetAccountID() ([]Account, error) { return acc, nil } -//GetAccountInfo retrieves balances for all enabled currencies for the +// GetAccountInfo retrieves balances for all enabled currencies for the // HUOBI exchange - to-do func (h *HUOBI) GetAccountInfo() (exchange.AccountInfo, error) { var info exchange.AccountInfo @@ -261,24 +261,23 @@ func (h *HUOBI) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderT AccountID: int(accountID), } - if side == exchange.BuyOrderSide && orderType == exchange.MarketOrderType { + switch { + case side == exchange.BuyOrderSide && orderType == exchange.MarketOrderType: formattedType = SpotNewOrderRequestTypeBuyMarket - } else if side == exchange.SellOrderSide && orderType == exchange.MarketOrderType { + case side == exchange.SellOrderSide && orderType == exchange.MarketOrderType: formattedType = SpotNewOrderRequestTypeSellMarket - } else if side == exchange.BuyOrderSide && orderType == exchange.LimitOrderType { + case side == exchange.BuyOrderSide && orderType == exchange.LimitOrderType: formattedType = SpotNewOrderRequestTypeBuyLimit params.Price = price - } else if side == exchange.SellOrderSide && orderType == exchange.LimitOrderType { + case side == exchange.SellOrderSide && orderType == exchange.LimitOrderType: formattedType = SpotNewOrderRequestTypeSellLimit params.Price = price - } else { - return submitOrderResponse, errors.New("Unsupported order type") + default: + return submitOrderResponse, errors.New("unsupported order type") } params.Type = formattedType - response, err := h.SpotNewOrder(params) - if response > 0 { submitOrderResponse.OrderID = fmt.Sprintf("%v", response) } @@ -374,8 +373,8 @@ func (h *HUOBI) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) { // GetActiveOrders retrieves any orders that are active/open func (h *HUOBI) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } side := "" @@ -419,8 +418,8 @@ func (h *HUOBI) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]e // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (h *HUOBI) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } states := "partial-canceled,filled,canceled" diff --git a/exchanges/huobihadax/huobihadax.go b/exchanges/huobihadax/huobihadax.go index 7fe173b497d..7a76c1a5522 100644 --- a/exchanges/huobihadax/huobihadax.go +++ b/exchanges/huobihadax/huobihadax.go @@ -158,9 +158,9 @@ func (h *HUOBIHADAX) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketHistoryKline) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketHistoryKline) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -178,9 +178,9 @@ func (h *HUOBIHADAX) GetMarketDetailMerged(symbol string) (DetailMerged, error) } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDetailMerged) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDetailMerged) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -202,9 +202,9 @@ func (h *HUOBIHADAX) GetDepth(symbol, depthType string) (Orderbook, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDepth) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDepth) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return result.Depth, errors.New(result.ErrorMessage) } @@ -224,9 +224,9 @@ func (h *HUOBIHADAX) GetTrades(symbol string) ([]Trade, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketTrade) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketTrade) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -243,7 +243,7 @@ func (h *HUOBIHADAX) GetLatestSpotPrice(symbol string) (float64, error) { return 0, err } if len(list) == 0 { - return 0, errors.New("The length of the list is 0") + return 0, errors.New("the length of the list is 0") } return list[0].Trades[0].Price, nil @@ -264,9 +264,9 @@ func (h *HUOBIHADAX) GetTradeHistory(symbol, size string) ([]TradeHistory, error } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketTradeHistory) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketTradeHistory) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -284,9 +284,9 @@ func (h *HUOBIHADAX) GetMarketDetail(symbol string) (Detail, error) { } var result response - url := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDetail) + urlPath := fmt.Sprintf("%s/%s", h.APIUrl, huobihadaxMarketDetail) - err := h.SendHTTPRequest(common.EncodeURLValues(url, vals), &result) + err := h.SendHTTPRequest(common.EncodeURLValues(urlPath, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -301,9 +301,9 @@ func (h *HUOBIHADAX) GetSymbols() ([]Symbol, error) { } var result response - url := fmt.Sprintf("%s/v%s/%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxAPIName, huobihadaxSymbols) + urlPath := fmt.Sprintf("%s/v%s/%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxAPIName, huobihadaxSymbols) - err := h.SendHTTPRequest(url, &result) + err := h.SendHTTPRequest(urlPath, &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -318,9 +318,9 @@ func (h *HUOBIHADAX) GetCurrencies() ([]string, error) { } var result response - url := fmt.Sprintf("%s/v%s/%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxAPIName, huobihadaxCurrencies) + urlPath := fmt.Sprintf("%s/v%s/%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxAPIName, huobihadaxCurrencies) - err := h.SendHTTPRequest(url, &result) + err := h.SendHTTPRequest(urlPath, &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -335,9 +335,9 @@ func (h *HUOBIHADAX) GetTimestamp() (int64, error) { } var result response - url := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxTimestamp) + urlPath := fmt.Sprintf("%s/v%s/%s", h.APIUrl, huobihadaxAPIVersion, huobihadaxTimestamp) - err := h.SendHTTPRequest(url, &result) + err := h.SendHTTPRequest(urlPath, &result) if result.ErrorMessage != "" { return 0, errors.New(result.ErrorMessage) } @@ -482,7 +482,7 @@ func (h *HUOBIHADAX) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpen err := h.SendAuthenticatedHTTPPostRequest(http.MethodPost, huobiHadaxBatchCancelOpenOrders, postBodyParams, &result) if result.Data.FailedCount > 0 { - return result, fmt.Errorf("There were %v failed order cancellations", result.Data.FailedCount) + return result, fmt.Errorf("there were %v failed order cancellations", result.Data.FailedCount) } return result, err @@ -851,11 +851,9 @@ func (h *HUOBIHADAX) SendAuthenticatedHTTPPostRequest(method, endpoint, postBody hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret)) signatureParams.Set("Signature", common.Base64Encode(hmac)) - - url := fmt.Sprintf("%s%s", h.APIUrl, endpoint) - url = common.EncodeURLValues(url, signatureParams) - - return h.SendPayload(method, url, headers, bytes.NewBufferString(postBodyValues), result, true, h.Verbose) + urlPath := common.EncodeURLValues(fmt.Sprintf("%s%s", h.APIUrl, endpoint), + signatureParams) + return h.SendPayload(method, urlPath, headers, bytes.NewBufferString(postBodyValues), result, true, h.Verbose) } // SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API @@ -879,17 +877,15 @@ func (h *HUOBIHADAX) SendAuthenticatedHTTPRequest(method, endpoint string, value hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret)) values.Set("Signature", common.Base64Encode(hmac)) - url := fmt.Sprintf("%s%s", h.APIUrl, endpoint) - url = common.EncodeURLValues(url, values) - - return h.SendPayload(method, url, headers, bytes.NewBufferString(""), result, true, h.Verbose) + urlPath := common.EncodeURLValues(fmt.Sprintf("%s%s", h.APIUrl, endpoint), + values) + return h.SendPayload(method, urlPath, headers, bytes.NewBufferString(""), result, true, h.Verbose) } // GetFee returns an estimate of fee based on type of transaction func (h *HUOBIHADAX) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { var fee float64 - switch feeBuilder.FeeType { - case exchange.CryptocurrencyTradeFee: + if feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount) } if fee < 0 { @@ -905,7 +901,7 @@ func calculateTradingFee(purchasePrice, amount float64) float64 { } // GetDepositWithdrawalHistory returns deposit or withdrawal data -func (h *HUOBIHADAX) GetDepositWithdrawalHistory(associatedID string, currency string, isDeposit bool, size int64) ([]History, error) { +func (h *HUOBIHADAX) GetDepositWithdrawalHistory(associatedID, currency string, isDeposit bool, size int64) ([]History, error) { var resp = struct { Response Data []History `json:"data"` diff --git a/exchanges/huobihadax/huobihadax_wrapper.go b/exchanges/huobihadax/huobihadax_wrapper.go index eaca35141d8..82428739276 100644 --- a/exchanges/huobihadax/huobihadax_wrapper.go +++ b/exchanges/huobihadax/huobihadax_wrapper.go @@ -226,18 +226,19 @@ func (h *HUOBIHADAX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, o AccountID: int(accountID), } - if side == exchange.BuyOrderSide && orderType == exchange.MarketOrderType { + switch { + case side == exchange.BuyOrderSide && orderType == exchange.MarketOrderType: formattedType = SpotNewOrderRequestTypeBuyMarket - } else if side == exchange.SellOrderSide && orderType == exchange.MarketOrderType { + case side == exchange.SellOrderSide && orderType == exchange.MarketOrderType: formattedType = SpotNewOrderRequestTypeSellMarket - } else if side == exchange.BuyOrderSide && orderType == exchange.LimitOrderType { + case side == exchange.BuyOrderSide && orderType == exchange.LimitOrderType: formattedType = SpotNewOrderRequestTypeBuyLimit params.Price = price - } else if side == exchange.SellOrderSide && orderType == exchange.LimitOrderType { + case side == exchange.SellOrderSide && orderType == exchange.LimitOrderType: formattedType = SpotNewOrderRequestTypeSellLimit params.Price = price - } else { - return submitOrderResponse, errors.New("Unsupported order type") + default: + return submitOrderResponse, errors.New("unsupported order type") } params.Type = formattedType @@ -339,8 +340,8 @@ func (h *HUOBIHADAX) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, erro // GetActiveOrders retrieves any orders that are active/open func (h *HUOBIHADAX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } side := "" @@ -384,8 +385,8 @@ func (h *HUOBIHADAX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (h *HUOBIHADAX) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - if len(getOrdersRequest.Currencies) <= 0 { - return nil, errors.New("Currency must be supplied") + if len(getOrdersRequest.Currencies) == 0 { + return nil, errors.New("currency must be supplied") } states := "partial-canceled,filled,canceled" diff --git a/exchanges/itbit/itbit.go b/exchanges/itbit/itbit.go index a49202e6cf6..22476e82af2 100644 --- a/exchanges/itbit/itbit.go +++ b/exchanges/itbit/itbit.go @@ -223,8 +223,8 @@ func (i *ItBit) GetOrders(walletID, symbol, status string, page, perPage int64) // GetWalletTrades returns all trades for a specified wallet. func (i *ItBit) GetWalletTrades(walletID string, params url.Values) (Records, error) { resp := Records{} - url := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitTrades) - path := common.EncodeURLValues(url, params) + urlPath := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitTrades) + path := common.EncodeURLValues(urlPath, params) err := i.SendAuthenticatedHTTPRequest(http.MethodGet, path, nil, &resp) if err != nil { @@ -239,8 +239,8 @@ func (i *ItBit) GetWalletTrades(walletID string, params url.Values) (Records, er // GetFundingHistoryForWallet returns all funding history for a specified wallet. func (i *ItBit) GetFundingHistoryForWallet(walletID string, params url.Values) (FundingRecords, error) { resp := FundingRecords{} - url := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitFundingHistory) - path := common.EncodeURLValues(url, params) + urlPath := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitFundingHistory) + path := common.EncodeURLValues(urlPath, params) err := i.SendAuthenticatedHTTPRequest(http.MethodGet, path, nil, &resp) if err != nil { @@ -282,8 +282,8 @@ func (i *ItBit) PlaceOrder(walletID, side, orderType, currency string, amount, p // GetOrder returns an order by id. func (i *ItBit) GetOrder(walletID string, params url.Values) (Order, error) { resp := Order{} - url := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitOrders) - path := common.EncodeURLValues(url, params) + urlPath := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitOrders) + path := common.EncodeURLValues(urlPath, params) err := i.SendAuthenticatedHTTPRequest(http.MethodGet, path, nil, &resp) if err != nil { @@ -347,7 +347,7 @@ func (i *ItBit) SendHTTPRequest(path string, result interface{}) error { } // SendAuthenticatedHTTPRequest sends an authenticated request to itBit -func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params map[string]interface{}, result interface{}) error { +func (i *ItBit) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}) error { if !i.AuthenticatedAPISupport { return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, i.Name) } @@ -356,18 +356,18 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params return errors.New("client ID not set") } - request := make(map[string]interface{}) - url := i.APIUrl + path + req := make(map[string]interface{}) + urlPath := i.APIUrl + path for key, value := range params { - request[key] = value + req[key] = value } PayloadJSON := []byte("") var err error if params != nil { - PayloadJSON, err = common.JSONEncode(request) + PayloadJSON, err = common.JSONEncode(req) if err != nil { return err } @@ -380,13 +380,13 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params nonce := i.Nonce.GetValue(i.Name, false).String() timestamp := strconv.FormatInt(time.Now().UnixNano()/1000000, 10) - message, err := common.JSONEncode([]string{method, url, string(PayloadJSON), nonce, timestamp}) + message, err := common.JSONEncode([]string{method, urlPath, string(PayloadJSON), nonce, timestamp}) if err != nil { return err } hash := common.GetSHA256([]byte(nonce + string(message))) - hmac := common.GetHMAC(common.HashSHA512, []byte(url+string(hash)), []byte(i.APISecret)) + hmac := common.GetHMAC(common.HashSHA512, []byte(urlPath+string(hash)), []byte(i.APISecret)) signature := common.Base64Encode(hmac) headers := make(map[string]string) @@ -403,7 +403,7 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params RequestID string `json:"requestId"` }{} - err = i.SendPayload(method, url, headers, bytes.NewBuffer(PayloadJSON), &intermediary, true, i.Verbose) + err = i.SendPayload(method, urlPath, headers, bytes.NewBuffer(PayloadJSON), &intermediary, true, i.Verbose) if err != nil { return err } diff --git a/exchanges/itbit/itbit_wrapper.go b/exchanges/itbit/itbit_wrapper.go index 5213e7d8bdc..356e0439c2d 100644 --- a/exchanges/itbit/itbit_wrapper.go +++ b/exchanges/itbit/itbit_wrapper.go @@ -189,7 +189,7 @@ func (i *ItBit) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderT } if wallet == "" { - return submitOrderResponse, fmt.Errorf("No wallet found with currency: %s with amount >= %v", p.FirstCurrency.String(), amount) + return submitOrderResponse, fmt.Errorf("no wallet found with currency: %s with amount >= %v", p.FirstCurrency.String(), amount) } response, err := i.PlaceOrder(wallet, side.ToString(), orderType.ToString(), p.FirstCurrency.String(), amount, price, p.Pair().String(), "") diff --git a/exchanges/kraken/kraken.go b/exchanges/kraken/kraken.go index 3d397de680d..cd7bc686331 100644 --- a/exchanges/kraken/kraken.go +++ b/exchanges/kraken/kraken.go @@ -175,7 +175,7 @@ func (k *Kraken) GetAssetPairs() (map[string]AssetPairs, error) { // GetTicker returns ticker information from kraken func (k *Kraken) GetTicker(symbol string) (Ticker, error) { - ticker := Ticker{} + tick := Ticker{} values := url.Values{} values.Set("pair", symbol) @@ -189,25 +189,25 @@ func (k *Kraken) GetTicker(symbol string) (Ticker, error) { err := k.SendHTTPRequest(path, &resp) if err != nil { - return ticker, err + return tick, err } if len(resp.Error) > 0 { - return ticker, fmt.Errorf("Kraken error: %s", resp.Error) + return tick, fmt.Errorf("%s error: %s", k.Name, resp.Error) } for _, y := range resp.Data { - ticker.Ask, _ = strconv.ParseFloat(y.Ask[0], 64) - ticker.Bid, _ = strconv.ParseFloat(y.Bid[0], 64) - ticker.Last, _ = strconv.ParseFloat(y.Last[0], 64) - ticker.Volume, _ = strconv.ParseFloat(y.Volume[1], 64) - ticker.VWAP, _ = strconv.ParseFloat(y.VWAP[1], 64) - ticker.Trades = y.Trades[1] - ticker.Low, _ = strconv.ParseFloat(y.Low[1], 64) - ticker.High, _ = strconv.ParseFloat(y.High[1], 64) - ticker.Open, _ = strconv.ParseFloat(y.Open, 64) - } - return ticker, nil + tick.Ask, _ = strconv.ParseFloat(y.Ask[0], 64) + tick.Bid, _ = strconv.ParseFloat(y.Bid[0], 64) + tick.Last, _ = strconv.ParseFloat(y.Last[0], 64) + tick.Volume, _ = strconv.ParseFloat(y.Volume[1], 64) + tick.VWAP, _ = strconv.ParseFloat(y.VWAP[1], 64) + tick.Trades = y.Trades[1] + tick.Low, _ = strconv.ParseFloat(y.Low[1], 64) + tick.High, _ = strconv.ParseFloat(y.High[1], 64) + tick.Open, _ = strconv.ParseFloat(y.Open, 64) + } + return tick, nil } // GetTickers supports fetching multiple tickers from Kraken @@ -231,23 +231,23 @@ func (k *Kraken) GetTickers(pairList string) (Tickers, error) { } if len(resp.Error) > 0 { - return nil, fmt.Errorf("Kraken error: %s", resp.Error) + return nil, fmt.Errorf("%s error: %s", k.Name, resp.Error) } tickers := make(Tickers) for x, y := range resp.Data { - ticker := Ticker{} - ticker.Ask, _ = strconv.ParseFloat(y.Ask[0], 64) - ticker.Bid, _ = strconv.ParseFloat(y.Bid[0], 64) - ticker.Last, _ = strconv.ParseFloat(y.Last[0], 64) - ticker.Volume, _ = strconv.ParseFloat(y.Volume[1], 64) - ticker.VWAP, _ = strconv.ParseFloat(y.VWAP[1], 64) - ticker.Trades = y.Trades[1] - ticker.Low, _ = strconv.ParseFloat(y.Low[1], 64) - ticker.High, _ = strconv.ParseFloat(y.High[1], 64) - ticker.Open, _ = strconv.ParseFloat(y.Open, 64) - tickers[x] = ticker + tick := Ticker{} + tick.Ask, _ = strconv.ParseFloat(y.Ask[0], 64) + tick.Bid, _ = strconv.ParseFloat(y.Bid[0], 64) + tick.Last, _ = strconv.ParseFloat(y.Last[0], 64) + tick.Volume, _ = strconv.ParseFloat(y.Volume[1], 64) + tick.VWAP, _ = strconv.ParseFloat(y.VWAP[1], 64) + tick.Trades = y.Trades[1] + tick.Low, _ = strconv.ParseFloat(y.Low[1], 64) + tick.High, _ = strconv.ParseFloat(y.High[1], 64) + tick.Open, _ = strconv.ParseFloat(y.Open, 64) + tickers[x] = tick } return tickers, nil } @@ -273,7 +273,7 @@ func (k *Kraken) GetOHLC(symbol string) ([]OpenHighLowClose, error) { } if len(result.Error) != 0 { - return OHLC, fmt.Errorf("GetOHLC error: %s", result.Error) + return OHLC, fmt.Errorf("getOHLC error: %s", result.Error) } for _, y := range result.Data[symbol].([]interface{}) { @@ -514,11 +514,11 @@ func (k *Kraken) GetTradeBalance(args ...TradeBalanceOptions) (TradeBalanceInfo, params := url.Values{} if args != nil { - if len(args[0].Aclass) != 0 { + if len(args[0].Aclass) > 0 { params.Set("aclass", args[0].Aclass) } - if len(args[0].Asset) != 0 { + if len(args[0].Asset) > 0 { params.Set("asset", args[0].Asset) } @@ -572,19 +572,19 @@ func (k *Kraken) GetClosedOrders(args GetClosedOrdersOptions) (ClosedOrders, err params.Set("userref", strconv.FormatInt(int64(args.UserRef), 10)) } - if len(args.Start) != 0 { + if len(args.Start) > 0 { params.Set("start", args.Start) } - if len(args.End) != 0 { + if len(args.End) > 0 { params.Set("end", args.End) } - if args.Ofs != 0 { + if args.Ofs > 0 { params.Set("ofs", strconv.FormatInt(args.Ofs, 10)) } - if len(args.CloseTime) != 0 { + if len(args.CloseTime) > 0 { params.Set("closetime", args.CloseTime) } @@ -635,7 +635,7 @@ func (k *Kraken) GetTradesHistory(args ...GetTradesHistoryOptions) (TradesHistor params := url.Values{} if args != nil { - if len(args[0].Type) != 0 { + if len(args[0].Type) > 0 { params.Set("type", args[0].Type) } @@ -643,15 +643,15 @@ func (k *Kraken) GetTradesHistory(args ...GetTradesHistoryOptions) (TradesHistor params.Set("trades", "true") } - if len(args[0].Start) != 0 { + if len(args[0].Start) > 0 { params.Set("start", args[0].Start) } - if len(args[0].End) != 0 { + if len(args[0].End) > 0 { params.Set("end", args[0].End) } - if args[0].Ofs != 0 { + if args[0].Ofs > 0 { params.Set("ofs", strconv.FormatInt(args[0].Ofs, 10)) } } @@ -723,23 +723,23 @@ func (k *Kraken) GetLedgers(args ...GetLedgersOptions) (Ledgers, error) { params := url.Values{} if args != nil { - if len(args[0].Aclass) != 0 { + if args[0].Aclass == "" { params.Set("aclass", args[0].Aclass) } - if len(args[0].Asset) != 0 { + if args[0].Asset == "" { params.Set("asset", args[0].Asset) } - if len(args[0].Type) != 0 { + if args[0].Type == "" { params.Set("type", args[0].Type) } - if len(args[0].Start) != 0 { + if args[0].Start == "" { params.Set("start", args[0].Start) } - if len(args[0].End) != 0 { + if args[0].End == "" { params.Set("end", args[0].End) } @@ -827,19 +827,19 @@ func (k *Kraken) AddOrder(symbol, side, orderType string, volume, price, price2, params.Set("leverage", strconv.FormatFloat(leverage, 'f', -1, 64)) } - if len(args.Oflags) != 0 { + if args.Oflags == "" { params.Set("oflags", args.Oflags) } - if len(args.StartTm) != 0 { + if args.StartTm == "" { params.Set("starttm", args.StartTm) } - if len(args.ExpireTm) != 0 { + if args.ExpireTm == "" { params.Set("expiretm", args.ExpireTm) } - if len(args.CloseOrderType) != 0 { + if args.CloseOrderType != "" { params.Set("close[ordertype]", args.ExpireTm) } @@ -890,14 +890,14 @@ func (k *Kraken) CancelExistingOrder(txid string) (CancelOrderResponse, error) { // error = array of error messages in the format of: // :[:] // severity code can be E for error or W for warning -func GetError(errors []string) error { - - for _, e := range errors { +func GetError(apiErrors []string) error { + const exchangeName = "Kraken" + for _, e := range apiErrors { switch e[0] { case 'W': - log.Warnf("Kraken API warning: %v\n", e[1:]) + log.Warnf("%s API warning: %v\n", exchangeName, e[1:]) default: - return fmt.Errorf("Kraken API error: %v", e[1:]) + return fmt.Errorf("%s API error: %v", exchangeName, e[1:]) } } @@ -969,8 +969,7 @@ func (k *Kraken) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) { } for _, i := range depositMethods { - switch feeBuilder.BankTransactionType { - case exchange.WireTransfer: + if feeBuilder.BankTransactionType == exchange.WireTransfer { if i.Method == "SynapsePay (US Wire)" { fee = i.Fee return fee, nil @@ -1034,7 +1033,7 @@ func (k *Kraken) WithdrawStatus(currency, method string) ([]WithdrawStatusRespon params := url.Values{} params.Set("asset ", currency) - if len(method) != 0 { + if method != "" { params.Set("method", method) } diff --git a/exchanges/kraken/kraken_test.go b/exchanges/kraken/kraken_test.go index 0c7e8791405..ae059961fa6 100644 --- a/exchanges/kraken/kraken_test.go +++ b/exchanges/kraken/kraken_test.go @@ -563,13 +563,13 @@ func TestWithdrawStatus(t *testing.T) { if areTestAPIKeysSet() { _, err := k.WithdrawStatus(symbol.BTC, "") - if err == nil { + if err != nil { t.Error("Test Failed - WithdrawStatus() error", err) } } else { _, err := k.WithdrawStatus(symbol.BTC, "") if err == nil { - t.Error("Test Failed - WithdrawStatus() error", err) + t.Error("Test Failed - GetDepositAddress() error can not be nil", err) } } } diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index d5133594e77..1861f98166f 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -87,17 +87,18 @@ func (k *Kraken) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pri for _, x := range pairs { for y, z := range tickers { - if common.StringContains(y, x.FirstCurrency.Upper().String()) && common.StringContains(y, x.SecondCurrency.Upper().String()) { - var tp ticker.Price - tp.Pair = x - tp.Last = z.Last - tp.Ask = z.Ask - tp.Bid = z.Bid - tp.High = z.High - tp.Low = z.Low - tp.Volume = z.Volume - ticker.ProcessTicker(k.GetName(), x, tp, assetType) + if !common.StringContains(y, x.FirstCurrency.Upper().String()) && !common.StringContains(y, x.SecondCurrency.Upper().String()) { + continue } + var tp ticker.Price + tp.Pair = x + tp.Last = z.Last + tp.Ask = z.Ask + tp.Bid = z.Bid + tp.High = z.High + tp.Low = z.Low + tp.Volume = z.Volume + ticker.ProcessTicker(k.GetName(), x, tp, assetType) } } return ticker.GetTicker(k.GetName(), p, assetType) @@ -324,15 +325,15 @@ func (k *Kraken) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([] // GetOrderHistory retrieves account order information // Can Limit response to specific order status func (k *Kraken) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { - request := GetClosedOrdersOptions{} + req := GetClosedOrdersOptions{} if getOrdersRequest.StartTicks.Unix() > 0 { - request.Start = fmt.Sprintf("%v", getOrdersRequest.StartTicks.Unix()) + req.Start = fmt.Sprintf("%v", getOrdersRequest.StartTicks.Unix()) } if getOrdersRequest.EndTicks.Unix() > 0 { - request.End = fmt.Sprintf("%v", getOrdersRequest.EndTicks.Unix()) + req.End = fmt.Sprintf("%v", getOrdersRequest.EndTicks.Unix()) } - resp, err := k.GetClosedOrders(request) + resp, err := k.GetClosedOrders(req) if err != nil { return nil, err } diff --git a/exchanges/lakebtc/lakebtc.go b/exchanges/lakebtc/lakebtc.go index 1121352ded9..c48ba4d2658 100644 --- a/exchanges/lakebtc/lakebtc.go +++ b/exchanges/lakebtc/lakebtc.go @@ -132,30 +132,28 @@ func (l *LakeBTC) GetTicker() (map[string]Ticker, error) { result := make(map[string]Ticker) - var addresses []string for k, v := range response { - var ticker Ticker + var tick Ticker key := common.StringToUpper(k) if v.Ask != nil { - ticker.Ask, _ = strconv.ParseFloat(v.Ask.(string), 64) + tick.Ask, _ = strconv.ParseFloat(v.Ask.(string), 64) } if v.Bid != nil { - ticker.Bid, _ = strconv.ParseFloat(v.Bid.(string), 64) + tick.Bid, _ = strconv.ParseFloat(v.Bid.(string), 64) } if v.High != nil { - ticker.High, _ = strconv.ParseFloat(v.High.(string), 64) + tick.High, _ = strconv.ParseFloat(v.High.(string), 64) } if v.Last != nil { - ticker.Last, _ = strconv.ParseFloat(v.Last.(string), 64) + tick.Last, _ = strconv.ParseFloat(v.Last.(string), 64) } if v.Low != nil { - ticker.Low, _ = strconv.ParseFloat(v.Low.(string), 64) + tick.Low, _ = strconv.ParseFloat(v.Low.(string), 64) } if v.Volume != nil { - ticker.Volume, _ = strconv.ParseFloat(v.Volume.(string), 64) + tick.Volume, _ = strconv.ParseFloat(v.Volume.(string), 64) } - result[key] = ticker - addresses = append(addresses, key) + result[key] = tick } return result, nil } @@ -236,7 +234,7 @@ func (l *LakeBTC) Trade(isBuyOrder bool, amount, price float64, currency string) } if resp.Result != "order received" { - return resp, fmt.Errorf("Unexpected result: %s", resp.Result) + return resp, fmt.Errorf("unexpected result: %s", resp.Result) } return resp, nil diff --git a/exchanges/lakebtc/lakebtc_wrapper.go b/exchanges/lakebtc/lakebtc_wrapper.go index 9c1ca889c67..97bbfa67acd 100644 --- a/exchanges/lakebtc/lakebtc_wrapper.go +++ b/exchanges/lakebtc/lakebtc_wrapper.go @@ -117,13 +117,14 @@ func (l *LakeBTC) GetAccountInfo() (exchange.AccountInfo, error) { var currencies []exchange.AccountCurrencyInfo for x, y := range accountInfo.Balance { for z, w := range accountInfo.Locked { - if z == x { - var exchangeCurrency exchange.AccountCurrencyInfo - exchangeCurrency.CurrencyName = common.StringToUpper(x) - exchangeCurrency.TotalValue, _ = strconv.ParseFloat(y, 64) - exchangeCurrency.Hold, _ = strconv.ParseFloat(w, 64) - currencies = append(currencies, exchangeCurrency) + if z != x { + continue } + var exchangeCurrency exchange.AccountCurrencyInfo + exchangeCurrency.CurrencyName = common.StringToUpper(x) + exchangeCurrency.TotalValue, _ = strconv.ParseFloat(y, 64) + exchangeCurrency.Hold, _ = strconv.ParseFloat(w, 64) + currencies = append(currencies, exchangeCurrency) } } @@ -227,7 +228,7 @@ func (l *LakeBTC) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) // submitted func (l *LakeBTC) WithdrawCryptocurrencyFunds(withdrawRequest exchange.WithdrawRequest) (string, error) { if withdrawRequest.Currency.String() != symbol.BTC { - return "", errors.New("Only BTC supported for withdrawals") + return "", errors.New("only BTC is supported for withdrawals") } resp, err := l.CreateWithdraw(withdrawRequest.Amount, withdrawRequest.Description) diff --git a/exchanges/localbitcoins/localbitcoins.go b/exchanges/localbitcoins/localbitcoins.go index c0948d7f5d1..fb653cb07ce 100644 --- a/exchanges/localbitcoins/localbitcoins.go +++ b/exchanges/localbitcoins/localbitcoins.go @@ -225,8 +225,6 @@ func (l *LocalBitcoins) EditAd(_ AdEdit, adID string) error { } resp := response{} - //request := make(map[string]interface{}) - return l.SendAuthenticatedHTTPRequest(http.MethodPost, localbitcoinsAPIAdEdit+adID+"/", nil, &resp) } diff --git a/exchanges/localbitcoins/localbitcoins_wrapper.go b/exchanges/localbitcoins/localbitcoins_wrapper.go index 4e5f51f290f..a09a230453f 100644 --- a/exchanges/localbitcoins/localbitcoins_wrapper.go +++ b/exchanges/localbitcoins/localbitcoins_wrapper.go @@ -207,7 +207,7 @@ func (l *LocalBitcoins) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide if adID != "" { submitOrderResponse.OrderID = adID } else { - return submitOrderResponse, errors.New("Ad placed, but not found via API") + return submitOrderResponse, errors.New("ad placed, but not found via API") } return submitOrderResponse, err @@ -254,8 +254,8 @@ func (l *LocalBitcoins) GetOrderInfo(orderID int64) (exchange.OrderDetail, error // GetDepositAddress returns a deposit address for a specified currency func (l *LocalBitcoins) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) { if !strings.EqualFold(symbol.BTC, cryptocurrency.String()) { - return "", fmt.Errorf("Localbitcoins do not have support for currency %s just bitcoin", - cryptocurrency.String()) + return "", fmt.Errorf("%s does not have support for currency %s, it only supports bitcoin", + l.Name, cryptocurrency.String()) } return l.GetWalletAddress() @@ -368,11 +368,13 @@ func (l *LocalBitcoins) GetOrderHistory(getOrdersRequest exchange.GetOrdersReque } status := "" - if trade.Data.ReleasedAt != "" && trade.Data.ReleasedAt != null { + + switch { + case trade.Data.ReleasedAt != "" && trade.Data.ReleasedAt != null: status = "Released" - } else if trade.Data.CanceledAt != "" && trade.Data.CanceledAt != null { + case trade.Data.CanceledAt != "" && trade.Data.CanceledAt != null: status = "Cancelled" - } else if trade.Data.ClosedAt != "" && trade.Data.ClosedAt != null { + case trade.Data.ClosedAt != "" && trade.Data.ClosedAt != null: status = "Closed" } diff --git a/exchanges/okcoin/okcoin.go b/exchanges/okcoin/okcoin.go index 3e0197ba070..6bf18b54fde 100644 --- a/exchanges/okcoin/okcoin.go +++ b/exchanges/okcoin/okcoin.go @@ -398,11 +398,11 @@ func (o *OKCoin) Trade(amount, price float64, symbol, orderType string) (int64, } // GetTradeHistory returns client trade history -func (o *OKCoin) GetTradeHistory(symbol string, TradeID int64) ([]Trades, error) { +func (o *OKCoin) GetTradeHistory(symbol string, tradeID int64) ([]Trades, error) { result := []Trades{} v := url.Values{} v.Set("symbol", symbol) - v.Set("since", strconv.FormatInt(TradeID, 10)) + v.Set("since", strconv.FormatInt(tradeID, 10)) err := o.SendAuthenticatedHTTPRequest(okcoinTradeHistory, v, &result) @@ -414,7 +414,7 @@ func (o *OKCoin) GetTradeHistory(symbol string, TradeID int64) ([]Trades, error) } // BatchTrade initiates a trade by batch order -func (o *OKCoin) BatchTrade(orderData string, symbol, orderType string) (BatchTrade, error) { +func (o *OKCoin) BatchTrade(orderData, symbol, orderType string) (BatchTrade, error) { v := url.Values{} v.Set("orders_data", orderData) v.Set("symbol", symbol) @@ -811,7 +811,7 @@ func (o *OKCoin) FuturesTrade(amount, price float64, matchPrice, leverage int64, // FuturesBatchTrade initiates a batch of futures contract trades func (o *OKCoin) FuturesBatchTrade(orderData, symbol, contractType string, leverage int64, _ string) { - v := url.Values{} //to-do batch trade support for orders_data) + v := url.Values{} // to-do batch trade support for orders_data) v.Set("symbol", symbol) v.Set("contract_type", contractType) v.Set("orders_data", orderData) diff --git a/exchanges/okcoin/okcoin_websocket.go b/exchanges/okcoin/okcoin_websocket.go index b71cd0d1e14..efc2c48772f 100644 --- a/exchanges/okcoin/okcoin_websocket.go +++ b/exchanges/okcoin/okcoin_websocket.go @@ -34,12 +34,12 @@ func (o *OKCoin) PingHandler(_ string) error { // AddChannel adds a new channel on the websocket client func (o *OKCoin) AddChannel(channel string) error { event := WebsocketEvent{"addChannel", channel} - json, err := common.JSONEncode(event) + data, err := common.JSONEncode(event) if err != nil { return err } - return o.WebsocketConn.WriteMessage(websocket.TextMessage, json) + return o.WebsocketConn.WriteMessage(websocket.TextMessage, data) } // WsConnect initiates a websocket connection @@ -144,8 +144,7 @@ func (o *OKCoin) WsHandleData() { var currencyPairSlice []string splitChar := common.SplitStrings(init[0].Channel, "_") currencyPairSlice = append(currencyPairSlice, - common.StringToUpper(splitChar[3])) - currencyPairSlice = append(currencyPairSlice, + common.StringToUpper(splitChar[3]), common.StringToUpper(splitChar[4])) currencyPair := common.JoinStrings(currencyPairSlice, "-") @@ -243,8 +242,8 @@ func (o *OKCoin) WsHandleData() { newDeal.Amount, _ = strconv.ParseFloat(data[2].(string), 64) newDeal.Timestamp, _ = data[3].(string) newDeal.Type, _ = data[4].(string) - - deals = append(deals, newDeal) + deals = append(deals, newDeal) // nolint: staticcheck + // TODO: will need to link this up } } } diff --git a/exchanges/okcoin/okcoin_wrapper.go b/exchanges/okcoin/okcoin_wrapper.go index 75b8e09b86d..f14b0c2daf4 100644 --- a/exchanges/okcoin/okcoin_wrapper.go +++ b/exchanges/okcoin/okcoin_wrapper.go @@ -153,32 +153,28 @@ func (o *OKCoin) GetAccountInfo() (exchange.AccountInfo, error) { return response, err } - var currencies []exchange.AccountCurrencyInfo - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "BTC", - TotalValue: assets.Info.Funds.Free.BTC, - Hold: assets.Info.Funds.Freezed.BTC, - }) - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "LTC", - TotalValue: assets.Info.Funds.Free.LTC, - Hold: assets.Info.Funds.Freezed.LTC, - }) - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "USD", - TotalValue: assets.Info.Funds.Free.USD, - Hold: assets.Info.Funds.Freezed.USD, - }) - - currencies = append(currencies, exchange.AccountCurrencyInfo{ - CurrencyName: "CNY", - TotalValue: assets.Info.Funds.Free.CNY, - Hold: assets.Info.Funds.Freezed.CNY, - }) - + var currencies = []exchange.AccountCurrencyInfo{ + { + CurrencyName: "BTC", + TotalValue: assets.Info.Funds.Free.BTC, + Hold: assets.Info.Funds.Freezed.BTC, + }, + { + CurrencyName: "LTC", + TotalValue: assets.Info.Funds.Free.LTC, + Hold: assets.Info.Funds.Freezed.LTC, + }, + { + CurrencyName: "USD", + TotalValue: assets.Info.Funds.Free.USD, + Hold: assets.Info.Funds.Freezed.USD, + }, + { + CurrencyName: "CNY", + TotalValue: assets.Info.Funds.Free.CNY, + Hold: assets.Info.Funds.Freezed.CNY, + }, + } response.Accounts = append(response.Accounts, exchange.Account{ Currencies: currencies, }) @@ -204,20 +200,20 @@ func (o *OKCoin) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]ex func (o *OKCoin) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) { var submitOrderResponse exchange.SubmitOrderResponse var oT string - if orderType == exchange.LimitOrderType { + + switch orderType { + case exchange.LimitOrderType: + oT = "sell" if side == exchange.BuyOrderSide { oT = "buy" - } else { - oT = "sell" } - } else if orderType == exchange.MarketOrderType { + case exchange.MarketOrderType: + oT = "sell_market" if side == exchange.BuyOrderSide { oT = "buy_market" - } else { - oT = "sell_market" } - } else { - return submitOrderResponse, errors.New("Unsupported order type") + default: + return submitOrderResponse, errors.New("unsupported order type") } response, err := o.Trade(amount, price, p.Pair().String(), oT) diff --git a/exchanges/okex/okex.go b/exchanges/okex/okex.go index d3f8cd0d08d..727dc86cdd8 100644 --- a/exchanges/okex/okex.go +++ b/exchanges/okex/okex.go @@ -481,10 +481,13 @@ func (o *OKEX) GetContractCandlestickData(symbol, typeInput, contractType string // GetContractHoldingsNumber returns current number of holdings func (o *OKEX) GetContractHoldingsNumber(symbol, contractType string) (number float64, contract string, err error) { - if err = o.CheckSymbol(symbol); err != nil { + err = o.CheckSymbol(symbol) + if err != nil { return number, contract, err } - if err = o.CheckContractType(contractType); err != nil { + + err = o.CheckContractType(contractType) + if err != nil { return number, contract, err } @@ -495,7 +498,8 @@ func (o *OKEX) GetContractHoldingsNumber(symbol, contractType string) (number fl path := fmt.Sprintf("%s%s%s.do?%s", o.APIUrl, apiVersion, contractFutureHoldAmount, values.Encode()) var resp interface{} - if err = o.SendHTTPRequest(path, &resp); err != nil { + err = o.SendHTTPRequest(path, &resp) + if err != nil { return number, contract, err } @@ -511,7 +515,7 @@ func (o *OKEX) GetContractHoldingsNumber(symbol, contractType string) (number fl contract = holdingMap["contract_name"].(string) } } - return + return number, contract, err } // GetContractlimit returns upper and lower price limit @@ -716,7 +720,10 @@ func (o *OKEX) SpotCancelOrder(symbol string, argOrderID int64) (int64, error) { } if res.ErrorCode != 0 { - return returnOrderID, fmt.Errorf("ErrCode:%d ErrMsg:%s", res.ErrorCode, o.ErrorCodes[strconv.Itoa(res.ErrorCode)]) + return returnOrderID, fmt.Errorf("failed to cancel order. code: %d err: %s", + res.ErrorCode, + o.ErrorCodes[strconv.Itoa(res.ErrorCode)], + ) } returnOrderID, _ = common.Int64FromString(res.OrderID) @@ -755,7 +762,7 @@ func (o *OKEX) GetSpotTicker(symbol string) (SpotPrice, error) { return resp, nil } -//GetSpotMarketDepth returns Market Depth +// GetSpotMarketDepth returns Market Depth func (o *OKEX) GetSpotMarketDepth(asd ActualSpotDepthRequestParams) (ActualSpotDepth, error) { resp := SpotDepth{} fullDepth := ActualSpotDepth{} @@ -963,7 +970,7 @@ func (o *OKEX) SendAuthenticatedHTTPRequest(method string, values url.Values, re err = common.JSONDecode(intermediary, &errCap) if err == nil { if !errCap.Result { - return fmt.Errorf("SendAuthenticatedHTTPRequest error - %s", + return fmt.Errorf("sendAuthenticatedHTTPRequest error - %s", o.ErrorCodes[strconv.FormatInt(errCap.Error, 10)]) } } @@ -974,24 +981,24 @@ func (o *OKEX) SendAuthenticatedHTTPRequest(method string, values url.Values, re // SetErrorDefaults sets the full error default list func (o *OKEX) SetErrorDefaults() { o.ErrorCodes = map[string]error{ - //Spot Errors - "10000": errors.New("Required field, can not be null"), - "10001": errors.New("Request frequency too high to exceed the limit allowed"), - "10002": errors.New("System error"), - "10004": errors.New("Request failed - Your API key might need to be recreated"), - "10005": errors.New("'SecretKey' does not exist"), - "10006": errors.New("'Api_key' does not exist"), - "10007": errors.New("Signature does not match"), - "10008": errors.New("Illegal parameter"), - "10009": errors.New("Order does not exist"), - "10010": errors.New("Insufficient funds"), - "10011": errors.New("Amount too low"), - "10012": errors.New("Only btc_usd ltc_usd supported"), - "10013": errors.New("Only support https request"), - "10014": errors.New("Order price must be between 0 and 1,000,000"), - "10015": errors.New("Order price differs from current market price too much"), - "10016": errors.New("Insufficient coins balance"), - "10017": errors.New("API authorization error"), + // Spot Errors + "10000": errors.New("required field, can not be null"), + "10001": errors.New("request frequency too high to exceed the limit allowed"), + "10002": errors.New("system error"), + "10004": errors.New("request failed - Your API key might need to be recreated"), + "10005": errors.New("'secretKey' does not exist"), + "10006": errors.New("'api_key' does not exist"), + "10007": errors.New("signature does not match"), + "10008": errors.New("illegal parameter"), + "10009": errors.New("order does not exist"), + "10010": errors.New("insufficient funds"), + "10011": errors.New("amount too low"), + "10012": errors.New("only btc_usd ltc_usd supported"), + "10013": errors.New("only support https request"), + "10014": errors.New("order price must be between 0 and 1,000,000"), + "10015": errors.New("order price differs from current market price too much"), + "10016": errors.New("insufficient coins balance"), + "10017": errors.New("api authorization error"), "10018": errors.New("borrow amount less than lower limit [usd:100,btc:0.1,ltc:1]"), "10019": errors.New("loan agreement not checked"), "10020": errors.New("rate cannot exceed 1%"), @@ -999,119 +1006,119 @@ func (o *OKEX) SetErrorDefaults() { "10023": errors.New("fail to get latest ticker"), "10024": errors.New("balance not sufficient"), "10025": errors.New("quota is full, cannot borrow temporarily"), - "10026": errors.New("Loan (including reserved loan) and margin cannot be withdrawn"), - "10027": errors.New("Cannot withdraw within 24 hrs of authentication information modification"), - "10028": errors.New("Withdrawal amount exceeds daily limit"), - "10029": errors.New("Account has unpaid loan, please cancel/pay off the loan before withdraw"), - "10031": errors.New("Deposits can only be withdrawn after 6 confirmations"), - "10032": errors.New("Please enabled phone/google authenticator"), - "10033": errors.New("Fee higher than maximum network transaction fee"), - "10034": errors.New("Fee lower than minimum network transaction fee"), - "10035": errors.New("Insufficient BTC/LTC"), - "10036": errors.New("Withdrawal amount too low"), - "10037": errors.New("Trade password not set"), - "10040": errors.New("Withdrawal cancellation fails"), - "10041": errors.New("Withdrawal address not exsit or approved"), - "10042": errors.New("Admin password error"), - "10043": errors.New("Account equity error, withdrawal failure"), + "10026": errors.New("loan (including reserved loan) and margin cannot be withdrawn"), + "10027": errors.New("cannot withdraw within 24 hrs of authentication information modification"), + "10028": errors.New("withdrawal amount exceeds daily limit"), + "10029": errors.New("account has unpaid loan, please cancel/pay off the loan before withdraw"), + "10031": errors.New("deposits can only be withdrawn after 6 confirmations"), + "10032": errors.New("please enabled phone/google authenticator"), + "10033": errors.New("fee higher than maximum network transaction fee"), + "10034": errors.New("fee lower than minimum network transaction fee"), + "10035": errors.New("insufficient BTC/LTC"), + "10036": errors.New("withdrawal amount too low"), + "10037": errors.New("trade password not set"), + "10040": errors.New("withdrawal cancellation fails"), + "10041": errors.New("withdrawal address not exsit or approved"), + "10042": errors.New("admin password error"), + "10043": errors.New("account equity error, withdrawal failure"), "10044": errors.New("fail to cancel borrowing order"), "10047": errors.New("this function is disabled for sub-account"), "10048": errors.New("withdrawal information does not exist"), - "10049": errors.New("User can not have more than 50 unfilled small orders (amount<0.15BTC)"), + "10049": errors.New("user can not have more than 50 unfilled small orders (amount<0.15BTC)"), "10050": errors.New("can't cancel more than once"), "10051": errors.New("order completed transaction"), "10052": errors.New("not allowed to withdraw"), "10064": errors.New("after a USD deposit, that portion of assets will not be withdrawable for the next 48 hours"), - "10100": errors.New("User account frozen"), + "10100": errors.New("user account frozen"), "10101": errors.New("order type is wrong"), "10102": errors.New("incorrect ID"), "10103": errors.New("the private otc order's key incorrect"), - "10216": errors.New("Non-available API"), - "1002": errors.New("The transaction amount exceed the balance"), - "1003": errors.New("The transaction amount is less than the minimum requirement"), - "1004": errors.New("The transaction amount is less than 0"), - "1007": errors.New("No trading market information"), - "1008": errors.New("No latest market information"), - "1009": errors.New("No order"), - "1010": errors.New("Different user of the cancelled order and the original order"), - "1011": errors.New("No documented user"), - "1013": errors.New("No order type"), - "1014": errors.New("No login"), - "1015": errors.New("No market depth information"), - "1017": errors.New("Date error"), - "1018": errors.New("Order failed"), - "1019": errors.New("Undo order failed"), - "1024": errors.New("Currency does not exist"), - "1025": errors.New("No chart type"), - "1026": errors.New("No base currency quantity"), - "1027": errors.New("Incorrect parameter may exceeded limits"), - "1028": errors.New("Reserved decimal failed"), - "1029": errors.New("Preparing"), - "1030": errors.New("Account has margin and futures, transactions can not be processed"), - "1031": errors.New("Insufficient Transferring Balance"), - "1032": errors.New("Transferring Not Allowed"), - "1035": errors.New("Password incorrect"), - "1036": errors.New("Google Verification code Invalid"), - "1037": errors.New("Google Verification code incorrect"), - "1038": errors.New("Google Verification replicated"), - "1039": errors.New("Message Verification Input exceed the limit"), - "1040": errors.New("Message Verification invalid"), - "1041": errors.New("Message Verification incorrect"), - "1042": errors.New("Wrong Google Verification Input exceed the limit"), - "1043": errors.New("Login password cannot be same as the trading password"), - "1044": errors.New("Old password incorrect"), + "10216": errors.New("non-available API"), + "1002": errors.New("the transaction amount exceed the balance"), + "1003": errors.New("the transaction amount is less than the minimum requirement"), + "1004": errors.New("the transaction amount is less than 0"), + "1007": errors.New("no trading market information"), + "1008": errors.New("no latest market information"), + "1009": errors.New("no order"), + "1010": errors.New("different user of the cancelled order and the original order"), + "1011": errors.New("no documented user"), + "1013": errors.New("no order type"), + "1014": errors.New("no login"), + "1015": errors.New("no market depth information"), + "1017": errors.New("date error"), + "1018": errors.New("order failed"), + "1019": errors.New("undo order failed"), + "1024": errors.New("currency does not exist"), + "1025": errors.New("no chart type"), + "1026": errors.New("no base currency quantity"), + "1027": errors.New("incorrect parameter may exceeded limits"), + "1028": errors.New("reserved decimal failed"), + "1029": errors.New("preparing"), + "1030": errors.New("account has margin and futures, transactions can not be processed"), + "1031": errors.New("insufficient Transferring Balance"), + "1032": errors.New("transferring Not Allowed"), + "1035": errors.New("password incorrect"), + "1036": errors.New("google Verification code Invalid"), + "1037": errors.New("google Verification code incorrect"), + "1038": errors.New("google Verification replicated"), + "1039": errors.New("message Verification Input exceed the limit"), + "1040": errors.New("message Verification invalid"), + "1041": errors.New("message Verification incorrect"), + "1042": errors.New("wrong Google Verification Input exceed the limit"), + "1043": errors.New("login password cannot be same as the trading password"), + "1044": errors.New("old password incorrect"), "1045": errors.New("2nd Verification Needed"), - "1046": errors.New("Please input old password"), - "1048": errors.New("Account Blocked"), - "1201": errors.New("Account Deleted at 00: 00"), - "1202": errors.New("Account Not Exist"), - "1203": errors.New("Insufficient Balance"), - "1204": errors.New("Invalid currency"), - "1205": errors.New("Invalid Account"), - "1206": errors.New("Cash Withdrawal Blocked"), - "1207": errors.New("Transfer Not Support"), - "1208": errors.New("No designated account"), - "1209": errors.New("Invalid api"), - "1216": errors.New("Market order temporarily suspended. Please send limit order"), - "1217": errors.New("Order was sent at ±5% of the current market price. Please resend"), - "1218": errors.New("Place order failed. Please try again later"), + "1046": errors.New("please input old password"), + "1048": errors.New("account Blocked"), + "1201": errors.New("account Deleted at 00: 00"), + "1202": errors.New("account Not Exist"), + "1203": errors.New("insufficient Balance"), + "1204": errors.New("invalid currency"), + "1205": errors.New("invalid Account"), + "1206": errors.New("cash Withdrawal Blocked"), + "1207": errors.New("transfer Not Support"), + "1208": errors.New("no designated account"), + "1209": errors.New("invalid api"), + "1216": errors.New("market order temporarily suspended. Please send limit order"), + "1217": errors.New("order was sent at ±5% of the current market price. Please resend"), + "1218": errors.New("place order failed. Please try again later"), // Errors for both - "HTTP ERROR CODE 403": errors.New("Too many requests, IP is shielded"), - "Request Timed Out": errors.New("Too many requests, IP is shielded"), + "HTTP ERROR CODE 403": errors.New("too many requests, IP is shielded"), + "Request Timed Out": errors.New("too many requests, IP is shielded"), // contract errors "405": errors.New("method not allowed"), - "20001": errors.New("User does not exist"), - "20002": errors.New("Account frozen"), - "20003": errors.New("Account frozen due to liquidation"), - "20004": errors.New("Contract account frozen"), - "20005": errors.New("User contract account does not exist"), - "20006": errors.New("Required field missing"), - "20007": errors.New("Illegal parameter"), - "20008": errors.New("Contract account balance is too low"), - "20009": errors.New("Contract status error"), - "20010": errors.New("Risk rate ratio does not exist"), - "20011": errors.New("Risk rate lower than 90%/80% before opening BTC position with 10x/20x leverage. or risk rate lower than 80%/60% before opening LTC position with 10x/20x leverage"), - "20012": errors.New("Risk rate lower than 90%/80% after opening BTC position with 10x/20x leverage. or risk rate lower than 80%/60% after opening LTC position with 10x/20x leverage"), - "20013": errors.New("Temporally no counter party price"), - "20014": errors.New("System error"), - "20015": errors.New("Order does not exist"), - "20016": errors.New("Close amount bigger than your open positions"), - "20017": errors.New("Not authorized/illegal operation"), - "20018": errors.New("Order price cannot be more than 103% or less than 97% of the previous minute price"), - "20019": errors.New("IP restricted from accessing the resource"), + "20001": errors.New("user does not exist"), + "20002": errors.New("account frozen"), + "20003": errors.New("account frozen due to liquidation"), + "20004": errors.New("contract account frozen"), + "20005": errors.New("user contract account does not exist"), + "20006": errors.New("required field missing"), + "20007": errors.New("illegal parameter"), + "20008": errors.New("contract account balance is too low"), + "20009": errors.New("contract status error"), + "20010": errors.New("risk rate ratio does not exist"), + "20011": errors.New("risk rate lower than 90%/80% before opening BTC position with 10x/20x leverage. or risk rate lower than 80%/60% before opening LTC position with 10x/20x leverage"), + "20012": errors.New("risk rate lower than 90%/80% after opening BTC position with 10x/20x leverage. or risk rate lower than 80%/60% after opening LTC position with 10x/20x leverage"), + "20013": errors.New("temporally no counter party price"), + "20014": errors.New("system error"), + "20015": errors.New("order does not exist"), + "20016": errors.New("close amount bigger than your open positions"), + "20017": errors.New("not authorized/illegal operation"), + "20018": errors.New("order price cannot be more than 103% or less than 97% of the previous minute price"), + "20019": errors.New("ip restricted from accessing the resource"), "20020": errors.New("secretKey does not exist"), - "20021": errors.New("Index information does not exist"), - "20022": errors.New("Wrong API interface (Cross margin mode shall call cross margin API, fixed margin mode shall call fixed margin API)"), - "20023": errors.New("Account in fixed-margin mode"), - "20024": errors.New("Signature does not match"), - "20025": errors.New("Leverage rate error"), - "20026": errors.New("API Permission Error"), + "20021": errors.New("index information does not exist"), + "20022": errors.New("wrong API interface (Cross margin mode shall call cross margin API, fixed margin mode shall call fixed margin API)"), + "20023": errors.New("account in fixed-margin mode"), + "20024": errors.New("signature does not match"), + "20025": errors.New("leverage rate error"), + "20026": errors.New("api permission error"), "20027": errors.New("no transaction record"), "20028": errors.New("no such contract"), - "20029": errors.New("Amount is large than available funds"), - "20030": errors.New("Account still has debts"), - "20038": errors.New("Due to regulation, this function is not available in the country/region your currently reside in"), - "20049": errors.New("Request frequency too high"), + "20029": errors.New("amount is large than available funds"), + "20030": errors.New("account still has debts"), + "20038": errors.New("due to regulation, this function is not available in the country/region your currently reside in"), + "20049": errors.New("request frequency too high"), } } diff --git a/exchanges/okex/okex_websocket.go b/exchanges/okex/okex_websocket.go index aa6210b3bf6..7b22e694dcf 100644 --- a/exchanges/okex/okex_websocket.go +++ b/exchanges/okex/okex_websocket.go @@ -61,8 +61,8 @@ func (o *OKEX) WsConnect() error { err = o.WsSubscribe() if err != nil { - return fmt.Errorf("Error: Could not subscribe to the OKEX websocket %s", - err) + return fmt.Errorf("%s could not subscribe to websocket %s", + o.Name, err) } return nil @@ -90,17 +90,11 @@ func (o *OKEX) WsSubscribe() error { myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_ticker'}", - symbolRedone)) - - myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, + symbolRedone), fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_depth'}", - symbolRedone)) - - myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, + symbolRedone), fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_deals'}", - symbolRedone)) - - myEnabledSubscriptionChannels = append(myEnabledSubscriptionChannels, + symbolRedone), fmt.Sprintf("{'event':'addChannel','channel':'ok_sub_spot_%s_kline_1min'}", symbolRedone)) } @@ -221,7 +215,8 @@ func (o *OKEX) WsHandleData() { assetType = currencyPairSlice[2] } - if strings.Contains(multiStreamData.Channel, "ticker") { + switch multiStreamData.Channel { + case "ticker": var ticker TickerStreamData err = common.JSONDecode(multiStreamData.Data, &ticker) @@ -235,8 +230,7 @@ func (o *OKEX) WsHandleData() { Exchange: o.GetName(), AssetType: assetType, } - - } else if strings.Contains(multiStreamData.Channel, "deals") { + case "deals": var deals DealsStreamData err = common.JSONDecode(multiStreamData.Data, &deals) @@ -248,10 +242,10 @@ func (o *OKEX) WsHandleData() { for _, trade := range deals { price, _ := strconv.ParseFloat(trade[1], 64) amount, _ := strconv.ParseFloat(trade[2], 64) - time, _ := time.Parse(time.RFC3339, trade[3]) + tradeTime, _ := time.Parse(time.RFC3339, trade[3]) o.Websocket.DataHandler <- exchange.TradeData{ - Timestamp: time, + Timestamp: tradeTime, Exchange: o.GetName(), AssetType: assetType, CurrencyPair: pair.NewCurrencyPairFromString(newPair), @@ -260,8 +254,7 @@ func (o *OKEX) WsHandleData() { EventType: trade[4], } } - - } else if strings.Contains(multiStreamData.Channel, "kline") { + case "kline": var klines KlineStreamData err := common.JSONDecode(multiStreamData.Data, &klines) @@ -275,7 +268,7 @@ func (o *OKEX) WsHandleData() { open, _ := strconv.ParseFloat(kline[1], 64) high, _ := strconv.ParseFloat(kline[2], 64) low, _ := strconv.ParseFloat(kline[3], 64) - close, _ := strconv.ParseFloat(kline[4], 64) + klineClose, _ := strconv.ParseFloat(kline[4], 64) volume, _ := strconv.ParseFloat(kline[5], 64) o.Websocket.DataHandler <- exchange.KlineData{ @@ -286,12 +279,11 @@ func (o *OKEX) WsHandleData() { OpenPrice: open, HighPrice: high, LowPrice: low, - ClosePrice: close, + ClosePrice: klineClose, Volume: volume, } } - - } else if strings.Contains(multiStreamData.Channel, "depth") { + case "depth": var depth DepthStreamData err := common.JSONDecode(multiStreamData.Data, &depth) diff --git a/exchanges/okex/okex_wrapper.go b/exchanges/okex/okex_wrapper.go index aec7a7ec07e..0ecfddc5b10 100644 --- a/exchanges/okex/okex_wrapper.go +++ b/exchanges/okex/okex_wrapper.go @@ -196,20 +196,19 @@ func (o *OKEX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTy var submitOrderResponse exchange.SubmitOrderResponse var oT SpotNewOrderRequestType - if orderType == exchange.LimitOrderType { + switch orderType { + case exchange.LimitOrderType: + oT = SpotNewOrderRequestTypeSell if side == exchange.BuyOrderSide { oT = SpotNewOrderRequestTypeBuy - } else { - oT = SpotNewOrderRequestTypeSell } - } else if orderType == exchange.MarketOrderType { + case exchange.MarketOrderType: + oT = SpotNewOrderRequestTypeSellMarket if side == exchange.BuyOrderSide { oT = SpotNewOrderRequestTypeBuyMarket - } else { - oT = SpotNewOrderRequestTypeSellMarket } - } else { - return submitOrderResponse, errors.New("Unsupported order type") + default: + return submitOrderResponse, errors.New("unsupported order type") } var params = SpotNewOrderRequestParams{ @@ -263,7 +262,7 @@ func (o *OKEX) CancelAllOrders(_ exchange.OrderCancellation) (exchange.CancelAll } if !openOrders.Result { - return cancelAllOrdersResponse, fmt.Errorf("Something went wrong for currency %s", formattedCurrency) + return cancelAllOrdersResponse, fmt.Errorf("something went wrong for currency %s", formattedCurrency) } allOpenOrders = append(allOpenOrders, openOrders.Orders...) diff --git a/exchanges/orderbook/orderbook.go b/exchanges/orderbook/orderbook.go index 5f29a63d44c..7d3ebf6f8a4 100644 --- a/exchanges/orderbook/orderbook.go +++ b/exchanges/orderbook/orderbook.go @@ -10,9 +10,9 @@ import ( // Const values for orderbook package const ( - ErrOrderbookForExchangeNotFound = "Ticker for exchange does not exist." - ErrPrimaryCurrencyNotFound = "Error primary currency for orderbook not found." - ErrSecondaryCurrencyNotFound = "Error secondary currency for orderbook not found." + ErrOrderbookForExchangeNotFound = "ticker for exchange does not exist" + ErrPrimaryCurrencyNotFound = "primary currency for orderbook not found" + ErrSecondaryCurrencyNotFound = "secondary currency for orderbook not found" Spot = "SPOT" ) @@ -48,9 +48,7 @@ type Orderbook struct { // CalculateTotalBids returns the total amount of bids and the total orderbook // bids value -func (o *Base) CalculateTotalBids() (float64, float64) { - amountCollated := float64(0) - total := float64(0) +func (o *Base) CalculateTotalBids() (amountCollated, total float64) { for _, x := range o.Bids { amountCollated += x.Amount total += x.Amount * x.Price @@ -60,9 +58,7 @@ func (o *Base) CalculateTotalBids() (float64, float64) { // CalculateTotalAsks returns the total amount of asks and the total orderbook // asks value -func (o *Base) CalculateTotalAsks() (float64, float64) { - amountCollated := float64(0) - total := float64(0) +func (o *Base) CalculateTotalAsks() (amountCollated, total float64) { for _, x := range o.Asks { amountCollated += x.Amount total += x.Amount * x.Price @@ -71,9 +67,9 @@ func (o *Base) CalculateTotalAsks() (float64, float64) { } // Update updates the bids and asks -func (o *Base) Update(Bids, Asks []Item) { - o.Bids = Bids - o.Asks = Asks +func (o *Base) Update(bids, asks []Item) { + o.Bids = bids + o.Asks = asks o.LastUpdated = time.Now() } @@ -100,9 +96,9 @@ func GetOrderbook(exchange string, p pair.CurrencyPair, orderbookType string) (B func GetOrderbookByExchange(exchange string) (*Orderbook, error) { m.Lock() defer m.Unlock() - for _, y := range Orderbooks { - if y.ExchangeName == exchange { - return &y, nil + for x := range Orderbooks { + if Orderbooks[x].ExchangeName == exchange { + return &Orderbooks[x], nil } } return nil, errors.New(ErrOrderbookForExchangeNotFound) diff --git a/exchanges/orderbook/orderbook_test.go b/exchanges/orderbook/orderbook_test.go index aa2a2e29f4c..2f6689c9dc9 100644 --- a/exchanges/orderbook/orderbook_test.go +++ b/exchanges/orderbook/orderbook_test.go @@ -308,10 +308,12 @@ func TestProcessOrderbook(t *testing.T) { for _, test := range testArray { wg.Add(1) + fatalErr := false go func(test quick) { result, err := GetOrderbook(test.Name, test.P, Spot) if err != nil { - t.Fatal("Test failed. TestProcessOrderbook failed to retrieve new orderbook") + fatalErr = true + return } if result.Asks[0] != test.Asks[0] { @@ -324,6 +326,10 @@ func TestProcessOrderbook(t *testing.T) { wg.Done() }(test) + + if fatalErr { + t.Fatal("Test failed. TestProcessOrderbook failed to retrieve new orderbook") + } } wg.Wait() diff --git a/exchanges/orders/orders.go b/exchanges/orders/orders.go index 81b65d1d993..698a0bc6dfe 100644 --- a/exchanges/orders/orders.go +++ b/exchanges/orders/orders.go @@ -18,7 +18,7 @@ type Order struct { } // NewOrder creates a new order and returns a an orderID -func NewOrder(Exchange string, amount, price float64) int { +func NewOrder(exchangeName string, amount, price float64) int { order := &Order{} if len(Orders) == 0 { order.OrderID = 0 @@ -26,7 +26,7 @@ func NewOrder(Exchange string, amount, price float64) int { order.OrderID = len(Orders) } - order.Exchange = Exchange + order.Exchange = exchangeName order.Amount = amount order.Price = price Orders = append(Orders, order) diff --git a/exchanges/poloniex/poloniex.go b/exchanges/poloniex/poloniex.go index 8b437c81bf8..9faeb280415 100644 --- a/exchanges/poloniex/poloniex.go +++ b/exchanges/poloniex/poloniex.go @@ -172,8 +172,8 @@ func (p *Poloniex) GetOrderbook(currencyPair string, depth int) (OrderbookAll, e if err != nil { return oba, err } - if len(resp.Error) != 0 { - return oba, fmt.Errorf("Poloniex GetOrderbook() error: %s", resp.Error) + if resp.Error != "" { + return oba, fmt.Errorf("%s GetOrderbook() error: %s", p.Name, resp.Error) } ob := Orderbook{} for x := range resp.Asks { @@ -544,11 +544,11 @@ func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64, postOnly, imme values := url.Values{} if orderID == 0 { - return result, errors.New("OrderID cannot be zero") + return result, errors.New("orderID cannot be zero") } if rate == 0 { - return result, errors.New("Rate cannot be zero") + return result, errors.New("rate cannot be zero") } values.Set("orderNumber", strconv.FormatInt(orderID, 10)) diff --git a/exchanges/poloniex/poloniex_test.go b/exchanges/poloniex/poloniex_test.go index 8d92ec7503a..1b32b5a7172 100644 --- a/exchanges/poloniex/poloniex_test.go +++ b/exchanges/poloniex/poloniex_test.go @@ -7,7 +7,7 @@ import ( "github.com/thrasher-/gocryptotrader/config" "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/thrasher-/gocryptotrader/currency/symbol" - "github.com/thrasher-/gocryptotrader/exchanges" + exchange "github.com/thrasher-/gocryptotrader/exchanges" ) var p Poloniex @@ -242,12 +242,12 @@ func TestSubmitOrder(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - var pair = pair.CurrencyPair{ + var currencyPair = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.BTC, SecondCurrency: symbol.LTC, } - response, err := p.SubmitOrder(pair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi") + response, err := p.SubmitOrder(currencyPair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi") if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index 07b1fbe32c3..c6d76d8a2f8 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -251,7 +251,7 @@ func (p *Poloniex) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) address, ok := a.Addresses[cryptocurrency.Upper().String()] if !ok { - return "", fmt.Errorf("Cannot find deposit address for %s", + return "", fmt.Errorf("cannot find deposit address for %s", cryptocurrency) } diff --git a/exchanges/request/request.go b/exchanges/request/request.go index 8607f9f03d8..3772f1fa505 100644 --- a/exchanges/request/request.go +++ b/exchanges/request/request.go @@ -368,20 +368,22 @@ func (r *Requester) worker() { time.Sleep(diff) for { - if !r.IsRateLimited(x.AuthRequest) { - r.IncrementRequests(x.AuthRequest) - - if x.Verbose { - log.Debugf("%s request. No longer rate limited! Doing request", r.Name) - } - - err := r.DoRequest(x.Request, x.Path, x.Body, x.Result, x.AuthRequest, x.Verbose) - x.JobResult <- &JobResult{ - Error: err, - Result: x.Result, - } - break + if r.IsRateLimited(x.AuthRequest) { + time.Sleep(time.Millisecond) + continue } + r.IncrementRequests(x.AuthRequest) + + if x.Verbose { + log.Debugf("%s request. No longer rate limited! Doing request", r.Name) + } + + err := r.DoRequest(x.Request, x.Path, x.Body, x.Result, x.AuthRequest, x.Verbose) + x.JobResult <- &JobResult{ + Error: err, + Result: x.Result, + } + break } } } @@ -456,7 +458,7 @@ func (r *Requester) SendPayload(method, path string, headers map[string]string, // SetProxy sets a proxy address to the client transport func (r *Requester) SetProxy(p *url.URL) error { if p.String() == "" { - return errors.New("No proxy URL supplied") + return errors.New("no proxy URL supplied") } r.HTTPClient.Transport = &http.Transport{ diff --git a/exchanges/stats/stats_test.go b/exchanges/stats/stats_test.go index db3c17fa83b..1586c9e6640 100644 --- a/exchanges/stats/stats_test.go +++ b/exchanges/stats/stats_test.go @@ -8,15 +8,16 @@ import ( func TestLenByPrice(t *testing.T) { p := pair.NewCurrencyPair("BTC", "USD") - i := Item{ - Exchange: "ANX", - Pair: p, - AssetType: "SPOT", - Price: 1200, - Volume: 5, + Items = []Item{ + { + Exchange: "ANX", + Pair: p, + AssetType: "SPOT", + Price: 1200, + Volume: 5, + }, } - Items = append(Items, i) if ByPrice.Len(Items) < 1 { t.Error("Test Failed - stats LenByPrice() length not correct.") } @@ -24,78 +25,77 @@ func TestLenByPrice(t *testing.T) { func TestLessByPrice(t *testing.T) { p := pair.NewCurrencyPair("BTC", "USD") - i := Item{ - Exchange: "alphapoint", - Pair: p, - AssetType: "SPOT", - Price: 1200, - Volume: 5, - } - - i2 := Item{ - Exchange: "bitfinex", - Pair: p, - AssetType: "SPOT", - Price: 1198, - Volume: 20, - } - Items = append(Items, i) - Items = append(Items, i2) - - if !ByPrice.Less(Items, 2, 1) { + Items = []Item{ + { + Exchange: "alphapoint", + Pair: p, + AssetType: "SPOT", + Price: 1200, + Volume: 5, + }, + { + Exchange: "bitfinex", + Pair: p, + AssetType: "SPOT", + Price: 1198, + Volume: 20, + }, + } + + if !ByPrice.Less(Items, 1, 0) { t.Error("Test Failed - stats LessByPrice() incorrect return.") } - if ByPrice.Less(Items, 1, 2) { + if ByPrice.Less(Items, 0, 1) { t.Error("Test Failed - stats LessByPrice() incorrect return.") } } func TestSwapByPrice(t *testing.T) { p := pair.NewCurrencyPair("BTC", "USD") - i := Item{ - Exchange: "bitstamp", - Pair: p, - AssetType: "SPOT", - Price: 1324, - Volume: 5, - } - - i2 := Item{ - Exchange: "btcc", - Pair: p, - AssetType: "SPOT", - Price: 7863, - Volume: 20, - } - - Items = append(Items, i) - Items = append(Items, i2) - ByPrice.Swap(Items, 3, 4) - if Items[3].Exchange != "btcc" || Items[4].Exchange != "bitstamp" { + + Items = []Item{ + { + Exchange: "bitstamp", + Pair: p, + AssetType: "SPOT", + Price: 1324, + Volume: 5, + }, + { + Exchange: "btcc", + Pair: p, + AssetType: "SPOT", + Price: 7863, + Volume: 20, + }, + } + + ByPrice.Swap(Items, 0, 1) + if Items[0].Exchange != "btcc" || Items[1].Exchange != "bitstamp" { t.Error("Test Failed - stats SwapByPrice did not swap values.") } } func TestLenByVolume(t *testing.T) { - if ByVolume.Len(Items) != 5 { + if ByVolume.Len(Items) != 2 { t.Error("Test Failed - stats lenByVolume did not swap values.") } } func TestLessByVolume(t *testing.T) { - if !ByVolume.Less(Items, 1, 2) { + if !ByVolume.Less(Items, 1, 0) { t.Error("Test Failed - stats LessByVolume() incorrect return.") } - if ByVolume.Less(Items, 2, 1) { + if ByVolume.Less(Items, 0, 1) { t.Error("Test Failed - stats LessByVolume() incorrect return.") } } func TestSwapByVolume(t *testing.T) { - ByPrice.Swap(Items, 3, 4) + ByPrice.Swap(Items, 0, 1) - if Items[4].Exchange != "btcc" || Items[3].Exchange != "bitstamp" { + if Items[1].Exchange != "btcc" || Items[0].Exchange != "bitstamp" { t.Error("Test Failed - stats SwapByVolume did not swap values.") } } diff --git a/exchanges/ticker/ticker.go b/exchanges/ticker/ticker.go index 6f424803cb3..fdf3204dd27 100644 --- a/exchanges/ticker/ticker.go +++ b/exchanges/ticker/ticker.go @@ -12,9 +12,9 @@ import ( // Const values for the ticker package const ( - ErrTickerForExchangeNotFound = "Ticker for exchange does not exist." - ErrPrimaryCurrencyNotFound = "Error primary currency for ticker not found." - ErrSecondaryCurrencyNotFound = "Error secondary currency for ticker not found." + ErrTickerForExchangeNotFound = "ticker for exchange does not exist" + ErrPrimaryCurrencyNotFound = "primary currency for ticker not found" + ErrSecondaryCurrencyNotFound = "secondary currency for ticker not found" Spot = "SPOT" ) @@ -91,9 +91,9 @@ func GetTicker(exchange string, p pair.CurrencyPair, tickerType string) (Price, func GetTickerByExchange(exchange string) (*Ticker, error) { m.Lock() defer m.Unlock() - for _, y := range Tickers { - if y.ExchangeName == exchange { - return &y, nil + for x := range Tickers { + if Tickers[x].ExchangeName == exchange { + return &Tickers[x], nil } } return nil, errors.New(ErrTickerForExchangeNotFound) diff --git a/exchanges/ticker/ticker_test.go b/exchanges/ticker/ticker_test.go index b850161b298..03390f97661 100644 --- a/exchanges/ticker/ticker_test.go +++ b/exchanges/ticker/ticker_test.go @@ -200,6 +200,7 @@ func TestCreateNewTicker(t *testing.T) { } newTicker := CreateNewTicker("ANX", newPair, priceStruct, Spot) + const float64Type = "float64" if reflect.ValueOf(newTicker).NumField() != 2 { t.Error("Test Failed - ticker CreateNewTicker struct change/or updated") @@ -214,33 +215,33 @@ func TestCreateNewTicker(t *testing.T) { if newTicker.Price["BTC"]["USD"][Spot].Pair.Pair().String() != "BTCUSD" { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].Pair.Pair().String() value is not expected 'BTCUSD'") } - if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Ask).String() != "float64" { + if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Ask).String() != float64Type { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].Ask value is not a float64") } - if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Bid).String() != "float64" { + if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Bid).String() != float64Type { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].Bid value is not a float64") } if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].CurrencyPair).String() != "string" { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].CurrencyPair value is not a string") } - if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].High).String() != "float64" { + if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].High).String() != float64Type { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].High value is not a float64") } - if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Last).String() != "float64" { + if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Last).String() != float64Type { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].Last value is not a float64") } - if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Low).String() != "float64" { + if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Low).String() != float64Type { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].Low value is not a float64") } - if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].PriceATH).String() != "float64" { + if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].PriceATH).String() != float64Type { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].PriceATH value is not a float64") } - if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Volume).String() != "float64" { + if reflect.TypeOf(newTicker.Price["BTC"]["USD"][Spot].Volume).String() != float64Type { t.Error("Test Failed - ticker newTicker.Price[BTC][USD].Volume value is not a float64") } } -func TestProcessTicker(t *testing.T) { //non-appending function to tickers +func TestProcessTicker(t *testing.T) { // non-appending function to tickers Tickers = []Ticker{} newPair := pair.NewCurrencyPair("BTC", "USD") priceStruct := Price{ @@ -317,10 +318,12 @@ func TestProcessTicker(t *testing.T) { //non-appending function to tickers for _, test := range testArray { wg.Add(1) + fatalErr := false go func(test quick) { result, err := GetTicker(test.Name, test.P, Spot) if err != nil { - t.Fatal("Test failed. TestProcessTicker failed to retrieve new ticker") + fatalErr = true + return } if result.Last != test.TP.Last { @@ -329,6 +332,10 @@ func TestProcessTicker(t *testing.T) { //non-appending function to tickers wg.Done() }(test) + + if fatalErr { + t.Fatal("Test failed. TestProcessTicker failed to retrieve new ticker") + } } wg.Wait() diff --git a/exchanges/yobit/yobit.go b/exchanges/yobit/yobit.go index 93adc893862..c0fbe5ebd03 100644 --- a/exchanges/yobit/yobit.go +++ b/exchanges/yobit/yobit.go @@ -206,9 +206,9 @@ func (y *Yobit) GetOpenOrders(pair string) (map[string]ActiveOrders, error) { } // GetOrderInformation returns the order info for a specific order ID -func (y *Yobit) GetOrderInformation(OrderID int64) (map[string]OrderInfo, error) { +func (y *Yobit) GetOrderInformation(orderID int64) (map[string]OrderInfo, error) { req := url.Values{} - req.Add("order_id", strconv.FormatInt(OrderID, 10)) + req.Add("order_id", strconv.FormatInt(orderID, 10)) result := map[string]OrderInfo{} @@ -216,9 +216,9 @@ func (y *Yobit) GetOrderInformation(OrderID int64) (map[string]OrderInfo, error) } // CancelExistingOrder cancels an order for a specific order ID -func (y *Yobit) CancelExistingOrder(OrderID int64) (bool, error) { +func (y *Yobit) CancelExistingOrder(orderID int64) (bool, error) { req := url.Values{} - req.Add("order_id", strconv.FormatInt(OrderID, 10)) + req.Add("order_id", strconv.FormatInt(orderID, 10)) result := CancelOrder{} @@ -233,12 +233,12 @@ func (y *Yobit) CancelExistingOrder(OrderID int64) (bool, error) { } // GetTradeHistory returns the trade history -func (y *Yobit) GetTradeHistory(TIDFrom, Count, TIDEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) { +func (y *Yobit) GetTradeHistory(tidFrom, count, tidEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) { req := url.Values{} - req.Add("from", strconv.FormatInt(TIDFrom, 10)) - req.Add("count", strconv.FormatInt(Count, 10)) - req.Add("from_id", strconv.FormatInt(TIDFrom, 10)) - req.Add("end_id", strconv.FormatInt(TIDEnd, 10)) + req.Add("from", strconv.FormatInt(tidFrom, 10)) + req.Add("count", strconv.FormatInt(count, 10)) + req.Add("from_id", strconv.FormatInt(tidFrom, 10)) + req.Add("end_id", strconv.FormatInt(tidEnd, 10)) req.Add("order", order) req.Add("since", strconv.FormatInt(since, 10)) req.Add("end", strconv.FormatInt(end, 10)) @@ -400,8 +400,7 @@ func getInternationalBankWithdrawalFee(currency string, amount float64, bankTran switch bankTransactionType { case exchange.PerfectMoney: - switch currency { - case symbol.USD: + if currency == symbol.USD { fee = 0.02 * amount } case exchange.Payeer: @@ -419,13 +418,11 @@ func getInternationalBankWithdrawalFee(currency string, amount float64, bankTran fee = 0.03 * amount } case exchange.Qiwi: - switch currency { - case symbol.RUR: + if currency == symbol.RUR { fee = 0.04 * amount } case exchange.Capitalist: - switch currency { - case symbol.USD: + if currency == symbol.USD { fee = 0.06 * amount } } @@ -438,8 +435,7 @@ func getInternationalBankDepositFee(currency string, bankTransactionType exchang var fee float64 switch bankTransactionType { case exchange.PerfectMoney: - switch currency { - case symbol.USD: + if currency == symbol.USD { fee = 0 } case exchange.Payeer: @@ -457,8 +453,7 @@ func getInternationalBankDepositFee(currency string, bankTransactionType exchang fee = 0 } case exchange.Qiwi: - switch currency { - case symbol.RUR: + if currency == symbol.RUR { fee = 0 } case exchange.Capitalist: diff --git a/exchanges/yobit/yobit_test.go b/exchanges/yobit/yobit_test.go index 9687ad734bc..ad0b3fc7783 100644 --- a/exchanges/yobit/yobit_test.go +++ b/exchanges/yobit/yobit_test.go @@ -352,12 +352,12 @@ func TestSubmitOrder(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - var pair = pair.CurrencyPair{ + var p = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.BTC, SecondCurrency: symbol.USD, } - response, err := y.SubmitOrder(pair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi") + response, err := y.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi") if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { diff --git a/exchanges/yobit/yobit_types.go b/exchanges/yobit/yobit_types.go index 42fc436e3a3..1f5e5fdb1d4 100644 --- a/exchanges/yobit/yobit_types.go +++ b/exchanges/yobit/yobit_types.go @@ -105,7 +105,7 @@ type Trade struct { Error string `json:"error"` } -//TradeHistoryResponse returns all your trade history +// TradeHistoryResponse returns all your trade history type TradeHistoryResponse struct { Success int64 `json:"success"` Data map[string]TradeHistory `json:"return,omitempty"` diff --git a/exchanges/zb/zb.go b/exchanges/zb/zb.go index b1c8d86fe17..ef6d6e1abb4 100644 --- a/exchanges/zb/zb.go +++ b/exchanges/zb/zb.go @@ -145,7 +145,7 @@ func (z *ZB) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) { return 0, err } if result.Code != 1000 { - + return 0, fmt.Errorf("unsucessful new order, message: %s code: %d", result.Message, result.Code) } newOrderID, err := strconv.ParseInt(result.ID, 10, 64) if err != nil { @@ -220,10 +220,10 @@ func (z *ZB) GetOrders(currency string, pageindex, side int64) ([]Order, error) // GetMarkets returns market information including pricing, symbols and // each symbols decimal precision func (z *ZB) GetMarkets() (map[string]MarketResponseItem, error) { - url := fmt.Sprintf("%s/%s/%s", z.APIUrl, zbAPIVersion, zbMarkets) + endpoint := fmt.Sprintf("%s/%s/%s", z.APIUrl, zbAPIVersion, zbMarkets) var res interface{} - err := z.SendHTTPRequest(url, &res) + err := z.SendHTTPRequest(endpoint, &res) if err != nil { return nil, err } @@ -256,28 +256,28 @@ func (z *ZB) GetLatestSpotPrice(symbol string) (float64, error) { // GetTicker returns a ticker for a given symbol func (z *ZB) GetTicker(symbol string) (TickerResponse, error) { - url := fmt.Sprintf("%s/%s/%s?market=%s", z.APIUrl, zbAPIVersion, zbTicker, symbol) + urlPath := fmt.Sprintf("%s/%s/%s?market=%s", z.APIUrl, zbAPIVersion, zbTicker, symbol) var res TickerResponse - err := z.SendHTTPRequest(url, &res) + err := z.SendHTTPRequest(urlPath, &res) return res, err } // GetTickers returns ticker data for all supported symbols func (z *ZB) GetTickers() (map[string]TickerChildResponse, error) { - url := fmt.Sprintf("%s/%s/%s", z.APIUrl, zbAPIVersion, zbTickers) + urlPath := fmt.Sprintf("%s/%s/%s", z.APIUrl, zbAPIVersion, zbTickers) resp := make(map[string]TickerChildResponse) - err := z.SendHTTPRequest(url, &resp) + err := z.SendHTTPRequest(urlPath, &resp) return resp, err } // GetOrderbook returns the orderbook for a given symbol func (z *ZB) GetOrderbook(symbol string) (OrderbookResponse, error) { - url := fmt.Sprintf("%s/%s/%s?market=%s", z.APIUrl, zbAPIVersion, zbDepth, symbol) + urlPath := fmt.Sprintf("%s/%s/%s?market=%s", z.APIUrl, zbAPIVersion, zbDepth, symbol) var res OrderbookResponse - err := z.SendHTTPRequest(url, &res) + err := z.SendHTTPRequest(urlPath, &res) if err != nil { return res, err } @@ -304,11 +304,11 @@ func (z *ZB) GetSpotKline(arg KlinesRequestParams) (KLineResponse, error) { vals.Set("size", fmt.Sprintf("%d", arg.Size)) } - url := fmt.Sprintf("%s/%s/%s?%s", z.APIUrl, zbAPIVersion, zbKline, vals.Encode()) + urlPath := fmt.Sprintf("%s/%s/%s?%s", z.APIUrl, zbAPIVersion, zbKline, vals.Encode()) var res KLineResponse var rawKlines map[string]interface{} - err := z.SendHTTPRequest(url, &rawKlines) + err := z.SendHTTPRequest(urlPath, &rawKlines) if err != nil { return res, err } @@ -378,7 +378,7 @@ func (z *ZB) SendAuthenticatedHTTPRequest(httpMethod string, params url.Values, params.Set("reqTime", fmt.Sprintf("%d", common.UnixMillis(time.Now()))) params.Set("sign", fmt.Sprintf("%x", hmac)) - url := fmt.Sprintf("%s/%s?%s", + urlPath := fmt.Sprintf("%s/%s?%s", z.APIUrlSecondary, params.Get("method"), params.Encode()) @@ -391,7 +391,7 @@ func (z *ZB) SendAuthenticatedHTTPRequest(httpMethod string, params url.Values, }{} err := z.SendPayload(httpMethod, - url, + urlPath, nil, strings.NewReader(""), &intermediary, @@ -404,7 +404,7 @@ func (z *ZB) SendAuthenticatedHTTPRequest(httpMethod string, params url.Values, err = common.JSONDecode(intermediary, &errCap) if err == nil { if errCap.Code != 0 { - return fmt.Errorf("SendAuthenticatedHTTPRequest error code: %d message %s", + return fmt.Errorf("sendAuthenticatedHTTPRequest error code: %d message %s", errCap.Code, errorCode[errCap.Code]) } diff --git a/exchanges/zb/zb_test.go b/exchanges/zb/zb_test.go index 66bddd105d3..a358e9afd75 100644 --- a/exchanges/zb/zb_test.go +++ b/exchanges/zb/zb_test.go @@ -281,12 +281,13 @@ func TestSubmitOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", z.APIKey, canManipulateRealOrders)) } - var pair = pair.CurrencyPair{ + var currencyPair = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.QTUM, SecondCurrency: symbol.USDT, } - response, err := z.SubmitOrder(pair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi") + + response, err := z.SubmitOrder(currencyPair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi") if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { diff --git a/exchanges/zb/zb_types.go b/exchanges/zb/zb_types.go index 73791558824..bdb7a20fb9d 100644 --- a/exchanges/zb/zb_types.go +++ b/exchanges/zb/zb_types.go @@ -16,21 +16,21 @@ type OrderbookResponse struct { // AccountsResponseCoin holds the accounts coin details type AccountsResponseCoin struct { - Freez string `json:"freez"` //冻结资产 - EnName string `json:"enName"` //币种英文名 - UnitDecimal int `json:"unitDecimal"` //保留小数位 - UnName string `json:"cnName"` //币种中文名 - UnitTag string `json:"unitTag"` //币种符号 - Available string `json:"available"` //可用资产 - Key string `json:"key"` //币种 + Freez string `json:"freez"` // 冻结资产 + EnName string `json:"enName"` // 币种英文名 + UnitDecimal int `json:"unitDecimal"` // 保留小数位 + UnName string `json:"cnName"` // 币种中文名 + UnitTag string `json:"unitTag"` // 币种符号 + Available string `json:"available"` // 可用资产 + Key string `json:"key"` // 币种 } // AccountsBaseResponse holds basic account details type AccountsBaseResponse struct { - UserName string `json:"username"` //用户名 - TradePasswordEnabled bool `json:"trade_password_enabled"` //是否开通交易密码 - AuthGoogleEnabled bool `json:"auth_google_enabled"` //是否开通谷歌验证 - AuthMobileEnabled bool `json:"auth_mobile_enabled"` //是否开通手机验证 + UserName string `json:"username"` // 用户名 + TradePasswordEnabled bool `json:"trade_password_enabled"` // 是否开通交易密码 + AuthGoogleEnabled bool `json:"auth_google_enabled"` // 是否开通谷歌验证 + AuthMobileEnabled bool `json:"auth_mobile_enabled"` // 是否开通手机验证 } // Order is the order details for retrieving all orders @@ -51,10 +51,10 @@ type AccountsResponse struct { Result struct { Coins []AccountsResponseCoin `json:"coins"` Base AccountsBaseResponse `json:"base"` - } `json:"result"` //用户名 - AssetPerm bool `json:"assetPerm"` //是否开通交易密码 - LeverPerm bool `json:"leverPerm"` //是否开通谷歌验证 - EntrustPerm bool `json:"entrustPerm"` //是否开通手机验证 + } `json:"result"` // 用户名 + AssetPerm bool `json:"assetPerm"` // 是否开通交易密码 + LeverPerm bool `json:"leverPerm"` // 是否开通谷歌验证 + EntrustPerm bool `json:"entrustPerm"` // 是否开通手机验证 MoneyPerm bool `json:"moneyPerm"` // 资产列表 } @@ -72,12 +72,12 @@ type TickerResponse struct { // TickerChildResponse holds the ticker child response data type TickerChildResponse struct { - Vol float64 `json:"vol,string"` //成交量(最近的24小时) - Last float64 `json:"last,string"` //最新成交价 - Sell float64 `json:"sell,string"` //卖一价 - Buy float64 `json:"buy,string"` //买一价 - High float64 `json:"high,string"` //最高价 - Low float64 `json:"low,string"` //最低价 + Vol float64 `json:"vol,string"` // 成交量(最近的24小时) + Last float64 `json:"last,string"` // 最新成交价 + Sell float64 `json:"sell,string"` // 卖一价 + Buy float64 `json:"buy,string"` // 买一价 + High float64 `json:"high,string"` // 最高价 + Low float64 `json:"low,string"` // 最低价 } // SpotNewOrderRequestParamsType ZB 交易类型 @@ -100,19 +100,19 @@ type SpotNewOrderRequestParams struct { // SpotNewOrderResponse stores the new order response data type SpotNewOrderResponse struct { - Code int `json:"code"` //返回代码 - Message string `json:"message"` //提示信息 - ID string `json:"id"` //委托挂单号 + Code int `json:"code"` // 返回代码 + Message string `json:"message"` // 提示信息 + ID string `json:"id"` // 委托挂单号 } // //-------------Kline // KlinesRequestParams represents Klines request data. type KlinesRequestParams struct { - Symbol string //交易对, zb_qc,zb_usdt,zb_btc... - Type TimeInterval //K线类型, 1min, 3min, 15min, 30min, 1hour...... - Since string //从这个时间戳之后的 - Size int //返回数据的条数限制(默认为1000,如果返回数据多于1000条,那么只返回1000条) + Symbol string // 交易对, zb_qc,zb_usdt,zb_btc... + Type TimeInterval // K线类型, 1min, 3min, 15min, 30min, 1hour...... + Since string // 从这个时间戳之后的 + Size int // 返回数据的条数限制(默认为1000,如果返回数据多于1000条,那么只返回1000条) } // KLineResponseData Kline Data diff --git a/exchanges/zb/zb_websocket.go b/exchanges/zb/zb_websocket.go index 323d8d777f1..2f4c34c06d5 100644 --- a/exchanges/zb/zb_websocket.go +++ b/exchanges/zb/zb_websocket.go @@ -10,7 +10,7 @@ import ( "github.com/gorilla/websocket" "github.com/thrasher-/gocryptotrader/common" "github.com/thrasher-/gocryptotrader/currency/pair" - "github.com/thrasher-/gocryptotrader/exchanges" + exchange "github.com/thrasher-/gocryptotrader/exchanges" "github.com/thrasher-/gocryptotrader/exchanges/orderbook" ) diff --git a/exchanges/zb/zb_wrapper.go b/exchanges/zb/zb_wrapper.go index 3e559771849..38ef1297135 100644 --- a/exchanges/zb/zb_wrapper.go +++ b/exchanges/zb/zb_wrapper.go @@ -340,7 +340,7 @@ func (z *ZB) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exch // This function is not concurrency safe due to orderSide/orderType maps func (z *ZB) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) { if getOrdersRequest.OrderSide == exchange.AnyOrderSide || getOrdersRequest.OrderSide == "" { - return nil, errors.New("Specific order side is required") + return nil, errors.New("specific order side is required") } var allOrders []Order diff --git a/go.mod b/go.mod index 4cc81245ae9..c3dad935d09 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,9 @@ module github.com/thrasher-/gocryptotrader require ( - github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f // indirect - github.com/gorilla/mux v1.6.1 - github.com/gorilla/websocket v1.2.0 - github.com/toorop/go-pusher v0.0.0-20180107133620-4549deda5702 - golang.org/x/crypto v0.0.0-20180602220124-df8d4716b347 - golang.org/x/net v0.0.0-20180201030042-309822c5b9b9 // indirect + github.com/gorilla/mux v1.7.0 + github.com/gorilla/websocket v1.4.0 + github.com/toorop/go-pusher v0.0.0-20180521062818-4521e2eb39fb + golang.org/x/crypto v0.0.0-20190227175134-215aa809caaf + golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 // indirect ) diff --git a/go.sum b/go.sum index cbcfba91e03..7dffd19f848 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,11 @@ -github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= -github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.1 h1:KOwqsTYZdeuMacU7CxjMNYEKeBvLbxW+psodrbcEa3A= -github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= -github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/toorop/go-pusher v0.0.0-20180107133620-4549deda5702 h1:5++uRlIqjhFXdgYOontPMHx6MQLun4kekOL/5AjC384= -github.com/toorop/go-pusher v0.0.0-20180107133620-4549deda5702/go.mod h1:VTLqNCX1tXrur6pdIRCl8Q90FR7nw/mEBdyMkWMcsb0= -golang.org/x/crypto v0.0.0-20180602220124-df8d4716b347 h1:+jjpoZyGXummmGKty7FoOcAE9yNHXYwr4nOv+07g6X4= -golang.org/x/crypto v0.0.0-20180602220124-df8d4716b347/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/net v0.0.0-20180201030042-309822c5b9b9 h1:+Va2hqur1pIoaZgDZSzTxfatSy6IY0IOu7qmCh8b2W8= -golang.org/x/net v0.0.0-20180201030042-309822c5b9b9/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= +github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/toorop/go-pusher v0.0.0-20180521062818-4521e2eb39fb h1:9kcmLvQdiIecpgVEL3/+J5QIP/ElRBJDljOay0SvqnA= +github.com/toorop/go-pusher v0.0.0-20180521062818-4521e2eb39fb/go.mod h1:VTLqNCX1tXrur6pdIRCl8Q90FR7nw/mEBdyMkWMcsb0= +golang.org/x/crypto v0.0.0-20190227175134-215aa809caaf h1:CGelmUfSfeZpx2Pu+OznGcS0ff71WZ/ZOEkhMAB4hVQ= +golang.org/x/crypto v0.0.0-20190227175134-215aa809caaf/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/helpers.go b/helpers.go index e1cf89ec4a9..2feccf1a56b 100644 --- a/helpers.go +++ b/helpers.go @@ -222,14 +222,14 @@ func GetRelatableCurrencies(p pair.CurrencyPair, incOrig, incUSDT bool) []pair.C // GetSpecificOrderbook returns a specific orderbook given the currency, // exchangeName and assetType -func GetSpecificOrderbook(currency, exchangeName, assetType string) (orderbook.Base, error) { +func GetSpecificOrderbook(currencyPair, exchangeName, assetType string) (orderbook.Base, error) { var specificOrderbook orderbook.Base var err error for x := range bot.exchanges { if bot.exchanges[x] != nil { if bot.exchanges[x].GetName() == exchangeName { specificOrderbook, err = bot.exchanges[x].GetOrderbookEx( - pair.NewCurrencyPairFromString(currency), + pair.NewCurrencyPairFromString(currencyPair), assetType, ) break @@ -241,14 +241,14 @@ func GetSpecificOrderbook(currency, exchangeName, assetType string) (orderbook.B // GetSpecificTicker returns a specific ticker given the currency, // exchangeName and assetType -func GetSpecificTicker(currency, exchangeName, assetType string) (ticker.Price, error) { +func GetSpecificTicker(currencyPair, exchangeName, assetType string) (ticker.Price, error) { var specificTicker ticker.Price var err error for x := range bot.exchanges { if bot.exchanges[x] != nil { if bot.exchanges[x].GetName() == exchangeName { specificTicker, err = bot.exchanges[x].GetTickerPrice( - pair.NewCurrencyPairFromString(currency), + pair.NewCurrencyPairFromString(currencyPair), assetType, ) break diff --git a/helpers_test.go b/helpers_test.go index 7506625eb71..a4ceb53b28a 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -191,9 +191,10 @@ func TestGetRelatableFiatCurrencies(t *testing.T) { func TestMapCurrenciesByExchange(t *testing.T) { SetupTestHelpers(t) - var pairs []pair.CurrencyPair - pairs = append(pairs, pair.NewCurrencyPair("BTC", "USD")) - pairs = append(pairs, pair.NewCurrencyPair("BTC", "EUR")) + var pairs = []pair.CurrencyPair{ + pair.NewCurrencyPair("BTC", "USD"), + pair.NewCurrencyPair("BTC", "EUR"), + } result := MapCurrenciesByExchange(pairs, true) pairs, ok := result["Bitstamp"] @@ -370,12 +371,12 @@ func TestGetExchangeHighestPriceByCurrencyPair(t *testing.T) { p := pair.NewCurrencyPair("BTC", "USD") stats.Add("Bitfinex", p, ticker.Spot, 1000, 10000) stats.Add("Bitstamp", p, ticker.Spot, 1337, 10000) - exchange, err := GetExchangeHighestPriceByCurrencyPair(p, ticker.Spot) + exchangeName, err := GetExchangeHighestPriceByCurrencyPair(p, ticker.Spot) if err != nil { t.Error(err) } - if exchange != "Bitstamp" { + if exchangeName != "Bitstamp" { t.Error("Unexpected result") } @@ -391,12 +392,12 @@ func TestGetExchangeLowestPriceByCurrencyPair(t *testing.T) { p := pair.NewCurrencyPair("BTC", "USD") stats.Add("Bitfinex", p, ticker.Spot, 1000, 10000) stats.Add("Bitstamp", p, ticker.Spot, 1337, 10000) - exchange, err := GetExchangeLowestPriceByCurrencyPair(p, ticker.Spot) + exchangeName, err := GetExchangeLowestPriceByCurrencyPair(p, ticker.Spot) if err != nil { t.Error(err) } - if exchange != "Bitfinex" { + if exchangeName != "Bitfinex" { t.Error("Unexpected result") } diff --git a/logger/logger.go b/logger/logger.go index a3b80880450..3bbfd5b4e03 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -95,7 +95,7 @@ func setupOutputs() (err error) { newFile := newName + " " + Logger.File err = os.Rename(logFile, path.Join(LogPath, newFile)) if err != nil { - err = fmt.Errorf("Failed to rename old log file %s", err) + err = fmt.Errorf("failed to rename old log file %s", err) return } } diff --git a/main.go b/main.go index f4251032681..e06abf5d994 100644 --- a/main.go +++ b/main.go @@ -54,7 +54,7 @@ func main() { log.Fatal(err) } - //Handle flags + // Handle flags flag.StringVar(&bot.configFile, "config", defaultPath, "config file to load") flag.StringVar(&bot.dataDir, "datadir", common.GetDefaultDataDir(runtime.GOOS), "default data directory for GoCryptoTrader files") dryrun := flag.Bool("dryrun", false, "dry runs bot, doesn't save config file") @@ -64,7 +64,7 @@ func main() { flag.Parse() if *version { - fmt.Printf(BuildVersion(true)) + fmt.Print(BuildVersion(true)) os.Exit(0) } @@ -115,7 +115,8 @@ func main() { } log.Debugf("Starting communication mediums..") - bot.comms = communications.NewComm(bot.config.GetCommunicationsConfig()) + cfg := bot.config.GetCommunicationsConfig() + bot.comms = communications.NewComm(&cfg) bot.comms.GetEnabledCommunicationMediums() if bot.config.GetCryptocurrencyProviderConfig().Enabled { @@ -123,21 +124,17 @@ func main() { err = currency.SeedCryptocurrencyMarketData(coinmarketcap.Settings(bot.config.GetCryptocurrencyProviderConfig())) if err != nil { log.Warnf("Failure seeding cryptocurrency market data %s", err) - } else { - if *verbosity { - log.Debugf("Total market cryptocurrencies: %d", - len(currency.GetTotalMarketCryptocurrencies())) - } + } else if *verbosity { + log.Debugf("Total market cryptocurrencies: %d", + len(currency.GetTotalMarketCryptocurrencies())) } err = currency.SeedExchangeMarketData(coinmarketcap.Settings(bot.config.GetCryptocurrencyProviderConfig())) if err != nil { log.Warnf("Failure seeding exchange market data %s", err) - } else { - if *verbosity { - log.Debugf("Total market exchanges: %d", - len(currency.GetTotalMarketExchanges())) - } + } else if *verbosity { + log.Debugf("Total market exchanges: %d", + len(currency.GetTotalMarketExchanges())) } } else { log.Debug("Cryptocurrency provider not enabled.") diff --git a/portfolio/portfolio.go b/portfolio/portfolio.go index e5b13523b54..561625fcadf 100644 --- a/portfolio/portfolio.go +++ b/portfolio/portfolio.go @@ -29,27 +29,27 @@ var Portfolio Base func GetEthereumBalance(address string) (EthplorerResponse, error) { valid, _ := common.IsValidCryptoAddress(address, "eth") if !valid { - return EthplorerResponse{}, errors.New("Not an ethereum address") + return EthplorerResponse{}, errors.New("not an Ethereum address") } - url := fmt.Sprintf( + urlPath := fmt.Sprintf( "%s/%s/%s?apiKey=freekey", ethplorerAPIURL, ethplorerAddressInfo, address, ) result := EthplorerResponse{} - return result, common.SendHTTPGetRequest(url, true, false, &result) + return result, common.SendHTTPGetRequest(urlPath, true, false, &result) } // GetCryptoIDAddress queries CryptoID for an address balance for a // specified cryptocurrency -func GetCryptoIDAddress(address string, coinType string) (float64, error) { +func GetCryptoIDAddress(address, coinType string) (float64, error) { ok, err := common.IsValidCryptoAddress(address, coinType) if !ok || err != nil { return 0, errors.New("invalid address") } var result interface{} - url := fmt.Sprintf("%s/%s/api.dws?q=getbalance&a=%s", cryptoIDAPIURL, common.StringToLower(coinType), address) - err = common.SendHTTPGetRequest(url, true, false, &result) + urlPath := fmt.Sprintf("%s/%s/api.dws?q=getbalance&a=%s", cryptoIDAPIURL, common.StringToLower(coinType), address) + err = common.SendHTTPGetRequest(urlPath, true, false, &result) if err != nil { return 0, err } @@ -179,22 +179,22 @@ func (p *Base) UpdatePortfolio(addresses []string, coinType string) bool { return true } - errors := 0 + numErrors := 0 if coinType == "ETH" { for x := range addresses { result, err := GetEthereumBalance(addresses[x]) if err != nil { - errors++ + numErrors++ continue } if result.Error.Message != "" { - errors++ + numErrors++ continue } p.AddAddress(addresses[x], coinType, PortfolioAddressPersonal, result.ETH.Balance) } - return errors == 0 + return numErrors == 0 } for x := range addresses { result, err := GetCryptoIDAddress(addresses[x], coinType) diff --git a/portfolio/portfolio_test.go b/portfolio/portfolio_test.go index de33747fb7b..40614cf45a9 100644 --- a/portfolio/portfolio_test.go +++ b/portfolio/portfolio_test.go @@ -4,6 +4,8 @@ import ( "reflect" "testing" "time" + + "github.com/thrasher-/gocryptotrader/currency/symbol" ) func TestGetEthereumBalance(t *testing.T) { @@ -28,7 +30,7 @@ func TestGetEthereumBalance(t *testing.T) { func TestGetCryptoIDBalance(t *testing.T) { ltcAddress := "LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1" - _, err := GetCryptoIDAddress(ltcAddress, "ltc") + _, err := GetCryptoIDAddress(ltcAddress, symbol.LTC) if err != nil { t.Fatalf("Test failed. TestGetCryptoIDBalance error: %s", err) } @@ -36,7 +38,7 @@ func TestGetCryptoIDBalance(t *testing.T) { func TestGetAddressBalance(t *testing.T) { ltcAddress := "LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL" - ltc := "ltc" + ltc := symbol.LTC description := "Description of Wallet" balance := float64(1000) @@ -59,7 +61,7 @@ func TestGetAddressBalance(t *testing.T) { func TestExchangeExists(t *testing.T) { newBase := Base{} - newBase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) + newBase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) if !newBase.ExchangeExists("someaddress") { t.Error("Test Failed - portfolio_test.go - AddressExists error") } @@ -70,7 +72,7 @@ func TestExchangeExists(t *testing.T) { func TestAddressExists(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) + newbase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) if !newbase.AddressExists("someaddress") { t.Error("Test Failed - portfolio_test.go - AddressExists error") } @@ -81,11 +83,11 @@ func TestAddressExists(t *testing.T) { func TestExchangeAddressExists(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) - if !newbase.ExchangeAddressExists("someaddress", "LTC") { + newbase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) + if !newbase.ExchangeAddressExists("someaddress", symbol.LTC) { t.Error("Test Failed - portfolio_test.go - ExchangeAddressExists error") } - if newbase.ExchangeAddressExists("TEST", "LTC") { + if newbase.ExchangeAddressExists("TEST", symbol.LTC) { t.Error("Test Failed - portfolio_test.go - ExchangeAddressExists error") } @@ -93,34 +95,34 @@ func TestExchangeAddressExists(t *testing.T) { func TestAddExchangeAddress(t *testing.T) { newbase := Base{} - newbase.AddExchangeAddress("ANX", "BTC", 100) - newbase.AddExchangeAddress("ANX", "BTC", 200) + newbase.AddExchangeAddress("ANX", symbol.BTC, 100) + newbase.AddExchangeAddress("ANX", symbol.BTC, 200) - if !newbase.ExchangeAddressExists("ANX", "BTC") { + if !newbase.ExchangeAddressExists("ANX", symbol.BTC) { t.Error("Test Failed - TestExchangeAddressExists address doesn't exist") } } func TestUpdateAddressBalance(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) + newbase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) newbase.UpdateAddressBalance("someaddress", 0.03) value := newbase.GetPortfolioSummary() - if value.Totals[0].Coin != "LTC" && value.Totals[0].Balance != 0.03 { + if value.Totals[0].Coin != symbol.LTC && value.Totals[0].Balance != 0.03 { t.Error("Test Failed - portfolio_test.go - UpdateUpdateAddressBalance error") } } func TestRemoveAddress(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddr", "LTC", "LTCWALLETTEST", 420) + newbase.AddAddress("someaddr", symbol.LTC, "LTCWALLETTEST", 420) if !newbase.AddressExists("someaddr") { t.Error("Test failed - portfolio_test.go - TestRemoveAddress") } - newbase.RemoveAddress("someaddr", "LTC", "LTCWALLETTEST") + newbase.RemoveAddress("someaddr", symbol.LTC, "LTCWALLETTEST") if newbase.AddressExists("someaddr") { t.Error("Test failed - portfolio_test.go - TestRemoveAddress") } @@ -129,7 +131,7 @@ func TestRemoveAddress(t *testing.T) { func TestRemoveExchangeAddress(t *testing.T) { newbase := Base{} exchangeName := "BallerExchange" - coinType := "LTC" + coinType := symbol.LTC newbase.AddExchangeAddress(exchangeName, coinType, 420) @@ -145,20 +147,20 @@ func TestRemoveExchangeAddress(t *testing.T) { func TestUpdateExchangeAddressBalance(t *testing.T) { newbase := Base{} - newbase.AddExchangeAddress("someaddress", "LTC", 0.02) + newbase.AddExchangeAddress("someaddress", symbol.LTC, 0.02) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) - portfolio.UpdateExchangeAddressBalance("someaddress", "LTC", 0.04) + portfolio.UpdateExchangeAddressBalance("someaddress", symbol.LTC, 0.04) value := portfolio.GetPortfolioSummary() - if value.Totals[0].Coin != "LTC" && value.Totals[0].Balance != 0.04 { + if value.Totals[0].Coin != symbol.LTC && value.Totals[0].Balance != 0.04 { t.Error("Test Failed - portfolio_test.go - UpdateExchangeAddressBalance error") } } func TestAddAddress(t *testing.T) { newbase := Base{} - newbase.AddAddress("Gibson", "LTC", "LTCWALLETTEST", 0.02) + newbase.AddAddress("Gibson", symbol.LTC, "LTCWALLETTEST", 0.02) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) if !portfolio.AddressExists("Gibson") { @@ -167,7 +169,7 @@ func TestAddAddress(t *testing.T) { // Test updating balance to <= 0, expected result is to remove the address. // Fail if address still exists. - newbase.AddAddress("Gibson", "LTC", "LTCWALLETTEST", -1) + newbase.AddAddress("Gibson", symbol.LTC, "LTCWALLETTEST", -1) if newbase.AddressExists("Gibson") { t.Error("Test Failed - portfolio_test.go - AddAddress error") } @@ -175,29 +177,29 @@ func TestAddAddress(t *testing.T) { func TestUpdatePortfolio(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) + newbase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) value := portfolio.UpdatePortfolio( - []string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL"}, "LTC", + []string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL"}, symbol.LTC, ) if !value { t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error") } - value = portfolio.UpdatePortfolio([]string{"Testy"}, "LTC") + value = portfolio.UpdatePortfolio([]string{"Testy"}, symbol.LTC) if value { t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error") } value = portfolio.UpdatePortfolio( []string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "LVa8wZ983PvWtdwXZ8viK6SocMENLCXkEy"}, - "LTC", + symbol.LTC, ) if !value { t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error") } value = portfolio.UpdatePortfolio( - []string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "Testy"}, "LTC", + []string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "Testy"}, symbol.LTC, ) if value { t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error") @@ -206,20 +208,20 @@ func TestUpdatePortfolio(t *testing.T) { time.Sleep(time.Second * 5) value = portfolio.UpdatePortfolio( []string{"0xb794f5ea0ba39494ce839613fffba74279579268", - "0xe853c56864a2ebe4576a807d26fdc4a0ada51919"}, "ETH", + "0xe853c56864a2ebe4576a807d26fdc4a0ada51919"}, symbol.ETH, ) if !value { t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error") } value = portfolio.UpdatePortfolio( - []string{"0xb794f5ea0ba39494ce839613fffba74279579268", "TESTY"}, "ETH", + []string{"0xb794f5ea0ba39494ce839613fffba74279579268", "TESTY"}, symbol.ETH, ) if value { t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error") } value = portfolio.UpdatePortfolio( - []string{PortfolioAddressExchange, PortfolioAddressPersonal}, "LTC") + []string{PortfolioAddressExchange, PortfolioAddressPersonal}, symbol.LTC) if !value { t.Error("Test Failed - portfolio_test.go - UpdatePortfolio error") @@ -228,13 +230,13 @@ func TestUpdatePortfolio(t *testing.T) { func TestGetPortfolioByExchange(t *testing.T) { newbase := Base{} - newbase.AddExchangeAddress("ANX", "LTC", 0.07) - newbase.AddExchangeAddress("Bitfinex", "LTC", 0.05) - newbase.AddAddress("someaddress", "LTC", PortfolioAddressPersonal, 0.03) + newbase.AddExchangeAddress("ANX", symbol.LTC, 0.07) + newbase.AddExchangeAddress("Bitfinex", symbol.LTC, 0.05) + newbase.AddAddress("someaddress", symbol.LTC, PortfolioAddressPersonal, 0.03) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) value := portfolio.GetPortfolioByExchange("ANX") - result, ok := value["LTC"] + result, ok := value[symbol.LTC] if !ok { t.Error("Test Failed - portfolio_test.go - GetPortfolioByExchange error") } @@ -244,7 +246,7 @@ func TestGetPortfolioByExchange(t *testing.T) { } value = portfolio.GetPortfolioByExchange("Bitfinex") - result, ok = value["LTC"] + result, ok = value[symbol.LTC] if !ok { t.Error("Test Failed - portfolio_test.go - GetPortfolioByExchange error") } @@ -256,14 +258,14 @@ func TestGetPortfolioByExchange(t *testing.T) { func TestGetExchangePortfolio(t *testing.T) { newbase := Base{} - newbase.AddAddress("ANX", "LTC", PortfolioAddressExchange, 0.03) - newbase.AddAddress("Bitfinex", "LTC", PortfolioAddressExchange, 0.05) - newbase.AddAddress("someaddress", "LTC", PortfolioAddressPersonal, 0.03) + newbase.AddAddress("ANX", symbol.LTC, PortfolioAddressExchange, 0.03) + newbase.AddAddress("Bitfinex", symbol.LTC, PortfolioAddressExchange, 0.05) + newbase.AddAddress("someaddress", symbol.LTC, PortfolioAddressPersonal, 0.03) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) value := portfolio.GetExchangePortfolio() - result, ok := value["LTC"] + result, ok := value[symbol.LTC] if !ok { t.Error("Test Failed - portfolio_test.go - GetExchangePortfolio error") } @@ -275,13 +277,13 @@ func TestGetExchangePortfolio(t *testing.T) { func TestGetPersonalPortfolio(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) - newbase.AddAddress("anotheraddress", "LTC", "LTCWALLETTEST", 0.03) - newbase.AddAddress("Exchange", "LTC", PortfolioAddressExchange, 0.01) + newbase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) + newbase.AddAddress("anotheraddress", symbol.LTC, "LTCWALLETTEST", 0.03) + newbase.AddAddress("Exchange", symbol.LTC, PortfolioAddressExchange, 0.01) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) value := portfolio.GetPersonalPortfolio() - result, ok := value["LTC"] + result, ok := value[symbol.LTC] if !ok { t.Error("Test Failed - portfolio_test.go - GetPersonalPortfolio error") } @@ -294,18 +296,18 @@ func TestGetPersonalPortfolio(t *testing.T) { func TestGetPortfolioSummary(t *testing.T) { newbase := Base{} // Personal holdings - newbase.AddAddress("someaddress", "LTC", PortfolioAddressPersonal, 1) - newbase.AddAddress("someaddress2", "LTC", PortfolioAddressPersonal, 2) - newbase.AddAddress("someaddress3", "BTC", PortfolioAddressPersonal, 100) - newbase.AddAddress("0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", "ETH", + newbase.AddAddress("someaddress", symbol.LTC, PortfolioAddressPersonal, 1) + newbase.AddAddress("someaddress2", symbol.LTC, PortfolioAddressPersonal, 2) + newbase.AddAddress("someaddress3", symbol.BTC, PortfolioAddressPersonal, 100) + newbase.AddAddress("0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae", symbol.ETH, PortfolioAddressPersonal, 865346880000000000) - newbase.AddAddress("0x9edc81c813b26165f607a8d1b8db87a02f34307f", "ETH", + newbase.AddAddress("0x9edc81c813b26165f607a8d1b8db87a02f34307f", symbol.ETH, PortfolioAddressPersonal, 165346880000000000) // Exchange holdings - newbase.AddExchangeAddress("Bitfinex", "LTC", 20) - newbase.AddExchangeAddress("Bitfinex", "BTC", 100) - newbase.AddExchangeAddress("ANX", "ETH", 42) + newbase.AddExchangeAddress("Bitfinex", symbol.LTC, 20) + newbase.AddExchangeAddress("Bitfinex", symbol.BTC, 100) + newbase.AddExchangeAddress("ANX", symbol.ETH, 42) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) @@ -320,38 +322,38 @@ func TestGetPortfolioSummary(t *testing.T) { return Coin{} } - if getTotalsVal("LTC").Coin != "LTC" { + if getTotalsVal(symbol.LTC).Coin != symbol.LTC { t.Error("Test Failed - portfolio_test.go - TestGetPortfolioSummary error") } - if getTotalsVal("ETH").Coin != "ETH" { + if getTotalsVal(symbol.ETH).Coin != symbol.ETH { t.Error("Test Failed - portfolio_test.go - TestGetPortfolioSummary error") } - if getTotalsVal("LTC").Balance != 23 { + if getTotalsVal(symbol.LTC).Balance != 23 { t.Error("Test Failed - portfolio_test.go - TestGetPortfolioSummary error") } - if getTotalsVal("BTC").Balance != 200 { + if getTotalsVal(symbol.BTC).Balance != 200 { t.Error("Test Failed - portfolio_test.go - TestGetPortfolioSummary error") } } func TestGetPortfolioGroupedCoin(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) - newbase.AddAddress("Exchange", "LTC", PortfolioAddressExchange, 0.05) + newbase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) + newbase.AddAddress("Exchange", symbol.LTC, PortfolioAddressExchange, 0.05) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) value := portfolio.GetPortfolioGroupedCoin() - if value["LTC"][0] != "someaddress" && len(value["LTC"][0]) != 1 { + if value[symbol.LTC][0] != "someaddress" && len(value[symbol.LTC][0]) != 1 { t.Error("Test Failed - portfolio_test.go - GetPortfolioGroupedCoin error") } } func TestSeedPortfolio(t *testing.T) { newbase := Base{} - newbase.AddAddress("someaddress", "LTC", "LTCWALLETTEST", 0.02) + newbase.AddAddress("someaddress", symbol.LTC, "LTCWALLETTEST", 0.02) portfolio := GetPortfolio() portfolio.SeedPortfolio(newbase) @@ -362,8 +364,8 @@ func TestSeedPortfolio(t *testing.T) { func TestStartPortfolioWatcher(t *testing.T) { newBase := Base{} - newBase.AddAddress("LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1", "LTC", PortfolioAddressPersonal, 0.02) - newBase.AddAddress("Testy", "LTC", PortfolioAddressPersonal, 0.02) + newBase.AddAddress("LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1", symbol.LTC, PortfolioAddressPersonal, 0.02) + newBase.AddAddress("Testy", symbol.LTC, PortfolioAddressPersonal, 0.02) portfolio := GetPortfolio() portfolio.SeedPortfolio(newBase) diff --git a/restful_router.go b/restful_router.go index 157feee9cc7..6b8e2323bfe 100644 --- a/restful_router.go +++ b/restful_router.go @@ -117,7 +117,7 @@ func NewRouter() *mux.Router { return router } -func getIndex(w http.ResponseWriter, r *http.Request) { +func getIndex(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, "GoCryptoTrader RESTful interface. For the web GUI, please visit the web GUI readme.") w.WriteHeader(http.StatusOK) } diff --git a/restful_server.go b/restful_server.go index 2a329eaa572..2dd6f671bc8 100644 --- a/restful_server.go +++ b/restful_server.go @@ -66,14 +66,15 @@ func RESTGetAllSettings(w http.ResponseWriter, r *http.Request) { // RESTSaveAllSettings saves all current settings from request body as a JSON // document then reloads state and returns the settings func RESTSaveAllSettings(w http.ResponseWriter, r *http.Request) { - //Get the data from the request + // Get the data from the request decoder := json.NewDecoder(r.Body) var responseData config.Post err := decoder.Decode(&responseData) if err != nil { RESTfulError(r.Method, err) } - //Save change the settings + + // Save change the settings err = bot.config.UpdateConfig(bot.configFile, responseData.Data) if err != nil { RESTfulError(r.Method, err) @@ -92,16 +93,16 @@ func RESTSaveAllSettings(w http.ResponseWriter, r *http.Request) { func RESTGetOrderbook(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) currency := vars["currency"] - exchange := vars["exchangeName"] + exchangeName := vars["exchangeName"] assetType := vars["assetType"] if assetType == "" { assetType = orderbook.Spot } - response, err := GetSpecificOrderbook(currency, exchange, assetType) + response, err := GetSpecificOrderbook(currency, exchangeName, assetType) if err != nil { - log.Errorf("Failed to fetch orderbook for %s currency: %s\n", exchange, + log.Errorf("Failed to fetch orderbook for %s currency: %s\n", exchangeName, currency) return } @@ -117,45 +118,48 @@ func GetAllActiveOrderbooks() []EnabledExchangeOrderbooks { var orderbookData []EnabledExchangeOrderbooks for _, individualBot := range bot.exchanges { - if individualBot != nil && individualBot.IsEnabled() { - var individualExchange EnabledExchangeOrderbooks - exchangeName := individualBot.GetName() - individualExchange.ExchangeName = exchangeName - currencies := individualBot.GetEnabledCurrencies() - assetTypes, err := exchange.GetExchangeAssetTypes(exchangeName) - if err != nil { - log.Errorf("failed to get %s exchange asset types. Error: %s", - exchangeName, err) - continue - } - for _, x := range currencies { - currency := x - - var ob orderbook.Base - if len(assetTypes) > 1 { - for y := range assetTypes { - ob, err = individualBot.GetOrderbookEx(currency, - assetTypes[y]) - } - } else { - ob, err = individualBot.GetOrderbookEx(currency, - assetTypes[0]) - } + if individualBot == nil || !individualBot.IsEnabled() { + continue + } - if err != nil { - log.Errorf("failed to get %s %s orderbook. Error: %s", - currency.Pair().String(), - exchangeName, - err) - continue + var individualExchange EnabledExchangeOrderbooks + exchangeName := individualBot.GetName() + individualExchange.ExchangeName = exchangeName + currencies := individualBot.GetEnabledCurrencies() + assetTypes, err := exchange.GetExchangeAssetTypes(exchangeName) + if err != nil { + log.Errorf("failed to get %s exchange asset types. Error: %s", + exchangeName, err) + continue + } + for _, x := range currencies { + currency := x + + var ob orderbook.Base + if len(assetTypes) > 1 { + for y := range assetTypes { + ob, err = individualBot.GetOrderbookEx(currency, + assetTypes[y]) } + } else { + ob, err = individualBot.GetOrderbookEx(currency, + assetTypes[0]) + } - individualExchange.ExchangeValues = append( - individualExchange.ExchangeValues, ob, - ) + if err != nil { + log.Errorf("failed to get %s %s orderbook. Error: %s", + currency.Pair().String(), + exchangeName, + err) + continue } - orderbookData = append(orderbookData, individualExchange) + + individualExchange.ExchangeValues = append( + individualExchange.ExchangeValues, ob, + ) } + orderbookData = append(orderbookData, individualExchange) + } return orderbookData } @@ -185,15 +189,15 @@ func RESTGetPortfolio(w http.ResponseWriter, r *http.Request) { func RESTGetTicker(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) currency := vars["currency"] - exchange := vars["exchangeName"] + exchangeName := vars["exchangeName"] assetType := vars["assetType"] if assetType == "" { assetType = ticker.Spot } - response, err := GetSpecificTicker(currency, exchange, assetType) + response, err := GetSpecificTicker(currency, exchangeName, assetType) if err != nil { - log.Errorf("Failed to fetch ticker for %s currency: %s\n", exchange, + log.Errorf("Failed to fetch ticker for %s currency: %s\n", exchangeName, currency) return } @@ -208,44 +212,46 @@ func GetAllActiveTickers() []EnabledExchangeCurrencies { var tickerData []EnabledExchangeCurrencies for _, individualBot := range bot.exchanges { - if individualBot != nil && individualBot.IsEnabled() { - var individualExchange EnabledExchangeCurrencies - exchangeName := individualBot.GetName() - individualExchange.ExchangeName = exchangeName - currencies := individualBot.GetEnabledCurrencies() - for _, x := range currencies { - currency := x - assetTypes, err := exchange.GetExchangeAssetTypes(exchangeName) - if err != nil { - log.Errorf("failed to get %s exchange asset types. Error: %s", - exchangeName, err) - continue - } - var tickerPrice ticker.Price - if len(assetTypes) > 1 { - for y := range assetTypes { - tickerPrice, err = individualBot.GetTickerPrice(currency, - assetTypes[y]) - } - } else { - tickerPrice, err = individualBot.GetTickerPrice(currency, - assetTypes[0]) - } + if individualBot == nil || !individualBot.IsEnabled() { + continue + } - if err != nil { - log.Errorf("failed to get %s %s ticker. Error: %s", - currency.Pair().String(), - exchangeName, - err) - continue + var individualExchange EnabledExchangeCurrencies + exchangeName := individualBot.GetName() + individualExchange.ExchangeName = exchangeName + currencies := individualBot.GetEnabledCurrencies() + for _, x := range currencies { + currency := x + assetTypes, err := exchange.GetExchangeAssetTypes(exchangeName) + if err != nil { + log.Errorf("failed to get %s exchange asset types. Error: %s", + exchangeName, err) + continue + } + var tickerPrice ticker.Price + if len(assetTypes) > 1 { + for y := range assetTypes { + tickerPrice, err = individualBot.GetTickerPrice(currency, + assetTypes[y]) } + } else { + tickerPrice, err = individualBot.GetTickerPrice(currency, + assetTypes[0]) + } - individualExchange.ExchangeValues = append( - individualExchange.ExchangeValues, tickerPrice, - ) + if err != nil { + log.Errorf("failed to get %s %s ticker. Error: %s", + currency.Pair().String(), + exchangeName, + err) + continue } - tickerData = append(tickerData, individualExchange) + + individualExchange.ExchangeValues = append( + individualExchange.ExchangeValues, tickerPrice, + ) } + tickerData = append(tickerData, individualExchange) } return tickerData } diff --git a/restful_server_test.go b/restful_server_test.go index 6811b22ad78..53b2c6985cd 100644 --- a/restful_server_test.go +++ b/restful_server_test.go @@ -21,7 +21,7 @@ func loadConfig(t *testing.T) *config.Config { return cfg } -func makeHTTPGetRequest(t *testing.T, url string, response interface{}) *http.Response { +func makeHTTPGetRequest(t *testing.T, response interface{}) *http.Response { w := httptest.NewRecorder() err := RESTfulJSONResponse(w, response) @@ -34,7 +34,7 @@ func makeHTTPGetRequest(t *testing.T, url string, response interface{}) *http.Re // TestConfigAllJsonResponse test if config/all restful json response is valid func TestConfigAllJsonResponse(t *testing.T) { cfg := loadConfig(t) - resp := makeHTTPGetRequest(t, "http://localhost:9050/config/all", cfg) + resp := makeHTTPGetRequest(t, cfg) body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Error("Test failed. Body not readable", err) diff --git a/routines.go b/routines.go index 9b37d2aee1b..7e215dae25c 100644 --- a/routines.go +++ b/routines.go @@ -53,7 +53,7 @@ func printConvertCurrencyFormat(origCurrency string, origPrice float64) string { ) } -func printTickerSummary(result ticker.Price, p pair.CurrencyPair, assetType, exchangeName string, err error) { +func printTickerSummary(result *ticker.Price, p pair.CurrencyPair, assetType, exchangeName string, err error) { if err != nil { log.Errorf("Failed to get %s %s ticker. Error: %s", p.Pair().String(), @@ -102,7 +102,7 @@ func printTickerSummary(result ticker.Price, p pair.CurrencyPair, assetType, exc } } -func printOrderbookSummary(result orderbook.Base, p pair.CurrencyPair, assetType, exchangeName string, err error) { +func printOrderbookSummary(result *orderbook.Base, p pair.CurrencyPair, assetType, exchangeName string, err error) { if err != nil { log.Errorf("Failed to get %s %s orderbook. Error: %s", p.Pair().String(), @@ -207,9 +207,9 @@ func TickerUpdaterRoutine() { } else { result, err = exch.GetTickerPrice(c, assetType) } - printTickerSummary(result, c, assetType, exchangeName, err) + printTickerSummary(&result, c, assetType, exchangeName, err) if err == nil { - bot.comms.StageTickerData(exchangeName, assetType, result) + bot.comms.StageTickerData(exchangeName, assetType, &result) if bot.config.Webserver.Enabled { relayWebsocketEvent(result, "ticker_update", assetType, exchangeName) } @@ -258,9 +258,9 @@ func OrderbookUpdaterRoutine() { processOrderbook := func(exch exchange.IBotExchange, c pair.CurrencyPair, assetType string) { result, err := exch.UpdateOrderbook(c, assetType) - printOrderbookSummary(result, c, assetType, exchangeName, err) + printOrderbookSummary(&result, c, assetType, exchangeName, err) if err == nil { - bot.comms.StageOrderbookData(exchangeName, assetType, result) + bot.comms.StageOrderbookData(exchangeName, assetType, &result) if bot.config.Webserver.Enabled { relayWebsocketEvent(result, "orderbook_update", assetType, exchangeName) } @@ -449,13 +449,13 @@ func WebsocketReconnect(ws *exchange.Websocket, verbose bool) { wg.Add(1) defer wg.Done() - ticker := time.NewTicker(3 * time.Second) + tick := time.NewTicker(3 * time.Second) for { select { case <-shutdowner: return - case <-ticker.C: + case <-tick.C: err = ws.Connect() if err == nil { return diff --git a/tools/documentation/documentation.go b/tools/documentation/documentation.go index 82f70d335ff..f8a948d51b6 100644 --- a/tools/documentation/documentation.go +++ b/tools/documentation/documentation.go @@ -278,10 +278,10 @@ func getName(name string, capital bool) string { } func getCapital(name string) string { - cap := strings.ToUpper(string(name[0])) + capLetter := strings.ToUpper(string(name[0])) last := name[1:] - return cap + last + return capLetter + last } // getslashFromName returns a string for godoc package names @@ -352,20 +352,20 @@ func replaceReadme(packageName string) error { func createReadme(packageName string) error { if packageName == licenseName || packageName == contributorName { file, err := os.Create(codebasePaths[packageName] + packageName) - defer file.Close() if err != nil { return err } + defer file.Close() if verbose { fmt.Println("File done") } return tmpl.ExecuteTemplate(file, packageName, codebaseReadme[packageName]) } file, err := os.Create(codebasePaths[packageName] + "README.md") - defer file.Close() if err != nil { return err } + defer file.Close() if verbose { fmt.Println("File done") } diff --git a/tools/exchange_template/exchange_template.go b/tools/exchange_template/exchange_template.go index af3f75f7dc5..3735ac254b4 100644 --- a/tools/exchange_template/exchange_template.go +++ b/tools/exchange_template/exchange_template.go @@ -106,8 +106,8 @@ func main() { var configTestExchanges []string - for _, exch := range configTestFile.Exchanges { - configTestExchanges = append(configTestExchanges, exch.Name) + for x := range configTestFile.Exchanges { + configTestExchanges = append(configTestExchanges, configTestFile.Exchanges[x].Name) } if common.StringDataContainsUpper(configTestExchanges, capName) { @@ -227,9 +227,9 @@ func newFile(path string) { if os.IsNotExist(err) { var file, err = os.Create(path) - defer file.Close() if err != nil { log.Fatal("GoCryptoTrader: Exchange templating tool file creation error ", err) } + file.Close() } } diff --git a/tools/huobi_auth/main.go b/tools/huobi_auth/main.go index d979ed18aaf..e174c6bd478 100644 --- a/tools/huobi_auth/main.go +++ b/tools/huobi_auth/main.go @@ -42,8 +42,8 @@ func encodePEM(privKey *ecdsa.PrivateKey, pubKey bool) ([]byte, error) { ), nil } -func decodePEM(PEMPrivKey []byte) (*ecdsa.PrivateKey, error) { - block, _ := pem.Decode(PEMPrivKey) +func decodePEM(pemPrivKey []byte) (*ecdsa.PrivateKey, error) { + block, _ := pem.Decode(pemPrivKey) if block == nil { return nil, errors.New("priv block data is nil") }