mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
Migrate from gometalinter.v2 to golangci-lint (#249)
* Migrate from gometalinter.v2 to golangci-lint
This commit is contained in:
83
.golangci.yml
Normal file
83
.golangci.yml
Normal 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
|
||||
@@ -15,7 +15,7 @@ matrix:
|
||||
|
||||
- language: go
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
install: true
|
||||
|
||||
39
Makefile
39
Makefile
@@ -1,38 +1,15 @@
|
||||
LDFLAGS = -ldflags "-w -s"
|
||||
GCTPKG = github.com/thrasher-/gocryptotrader
|
||||
LINTPKG = gopkg.in/alecthomas/gometalinter.v2
|
||||
LINTBIN = $(GOPATH)/bin/gometalinter.v2
|
||||
ENABLELLL = false
|
||||
LINTOPTS = \
|
||||
--disable-all \
|
||||
--enable=gofmt \
|
||||
--enable=vet \
|
||||
--enable=vetshadow \
|
||||
--enable=misspell \
|
||||
--enable=golint \
|
||||
--enable=ineffassign \
|
||||
--enable=goconst \
|
||||
--enable=structcheck \
|
||||
--enable=unparam \
|
||||
--enable=gosimple \
|
||||
--enable=unconvert
|
||||
ifeq ($(ENABLELLL), true)
|
||||
LINTOPTS += \
|
||||
--enable=lll \
|
||||
--line-length=80
|
||||
endif
|
||||
LINTOPTS += \
|
||||
--deadline=5m ./... | \
|
||||
tee /dev/stderr
|
||||
LINTPKG = github.com/golangci/golangci-lint/cmd/golangci-lint@v1.15.0
|
||||
LINTBIN = $(GOPATH)/bin/golangci-lint
|
||||
|
||||
get:
|
||||
GO111MODULE=on go get $(GCTPKG)
|
||||
|
||||
linter:
|
||||
GO111MODULE=on go get $(GCTPKG)
|
||||
GO111MODULE=off go get -u $(LINTPKG)
|
||||
$(LINTBIN) --install
|
||||
test -z "$$($(LINTBIN) $(LINTOPTS))"
|
||||
GO111MODULE=on go get $(LINTPKG)
|
||||
test -z "$$($(LINTBIN) run --verbose | tee /dev/stderr)"
|
||||
|
||||
check: linter test
|
||||
|
||||
@@ -46,4 +23,10 @@ install:
|
||||
GO111MODULE=on go install $(LDFLAGS)
|
||||
|
||||
fmt:
|
||||
gofmt -l -w -s $(shell find . -type f -name '*.go')
|
||||
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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
107
config/config.go
107
config/config.go
@@ -37,25 +37,20 @@ const (
|
||||
|
||||
// Constants here hold some messages
|
||||
const (
|
||||
ErrExchangeNameEmpty = "Exchange #%d in config: Exchange name is empty."
|
||||
ErrExchangeAvailablePairsEmpty = "Exchange %s: Available pairs is empty."
|
||||
ErrExchangeEnabledPairsEmpty = "Exchange %s: Enabled pairs is empty."
|
||||
ErrExchangeBaseCurrenciesEmpty = "Exchange %s: Base currencies is empty."
|
||||
ErrExchangeNotFound = "Exchange %s: Not found."
|
||||
ErrNoEnabledExchanges = "No Exchanges enabled."
|
||||
ErrCryptocurrenciesEmpty = "Cryptocurrencies variable is empty."
|
||||
ErrFailureOpeningConfig = "Fatal error opening %s file. Error: %s"
|
||||
ErrCheckingConfigValues = "Fatal error checking config values. Error: %s"
|
||||
ErrSavingConfigBytesMismatch = "Config file %q bytes comparison doesn't match, read %s expected %s."
|
||||
WarningSMSGlobalDefaultOrEmptyValues = "WARNING -- SMS Support disabled due to default or empty Username/Password values."
|
||||
WarningSSMSGlobalSMSContactDefaultOrEmptyValues = "WARNING -- SMS contact #%d Name/Number disabled due to default or empty values."
|
||||
WarningSSMSGlobalSMSNoContacts = "WARNING -- SMS Support disabled due to no enabled contacts."
|
||||
WarningWebserverCredentialValuesEmpty = "WARNING -- Webserver support disabled due to empty Username/Password values."
|
||||
WarningWebserverListenAddressInvalid = "WARNING -- Webserver support disabled due to invalid listen address."
|
||||
WarningWebserverRootWebFolderNotFound = "WARNING -- Webserver support disabled due to missing web folder."
|
||||
WarningExchangeAuthAPIDefaultOrEmptyValues = "WARNING -- Exchange %s: Authenticated API support disabled due to default/empty APIKey/Secret/ClientID values."
|
||||
WarningCurrencyExchangeProvider = "WARNING -- Currency exchange provider invalid valid. Reset to Fixer."
|
||||
WarningPairsLastUpdatedThresholdExceeded = "WARNING -- Exchange %s: Last manual update of available currency pairs has exceeded %d days. Manual update required!"
|
||||
ErrExchangeNameEmpty = "exchange #%d name is empty"
|
||||
ErrExchangeAvailablePairsEmpty = "exchange %s avaiable pairs is emtpy"
|
||||
ErrExchangeEnabledPairsEmpty = "exchange %s enabled pairs is empty"
|
||||
ErrExchangeBaseCurrenciesEmpty = "exchange %s base currencies is empty"
|
||||
ErrExchangeNotFound = "exchange %s not found"
|
||||
ErrNoEnabledExchanges = "no exchanges enabled"
|
||||
ErrCryptocurrenciesEmpty = "cryptocurrencies variable is empty"
|
||||
ErrFailureOpeningConfig = "fatal error opening %s file. Error: %s"
|
||||
ErrCheckingConfigValues = "fatal error checking config values. Error: %s"
|
||||
ErrSavingConfigBytesMismatch = "config file %q bytes comparison doesn't match, read %s expected %s"
|
||||
WarningWebserverCredentialValuesEmpty = "webserver support disabled due to empty Username/Password values"
|
||||
WarningWebserverListenAddressInvalid = "webserver support disabled due to invalid listen address"
|
||||
WarningExchangeAuthAPIDefaultOrEmptyValues = "exchange %s authenticated API support disabled due to default/empty APIKey/Secret/ClientID values"
|
||||
WarningPairsLastUpdatedThresholdExceeded = "exchange %s last manual update of available currency pairs has exceeded %d days. Manual update required!"
|
||||
)
|
||||
|
||||
// Constants here define unset default values displayed in the config.json
|
||||
@@ -257,20 +252,21 @@ func (c *Config) GetCurrencyConfig() CurrencyConfig {
|
||||
|
||||
// GetExchangeBankAccounts returns banking details associated with an exchange
|
||||
// for depositing funds
|
||||
func (c *Config) GetExchangeBankAccounts(exchangeName string, depositingCurrency string) (BankAccount, error) {
|
||||
func (c *Config) GetExchangeBankAccounts(exchangeName, depositingCurrency string) (BankAccount, error) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
for _, exch := range c.Exchanges {
|
||||
if exch.Name == exchangeName {
|
||||
for _, account := range exch.BankAccounts {
|
||||
if common.StringContains(account.SupportedCurrencies, depositingCurrency) {
|
||||
return account, nil
|
||||
for x := range c.Exchanges {
|
||||
if c.Exchanges[x].Name == exchangeName {
|
||||
for y := range c.Exchanges[x].BankAccounts {
|
||||
if common.StringContains(c.Exchanges[x].BankAccounts[y].SupportedCurrencies,
|
||||
depositingCurrency) {
|
||||
return c.Exchanges[x].BankAccounts[y], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return BankAccount{}, fmt.Errorf("Exchange %s bank details not found for %s",
|
||||
return BankAccount{}, fmt.Errorf("exchange %s bank details not found for %s",
|
||||
exchangeName,
|
||||
depositingCurrency)
|
||||
}
|
||||
@@ -287,19 +283,21 @@ func (c *Config) UpdateExchangeBankAccounts(exchangeName string, bankCfg []BankA
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("UpdateExchangeBankAccounts() error exchange %s not found",
|
||||
return fmt.Errorf("exchange %s not found",
|
||||
exchangeName)
|
||||
}
|
||||
|
||||
// GetClientBankAccounts returns banking details used for a given exchange
|
||||
// and currency
|
||||
func (c *Config) GetClientBankAccounts(exchangeName string, targetCurrency string) (BankAccount, error) {
|
||||
func (c *Config) GetClientBankAccounts(exchangeName, targetCurrency string) (BankAccount, error) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
for _, bank := range c.BankAccounts {
|
||||
if (common.StringContains(bank.SupportedExchanges, exchangeName) || bank.SupportedExchanges == "ALL") && common.StringContains(bank.SupportedCurrencies, targetCurrency) {
|
||||
return bank, nil
|
||||
for x := range c.BankAccounts {
|
||||
if (common.StringContains(c.BankAccounts[x].SupportedExchanges, exchangeName) ||
|
||||
c.BankAccounts[x].SupportedExchanges == "ALL") &&
|
||||
common.StringContains(c.BankAccounts[x].SupportedCurrencies, targetCurrency) {
|
||||
return c.BankAccounts[x], nil
|
||||
|
||||
}
|
||||
}
|
||||
@@ -309,13 +307,13 @@ func (c *Config) GetClientBankAccounts(exchangeName string, targetCurrency strin
|
||||
}
|
||||
|
||||
// UpdateClientBankAccounts updates the configuration for a bank
|
||||
func (c *Config) UpdateClientBankAccounts(bankCfg BankAccount) error {
|
||||
func (c *Config) UpdateClientBankAccounts(bankCfg *BankAccount) error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
for i := range c.BankAccounts {
|
||||
if c.BankAccounts[i].BankName == bankCfg.BankName && c.BankAccounts[i].AccountNumber == bankCfg.AccountNumber {
|
||||
c.BankAccounts[i] = bankCfg
|
||||
c.BankAccounts[i] = *bankCfg
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -378,9 +376,9 @@ func (c *Config) GetCommunicationsConfig() CommunicationsConfig {
|
||||
|
||||
// UpdateCommunicationsConfig sets a new updated version of a Communications
|
||||
// configuration
|
||||
func (c *Config) UpdateCommunicationsConfig(config CommunicationsConfig) {
|
||||
func (c *Config) UpdateCommunicationsConfig(config *CommunicationsConfig) {
|
||||
m.Lock()
|
||||
c.Communications = config
|
||||
c.Communications = *config
|
||||
m.Unlock()
|
||||
}
|
||||
|
||||
@@ -563,7 +561,7 @@ func (c *Config) CheckPairConsistency(exchName string) error {
|
||||
exchCfg.EnabledPairs = common.JoinStrings(pair.PairsToStringArray(pairs), ",")
|
||||
}
|
||||
|
||||
err = c.UpdateExchangeConfig(exchCfg)
|
||||
err = c.UpdateExchangeConfig(&exchCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -710,12 +708,12 @@ func (c *Config) GetPrimaryForexProvider() string {
|
||||
}
|
||||
|
||||
// UpdateExchangeConfig updates exchange configurations
|
||||
func (c *Config) UpdateExchangeConfig(e ExchangeConfig) error {
|
||||
func (c *Config) UpdateExchangeConfig(e *ExchangeConfig) error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
for i := range c.Exchanges {
|
||||
if c.Exchanges[i].Name == e.Name {
|
||||
c.Exchanges[i] = e
|
||||
c.Exchanges[i] = *e
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -769,11 +767,11 @@ func (c *Config) CheckExchangeConfigValues() error {
|
||||
exch.APIKey == DefaultUnsetAPIKey ||
|
||||
exch.APISecret == DefaultUnsetAPISecret {
|
||||
c.Exchanges[i].AuthenticatedAPISupport = false
|
||||
log.Warn(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
|
||||
log.Warnf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
|
||||
} else if exch.Name == "ITBIT" || exch.Name == "Bitstamp" || exch.Name == "COINUT" || exch.Name == "CoinbasePro" {
|
||||
if exch.ClientID == "" || exch.ClientID == "ClientID" {
|
||||
c.Exchanges[i].AuthenticatedAPISupport = false
|
||||
log.Warn(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
|
||||
log.Warnf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -798,27 +796,32 @@ func (c *Config) CheckExchangeConfigValues() error {
|
||||
if len(exch.BankAccounts) == 0 {
|
||||
c.Exchanges[i].BankAccounts = append(c.Exchanges[i].BankAccounts, BankAccount{})
|
||||
} else {
|
||||
for _, bankAccount := range exch.BankAccounts {
|
||||
for y := range c.Exchanges[i].BankAccounts {
|
||||
bankAccount := &c.Exchanges[i].BankAccounts[y]
|
||||
if bankAccount.Enabled {
|
||||
if bankAccount.BankName == "" || bankAccount.BankAddress == "" {
|
||||
return fmt.Errorf("banking details for %s is enabled but variables not set",
|
||||
log.Warnf("banking details for %s is enabled but variables not set",
|
||||
exch.Name)
|
||||
bankAccount.Enabled = false
|
||||
}
|
||||
|
||||
if bankAccount.AccountName == "" || bankAccount.AccountNumber == "" {
|
||||
return fmt.Errorf("banking account details for %s variables not set",
|
||||
log.Warnf("banking account details for %s variables not set",
|
||||
exch.Name)
|
||||
bankAccount.Enabled = false
|
||||
}
|
||||
|
||||
if bankAccount.SupportedCurrencies == "" {
|
||||
return fmt.Errorf("banking account details for %s acceptable funding currencies not set",
|
||||
log.Warnf("banking account details for %s acceptable funding currencies not set",
|
||||
exch.Name)
|
||||
bankAccount.Enabled = false
|
||||
}
|
||||
|
||||
if bankAccount.BSBNumber == "" && bankAccount.IBAN == "" &&
|
||||
bankAccount.SWIFTCode == "" {
|
||||
return fmt.Errorf("banking account details for %s critical banking numbers not set",
|
||||
log.Warnf("banking account details for %s critical banking numbers not set",
|
||||
exch.Name)
|
||||
bankAccount.Enabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -954,8 +957,8 @@ func (c *Config) CheckCurrencyConfigValues() error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(c.Currency.Cryptocurrencies) == 0 {
|
||||
if len(c.Cryptocurrencies) != 0 {
|
||||
if c.Currency.Cryptocurrencies == "" {
|
||||
if c.Cryptocurrencies != "" {
|
||||
c.Currency.Cryptocurrencies = c.Cryptocurrencies
|
||||
c.Cryptocurrencies = ""
|
||||
} else {
|
||||
@@ -1038,7 +1041,7 @@ func (c *Config) RetrieveConfigCurrencyPairs(enabledOnly bool) error {
|
||||
|
||||
// CheckLoggerConfig checks to see logger values are present and valid in config
|
||||
// if not creates a default instance of the logger
|
||||
func (c *Config) CheckLoggerConfig() (err error) {
|
||||
func (c *Config) CheckLoggerConfig() error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
@@ -1065,13 +1068,13 @@ func (c *Config) CheckLoggerConfig() (err error) {
|
||||
|
||||
if len(c.Logging.File) > 0 {
|
||||
logPath := path.Join(common.GetDefaultDataDir(runtime.GOOS), "logs")
|
||||
err = common.CheckDir(logPath, true)
|
||||
err := common.CheckDir(logPath, true)
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
log.LogPath = logPath
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFilePath returns the desired config file or the default config file name
|
||||
@@ -1272,7 +1275,7 @@ func (c *Config) CheckConfig() error {
|
||||
if c.Webserver.Enabled {
|
||||
err = c.CheckWebserverConfigValues()
|
||||
if err != nil {
|
||||
log.Errorf(ErrCheckingConfigValues, err)
|
||||
log.Warnf(ErrCheckingConfigValues, err)
|
||||
c.Webserver.Enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(),
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = "~"
|
||||
|
||||
130
events/events.go
130
events/events.go
@@ -60,35 +60,35 @@ func SetComms(commsP *communications.Communications) {
|
||||
|
||||
// AddEvent adds an event to the Events chain and returns an index/eventID
|
||||
// and an error
|
||||
func AddEvent(Exchange, Item, Condition string, CurrencyPair pair.CurrencyPair, Asset, Action string) (int, error) {
|
||||
err := IsValidEvent(Exchange, Item, Condition, Action)
|
||||
func AddEvent(exchange, item, condition string, currencyPair pair.CurrencyPair, asset, action string) (int, error) {
|
||||
err := IsValidEvent(exchange, item, condition, action)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
Event := &Event{}
|
||||
evt := &Event{}
|
||||
|
||||
if len(Events) == 0 {
|
||||
Event.ID = 0
|
||||
evt.ID = 0
|
||||
} else {
|
||||
Event.ID = len(Events) + 1
|
||||
evt.ID = len(Events) + 1
|
||||
}
|
||||
|
||||
Event.Exchange = Exchange
|
||||
Event.Item = Item
|
||||
Event.Condition = Condition
|
||||
Event.Pair = CurrencyPair
|
||||
Event.Asset = Asset
|
||||
Event.Action = Action
|
||||
Event.Executed = false
|
||||
Events = append(Events, Event)
|
||||
return Event.ID, nil
|
||||
evt.Exchange = exchange
|
||||
evt.Item = item
|
||||
evt.Condition = condition
|
||||
evt.Pair = currencyPair
|
||||
evt.Asset = asset
|
||||
evt.Action = action
|
||||
evt.Executed = false
|
||||
Events = append(Events, evt)
|
||||
return evt.ID, nil
|
||||
}
|
||||
|
||||
// RemoveEvent deletes and event by its ID
|
||||
func RemoveEvent(EventID int) bool {
|
||||
func RemoveEvent(eventID int) bool {
|
||||
for i, x := range Events {
|
||||
if x.ID == EventID {
|
||||
if x.ID == eventID {
|
||||
Events = append(Events[:i], Events[i+1:]...)
|
||||
return true
|
||||
}
|
||||
@@ -98,9 +98,8 @@ func RemoveEvent(EventID int) bool {
|
||||
|
||||
// GetEventCounter displays the emount of total events on the chain and the
|
||||
// events that have been executed.
|
||||
func GetEventCounter() (int, int) {
|
||||
total := len(Events)
|
||||
executed := 0
|
||||
func GetEventCounter() (total, executed int) {
|
||||
total = len(Events)
|
||||
|
||||
for _, x := range Events {
|
||||
if x.Executed {
|
||||
@@ -154,78 +153,67 @@ func (e *Event) CheckCondition() bool {
|
||||
|
||||
switch condition[0] {
|
||||
case greaterThan:
|
||||
{
|
||||
if lastPrice > targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
if lastPrice > targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
case greaterThanOrEqual:
|
||||
{
|
||||
if lastPrice >= targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
if lastPrice >= targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
case lessThan:
|
||||
{
|
||||
if lastPrice < targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
if lastPrice < targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
case lessThanOrEqual:
|
||||
{
|
||||
if lastPrice <= targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
if lastPrice <= targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
case isEqual:
|
||||
{
|
||||
if lastPrice == targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
if lastPrice == targetPrice {
|
||||
return e.ExecuteAction()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsValidEvent checks the actions to be taken and returns an error if incorrect
|
||||
func IsValidEvent(Exchange, Item, Condition, Action string) error {
|
||||
Exchange = common.StringToUpper(Exchange)
|
||||
Item = common.StringToUpper(Item)
|
||||
Action = common.StringToUpper(Action)
|
||||
func IsValidEvent(exchange, item, condition, action string) error {
|
||||
exchange = common.StringToUpper(exchange)
|
||||
item = common.StringToUpper(item)
|
||||
action = common.StringToUpper(action)
|
||||
|
||||
if !IsValidExchange(Exchange) {
|
||||
if !IsValidExchange(exchange) {
|
||||
return errExchangeDisabled
|
||||
}
|
||||
|
||||
if !IsValidItem(Item) {
|
||||
if !IsValidItem(item) {
|
||||
return errInvalidItem
|
||||
}
|
||||
|
||||
if !common.StringContains(Condition, ",") {
|
||||
if !common.StringContains(condition, ",") {
|
||||
return errInvalidCondition
|
||||
}
|
||||
|
||||
condition := common.SplitStrings(Condition, ",")
|
||||
c := common.SplitStrings(condition, ",")
|
||||
|
||||
if !IsValidCondition(condition[0]) || len(condition[1]) == 0 {
|
||||
if !IsValidCondition(c[0]) || c[1] == "" {
|
||||
return errInvalidCondition
|
||||
}
|
||||
|
||||
if common.StringContains(Action, ",") {
|
||||
action := common.SplitStrings(Action, ",")
|
||||
if common.StringContains(action, ",") {
|
||||
a := common.SplitStrings(action, ",")
|
||||
|
||||
if action[0] != actionSMSNotify {
|
||||
if a[0] != actionSMSNotify {
|
||||
return errInvalidAction
|
||||
}
|
||||
|
||||
if action[1] != "ALL" {
|
||||
comms.PushEvent(base.Event{Type: action[1]})
|
||||
}
|
||||
} else {
|
||||
if Action != actionConsolePrint && Action != actionTest {
|
||||
return errInvalidAction
|
||||
if a[1] != "ALL" {
|
||||
comms.PushEvent(base.Event{Type: a[1]})
|
||||
}
|
||||
} else if action != actionConsolePrint && action != actionTest {
|
||||
return errInvalidAction
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -252,11 +240,11 @@ func CheckEvents() {
|
||||
}
|
||||
|
||||
// IsValidExchange validates the exchange
|
||||
func IsValidExchange(Exchange string) bool {
|
||||
Exchange = common.StringToUpper(Exchange)
|
||||
func IsValidExchange(exchange string) bool {
|
||||
exchange = common.StringToUpper(exchange)
|
||||
cfg := config.GetConfig()
|
||||
for _, x := range cfg.Exchanges {
|
||||
if x.Name == Exchange && x.Enabled {
|
||||
for x := range cfg.Exchanges {
|
||||
if cfg.Exchanges[x].Name == exchange && cfg.Exchanges[x].Enabled {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -264,8 +252,8 @@ func IsValidExchange(Exchange string) bool {
|
||||
}
|
||||
|
||||
// IsValidCondition validates passed in condition
|
||||
func IsValidCondition(Condition string) bool {
|
||||
switch Condition {
|
||||
func IsValidCondition(condition string) bool {
|
||||
switch condition {
|
||||
case greaterThan, greaterThanOrEqual, lessThan, lessThanOrEqual, isEqual:
|
||||
return true
|
||||
}
|
||||
@@ -273,9 +261,9 @@ func IsValidCondition(Condition string) bool {
|
||||
}
|
||||
|
||||
// IsValidAction validates passed in action
|
||||
func IsValidAction(Action string) bool {
|
||||
Action = common.StringToUpper(Action)
|
||||
switch Action {
|
||||
func IsValidAction(action string) bool {
|
||||
action = common.StringToUpper(action)
|
||||
switch action {
|
||||
case actionSMSNotify, actionConsolePrint, actionTest:
|
||||
return true
|
||||
}
|
||||
@@ -283,11 +271,7 @@ func IsValidAction(Action string) bool {
|
||||
}
|
||||
|
||||
// IsValidItem validates passed in Item
|
||||
func IsValidItem(Item string) bool {
|
||||
Item = common.StringToUpper(Item)
|
||||
switch Item {
|
||||
case itemPrice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
func IsValidItem(item string) bool {
|
||||
item = common.StringToUpper(item)
|
||||
return (item == itemPrice)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(), "")
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user