Migrate from gometalinter.v2 to golangci-lint (#249)

* Migrate from gometalinter.v2 to golangci-lint
This commit is contained in:
Adrian Gallagher
2019-03-01 16:10:29 +11:00
committed by GitHub
parent 81852f2e01
commit 7dcb1ab553
133 changed files with 2179 additions and 2204 deletions

83
.golangci.yml Normal file
View File

@@ -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

View File

@@ -15,7 +15,7 @@ matrix:
- language: go
go:
- 1.11.x
- 1.12.x
env:
- GO111MODULE=on
install: true

View File

@@ -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')
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

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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])
}
}

View File

@@ -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()}
}

View File

@@ -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)
}

View File

@@ -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",

View File

@@ -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):

View File

@@ -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 {

View File

@@ -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,
},
)
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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) {

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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
}
}

View File

@@ -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 (

View File

@@ -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")
}
}

View File

@@ -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

View File

@@ -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")
}
}

View File

@@ -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(),
})

View File

@@ -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)

View File

@@ -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")
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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))

View File

@@ -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

View File

@@ -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 = "~"

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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")
}
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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
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 {
request["side"] = "buy"
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

View File

@@ -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{

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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

View File

@@ -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
subscriber.Arguments = append(subscriber.Arguments,
bitmexWSTrade+":"+contract.Pair().String())
// Orderbook and Trade subscribe
// NOTE more added here in future
subscriber.Arguments = append(subscriber.Arguments,
bitmexWSOrderbookL2+":"+contract.Pair().String(),
bitmexWSTrade+":"+contract.Pair().String())
}
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)
}

View File

@@ -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.

View File

@@ -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))

View File

@@ -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)

View File

@@ -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)
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
OrderDate: orderDate,
Exchange: b.Name,
CurrencyPair: currPair,
})
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)
}
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)

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
)

View File

@@ -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

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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:

View File

@@ -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

View File

@@ -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:

View File

@@ -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,

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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"

View File

@@ -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"`

View File

@@ -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"

View File

@@ -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
}

View File

@@ -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(), "")

View File

@@ -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)
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 ticker, nil
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:
// <char-severity code><string-error category>:<string-error type>[:<string-extra info>]
// 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)
}

View File

@@ -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)
}
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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"
}

View File

@@ -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)

View File

@@ -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
}
}
}

View File

@@ -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)

View File

@@ -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"),
}
}

View File

@@ -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)

View File

@@ -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...)

Some files were not shown because too many files have changed in this diff Show More